diff --git a/packages/cta-cli/src/cli.ts b/packages/cta-cli/src/cli.ts index e81b3c40..bc35192f 100644 --- a/packages/cta-cli/src/cli.ts +++ b/packages/cta-cli/src/cli.ts @@ -373,6 +373,11 @@ Remove your node_modules directory and package lock file and re-install.`, '--add-on-config ', 'JSON string with add-on configuration options', ) + .option( + '-f, --force', + 'force project creation even if the target directory is not empty', + false, + ) program.action(async (projectName: string, options: CliOptions) => { if (options.listAddOns) { diff --git a/packages/cta-cli/src/options.ts b/packages/cta-cli/src/options.ts index 365de8b5..d22bb900 100644 --- a/packages/cta-cli/src/options.ts +++ b/packages/cta-cli/src/options.ts @@ -1,4 +1,5 @@ -import { intro } from '@clack/prompts' +import fs from 'node:fs' +import { cancel, confirm, intro, isCancel } from '@clack/prompts' import { finalizeAddOns, @@ -12,8 +13,8 @@ import { getProjectName, promptForAddOnOptions, selectAddOns, - selectGit, selectDeployment, + selectGit, selectPackageManager, selectRouterType, selectTailwind, @@ -42,6 +43,7 @@ export async function promptForCreateOptions( options.framework = getFrameworkById(cliOptions.framework || 'react-cra')! + // Validate project name if (cliOptions.projectName) { const { valid, error } = validateProjectName(cliOptions.projectName) if (!valid) { @@ -53,6 +55,23 @@ export async function promptForCreateOptions( options.projectName = await getProjectName() } + // Check if target directory is empty + if ( + !cliOptions.force && + fs.existsSync(options.projectName) && + fs.readdirSync(options.projectName).length > 0 + ) { + const shouldContinue = await confirm({ + message: `Target directory ${options.projectName} is not empty. Do you want to continue?`, + initialValue: true, + }) + + if (isCancel(shouldContinue) || !shouldContinue) { + cancel('Operation cancelled.') + process.exit(0) + } + } + // Router type selection if (forcedMode) { options.mode = forcedMode diff --git a/packages/cta-cli/src/types.ts b/packages/cta-cli/src/types.ts index f52dd14f..e03e75de 100644 --- a/packages/cta-cli/src/types.ts +++ b/packages/cta-cli/src/types.ts @@ -21,4 +21,5 @@ export interface CliOptions { interactive?: boolean ui?: boolean addOnConfig?: string + force?: boolean } diff --git a/packages/cta-cli/src/ui-prompts.ts b/packages/cta-cli/src/ui-prompts.ts index c095c9c1..d58c2ff4 100644 --- a/packages/cta-cli/src/ui-prompts.ts +++ b/packages/cta-cli/src/ui-prompts.ts @@ -18,7 +18,6 @@ import { validateProjectName } from './utils.js' import type { AddOn, PackageManager } from '@tanstack/cta-engine' import type { Framework } from '@tanstack/cta-engine/dist/types/types.js' -import { InitialData } from '../../cta-ui/src/types' export async function getProjectName(): Promise { const value = await text({