@tanstack/cli 0.61.1 → 0.62.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/package.json +11 -5
- package/skills/CHANGELOG.md +18 -0
- package/skills/add-addons-existing-app/SKILL.md +113 -0
- package/skills/choose-ecosystem-integrations/SKILL.md +140 -0
- package/skills/choose-ecosystem-integrations/references/authentication-providers.md +19 -0
- package/skills/choose-ecosystem-integrations/references/data-layer-providers.md +20 -0
- package/skills/choose-ecosystem-integrations/references/deployment-targets.md +19 -0
- package/skills/create-app-scaffold/SKILL.md +132 -0
- package/skills/create-app-scaffold/references/create-flag-compatibility-matrix.md +34 -0
- package/skills/create-app-scaffold/references/deployment-providers.md +19 -0
- package/skills/create-app-scaffold/references/framework-adapters.md +17 -0
- package/skills/create-app-scaffold/references/toolchains.md +17 -0
- package/skills/maintain-custom-addons-dev-watch/SKILL.md +118 -0
- package/skills/query-docs-library-metadata/SKILL.md +85 -0
- package/skills/query-docs-library-metadata/references/discovery-command-output-schemas.md +70 -0
- package/CHANGELOG.md +0 -815
- package/playwright-report/index.html +0 -85
- package/playwright.config.ts +0 -21
- package/src/bin.ts +0 -15
- package/src/cli.ts +0 -1099
- package/src/command-line.ts +0 -612
- package/src/dev-watch.ts +0 -564
- package/src/discovery.ts +0 -209
- package/src/file-syncer.ts +0 -263
- package/src/index.ts +0 -21
- package/src/options.ts +0 -280
- package/src/types.ts +0 -27
- package/src/ui-environment.ts +0 -74
- package/src/ui-prompts.ts +0 -387
- package/src/utils.ts +0 -30
- package/test-results/.last-run.json +0 -4
- package/tests/command-line.test.ts +0 -703
- package/tests/index.test.ts +0 -9
- package/tests/options.test.ts +0 -281
- package/tests/setupVitest.ts +0 -6
- package/tests/ui-environment.test.ts +0 -97
- package/tests/ui-prompts.test.ts +0 -233
- package/tests-e2e/addons-smoke.spec.ts +0 -31
- package/tests-e2e/create-smoke.spec.ts +0 -39
- package/tests-e2e/helpers.ts +0 -526
- package/tests-e2e/matrix-opportunistic.spec.ts +0 -142
- package/tests-e2e/router-only-smoke.spec.ts +0 -54
- package/tests-e2e/solid-smoke.spec.ts +0 -26
- package/tests-e2e/templates-smoke.spec.ts +0 -52
- package/tsconfig.json +0 -17
- package/vitest.config.js +0 -8
package/src/options.ts
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import { intro } from '@clack/prompts'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
finalizeAddOns,
|
|
5
|
-
getFrameworkById,
|
|
6
|
-
getPackageManager,
|
|
7
|
-
loadStarter,
|
|
8
|
-
populateAddOnOptionsDefaults,
|
|
9
|
-
readConfigFile,
|
|
10
|
-
} from '@tanstack/create'
|
|
11
|
-
|
|
12
|
-
import {
|
|
13
|
-
getProjectName,
|
|
14
|
-
promptForAddOnOptions,
|
|
15
|
-
promptForEnvVars,
|
|
16
|
-
selectAddOns,
|
|
17
|
-
selectDeployment,
|
|
18
|
-
selectExamples,
|
|
19
|
-
selectGit,
|
|
20
|
-
selectPackageManager,
|
|
21
|
-
selectTemplate,
|
|
22
|
-
selectToolchain,
|
|
23
|
-
} from './ui-prompts.js'
|
|
24
|
-
import {
|
|
25
|
-
listTemplateChoices,
|
|
26
|
-
resolveStarterSpecifier,
|
|
27
|
-
} from './command-line.js'
|
|
28
|
-
|
|
29
|
-
import {
|
|
30
|
-
getCurrentDirectoryName,
|
|
31
|
-
sanitizePackageName,
|
|
32
|
-
validateProjectName,
|
|
33
|
-
} from './utils.js'
|
|
34
|
-
import type { Options } from '@tanstack/create'
|
|
35
|
-
|
|
36
|
-
import type { CliOptions } from './types.js'
|
|
37
|
-
|
|
38
|
-
export async function promptForCreateOptions(
|
|
39
|
-
cliOptions: CliOptions,
|
|
40
|
-
{
|
|
41
|
-
forcedAddOns = [],
|
|
42
|
-
showDeploymentOptions = false,
|
|
43
|
-
}: {
|
|
44
|
-
forcedAddOns?: Array<string>
|
|
45
|
-
showDeploymentOptions?: boolean
|
|
46
|
-
},
|
|
47
|
-
): Promise<Required<Options> | undefined> {
|
|
48
|
-
const options = {} as Required<Options>
|
|
49
|
-
|
|
50
|
-
options.framework = getFrameworkById(cliOptions.framework || 'react')!
|
|
51
|
-
|
|
52
|
-
// Validate project name
|
|
53
|
-
if (cliOptions.projectName) {
|
|
54
|
-
// Handle "." as project name - use sanitized current directory name
|
|
55
|
-
if (cliOptions.projectName === '.') {
|
|
56
|
-
options.projectName = sanitizePackageName(getCurrentDirectoryName())
|
|
57
|
-
} else {
|
|
58
|
-
options.projectName = cliOptions.projectName
|
|
59
|
-
}
|
|
60
|
-
const { valid, error } = validateProjectName(options.projectName)
|
|
61
|
-
if (!valid) {
|
|
62
|
-
console.error(error)
|
|
63
|
-
process.exit(1)
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
options.projectName = await getProjectName()
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Mode is always file-router (TanStack Start)
|
|
70
|
-
options.mode = 'file-router'
|
|
71
|
-
const template = cliOptions.template?.toLowerCase().trim()
|
|
72
|
-
const isLegacyTemplate =
|
|
73
|
-
template &&
|
|
74
|
-
['file-router', 'typescript', 'tsx', 'javascript', 'js', 'jsx'].includes(
|
|
75
|
-
template,
|
|
76
|
-
)
|
|
77
|
-
const routerOnly =
|
|
78
|
-
!!cliOptions.routerOnly ||
|
|
79
|
-
(isLegacyTemplate ? template !== 'file-router' : false)
|
|
80
|
-
|
|
81
|
-
if (!cliOptions.starter) {
|
|
82
|
-
if (cliOptions.template && !isLegacyTemplate) {
|
|
83
|
-
cliOptions.starter = cliOptions.template
|
|
84
|
-
} else if (cliOptions.templateId) {
|
|
85
|
-
cliOptions.starter = cliOptions.templateId
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!routerOnly && !cliOptions.starter) {
|
|
90
|
-
const starterChoices = await listTemplateChoices(options.framework.id)
|
|
91
|
-
const selectedTemplateId = await selectTemplate(
|
|
92
|
-
starterChoices.map((choice) => ({
|
|
93
|
-
id: choice.id,
|
|
94
|
-
name: choice.name,
|
|
95
|
-
description: choice.description,
|
|
96
|
-
})),
|
|
97
|
-
)
|
|
98
|
-
if (selectedTemplateId) {
|
|
99
|
-
cliOptions.starter = selectedTemplateId
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const starter = !routerOnly && cliOptions.starter
|
|
104
|
-
? await loadStarter(
|
|
105
|
-
await resolveStarterSpecifier(cliOptions.starter, options.framework.id),
|
|
106
|
-
)
|
|
107
|
-
: undefined
|
|
108
|
-
|
|
109
|
-
if (starter) {
|
|
110
|
-
options.framework = getFrameworkById(starter.framework) || options.framework
|
|
111
|
-
options.mode = starter.mode
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// TypeScript is always enabled with file-router
|
|
115
|
-
options.typescript = true
|
|
116
|
-
|
|
117
|
-
// Package manager selection
|
|
118
|
-
if (cliOptions.packageManager) {
|
|
119
|
-
options.packageManager = cliOptions.packageManager
|
|
120
|
-
} else {
|
|
121
|
-
const detectedPackageManager = await getPackageManager()
|
|
122
|
-
options.packageManager =
|
|
123
|
-
detectedPackageManager || (await selectPackageManager())
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Toolchain selection
|
|
127
|
-
const toolchain = await selectToolchain(
|
|
128
|
-
options.framework,
|
|
129
|
-
cliOptions.toolchain,
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
// Deployment selection
|
|
133
|
-
const deployment = showDeploymentOptions
|
|
134
|
-
? routerOnly
|
|
135
|
-
? undefined
|
|
136
|
-
: await selectDeployment(options.framework, cliOptions.deployment)
|
|
137
|
-
: undefined
|
|
138
|
-
|
|
139
|
-
// Add-ons selection
|
|
140
|
-
const addOns: Set<string> = new Set()
|
|
141
|
-
|
|
142
|
-
// Examples/demo pages are enabled by default
|
|
143
|
-
const includeExamples =
|
|
144
|
-
cliOptions.examples ?? (routerOnly ? false : await selectExamples())
|
|
145
|
-
;(options as Required<Options> & { includeExamples?: boolean }).includeExamples =
|
|
146
|
-
includeExamples
|
|
147
|
-
|
|
148
|
-
if (toolchain) {
|
|
149
|
-
addOns.add(toolchain)
|
|
150
|
-
}
|
|
151
|
-
if (deployment) {
|
|
152
|
-
addOns.add(deployment)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (!routerOnly) {
|
|
156
|
-
for (const addOn of starter?.dependsOn || []) {
|
|
157
|
-
addOns.add(addOn)
|
|
158
|
-
}
|
|
159
|
-
for (const addOn of forcedAddOns) {
|
|
160
|
-
addOns.add(addOn)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (!routerOnly && Array.isArray(cliOptions.addOns)) {
|
|
165
|
-
for (const addOn of cliOptions.addOns) {
|
|
166
|
-
if (addOn.toLowerCase() === 'start') {
|
|
167
|
-
continue
|
|
168
|
-
}
|
|
169
|
-
addOns.add(addOn)
|
|
170
|
-
}
|
|
171
|
-
} else if (!routerOnly) {
|
|
172
|
-
for (const addOn of await selectAddOns(
|
|
173
|
-
options.framework,
|
|
174
|
-
options.mode,
|
|
175
|
-
'add-on',
|
|
176
|
-
'What add-ons would you like for your project?',
|
|
177
|
-
forcedAddOns,
|
|
178
|
-
)) {
|
|
179
|
-
addOns.add(addOn)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (includeExamples) {
|
|
183
|
-
for (const addOn of await selectAddOns(
|
|
184
|
-
options.framework,
|
|
185
|
-
options.mode,
|
|
186
|
-
'example',
|
|
187
|
-
'Would you like an example?',
|
|
188
|
-
forcedAddOns,
|
|
189
|
-
false,
|
|
190
|
-
)) {
|
|
191
|
-
addOns.add(addOn)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const chosenAddOns = Array.from(
|
|
197
|
-
await finalizeAddOns(options.framework, options.mode, Array.from(addOns)),
|
|
198
|
-
)
|
|
199
|
-
options.chosenAddOns = includeExamples
|
|
200
|
-
? chosenAddOns
|
|
201
|
-
: chosenAddOns.filter((addOn) => addOn.type !== 'example')
|
|
202
|
-
|
|
203
|
-
// Tailwind is always enabled
|
|
204
|
-
options.tailwind = true
|
|
205
|
-
|
|
206
|
-
// Prompt for add-on options in interactive mode
|
|
207
|
-
if (Array.isArray(cliOptions.addOns)) {
|
|
208
|
-
// Non-interactive mode: use defaults
|
|
209
|
-
options.addOnOptions = populateAddOnOptionsDefaults(options.chosenAddOns)
|
|
210
|
-
} else {
|
|
211
|
-
// Interactive mode: prompt for options
|
|
212
|
-
const userOptions = await promptForAddOnOptions(
|
|
213
|
-
options.chosenAddOns.map((a) => a.id),
|
|
214
|
-
options.framework,
|
|
215
|
-
)
|
|
216
|
-
const defaultOptions = populateAddOnOptionsDefaults(options.chosenAddOns)
|
|
217
|
-
// Merge user options with defaults
|
|
218
|
-
options.addOnOptions = { ...defaultOptions, ...userOptions }
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Prompt for env vars exposed by selected add-ons in interactive mode
|
|
222
|
-
const envVarValues = Array.isArray(cliOptions.addOns)
|
|
223
|
-
? {}
|
|
224
|
-
: await promptForEnvVars(options.chosenAddOns)
|
|
225
|
-
;(options as Required<Options> & { envVarValues?: Record<string, string> }).envVarValues =
|
|
226
|
-
envVarValues
|
|
227
|
-
|
|
228
|
-
options.git = cliOptions.git ?? (await selectGit())
|
|
229
|
-
if (cliOptions.install === false) {
|
|
230
|
-
options.install = false
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (starter) {
|
|
234
|
-
options.starter = starter
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return options
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
export async function promptForAddOns(): Promise<Array<string>> {
|
|
241
|
-
const config = await readConfigFile(process.cwd())
|
|
242
|
-
|
|
243
|
-
if (!config) {
|
|
244
|
-
console.error('No config file found')
|
|
245
|
-
process.exit(1)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const framework = getFrameworkById(config.framework)
|
|
249
|
-
|
|
250
|
-
if (!framework) {
|
|
251
|
-
console.error(`Unknown framework: ${config.framework}`)
|
|
252
|
-
process.exit(1)
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
intro(`Adding new add-ons to '${config.projectName}'`)
|
|
256
|
-
|
|
257
|
-
const addOns: Set<string> = new Set()
|
|
258
|
-
|
|
259
|
-
for (const addOn of await selectAddOns(
|
|
260
|
-
framework,
|
|
261
|
-
config.mode!,
|
|
262
|
-
'add-on',
|
|
263
|
-
'What add-ons would you like for your project?',
|
|
264
|
-
config.chosenAddOns,
|
|
265
|
-
)) {
|
|
266
|
-
addOns.add(addOn)
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
for (const addOn of await selectAddOns(
|
|
270
|
-
framework,
|
|
271
|
-
config.mode!,
|
|
272
|
-
'example',
|
|
273
|
-
'Would you like any examples?',
|
|
274
|
-
config.chosenAddOns,
|
|
275
|
-
)) {
|
|
276
|
-
addOns.add(addOn)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return Array.from(addOns)
|
|
280
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { PackageManager } from '@tanstack/create'
|
|
2
|
-
|
|
3
|
-
export interface CliOptions {
|
|
4
|
-
framework?: string
|
|
5
|
-
packageManager?: PackageManager
|
|
6
|
-
toolchain?: string | false
|
|
7
|
-
deployment?: string
|
|
8
|
-
projectName?: string
|
|
9
|
-
git?: boolean
|
|
10
|
-
addOns?: Array<string> | boolean
|
|
11
|
-
listAddOns?: boolean
|
|
12
|
-
addonDetails?: string
|
|
13
|
-
json?: boolean
|
|
14
|
-
starter?: string
|
|
15
|
-
templateId?: string
|
|
16
|
-
targetDir?: string
|
|
17
|
-
interactive?: boolean
|
|
18
|
-
devWatch?: string
|
|
19
|
-
runDev?: boolean
|
|
20
|
-
install?: boolean
|
|
21
|
-
addOnConfig?: string
|
|
22
|
-
force?: boolean
|
|
23
|
-
routerOnly?: boolean
|
|
24
|
-
template?: string
|
|
25
|
-
tailwind?: boolean
|
|
26
|
-
examples?: boolean
|
|
27
|
-
}
|
package/src/ui-environment.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
cancel,
|
|
3
|
-
confirm,
|
|
4
|
-
intro,
|
|
5
|
-
isCancel,
|
|
6
|
-
log,
|
|
7
|
-
outro,
|
|
8
|
-
spinner,
|
|
9
|
-
} from '@clack/prompts'
|
|
10
|
-
import chalk from 'chalk'
|
|
11
|
-
|
|
12
|
-
import { createDefaultEnvironment } from '@tanstack/create'
|
|
13
|
-
|
|
14
|
-
import type { Environment } from '@tanstack/create'
|
|
15
|
-
|
|
16
|
-
export function createUIEnvironment(
|
|
17
|
-
appName: string,
|
|
18
|
-
silent: boolean,
|
|
19
|
-
): Environment {
|
|
20
|
-
const defaultEnvironment = createDefaultEnvironment()
|
|
21
|
-
|
|
22
|
-
let newEnvironment = {
|
|
23
|
-
...defaultEnvironment,
|
|
24
|
-
appName,
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!silent) {
|
|
28
|
-
newEnvironment = {
|
|
29
|
-
...newEnvironment,
|
|
30
|
-
intro: (message: string) => {
|
|
31
|
-
intro(message)
|
|
32
|
-
},
|
|
33
|
-
outro: (message: string) => {
|
|
34
|
-
outro(message)
|
|
35
|
-
},
|
|
36
|
-
info: (title?: string, message?: string) => {
|
|
37
|
-
log.info(
|
|
38
|
-
`${title ? chalk.red(title) : ''}${message ? '\n' + chalk.green(message) : ''}`,
|
|
39
|
-
)
|
|
40
|
-
},
|
|
41
|
-
error: (title?: string, message?: string) => {
|
|
42
|
-
log.error(
|
|
43
|
-
`${title ? `${title}: ` : ''}${message ? '\n' + message : ''}`,
|
|
44
|
-
)
|
|
45
|
-
},
|
|
46
|
-
warn: (title?: string, message?: string) => {
|
|
47
|
-
log.warn(`${title ? `${title}: ` : ''}${message ? '\n' + message : ''}`)
|
|
48
|
-
},
|
|
49
|
-
confirm: async (message: string) => {
|
|
50
|
-
const shouldContinue = await confirm({
|
|
51
|
-
message,
|
|
52
|
-
})
|
|
53
|
-
if (isCancel(shouldContinue)) {
|
|
54
|
-
cancel('Operation cancelled.')
|
|
55
|
-
process.exit(0)
|
|
56
|
-
}
|
|
57
|
-
return shouldContinue
|
|
58
|
-
},
|
|
59
|
-
spinner: () => {
|
|
60
|
-
const s = spinner()
|
|
61
|
-
return {
|
|
62
|
-
start: (message: string) => {
|
|
63
|
-
s.start(message)
|
|
64
|
-
},
|
|
65
|
-
stop: (message: string) => {
|
|
66
|
-
s.stop(message)
|
|
67
|
-
},
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return newEnvironment
|
|
74
|
-
}
|