diff --git a/packages/create-cli/src/actions/creates.ts b/packages/create-cli/src/actions/creates.ts index 3fdce47a..ca09a196 100644 --- a/packages/create-cli/src/actions/creates.ts +++ b/packages/create-cli/src/actions/creates.ts @@ -1,7 +1,7 @@ import * as fs from 'fs' import * as path from 'path' -import prompts from 'prompts' import { isValidUrl } from '../utils/directory.js' +import { askCreateInitialBrowserCheck, askUserWebsite } from '../utils/prompts.js' // Default Playwright-based Browser Check const defaultBrowserCheck = `import { test, expect } from '@playwright/test' @@ -16,29 +16,16 @@ test('Custom Browser Check', async ({ page }) => { })` export async function createCustomBrowserCheck ( - { onCancel }: { onCancel: () => void }, + { projectDirectory, onCancel }: { projectDirectory: string, onCancel: () => void }, ) { - const createInitialBrowserCheckResponse = await prompts({ - type: 'confirm', - name: 'value', - message: 'Would you like to create a custom Playwright-based Browser Check to check a URL?', - initial: true, - }, - { onCancel }, - ) + const { createInitialBrowserCheck } = await askCreateInitialBrowserCheck(onCancel) - if (createInitialBrowserCheckResponse.value) { - const userWebsiteResponse = await prompts({ - type: 'text', - name: 'url', - message: 'Please provide the URL of the site you want to check.', - }, - { onCancel }, - ) + if (createInitialBrowserCheck) { + const { userWebsite } = await askUserWebsite(onCancel) - if (isValidUrl(userWebsiteResponse.url)) { - fs.writeFileSync(path.join(process.cwd(), './__checks__/custom.spec.ts'), - defaultBrowserCheck.replace(/URL_TO_CHECK/i, new URL(userWebsiteResponse.url).toString())) + if (isValidUrl(userWebsite)) { + fs.writeFileSync(path.join(projectDirectory, './__checks__/custom.spec.ts'), + defaultBrowserCheck.replace(/URL_TO_CHECK/i, new URL(userWebsite).toString())) } else { process.stdout.write('Custom check wasn\'t created: the specified URL isn\'t valid.\n') } diff --git a/packages/create-cli/src/actions/dependencies.ts b/packages/create-cli/src/actions/dependencies.ts index 2b8b754f..cbefe68d 100644 --- a/packages/create-cli/src/actions/dependencies.ts +++ b/packages/create-cli/src/actions/dependencies.ts @@ -1,13 +1,13 @@ import * as fs from 'fs' import * as path from 'path' -import prompts from 'prompts' import detectPackageManager from 'which-pm-runs' import { execa } from 'execa' import { spinner } from '../utils/terminal.js' import { hint } from '../utils/messages.js' -import { PackageJson } from '../utils/package.js' +import { PackageJson } from '../utils/directory.js' +import { askInstallDependencies } from '../utils/prompts.js' -export function addDevDependecies (packageJson: PackageJson) { +export function addDevDependecies (projectDirectory: string, packageJson: PackageJson) { if (!Reflect.has(packageJson, 'devDependencies')) { packageJson.devDependencies = {} } @@ -18,18 +18,13 @@ export function addDevDependecies (packageJson: PackageJson) { typescript: 'latest', }) - fs.writeFileSync(path.join(process.cwd(), 'package.json'), JSON.stringify(packageJson, null, 2)) + fs.writeFileSync(path.join(projectDirectory, 'package.json'), JSON.stringify(packageJson, null, 2)) } -export async function installDependencies (targetDir: string = process.cwd()): Promise { - const installDepsResponse = await prompts({ - type: 'confirm', - name: 'installDeps', - message: 'Would you like to install NPM dependencies? (recommended)', - initial: true, - }) +export async function installDependencies (targetDir: string): Promise { + const { installDependencies } = await askInstallDependencies() - if (installDepsResponse.installDeps) { + if (installDependencies) { const packageManager = detectPackageManager()?.name || 'npm' const installExec = execa(packageManager, ['install'], { cwd: targetDir }) const installSpinner = spinner('installing packages') diff --git a/packages/create-cli/src/actions/git.ts b/packages/create-cli/src/actions/git.ts index b79520fa..80d62c7b 100644 --- a/packages/create-cli/src/actions/git.ts +++ b/packages/create-cli/src/actions/git.ts @@ -1,25 +1,20 @@ import * as fs from 'fs' import * as path from 'path' -import prompts from 'prompts' import { hasGitDir, hasGitIgnore } from '../utils/directory.js' import { execaCommand } from 'execa' +import { askInitializeGit } from '../utils/prompts.js' -export async function initGit (targetDir: string = process.cwd()): Promise { - if (hasGitDir()) { +export async function initGit (targetDir: string): Promise { + if (hasGitDir(targetDir)) { return } - const initGitResponse = await prompts({ - type: 'confirm', - name: 'initGit', - message: 'Would you like to initialize a new git repo? (optional)', - initial: true, - }) + const { initializeGit } = await askInitializeGit() - if (initGitResponse.initGit) { + if (initializeGit) { await execaCommand('git init', { cwd: targetDir }) - if (!hasGitIgnore()) { + if (!hasGitIgnore(targetDir)) { const gitIgnore = 'node_modules\n.DS_Store' fs.writeFileSync(path.join(targetDir, '.gitignore'), gitIgnore) } diff --git a/packages/create-cli/src/commands/bootstrap.ts b/packages/create-cli/src/commands/bootstrap.ts index d04afc89..ee760e4c 100644 --- a/packages/create-cli/src/commands/bootstrap.ts +++ b/packages/create-cli/src/commands/bootstrap.ts @@ -1,45 +1,27 @@ -import Debug from 'debug' import { Command, Flags } from '@oclif/core' -import { uniqueNamesGenerator, colors, animals } from 'unique-names-generator' import prompts from 'prompts' -import chalk from 'chalk' -import { isValidProjectDirectory, copyTemporaryFiles, usePackageName } from '../utils/directory.js' import { getUserGreeting, getVersion, header, bail, - hint, footer, + hint, } from '../utils/messages.js' -import { createCustomBrowserCheck } from '../actions/creates.js' -import { addDevDependecies, installDependencies } from '../actions/dependencies.js' -import { hasPackageJsonFile, readPackageJson } from '../utils/package.js' -import { copyTemplate } from '../actions/template.js' -import { initGit } from '../actions/git.js' +import { hasPackageJsonFile } from '../utils/directory.js' +import { + createProject, + getProjectDirectory, + installDependenciesAndInitGit, + installWithinProject, +} from '../utils/installation.js' +import path from 'path' /** * This code is heavily inspired by the amazing create-astro package over at * https://github.com/withastro/astro/tree/main/packages/create-astro */ -const debug = Debug('checkly:create-cli') -const templateBaseRepo = 'checkly/checkly-cli/examples' - -function generateProjectName (): string { - return uniqueNamesGenerator({ - dictionaries: [colors, animals], - separator: '-', - length: 2, - style: 'lowerCase', - }) -} - -function onCancel (): void { - bail() - process.exit(1) -} - export default class Bootstrap extends Command { static description = 'Bootstrap a Checkly project' @@ -54,6 +36,12 @@ export default class Bootstrap extends Command { const { flags } = await this.parse(Bootstrap) const { template } = flags + const onCancel = (): void => { + bail() + // TODO: replace this with oclif error() + process.exit(1) + } + // This overrides the template prompt and skips to the next prompt if (template) { prompts.override({ template }) @@ -63,103 +51,20 @@ export default class Bootstrap extends Command { await header(version, greeting) - // Init Checkly CLI for an existing project - if (hasPackageJsonFile()) { - debug('Existing package.json detected') - - const projectInitResponse = await prompts({ - type: 'confirm', - name: 'useDirectory', - message: 'It looks like you are already in a project, would you like to initialize?', - initial: true, - }, - { onCancel }, - ) - - if (projectInitResponse.useDirectory) { - const packageJson = readPackageJson() - const temporaryDir = generateProjectName() - - debug('Add dependencies to existing package.json') - addDevDependecies(packageJson) - - debug('Copy boilerplate project to temporary folder') - await copyTemplate({ - template: 'boilerplate-project', - templatePath: `github:${templateBaseRepo}/boilerplate-project#v${version}`, - targetDir: temporaryDir, - }) + const projectDirectory = await getProjectDirectory({ onCancel }) - copyTemporaryFiles(temporaryDir) - usePackageName(packageJson.name) - - debug('Create custom Browser check') - await createCustomBrowserCheck({ onCancel }) - - debug('Install npm dependencies') - await installDependencies() - - debug('Init .git & .gitignore') - await initGit() - - await footer() - - return - } + if (hasPackageJsonFile(projectDirectory)) { + // Init Checkly CLI for an existing project + await installWithinProject({ projectDirectory, version, onCancel }) + } else { + // Create a project from the scratch using a template + await hint('Cool.', `Your project will be created in the directory "${projectDirectory}"`) + await createProject({ projectDirectory, version, onCancel }) } - debug('Ask for directory name') - - const projectDirResponse = await prompts({ - type: 'text', - name: 'projectDirectory', - message: 'Where do you want to create your new project?', - initial: generateProjectName(), - validate (dirName) { - if (!isValidProjectDirectory(dirName)) { - return `"${chalk.bold(dirName)}" is not empty!` - } - return true - }, - }, - { onCancel }, - ) - - const targetDir = projectDirResponse.projectDirectory - - if (!targetDir) { - process.exit(1) - } - - await hint('Cool.', `Your project will be created in the directory "${targetDir}"`) - - const templateResponse = await prompts({ - type: 'select', - name: 'template', - message: 'Which template would you like to use for your new project', - choices: [ - { value: 'advanced-project', title: 'An advanced TypeScript project with multiple examples and best practices (recommended)' }, - { value: 'advanced-project-js', title: 'An advanced JavaScript project with multiple examples and best practices (recommended)' }, - { value: 'boilerplate-project', title: 'A boilerplate TypeScript project with basic config' }, - { value: 'boilerplate-project-js', title: 'A boilerplate JavaScript project with basic config' }, - ], - }, - { onCancel }, - ) - - debug('Downloading template') - await copyTemplate({ - template: templateResponse.template, - templatePath: `github:${templateBaseRepo}/${templateResponse.template}#v${version}`, - targetDir, - }) - - debug('Install npm dependencies') - await installDependencies(targetDir) - - debug('Init .git & .gitignore') - await initGit(targetDir) + // ask and install dependencies and initialize git + await installDependenciesAndInitGit({ projectDirectory }) - await footer(targetDir) + await footer(projectDirectory) } } diff --git a/packages/create-cli/src/utils/__tests__/directory.spec.ts b/packages/create-cli/src/utils/__tests__/directory.spec.ts index bcb315d1..9efb045f 100644 --- a/packages/create-cli/src/utils/__tests__/directory.spec.ts +++ b/packages/create-cli/src/utils/__tests__/directory.spec.ts @@ -1,5 +1,5 @@ import * as path from 'path' -import { isValidProjectDirectory } from '../directory' +import { hasPackageJsonFile, isValidProjectDirectory, readPackageJson } from '../directory' describe('isValidProjectDirectory()', () => { type TestTuple = [string, boolean] @@ -7,8 +7,39 @@ describe('isValidProjectDirectory()', () => { const cases: TestTuple[] = [ [path.join(__dirname, './fixtures/valid-dir'), true], [path.join(__dirname, './fixtures/invalid-dir-1'), false], + [path.join(__dirname, './fixtures/empty-project'), false], + [path.join(__dirname, './fixtures/initiated-project'), true], + [path.join(__dirname, './fixtures/checkly-project'), true], ] test.each(cases)('directory %s should return valid = %s', (dir, expected) => { expect(isValidProjectDirectory(dir)).toEqual(expected) }) }) + +describe('hasPackageJsonFile()', () => { + type TestTuple = [string, boolean] + const cases: TestTuple[] = [ + [path.join(__dirname, './fixtures/empty-project/'), false], + [path.join(__dirname, './fixtures/initiated-project/'), true], + ] + test.each(cases)('directory %s should return valid = %s', (dir, expected) => { + expect(hasPackageJsonFile(dir)).toEqual(expected) + }) +}) + +describe('readPackageJson()', () => { + type TestTuple = [string, string] + const cases: TestTuple[] = [ + [path.join(__dirname, './fixtures/empty-project/'), ''], + [path.join(__dirname, './fixtures/initiated-project/'), 'initiated-project'], + [path.join(__dirname, './fixtures/checkly-project/'), 'checkly-project'], + ] + test.each(cases)('directory %s should return name = %s', (dir, expected) => { + try { + expect(readPackageJson(dir).name).toEqual(expected) + } catch (error: any) { + expect(expected).toEqual('') + expect(error.message).toContain('ENOENT: no such file or directory') + } + }) +}) diff --git a/packages/create-cli/src/utils/__tests__/fixtures/checkly-project/checkly.config.ts b/packages/create-cli/src/utils/__tests__/fixtures/checkly-project/checkly.config.ts new file mode 100644 index 00000000..b1f7b7f4 --- /dev/null +++ b/packages/create-cli/src/utils/__tests__/fixtures/checkly-project/checkly.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'checkly' + +const config = defineConfig({ + projectName: 'My Project', + logicalId: 'my-project', + repoUrl: 'https://github.com/checkly/checkly-cli', + checks: { + frequency: 10, + locations: ['us-east-1', 'eu-west-1'], + tags: ['mac'], + runtimeId: '2023.02', + checkMatch: '**/__checks__/**/*.check.ts', + browserChecks: { + testMatch: '**/__checks__/**/*.spec.ts', + }, + }, + cli: { + runLocation: 'eu-west-1', + reporters: ['list'], + }, +}) + +export default config diff --git a/packages/create-cli/src/utils/__tests__/fixtures/checkly-project/package.json b/packages/create-cli/src/utils/__tests__/fixtures/checkly-project/package.json new file mode 100644 index 00000000..2214622f --- /dev/null +++ b/packages/create-cli/src/utils/__tests__/fixtures/checkly-project/package.json @@ -0,0 +1,17 @@ +{ + "name": "checkly-project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "commonjs", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "checkly": "latest", + "ts-node": "10.9.1", + "typescript": "4.9.5" + } +} diff --git a/packages/create-cli/src/utils/__tests__/fixtures/empty-project/README.md b/packages/create-cli/src/utils/__tests__/fixtures/empty-project/README.md new file mode 100644 index 00000000..fa24fec1 --- /dev/null +++ b/packages/create-cli/src/utils/__tests__/fixtures/empty-project/README.md @@ -0,0 +1 @@ +This is an empty project \ No newline at end of file diff --git a/packages/create-cli/src/utils/__tests__/fixtures/initiated-project/package.json b/packages/create-cli/src/utils/__tests__/fixtures/initiated-project/package.json new file mode 100644 index 00000000..7dea701c --- /dev/null +++ b/packages/create-cli/src/utils/__tests__/fixtures/initiated-project/package.json @@ -0,0 +1,11 @@ +{ + "name": "initiated-project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/packages/create-cli/src/utils/directory.ts b/packages/create-cli/src/utils/directory.ts index da8db27d..7c5824be 100644 --- a/packages/create-cli/src/utils/directory.ts +++ b/packages/create-cli/src/utils/directory.ts @@ -1,34 +1,55 @@ import * as fs from 'fs' import * as path from 'path' +import { uniqueNamesGenerator, colors, animals } from 'unique-names-generator' + +export interface PackageJson { + name: string; + devDependencies: { + [key: string]: string; + }; +} + +export function hasPackageJsonFile (dirPath: string) { + return fs.existsSync(path.join(dirPath, 'package.json')) +} + +export function readPackageJson (dirPath: string): PackageJson { + return JSON.parse(fs.readFileSync(path.join(dirPath, 'package.json'), 'utf-8')) +} export function isValidProjectDirectory (dirPath: string) { if (!fs.existsSync(dirPath)) { return true } + // allow already initiated projects directory + if (hasPackageJsonFile(dirPath)) { + return true + } + // only allow non initiated directory if it's empty return fs.readdirSync(dirPath).length === 0 } -export function hasGitDir () { - return fs.existsSync('./.git') +export function hasGitDir (dirPath: string) { + return fs.existsSync(path.join(dirPath, './.git')) } -export function copyTemporaryFiles (dirPath: string) { +export function copyTemporaryFiles (dirPath: string, tempPath: string) { const FILE_TO_KEEP = ['__checks__', 'checkly.config.ts'] if (FILE_TO_KEEP.some(file => - fs.existsSync(path.join(process.cwd(), file)))) { + fs.existsSync(path.join(dirPath, file)))) { // eslint-disable-next-line no-console - console.error('It looks like you already have "__checks__" folder or "checkly.config.ts". ' + - 'Please, remove them and try again.') - fs.rmSync(dirPath, { recursive: true }) + process.stderr.write('It looks like you already have "__checks__" folder or "checkly.config.ts". ' + + 'Please, remove them and try again.' + '\n') + fs.rmSync(tempPath, { recursive: true }) process.exit(1) } else { for (const file of FILE_TO_KEEP) { - fs.renameSync(`${dirPath}/${file}`, path.join(process.cwd(), file)) + fs.renameSync(`${tempPath}/${file}`, path.join(dirPath, file)) } } - fs.rmSync(dirPath, { recursive: true }) + fs.rmSync(tempPath, { recursive: true }) } export function usePackageName (packageName: string) { @@ -40,8 +61,8 @@ export function usePackageName (packageName: string) { .replace(/boilerplate-project/, packageName), ) } -export function hasGitIgnore () { - return fs.existsSync(path.join(process.cwd(), '.gitignore')) +export function hasGitIgnore (dirPath: string) { + return fs.existsSync(path.join(dirPath, '.gitignore')) } export function isValidUrl (string: string) { @@ -52,3 +73,12 @@ export function isValidUrl (string: string) { return false } } + +export function generateProjectName (): string { + return uniqueNamesGenerator({ + dictionaries: [colors, animals], + separator: '-', + length: 2, + style: 'lowerCase', + }) +} diff --git a/packages/create-cli/src/utils/installation.ts b/packages/create-cli/src/utils/installation.ts new file mode 100644 index 00000000..a8a4ed40 --- /dev/null +++ b/packages/create-cli/src/utils/installation.ts @@ -0,0 +1,76 @@ +import Debug from 'debug' +import { copyTemporaryFiles, generateProjectName, usePackageName, readPackageJson, hasPackageJsonFile } from './directory.js' +import { askInitializeProject, askProjectDirectory, askTemplate } from './prompts.js' +import { addDevDependecies, installDependencies } from '../actions/dependencies.js' +import { copyTemplate } from '../actions/template.js' +import { createCustomBrowserCheck } from '../actions/creates.js' +import { initGit } from '../actions/git.js' + +const debug = Debug('checkly:create-cli') +const templateBaseRepo = 'checkly/checkly-cli/examples' + +export async function getProjectDirectory ({ onCancel }: { onCancel: () => void }): Promise { + debug('Ask or detect directory name') + const cwd = process.cwd() + + // if directory has a package.json, do not ask project directory and use CWD + const { projectDirectory } = hasPackageJsonFile(cwd) + ? { projectDirectory: cwd } + : await askProjectDirectory(onCancel) + + if (!projectDirectory) { + process.stderr.write('You must provide a valid directory name. Please try again.') + } + + return projectDirectory +} + +export async function installWithinProject ( + { projectDirectory, version, onCancel }: { projectDirectory: string, version: string, onCancel: () => void }) { + debug('Existing package.json detected') + const { initializeProject } = await askInitializeProject(onCancel) + + if (initializeProject) { + const packageJson = readPackageJson(projectDirectory) + const temporaryDir = generateProjectName() + + debug('Add dependencies to existing package.json') + addDevDependecies(projectDirectory, packageJson) + + debug('Copy boilerplate project to temporary folder') + await copyTemplate({ + template: 'boilerplate-project', + templatePath: `github:${templateBaseRepo}/boilerplate-project#v${version}`, + targetDir: temporaryDir, + }) + + copyTemporaryFiles(projectDirectory, temporaryDir) + usePackageName(packageJson.name) + + debug('Create custom Browser check') + await createCustomBrowserCheck({ projectDirectory, onCancel }) + } else { + process.exit(0) + } +} + +export async function createProject ( + { projectDirectory, version, onCancel }: { projectDirectory: string, version: string, onCancel: () => void }) { + const templateResponse = await askTemplate(onCancel) + + debug('Downloading template') + await copyTemplate({ + template: templateResponse.template, + templatePath: `github:${templateBaseRepo}/${templateResponse.template}#v${version}`, + targetDir: projectDirectory, + }) +} + +export async function installDependenciesAndInitGit ( + { projectDirectory }: { projectDirectory: string }) { + debug('Install npm dependencies') + await installDependencies(projectDirectory) + + debug('Init .git & .gitignore') + await initGit(projectDirectory) +} diff --git a/packages/create-cli/src/utils/messages.ts b/packages/create-cli/src/utils/messages.ts index c53a374f..5d23a3a4 100644 --- a/packages/create-cli/src/utils/messages.ts +++ b/packages/create-cli/src/utils/messages.ts @@ -55,7 +55,7 @@ export async function footer (targetDir?: string): Promise { if (targetDir) { await sleep(200) console.log( - `${prefix}> Enter your project directory using ${chalk.cyan(`cd ./${targetDir}`)}`, + `${prefix}> Enter your project directory using ${chalk.cyan(`cd ${targetDir}`)}`, ) } await sleep(200) diff --git a/packages/create-cli/src/utils/package.ts b/packages/create-cli/src/utils/package.ts deleted file mode 100644 index c484b690..00000000 --- a/packages/create-cli/src/utils/package.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as fs from 'fs' -import * as path from 'path' - -export interface PackageJson { - name: string; - devDependencies: { - [key: string]: string; - }; -} - -export function hasPackageJsonFile () { - return fs.existsSync(path.join(process.cwd(), 'package.json')) -} - -export function readPackageJson (): PackageJson { - return JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')) -} diff --git a/packages/create-cli/src/utils/prompts.ts b/packages/create-cli/src/utils/prompts.ts new file mode 100644 index 00000000..0f0b6026 --- /dev/null +++ b/packages/create-cli/src/utils/prompts.ts @@ -0,0 +1,79 @@ +import * as path from 'path' +import * as chalk from 'chalk' +import prompts from 'prompts' +import { generateProjectName, isValidProjectDirectory } from '../utils/directory.js' + +export function askInitializeProject (onCancel: any): Promise<{ initializeProject: boolean }> { + return prompts({ + type: 'confirm', + name: 'initializeProject', + message: 'It looks like you are already in a project, would you like to initialize?', + initial: true, + }, { onCancel }) +} + +export function askProjectDirectory (onCancel: any): Promise<{ projectDirectory: string }> { + return prompts({ + type: 'text', + name: 'projectDirectory', + message: 'Where do you want to create your new project?', + initial: generateProjectName(), + format: val => path.resolve(val), + validate (dirName) { + const absolutePath = path.resolve(dirName) + if (!isValidProjectDirectory(absolutePath)) { + return `"${chalk.bold(absolutePath)}" is not empty!` + } + return true + }, + }, { onCancel }) +} + +export function askTemplate (onCancel: any): Promise<{ template: string }> { + return prompts({ + type: 'select', + name: 'template', + message: 'Which template would you like to use for your new project?', + choices: [ + { value: 'advanced-project', title: 'An advanced TypeScript project with multiple examples and best practices (recommended)' }, + { value: 'advanced-project-js', title: 'An advanced JavaScript project with multiple examples and best practices' }, + { value: 'boilerplate-project', title: 'A boilerplate TypeScript project with basic config' }, + { value: 'boilerplate-project-js', title: 'A boilerplate JavaScript project with basic config' }, + ], + }, { onCancel }) +} + +export function askCreateInitialBrowserCheck (onCancel: any): Promise<{ createInitialBrowserCheck: boolean }> { + return prompts({ + type: 'confirm', + name: 'createInitialBrowserCheck', + message: 'Would you like to create a custom Playwright-based Browser Check to check a URL?', + initial: true, + }, { onCancel }) +} + +export function askUserWebsite (onCancel: any): Promise<{ userWebsite: string }> { + return prompts({ + type: 'text', + name: 'userWebsite', + message: 'Please provide the URL of the site you want to check.', + }, { onCancel }) +} + +export function askInstallDependencies (): Promise<{ installDependencies: boolean }> { + return prompts({ + type: 'confirm', + name: 'installDependencies', + message: 'Would you like to install NPM dependencies? (recommended)', + initial: true, + }, { onCancel: () => true }) +} + +export function askInitializeGit (): Promise<{ initializeGit: boolean }> { + return prompts({ + type: 'confirm', + name: 'initializeGit', + message: 'Would you like to initialize a new git repo? (optional)', + initial: true, + }, { onCancel: () => true }) +}