@tanstack/cta-cli 0.47.0 → 0.48.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @tanstack/cta-cli
2
2
 
3
+ ## 0.48.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`cdb6eef`](https://github.com/TanStack/create-tsrouter-app/commit/cdb6eef79274a4041eae5e8cd9d43539c9a9a77a)]:
8
+ - @tanstack/cta-engine@0.49.0
9
+ - @tanstack/cta-ui@0.48.1
10
+
11
+ ## 0.48.0
12
+
13
+ ### Minor Changes
14
+
15
+ - no will prompt about overriding a directory that has contents ([#289](https://github.com/TanStack/create-tsrouter-app/pull/289))
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [[`3087532`](https://github.com/TanStack/create-tsrouter-app/commit/308753249af11bf5c9e374789e973a934c753520)]:
20
+ - @tanstack/cta-engine@0.48.0
21
+ - @tanstack/cta-ui@0.48.0
22
+
3
23
  ## 0.47.0
4
24
 
5
25
  ### Minor Changes
package/dist/cli.js CHANGED
@@ -212,12 +212,14 @@ Remove your node_modules directory and package lock file and re-install.`);
212
212
  });
213
213
  }
214
214
  if (toolchains.size > 0) {
215
- program.option(`--toolchain <${Array.from(toolchains).join('|')}>`, `Explicitly tell the CLI to use this toolchain`, (value) => {
215
+ program
216
+ .option(`--toolchain <${Array.from(toolchains).join('|')}>`, `Explicitly tell the CLI to use this toolchain`, (value) => {
216
217
  if (!toolchains.has(value)) {
217
218
  throw new InvalidArgumentError(`Invalid toolchain: ${value}. The following are allowed: ${Array.from(toolchains).join(', ')}`);
218
219
  }
219
220
  return value;
220
- });
221
+ })
222
+ .option('--no-toolchain', 'skip toolchain selection');
221
223
  }
222
224
  program
223
225
  .option('--interactive', 'interactive mode', false)
@@ -237,7 +239,8 @@ Remove your node_modules directory and package lock file and re-install.`);
237
239
  .option('--mcp', 'run the MCP server', false)
238
240
  .option('--mcp-sse', 'run the MCP server in SSE mode', false)
239
241
  .option('--ui', 'Add with the UI')
240
- .option('--add-on-config <config>', 'JSON string with add-on configuration options');
242
+ .option('--add-on-config <config>', 'JSON string with add-on configuration options')
243
+ .option('-f, --force', 'force project creation even if the target directory is not empty', false);
241
244
  program.action(async (projectName, options) => {
242
245
  if (options.listAddOns) {
243
246
  const addOns = await getAllAddOns(getFrameworkByName(options.framework || defaultFramework || 'React'), defaultMode ||
package/dist/options.js CHANGED
@@ -1,10 +1,12 @@
1
- import { intro } from '@clack/prompts';
1
+ import fs from 'node:fs';
2
+ import { cancel, confirm, intro, isCancel } from '@clack/prompts';
2
3
  import { finalizeAddOns, getFrameworkById, getPackageManager, populateAddOnOptionsDefaults, readConfigFile, } from '@tanstack/cta-engine';
3
- import { getProjectName, promptForAddOnOptions, selectAddOns, selectGit, selectDeployment, selectPackageManager, selectRouterType, selectTailwind, selectToolchain, selectTypescript, } from './ui-prompts.js';
4
+ import { getProjectName, promptForAddOnOptions, selectAddOns, selectDeployment, selectGit, selectPackageManager, selectRouterType, selectTailwind, selectToolchain, selectTypescript, } from './ui-prompts.js';
4
5
  import { getCurrentDirectoryName, sanitizePackageName, validateProjectName, } from './utils.js';
5
6
  export async function promptForCreateOptions(cliOptions, { forcedAddOns = [], forcedMode, showDeploymentOptions = false, }) {
6
7
  const options = {};
7
8
  options.framework = getFrameworkById(cliOptions.framework || 'react-cra');
9
+ // Validate project name
8
10
  if (cliOptions.projectName) {
9
11
  // Handle "." as project name - use sanitized current directory name
10
12
  if (cliOptions.projectName === '.') {
@@ -22,6 +24,19 @@ export async function promptForCreateOptions(cliOptions, { forcedAddOns = [], fo
22
24
  else {
23
25
  options.projectName = await getProjectName();
24
26
  }
27
+ // Check if target directory is empty
28
+ if (!cliOptions.force &&
29
+ fs.existsSync(options.projectName) &&
30
+ fs.readdirSync(options.projectName).length > 0) {
31
+ const shouldContinue = await confirm({
32
+ message: `Target directory ${options.projectName} is not empty. Do you want to continue?`,
33
+ initialValue: true,
34
+ });
35
+ if (isCancel(shouldContinue) || !shouldContinue) {
36
+ cancel('Operation cancelled.');
37
+ process.exit(0);
38
+ }
39
+ }
25
40
  // Router type selection
26
41
  if (forcedMode) {
27
42
  options.mode = forcedMode;
@@ -119,6 +134,9 @@ export async function promptForCreateOptions(cliOptions, { forcedAddOns = [], fo
119
134
  options.addOnOptions = { ...defaultOptions, ...userOptions };
120
135
  }
121
136
  options.git = cliOptions.git || (await selectGit());
137
+ if (cliOptions.install === false) {
138
+ options.install = false;
139
+ }
122
140
  return options;
123
141
  }
124
142
  export async function promptForAddOns() {
@@ -5,7 +5,7 @@ export interface CliOptions {
5
5
  framework?: string;
6
6
  tailwind?: boolean;
7
7
  packageManager?: PackageManager;
8
- toolchain?: string;
8
+ toolchain?: string | false;
9
9
  deployment?: string;
10
10
  projectName?: string;
11
11
  git?: boolean;
@@ -21,4 +21,5 @@ export interface CliOptions {
21
21
  devWatch?: string;
22
22
  install?: boolean;
23
23
  addOnConfig?: string;
24
+ force?: boolean;
24
25
  }
@@ -7,6 +7,6 @@ export declare function selectTailwind(): Promise<boolean>;
7
7
  export declare function selectPackageManager(): Promise<PackageManager>;
8
8
  export declare function selectAddOns(framework: Framework, mode: string, type: string, message: string, forcedAddOns?: Array<string>, allowMultiple?: boolean): Promise<Array<string>>;
9
9
  export declare function selectGit(): Promise<boolean>;
10
- export declare function selectToolchain(framework: Framework, toolchain?: string): Promise<string | undefined>;
10
+ export declare function selectToolchain(framework: Framework, toolchain?: string | false): Promise<string | undefined>;
11
11
  export declare function promptForAddOnOptions(addOnIds: Array<string>, framework: Framework): Promise<Record<string, Record<string, any>>>;
12
12
  export declare function selectDeployment(framework: Framework, deployment?: string): Promise<string | undefined>;
@@ -147,6 +147,9 @@ export async function selectGit() {
147
147
  return git;
148
148
  }
149
149
  export async function selectToolchain(framework, toolchain) {
150
+ if (toolchain === false) {
151
+ return undefined;
152
+ }
150
153
  const toolchains = new Set();
151
154
  for (const addOn of framework.getAddOns()) {
152
155
  if (addOn.type === 'toolchain') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/cta-cli",
3
- "version": "0.47.0",
3
+ "version": "0.48.1",
4
4
  "description": "Tanstack Application Builder CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,8 +35,8 @@
35
35
  "tempy": "^3.1.0",
36
36
  "validate-npm-package-name": "^7.0.0",
37
37
  "zod": "^3.24.2",
38
- "@tanstack/cta-engine": "0.47.0",
39
- "@tanstack/cta-ui": "0.47.0"
38
+ "@tanstack/cta-engine": "0.49.0",
39
+ "@tanstack/cta-ui": "0.48.1"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@tanstack/config": "^0.16.2",
package/src/cli.ts CHANGED
@@ -338,20 +338,22 @@ Remove your node_modules directory and package lock file and re-install.`,
338
338
  }
339
339
 
340
340
  if (toolchains.size > 0) {
341
- program.option<string>(
342
- `--toolchain <${Array.from(toolchains).join('|')}>`,
343
- `Explicitly tell the CLI to use this toolchain`,
344
- (value) => {
345
- if (!toolchains.has(value)) {
346
- throw new InvalidArgumentError(
347
- `Invalid toolchain: ${value}. The following are allowed: ${Array.from(
348
- toolchains,
349
- ).join(', ')}`,
350
- )
351
- }
352
- return value
353
- },
354
- )
341
+ program
342
+ .option<string>(
343
+ `--toolchain <${Array.from(toolchains).join('|')}>`,
344
+ `Explicitly tell the CLI to use this toolchain`,
345
+ (value) => {
346
+ if (!toolchains.has(value)) {
347
+ throw new InvalidArgumentError(
348
+ `Invalid toolchain: ${value}. The following are allowed: ${Array.from(
349
+ toolchains,
350
+ ).join(', ')}`,
351
+ )
352
+ }
353
+ return value
354
+ },
355
+ )
356
+ .option('--no-toolchain', 'skip toolchain selection')
355
357
  }
356
358
 
357
359
  program
@@ -386,6 +388,11 @@ Remove your node_modules directory and package lock file and re-install.`,
386
388
  '--add-on-config <config>',
387
389
  'JSON string with add-on configuration options',
388
390
  )
391
+ .option(
392
+ '-f, --force',
393
+ 'force project creation even if the target directory is not empty',
394
+ false,
395
+ )
389
396
 
390
397
  program.action(async (projectName: string, options: CliOptions) => {
391
398
  if (options.listAddOns) {
package/src/options.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { intro } from '@clack/prompts'
1
+ import fs from 'node:fs'
2
+ import { cancel, confirm, intro, isCancel } from '@clack/prompts'
2
3
 
3
4
  import {
4
5
  finalizeAddOns,
@@ -12,8 +13,8 @@ import {
12
13
  getProjectName,
13
14
  promptForAddOnOptions,
14
15
  selectAddOns,
15
- selectGit,
16
16
  selectDeployment,
17
+ selectGit,
17
18
  selectPackageManager,
18
19
  selectRouterType,
19
20
  selectTailwind,
@@ -46,6 +47,7 @@ export async function promptForCreateOptions(
46
47
 
47
48
  options.framework = getFrameworkById(cliOptions.framework || 'react-cra')!
48
49
 
50
+ // Validate project name
49
51
  if (cliOptions.projectName) {
50
52
  // Handle "." as project name - use sanitized current directory name
51
53
  if (cliOptions.projectName === '.') {
@@ -62,6 +64,23 @@ export async function promptForCreateOptions(
62
64
  options.projectName = await getProjectName()
63
65
  }
64
66
 
67
+ // Check if target directory is empty
68
+ if (
69
+ !cliOptions.force &&
70
+ fs.existsSync(options.projectName) &&
71
+ fs.readdirSync(options.projectName).length > 0
72
+ ) {
73
+ const shouldContinue = await confirm({
74
+ message: `Target directory ${options.projectName} is not empty. Do you want to continue?`,
75
+ initialValue: true,
76
+ })
77
+
78
+ if (isCancel(shouldContinue) || !shouldContinue) {
79
+ cancel('Operation cancelled.')
80
+ process.exit(0)
81
+ }
82
+ }
83
+
65
84
  // Router type selection
66
85
  if (forcedMode) {
67
86
  options.mode = forcedMode
@@ -191,6 +210,9 @@ export async function promptForCreateOptions(
191
210
  }
192
211
 
193
212
  options.git = cliOptions.git || (await selectGit())
213
+ if (cliOptions.install === false) {
214
+ options.install = false
215
+ }
194
216
 
195
217
  return options
196
218
  }
package/src/types.ts CHANGED
@@ -7,7 +7,7 @@ export interface CliOptions {
7
7
  framework?: string
8
8
  tailwind?: boolean
9
9
  packageManager?: PackageManager
10
- toolchain?: string
10
+ toolchain?: string | false
11
11
  deployment?: string
12
12
  projectName?: string
13
13
  git?: boolean
@@ -23,4 +23,5 @@ export interface CliOptions {
23
23
  devWatch?: string
24
24
  install?: boolean
25
25
  addOnConfig?: string
26
+ force?: boolean
26
27
  }
package/src/ui-prompts.ts CHANGED
@@ -18,7 +18,6 @@ import { validateProjectName } from './utils.js'
18
18
  import type { AddOn, PackageManager } from '@tanstack/cta-engine'
19
19
 
20
20
  import type { Framework } from '@tanstack/cta-engine/dist/types/types.js'
21
- import { InitialData } from '../../cta-ui/src/types'
22
21
 
23
22
  export async function getProjectName(): Promise<string> {
24
23
  const value = await text({
@@ -197,8 +196,12 @@ export async function selectGit(): Promise<boolean> {
197
196
 
198
197
  export async function selectToolchain(
199
198
  framework: Framework,
200
- toolchain?: string,
199
+ toolchain?: string | false,
201
200
  ): Promise<string | undefined> {
201
+ if (toolchain === false) {
202
+ return undefined
203
+ }
204
+
202
205
  const toolchains = new Set<AddOn>()
203
206
  for (const addOn of framework.getAddOns()) {
204
207
  if (addOn.type === 'toolchain') {