@tanstack/cli 0.60.1 → 0.62.0
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/dist/cli.js +266 -11
- package/dist/command-line.js +103 -8
- package/dist/discovery.js +144 -0
- package/dist/options.js +35 -2
- package/dist/types/command-line.d.ts +7 -0
- package/dist/types/{mcp/types.d.ts → discovery.d.ts} +23 -75
- package/dist/types/types.d.ts +1 -2
- package/dist/types/ui-prompts.d.ts +5 -0
- package/dist/ui-prompts.js +26 -0
- package/package.json +6 -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 -787
- package/dist/mcp/api.js +0 -31
- package/dist/mcp/tools.js +0 -250
- package/dist/mcp/types.js +0 -37
- package/dist/mcp.js +0 -181
- package/dist/types/mcp/api.d.ts +0 -4
- package/dist/types/mcp/tools.d.ts +0 -2
- package/dist/types/mcp.d.ts +0 -5
- package/playwright-report/index.html +0 -85
- package/playwright.config.ts +0 -21
- package/src/bin.ts +0 -15
- package/src/cli.ts +0 -767
- package/src/command-line.ts +0 -473
- package/src/dev-watch.ts +0 -564
- package/src/file-syncer.ts +0 -263
- package/src/index.ts +0 -21
- package/src/mcp/api.ts +0 -42
- package/src/mcp/tools.ts +0 -323
- package/src/mcp/types.ts +0 -46
- package/src/mcp.ts +0 -263
- package/src/options.ts +0 -234
- package/src/types.ts +0 -28
- package/src/ui-environment.ts +0 -74
- package/src/ui-prompts.ts +0 -355
- package/src/utils.ts +0 -30
- package/test-results/.last-run.json +0 -4
- package/tests/command-line.test.ts +0 -622
- package/tests/index.test.ts +0 -9
- package/tests/mcp.test.ts +0 -225
- package/tests/options.test.ts +0 -216
- package/tests/setupVitest.ts +0 -6
- package/tests/ui-environment.test.ts +0 -97
- package/tests/ui-prompts.test.ts +0 -205
- 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 -68
- package/tests-e2e/solid-smoke.spec.ts +0 -25
- package/tests-e2e/templates-smoke.spec.ts +0 -52
- package/tsconfig.json +0 -17
- package/vitest.config.js +0 -8
package/src/mcp.ts
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
2
|
-
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'
|
|
3
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
4
|
-
import express from 'express'
|
|
5
|
-
import { z } from 'zod'
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
createApp,
|
|
9
|
-
createDefaultEnvironment,
|
|
10
|
-
finalizeAddOns,
|
|
11
|
-
getFrameworkByName,
|
|
12
|
-
getFrameworks,
|
|
13
|
-
populateAddOnOptionsDefaults,
|
|
14
|
-
} from '@tanstack/create'
|
|
15
|
-
|
|
16
|
-
import { registerDocTools } from './mcp/tools.js'
|
|
17
|
-
|
|
18
|
-
function createServer({
|
|
19
|
-
appName,
|
|
20
|
-
forcedAddOns = [],
|
|
21
|
-
}: {
|
|
22
|
-
appName?: string
|
|
23
|
-
forcedAddOns?: Array<string>
|
|
24
|
-
name?: string
|
|
25
|
-
}) {
|
|
26
|
-
const server = new McpServer({
|
|
27
|
-
name: `${appName} Application Builder`,
|
|
28
|
-
version: '1.0.0',
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const frameworks = getFrameworks()
|
|
32
|
-
const frameworkNames = frameworks.map((framework) => framework.name)
|
|
33
|
-
|
|
34
|
-
server.tool(
|
|
35
|
-
'listTanStackAddOns',
|
|
36
|
-
'List the available add-ons for creating TanStack applications',
|
|
37
|
-
{
|
|
38
|
-
framework: z
|
|
39
|
-
.string()
|
|
40
|
-
.describe(
|
|
41
|
-
`The framework to use. Available frameworks: ${frameworkNames.join(', ')}`,
|
|
42
|
-
),
|
|
43
|
-
},
|
|
44
|
-
({ framework: frameworkName }) => {
|
|
45
|
-
const framework = getFrameworkByName(frameworkName)!
|
|
46
|
-
return {
|
|
47
|
-
content: [
|
|
48
|
-
{
|
|
49
|
-
type: 'text',
|
|
50
|
-
text: JSON.stringify(
|
|
51
|
-
framework
|
|
52
|
-
.getAddOns()
|
|
53
|
-
.filter((addOn) => addOn.modes.includes('file-router'))
|
|
54
|
-
.map((addOn) => ({
|
|
55
|
-
id: addOn.id,
|
|
56
|
-
name: addOn.name,
|
|
57
|
-
description: addOn.description,
|
|
58
|
-
type: addOn.type,
|
|
59
|
-
category: addOn.category,
|
|
60
|
-
link: addOn.link,
|
|
61
|
-
warning: addOn.warning,
|
|
62
|
-
exclusive: addOn.exclusive,
|
|
63
|
-
options: addOn.options,
|
|
64
|
-
dependsOn: addOn.dependsOn,
|
|
65
|
-
})),
|
|
66
|
-
),
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
server.tool(
|
|
74
|
-
'getAddOnDetails',
|
|
75
|
-
'Get detailed information about a specific add-on including implementation patterns, routes, dependencies, and documentation',
|
|
76
|
-
{
|
|
77
|
-
framework: z
|
|
78
|
-
.string()
|
|
79
|
-
.describe(
|
|
80
|
-
`The framework to use. Available frameworks: ${frameworkNames.join(', ')}`,
|
|
81
|
-
),
|
|
82
|
-
addOnId: z
|
|
83
|
-
.string()
|
|
84
|
-
.describe('The ID of the add-on to get details for'),
|
|
85
|
-
},
|
|
86
|
-
async ({ framework: frameworkName, addOnId }) => {
|
|
87
|
-
const framework = getFrameworkByName(frameworkName)!
|
|
88
|
-
const allAddOns = framework.getAddOns()
|
|
89
|
-
const addOn =
|
|
90
|
-
allAddOns.find((a) => a.id === addOnId) ??
|
|
91
|
-
allAddOns.find(
|
|
92
|
-
(a) => a.id.toLowerCase() === addOnId.toLowerCase(),
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
if (!addOn) {
|
|
96
|
-
return {
|
|
97
|
-
content: [
|
|
98
|
-
{
|
|
99
|
-
type: 'text',
|
|
100
|
-
text: JSON.stringify({ error: `Add-on '${addOnId}' not found` }),
|
|
101
|
-
},
|
|
102
|
-
],
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Get file list for context
|
|
107
|
-
const files = await addOn.getFiles()
|
|
108
|
-
|
|
109
|
-
return {
|
|
110
|
-
content: [
|
|
111
|
-
{
|
|
112
|
-
type: 'text',
|
|
113
|
-
text: JSON.stringify({
|
|
114
|
-
id: addOn.id,
|
|
115
|
-
name: addOn.name,
|
|
116
|
-
description: addOn.description,
|
|
117
|
-
type: addOn.type,
|
|
118
|
-
category: addOn.category,
|
|
119
|
-
phase: addOn.phase,
|
|
120
|
-
modes: addOn.modes,
|
|
121
|
-
link: addOn.link,
|
|
122
|
-
warning: addOn.warning,
|
|
123
|
-
exclusive: addOn.exclusive,
|
|
124
|
-
dependsOn: addOn.dependsOn,
|
|
125
|
-
options: addOn.options,
|
|
126
|
-
routes: addOn.routes,
|
|
127
|
-
packageAdditions: addOn.packageAdditions,
|
|
128
|
-
shadcnComponents: addOn.shadcnComponents,
|
|
129
|
-
integrations: addOn.integrations,
|
|
130
|
-
readme: addOn.readme,
|
|
131
|
-
files,
|
|
132
|
-
author: addOn.author,
|
|
133
|
-
version: addOn.version,
|
|
134
|
-
license: addOn.license,
|
|
135
|
-
}),
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
server.tool(
|
|
143
|
-
'createTanStackApplication',
|
|
144
|
-
'Create a new TanStack application',
|
|
145
|
-
{
|
|
146
|
-
framework: z
|
|
147
|
-
.string()
|
|
148
|
-
.describe(
|
|
149
|
-
`The framework to use. Available frameworks: ${frameworkNames.join(', ')}`,
|
|
150
|
-
),
|
|
151
|
-
projectName: z
|
|
152
|
-
.string()
|
|
153
|
-
.describe(
|
|
154
|
-
'The package.json module name of the application (will also be the directory name)',
|
|
155
|
-
),
|
|
156
|
-
cwd: z.string().describe('The directory to create the application in'),
|
|
157
|
-
addOns: z.array(z.string()).describe('Array of add-on IDs to install. Use listTanStackAddOns tool to see available add-ons and their configuration options. Example: ["prisma", "shadcn", "tanstack-query"]'),
|
|
158
|
-
addOnOptions: z.record(z.record(z.any())).optional().describe('Configuration options for add-ons. Format: {"addOnId": {"optionName": "value"}}. Use listTanStackAddOns to see available options for each add-on.'),
|
|
159
|
-
targetDir: z
|
|
160
|
-
.string()
|
|
161
|
-
.describe(
|
|
162
|
-
'The directory to create the application in. Use the absolute path of the directory you want the application to be created in',
|
|
163
|
-
),
|
|
164
|
-
},
|
|
165
|
-
async ({
|
|
166
|
-
framework: frameworkName,
|
|
167
|
-
projectName,
|
|
168
|
-
addOns,
|
|
169
|
-
addOnOptions,
|
|
170
|
-
cwd,
|
|
171
|
-
targetDir,
|
|
172
|
-
}) => {
|
|
173
|
-
const framework = getFrameworkByName(frameworkName)!
|
|
174
|
-
try {
|
|
175
|
-
process.chdir(cwd)
|
|
176
|
-
try {
|
|
177
|
-
const chosenAddOns = await finalizeAddOns(
|
|
178
|
-
framework,
|
|
179
|
-
'file-router',
|
|
180
|
-
Array.from(
|
|
181
|
-
new Set([
|
|
182
|
-
...(addOns as unknown as Array<string>),
|
|
183
|
-
...forcedAddOns,
|
|
184
|
-
]),
|
|
185
|
-
),
|
|
186
|
-
)
|
|
187
|
-
await createApp(createDefaultEnvironment(), {
|
|
188
|
-
projectName: projectName.replace(/^\//, './'),
|
|
189
|
-
targetDir,
|
|
190
|
-
framework,
|
|
191
|
-
typescript: true,
|
|
192
|
-
tailwind: true,
|
|
193
|
-
packageManager: 'pnpm',
|
|
194
|
-
mode: 'file-router',
|
|
195
|
-
chosenAddOns,
|
|
196
|
-
addOnOptions: addOnOptions || populateAddOnOptionsDefaults(chosenAddOns),
|
|
197
|
-
git: true,
|
|
198
|
-
})
|
|
199
|
-
} catch (error) {
|
|
200
|
-
console.error(error)
|
|
201
|
-
return {
|
|
202
|
-
content: [
|
|
203
|
-
{ type: 'text', text: `Error creating application: ${error}` },
|
|
204
|
-
],
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return {
|
|
208
|
-
content: [{ type: 'text', text: 'Application created successfully' }],
|
|
209
|
-
}
|
|
210
|
-
} catch (error) {
|
|
211
|
-
return {
|
|
212
|
-
content: [
|
|
213
|
-
{ type: 'text', text: `Error creating application: ${error}` },
|
|
214
|
-
],
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
// Register doc/ecosystem tools from TanStack API
|
|
221
|
-
registerDocTools(server)
|
|
222
|
-
|
|
223
|
-
return server
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
export async function runMCPServer(
|
|
227
|
-
sse: boolean,
|
|
228
|
-
{
|
|
229
|
-
forcedAddOns,
|
|
230
|
-
appName,
|
|
231
|
-
name,
|
|
232
|
-
}: {
|
|
233
|
-
forcedAddOns?: Array<string>
|
|
234
|
-
appName?: string
|
|
235
|
-
name?: string
|
|
236
|
-
},
|
|
237
|
-
) {
|
|
238
|
-
let transport: SSEServerTransport | null = null
|
|
239
|
-
|
|
240
|
-
const server = createServer({ appName, forcedAddOns, name })
|
|
241
|
-
if (sse) {
|
|
242
|
-
const app = express()
|
|
243
|
-
|
|
244
|
-
app.get('/sse', (req, res) => {
|
|
245
|
-
transport = new SSEServerTransport('/messages', res)
|
|
246
|
-
server.connect(transport)
|
|
247
|
-
})
|
|
248
|
-
|
|
249
|
-
app.post('/messages', (req, res) => {
|
|
250
|
-
if (transport) {
|
|
251
|
-
transport.handlePostMessage(req, res)
|
|
252
|
-
}
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
const port = process.env.PORT || 8080
|
|
256
|
-
app.listen(port, () => {
|
|
257
|
-
console.log(`Server is running on port http://localhost:${port}/sse`)
|
|
258
|
-
})
|
|
259
|
-
} else {
|
|
260
|
-
const transport = new StdioServerTransport()
|
|
261
|
-
await server.connect(transport)
|
|
262
|
-
}
|
|
263
|
-
}
|
package/src/options.ts
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { intro } from '@clack/prompts'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
finalizeAddOns,
|
|
5
|
-
getFrameworkById,
|
|
6
|
-
getPackageManager,
|
|
7
|
-
populateAddOnOptionsDefaults,
|
|
8
|
-
readConfigFile,
|
|
9
|
-
} from '@tanstack/create'
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
getProjectName,
|
|
13
|
-
promptForAddOnOptions,
|
|
14
|
-
promptForEnvVars,
|
|
15
|
-
selectAddOns,
|
|
16
|
-
selectDeployment,
|
|
17
|
-
selectExamples,
|
|
18
|
-
selectGit,
|
|
19
|
-
selectPackageManager,
|
|
20
|
-
selectToolchain,
|
|
21
|
-
} from './ui-prompts.js'
|
|
22
|
-
|
|
23
|
-
import {
|
|
24
|
-
getCurrentDirectoryName,
|
|
25
|
-
sanitizePackageName,
|
|
26
|
-
validateProjectName,
|
|
27
|
-
} from './utils.js'
|
|
28
|
-
import type { Options } from '@tanstack/create'
|
|
29
|
-
|
|
30
|
-
import type { CliOptions } from './types.js'
|
|
31
|
-
|
|
32
|
-
export async function promptForCreateOptions(
|
|
33
|
-
cliOptions: CliOptions,
|
|
34
|
-
{
|
|
35
|
-
forcedAddOns = [],
|
|
36
|
-
showDeploymentOptions = false,
|
|
37
|
-
}: {
|
|
38
|
-
forcedAddOns?: Array<string>
|
|
39
|
-
showDeploymentOptions?: boolean
|
|
40
|
-
},
|
|
41
|
-
): Promise<Required<Options> | undefined> {
|
|
42
|
-
const options = {} as Required<Options>
|
|
43
|
-
|
|
44
|
-
options.framework = getFrameworkById(cliOptions.framework || 'react')!
|
|
45
|
-
|
|
46
|
-
// Validate project name
|
|
47
|
-
if (cliOptions.projectName) {
|
|
48
|
-
// Handle "." as project name - use sanitized current directory name
|
|
49
|
-
if (cliOptions.projectName === '.') {
|
|
50
|
-
options.projectName = sanitizePackageName(getCurrentDirectoryName())
|
|
51
|
-
} else {
|
|
52
|
-
options.projectName = cliOptions.projectName
|
|
53
|
-
}
|
|
54
|
-
const { valid, error } = validateProjectName(options.projectName)
|
|
55
|
-
if (!valid) {
|
|
56
|
-
console.error(error)
|
|
57
|
-
process.exit(1)
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
options.projectName = await getProjectName()
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Mode is always file-router (TanStack Start)
|
|
64
|
-
options.mode = 'file-router'
|
|
65
|
-
const template = cliOptions.template?.toLowerCase().trim()
|
|
66
|
-
const isLegacyTemplate =
|
|
67
|
-
template &&
|
|
68
|
-
['file-router', 'typescript', 'tsx', 'javascript', 'js', 'jsx'].includes(
|
|
69
|
-
template,
|
|
70
|
-
)
|
|
71
|
-
const routerOnly =
|
|
72
|
-
!!cliOptions.routerOnly ||
|
|
73
|
-
(isLegacyTemplate ? template !== 'file-router' : false)
|
|
74
|
-
|
|
75
|
-
// TypeScript is always enabled with file-router
|
|
76
|
-
options.typescript = true
|
|
77
|
-
|
|
78
|
-
// Package manager selection
|
|
79
|
-
if (cliOptions.packageManager) {
|
|
80
|
-
options.packageManager = cliOptions.packageManager
|
|
81
|
-
} else {
|
|
82
|
-
const detectedPackageManager = await getPackageManager()
|
|
83
|
-
options.packageManager =
|
|
84
|
-
detectedPackageManager || (await selectPackageManager())
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Toolchain selection
|
|
88
|
-
const toolchain = await selectToolchain(
|
|
89
|
-
options.framework,
|
|
90
|
-
cliOptions.toolchain,
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
// Deployment selection
|
|
94
|
-
const deployment = showDeploymentOptions
|
|
95
|
-
? routerOnly
|
|
96
|
-
? undefined
|
|
97
|
-
: await selectDeployment(options.framework, cliOptions.deployment)
|
|
98
|
-
: undefined
|
|
99
|
-
|
|
100
|
-
// Add-ons selection
|
|
101
|
-
const addOns: Set<string> = new Set()
|
|
102
|
-
|
|
103
|
-
// Examples/demo pages are enabled by default
|
|
104
|
-
const includeExamples =
|
|
105
|
-
cliOptions.examples ?? (routerOnly ? false : await selectExamples())
|
|
106
|
-
;(options as Required<Options> & { includeExamples?: boolean }).includeExamples =
|
|
107
|
-
includeExamples
|
|
108
|
-
|
|
109
|
-
if (toolchain) {
|
|
110
|
-
addOns.add(toolchain)
|
|
111
|
-
}
|
|
112
|
-
if (deployment) {
|
|
113
|
-
addOns.add(deployment)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (!routerOnly) {
|
|
117
|
-
for (const addOn of forcedAddOns) {
|
|
118
|
-
addOns.add(addOn)
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (!routerOnly && Array.isArray(cliOptions.addOns)) {
|
|
123
|
-
for (const addOn of cliOptions.addOns) {
|
|
124
|
-
if (addOn.toLowerCase() === 'start') {
|
|
125
|
-
continue
|
|
126
|
-
}
|
|
127
|
-
addOns.add(addOn)
|
|
128
|
-
}
|
|
129
|
-
} else if (!routerOnly) {
|
|
130
|
-
for (const addOn of await selectAddOns(
|
|
131
|
-
options.framework,
|
|
132
|
-
options.mode,
|
|
133
|
-
'add-on',
|
|
134
|
-
'What add-ons would you like for your project?',
|
|
135
|
-
forcedAddOns,
|
|
136
|
-
)) {
|
|
137
|
-
addOns.add(addOn)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (includeExamples) {
|
|
141
|
-
for (const addOn of await selectAddOns(
|
|
142
|
-
options.framework,
|
|
143
|
-
options.mode,
|
|
144
|
-
'example',
|
|
145
|
-
'Would you like an example?',
|
|
146
|
-
forcedAddOns,
|
|
147
|
-
false,
|
|
148
|
-
)) {
|
|
149
|
-
addOns.add(addOn)
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const chosenAddOns = Array.from(
|
|
155
|
-
await finalizeAddOns(options.framework, options.mode, Array.from(addOns)),
|
|
156
|
-
)
|
|
157
|
-
options.chosenAddOns = includeExamples
|
|
158
|
-
? chosenAddOns
|
|
159
|
-
: chosenAddOns.filter((addOn) => addOn.type !== 'example')
|
|
160
|
-
|
|
161
|
-
// Tailwind is always enabled
|
|
162
|
-
options.tailwind = true
|
|
163
|
-
|
|
164
|
-
// Prompt for add-on options in interactive mode
|
|
165
|
-
if (Array.isArray(cliOptions.addOns)) {
|
|
166
|
-
// Non-interactive mode: use defaults
|
|
167
|
-
options.addOnOptions = populateAddOnOptionsDefaults(options.chosenAddOns)
|
|
168
|
-
} else {
|
|
169
|
-
// Interactive mode: prompt for options
|
|
170
|
-
const userOptions = await promptForAddOnOptions(
|
|
171
|
-
options.chosenAddOns.map((a) => a.id),
|
|
172
|
-
options.framework,
|
|
173
|
-
)
|
|
174
|
-
const defaultOptions = populateAddOnOptionsDefaults(options.chosenAddOns)
|
|
175
|
-
// Merge user options with defaults
|
|
176
|
-
options.addOnOptions = { ...defaultOptions, ...userOptions }
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Prompt for env vars exposed by selected add-ons in interactive mode
|
|
180
|
-
const envVarValues = Array.isArray(cliOptions.addOns)
|
|
181
|
-
? {}
|
|
182
|
-
: await promptForEnvVars(options.chosenAddOns)
|
|
183
|
-
;(options as Required<Options> & { envVarValues?: Record<string, string> }).envVarValues =
|
|
184
|
-
envVarValues
|
|
185
|
-
|
|
186
|
-
options.git = cliOptions.git ?? (await selectGit())
|
|
187
|
-
if (cliOptions.install === false) {
|
|
188
|
-
options.install = false
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return options
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export async function promptForAddOns(): Promise<Array<string>> {
|
|
195
|
-
const config = await readConfigFile(process.cwd())
|
|
196
|
-
|
|
197
|
-
if (!config) {
|
|
198
|
-
console.error('No config file found')
|
|
199
|
-
process.exit(1)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const framework = getFrameworkById(config.framework)
|
|
203
|
-
|
|
204
|
-
if (!framework) {
|
|
205
|
-
console.error(`Unknown framework: ${config.framework}`)
|
|
206
|
-
process.exit(1)
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
intro(`Adding new add-ons to '${config.projectName}'`)
|
|
210
|
-
|
|
211
|
-
const addOns: Set<string> = new Set()
|
|
212
|
-
|
|
213
|
-
for (const addOn of await selectAddOns(
|
|
214
|
-
framework,
|
|
215
|
-
config.mode!,
|
|
216
|
-
'add-on',
|
|
217
|
-
'What add-ons would you like for your project?',
|
|
218
|
-
config.chosenAddOns,
|
|
219
|
-
)) {
|
|
220
|
-
addOns.add(addOn)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
for (const addOn of await selectAddOns(
|
|
224
|
-
framework,
|
|
225
|
-
config.mode!,
|
|
226
|
-
'example',
|
|
227
|
-
'Would you like any examples?',
|
|
228
|
-
config.chosenAddOns,
|
|
229
|
-
)) {
|
|
230
|
-
addOns.add(addOn)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return Array.from(addOns)
|
|
234
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,28 +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
|
-
mcp?: boolean
|
|
14
|
-
mcpSse?: boolean
|
|
15
|
-
starter?: string
|
|
16
|
-
templateId?: string
|
|
17
|
-
targetDir?: string
|
|
18
|
-
interactive?: boolean
|
|
19
|
-
devWatch?: string
|
|
20
|
-
runDev?: boolean
|
|
21
|
-
install?: boolean
|
|
22
|
-
addOnConfig?: string
|
|
23
|
-
force?: boolean
|
|
24
|
-
routerOnly?: boolean
|
|
25
|
-
template?: string
|
|
26
|
-
tailwind?: boolean
|
|
27
|
-
examples?: boolean
|
|
28
|
-
}
|
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
|
-
}
|