Skip to content

Commit 0c0ee31

Browse files
committed
fix(cli): handle deprecated create-tsrouter flags
Add explicit compatibility handling for legacy --router-only and --template flags in tanstack create, with deprecation warnings and clear errors for unsupported JavaScript templates. Fixes #331
1 parent d2e62d7 commit 0c0ee31

5 files changed

Lines changed: 111 additions & 3 deletions

File tree

.changeset/smart-penguins-enjoy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@tanstack/cli": patch
3+
---
4+
5+
Add compatibility handling for legacy `--router-only` and `--template` create flags, including clear deprecation warnings and explicit errors for unsupported JavaScript templates.

packages/cli/src/cli.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ import { launchUI } from '@tanstack/create-ui'
2424
import { runMCPServer } from './mcp.js'
2525

2626
import { promptForAddOns, promptForCreateOptions } from './options.js'
27-
import { normalizeOptions, validateDevWatchOptions } from './command-line.js'
27+
import {
28+
normalizeOptions,
29+
validateDevWatchOptions,
30+
validateLegacyCreateFlags,
31+
} from './command-line.js'
2832

2933
import { createUIEnvironment } from './ui-environment.js'
3034
import { DevWatchManager } from './dev-watch.js'
@@ -96,6 +100,16 @@ export function cli({
96100

97101
// Helper to create the create command action handler
98102
async function handleCreate(projectName: string, options: CliOptions) {
103+
const legacyCreateFlags = validateLegacyCreateFlags(options)
104+
if (legacyCreateFlags.error) {
105+
log.error(legacyCreateFlags.error)
106+
process.exit(1)
107+
}
108+
109+
for (const warning of legacyCreateFlags.warnings) {
110+
log.warn(warning)
111+
}
112+
99113
if (options.listAddOns) {
100114
const addOns = await getAllAddOns(
101115
getFrameworkByName(options.framework || defaultFramework || 'React')!,
@@ -386,6 +400,14 @@ export function cli({
386400
'--dev-watch <path>',
387401
'Watch a framework directory for changes and auto-rebuild',
388402
)
403+
.option(
404+
'--router-only',
405+
'Deprecated: compatibility flag from create-tsrouter-app',
406+
)
407+
.option(
408+
'--template <type>',
409+
'Deprecated: compatibility flag from create-tsrouter-app',
410+
)
389411

390412
if (deployments.size > 0) {
391413
cmd.option<string>(
@@ -461,7 +483,7 @@ export function cli({
461483
}
462484

463485
// === CREATE SUBCOMMAND ===
464-
// By default creates a TanStack Start app. Use --router-only for SPA without Start.
486+
// Creates a TanStack Start app (file-router mode).
465487
const createCommand = program
466488
.command('create')
467489
.description(`Create a new TanStack Start application`)

packages/cli/src/command-line.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,52 @@ import type { Options } from '@tanstack/create'
1919

2020
import type { CliOptions } from './types.js'
2121

22+
const SUPPORTED_LEGACY_TEMPLATES = new Set([
23+
'file-router',
24+
'typescript',
25+
'tsx',
26+
])
27+
28+
export function validateLegacyCreateFlags(cliOptions: CliOptions): {
29+
warnings: Array<string>
30+
error?: string
31+
} {
32+
const warnings: Array<string> = []
33+
34+
if (cliOptions.routerOnly) {
35+
warnings.push(
36+
'The --router-only flag is deprecated and ignored. `tanstack create` already creates router-based apps.',
37+
)
38+
}
39+
40+
if (!cliOptions.template) {
41+
return { warnings }
42+
}
43+
44+
const template = cliOptions.template.toLowerCase().trim()
45+
46+
if (template === 'javascript' || template === 'js' || template === 'jsx') {
47+
return {
48+
warnings,
49+
error:
50+
'JavaScript/JSX templates are not supported. TanStack Start file-router templates are TypeScript-only.',
51+
}
52+
}
53+
54+
if (!SUPPORTED_LEGACY_TEMPLATES.has(template)) {
55+
return {
56+
warnings,
57+
error: `Invalid --template value: ${cliOptions.template}. Supported values are: file-router, typescript, tsx.`,
58+
}
59+
}
60+
61+
warnings.push(
62+
'The --template flag is deprecated. TypeScript/TSX is the default and only supported template.',
63+
)
64+
65+
return { warnings }
66+
}
67+
2268
export async function normalizeOptions(
2369
cliOptions: CliOptions,
2470
forcedAddOns?: Array<string>,

packages/cli/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ export interface CliOptions {
2020
install?: boolean
2121
addOnConfig?: string
2222
force?: boolean
23+
routerOnly?: boolean
24+
template?: string
2325
}

packages/cli/tests/command-line.test.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { basename, resolve } from 'node:path'
22
import { beforeEach, describe, expect, it } from 'vitest'
33

4-
import { normalizeOptions } from '../src/command-line.js'
4+
import {
5+
normalizeOptions,
6+
validateLegacyCreateFlags,
7+
} from '../src/command-line.js'
58
import {
69
sanitizePackageName,
710
getCurrentDirectoryName,
@@ -273,3 +276,33 @@ describe('normalizeOptions', () => {
273276
expect(options?.chosenAddOns.map((a) => a.id).includes('baz')).toBe(true)
274277
})
275278
})
279+
280+
describe('validateLegacyCreateFlags', () => {
281+
it('returns no warnings or errors without legacy flags', () => {
282+
const result = validateLegacyCreateFlags({})
283+
expect(result.warnings).toEqual([])
284+
expect(result.error).toBeUndefined()
285+
})
286+
287+
it('warns when --router-only is used', () => {
288+
const result = validateLegacyCreateFlags({ routerOnly: true })
289+
expect(result.error).toBeUndefined()
290+
expect(result.warnings[0]).toContain('--router-only')
291+
})
292+
293+
it('errors for JavaScript templates', () => {
294+
const result = validateLegacyCreateFlags({ template: 'javascript' })
295+
expect(result.error).toContain('JavaScript/JSX templates are not supported')
296+
})
297+
298+
it('errors for unknown template values', () => {
299+
const result = validateLegacyCreateFlags({ template: 'foo' })
300+
expect(result.error).toContain('Invalid --template value')
301+
})
302+
303+
it('warns for supported deprecated template values', () => {
304+
const result = validateLegacyCreateFlags({ template: 'tsx' })
305+
expect(result.error).toBeUndefined()
306+
expect(result.warnings[0]).toContain('--template')
307+
})
308+
})

0 commit comments

Comments
 (0)