create-start-app 0.6.1 → 0.6.2
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 +4 -1
- package/dist/create-app.js +43 -72
- package/dist/environment.js +32 -0
- package/dist/mcp.js +3 -0
- package/package.json +4 -2
- package/src/cli.ts +5 -1
- package/src/create-app.ts +78 -79
- package/src/environment.ts +53 -0
- package/src/mcp.ts +3 -0
- package/templates/react/add-on/form/assets/src/components/demo.FormComponents.tsx +120 -0
- package/templates/react/add-on/form/assets/src/hooks/demo.form-context.ts +4 -0
- package/templates/react/add-on/form/assets/src/hooks/demo.form.ts +22 -0
- package/templates/react/add-on/form/assets/src/routes/demo.form.address.tsx.ejs +203 -0
- package/templates/react/add-on/form/assets/src/routes/demo.form.simple.tsx.ejs +79 -0
- package/templates/react/add-on/form/info.json +6 -2
- package/templates/react/add-on/form/package.json +2 -1
- package/templates/react/base/README.md.ejs +1 -1
- package/templates/react/example/tanchat/info.json +1 -1
- package/templates/solid/add-on/form/assets/src/routes/demo.form.tsx.ejs +310 -106
- package/templates/solid/add-on/form/package.json +1 -1
- package/tests/cra.test.ts +112 -0
- package/tests/snapshots/cra/cr-js-npm.json +34 -0
- package/tests/snapshots/cra/cr-ts-npm.json +35 -0
- package/tests/snapshots/cra/fr-ts-npm.json +35 -0
- package/tests/snapshots/cra/fr-ts-tw-npm.json +34 -0
- package/tests/test-utilities.ts +69 -0
- package/templates/react/add-on/form/assets/src/routes/demo.form.tsx.ejs +0 -62
package/dist/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ import { SUPPORTED_TOOLCHAINS } from './toolchain.js';
|
|
|
7
7
|
import runServer from './mcp.js';
|
|
8
8
|
import { listAddOns } from './add-ons.js';
|
|
9
9
|
import { DEFAULT_FRAMEWORK, SUPPORTED_FRAMEWORKS } from './constants.js';
|
|
10
|
+
import { createDefaultEnvironment } from './environment.js';
|
|
10
11
|
export function cli() {
|
|
11
12
|
const program = new Command();
|
|
12
13
|
program
|
|
@@ -72,7 +73,9 @@ export function cli() {
|
|
|
72
73
|
intro("Let's configure your TanStack application");
|
|
73
74
|
finalOptions = await promptForOptions(cliOptions);
|
|
74
75
|
}
|
|
75
|
-
await createApp(finalOptions
|
|
76
|
+
await createApp(finalOptions, {
|
|
77
|
+
environment: createDefaultEnvironment(),
|
|
78
|
+
});
|
|
76
79
|
}
|
|
77
80
|
catch (error) {
|
|
78
81
|
log.error(error instanceof Error
|
package/dist/create-app.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { appendFile, copyFile, mkdir, readFile, writeFile, } from 'node:fs/promises';
|
|
3
|
-
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
4
1
|
import { basename, dirname, resolve } from 'node:path';
|
|
5
2
|
import { fileURLToPath } from 'node:url';
|
|
6
3
|
import { log, outro, spinner } from '@clack/prompts';
|
|
7
|
-
import { execa } from 'execa';
|
|
8
4
|
import { render } from 'ejs';
|
|
9
5
|
import { format } from 'prettier';
|
|
10
6
|
import chalk from 'chalk';
|
|
@@ -17,7 +13,7 @@ function sortObject(obj) {
|
|
|
17
13
|
return acc;
|
|
18
14
|
}, {});
|
|
19
15
|
}
|
|
20
|
-
function createCopyFiles(targetDir) {
|
|
16
|
+
function createCopyFiles(environment, targetDir) {
|
|
21
17
|
return async function copyFiles(templateDir, files,
|
|
22
18
|
// optionally copy files from a folder to the root
|
|
23
19
|
toRoot) {
|
|
@@ -27,7 +23,7 @@ function createCopyFiles(targetDir) {
|
|
|
27
23
|
const fileNoPath = targetFileName.split('/').pop();
|
|
28
24
|
targetFileName = fileNoPath ? `./${fileNoPath}` : targetFileName;
|
|
29
25
|
}
|
|
30
|
-
await copyFile(resolve(templateDir, file), resolve(targetDir, targetFileName));
|
|
26
|
+
await environment.copyFile(resolve(templateDir, file), resolve(targetDir, targetFileName));
|
|
31
27
|
}
|
|
32
28
|
};
|
|
33
29
|
}
|
|
@@ -37,7 +33,7 @@ function jsSafeName(name) {
|
|
|
37
33
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
38
34
|
.join('');
|
|
39
35
|
}
|
|
40
|
-
function createTemplateFile(projectName, options, targetDir) {
|
|
36
|
+
function createTemplateFile(environment, projectName, options, targetDir) {
|
|
41
37
|
return async function templateFile(templateDir, file, targetFileName, extraTemplateValues) {
|
|
42
38
|
const templateValues = {
|
|
43
39
|
packageManager: options.packageManager,
|
|
@@ -56,7 +52,7 @@ function createTemplateFile(projectName, options, targetDir) {
|
|
|
56
52
|
addOns: options.chosenAddOns,
|
|
57
53
|
...extraTemplateValues,
|
|
58
54
|
};
|
|
59
|
-
const template = await readFile(resolve(templateDir, file), 'utf-8');
|
|
55
|
+
const template = await environment.readFile(resolve(templateDir, file), 'utf-8');
|
|
60
56
|
let content = '';
|
|
61
57
|
try {
|
|
62
58
|
content = render(template, templateValues);
|
|
@@ -75,17 +71,14 @@ function createTemplateFile(projectName, options, targetDir) {
|
|
|
75
71
|
parser: 'typescript',
|
|
76
72
|
});
|
|
77
73
|
}
|
|
78
|
-
await
|
|
79
|
-
recursive: true,
|
|
80
|
-
});
|
|
81
|
-
await writeFile(resolve(targetDir, target), content);
|
|
74
|
+
await environment.writeFile(resolve(targetDir, target), content);
|
|
82
75
|
};
|
|
83
76
|
}
|
|
84
|
-
async function createPackageJSON(projectName, options, templateDir, routerDir, targetDir, addOns) {
|
|
85
|
-
let packageJSON = JSON.parse(await readFile(resolve(templateDir, 'package.json'), 'utf8'));
|
|
77
|
+
async function createPackageJSON(environment, projectName, options, templateDir, routerDir, targetDir, addOns) {
|
|
78
|
+
let packageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.json'), 'utf8'));
|
|
86
79
|
packageJSON.name = projectName;
|
|
87
80
|
if (options.typescript) {
|
|
88
|
-
const tsPackageJSON = JSON.parse(await readFile(resolve(templateDir, 'package.ts.json'), 'utf8'));
|
|
81
|
+
const tsPackageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.ts.json'), 'utf8'));
|
|
89
82
|
packageJSON = {
|
|
90
83
|
...packageJSON,
|
|
91
84
|
devDependencies: {
|
|
@@ -95,7 +88,7 @@ async function createPackageJSON(projectName, options, templateDir, routerDir, t
|
|
|
95
88
|
};
|
|
96
89
|
}
|
|
97
90
|
if (options.tailwind) {
|
|
98
|
-
const twPackageJSON = JSON.parse(await readFile(resolve(templateDir, 'package.tw.json'), 'utf8'));
|
|
91
|
+
const twPackageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.tw.json'), 'utf8'));
|
|
99
92
|
packageJSON = {
|
|
100
93
|
...packageJSON,
|
|
101
94
|
dependencies: {
|
|
@@ -105,7 +98,7 @@ async function createPackageJSON(projectName, options, templateDir, routerDir, t
|
|
|
105
98
|
};
|
|
106
99
|
}
|
|
107
100
|
if (options.toolchain === 'biome') {
|
|
108
|
-
const biomePackageJSON = JSON.parse(await readFile(resolve(templateDir, 'package.biome.json'), 'utf8'));
|
|
101
|
+
const biomePackageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.biome.json'), 'utf8'));
|
|
109
102
|
packageJSON = {
|
|
110
103
|
...packageJSON,
|
|
111
104
|
scripts: {
|
|
@@ -119,7 +112,7 @@ async function createPackageJSON(projectName, options, templateDir, routerDir, t
|
|
|
119
112
|
};
|
|
120
113
|
}
|
|
121
114
|
if (options.mode === FILE_ROUTER) {
|
|
122
|
-
const frPackageJSON = JSON.parse(await readFile(resolve(routerDir, 'package.fr.json'), 'utf8'));
|
|
115
|
+
const frPackageJSON = JSON.parse(await environment.readFile(resolve(routerDir, 'package.fr.json'), 'utf8'));
|
|
123
116
|
packageJSON = {
|
|
124
117
|
...packageJSON,
|
|
125
118
|
dependencies: {
|
|
@@ -147,16 +140,15 @@ async function createPackageJSON(projectName, options, templateDir, routerDir, t
|
|
|
147
140
|
}
|
|
148
141
|
packageJSON.dependencies = sortObject(packageJSON.dependencies);
|
|
149
142
|
packageJSON.devDependencies = sortObject(packageJSON.devDependencies);
|
|
150
|
-
await writeFile(resolve(targetDir, 'package.json'), JSON.stringify(packageJSON, null, 2));
|
|
143
|
+
await environment.writeFile(resolve(targetDir, 'package.json'), JSON.stringify(packageJSON, null, 2));
|
|
151
144
|
}
|
|
152
|
-
async function copyFilesRecursively(source, target,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const files = readdirSync(source);
|
|
145
|
+
async function copyFilesRecursively(environment, source, target, templateFile) {
|
|
146
|
+
if (environment.isDirectory(source)) {
|
|
147
|
+
const files = environment.readdir(source);
|
|
156
148
|
for (const file of files) {
|
|
157
149
|
const sourceChild = resolve(source, file);
|
|
158
150
|
const targetChild = resolve(target, file);
|
|
159
|
-
await copyFilesRecursively(sourceChild, targetChild,
|
|
151
|
+
await copyFilesRecursively(environment, sourceChild, targetChild, templateFile);
|
|
160
152
|
}
|
|
161
153
|
}
|
|
162
154
|
else {
|
|
@@ -172,49 +164,42 @@ async function copyFilesRecursively(source, target, copyFile, templateFile) {
|
|
|
172
164
|
isAppend = true;
|
|
173
165
|
}
|
|
174
166
|
const targetPath = resolve(dirname(target), targetFile);
|
|
175
|
-
await mkdir(dirname(targetPath), {
|
|
176
|
-
recursive: true,
|
|
177
|
-
});
|
|
178
167
|
if (isTemplate) {
|
|
179
168
|
await templateFile(source, targetPath);
|
|
180
169
|
}
|
|
181
170
|
else {
|
|
182
171
|
if (isAppend) {
|
|
183
|
-
await appendFile(targetPath, (await readFile(source)).toString());
|
|
172
|
+
await environment.appendFile(targetPath, (await environment.readFile(source)).toString());
|
|
184
173
|
}
|
|
185
174
|
else {
|
|
186
|
-
await copyFile(source, targetPath);
|
|
175
|
+
await environment.copyFile(source, targetPath);
|
|
187
176
|
}
|
|
188
177
|
}
|
|
189
178
|
}
|
|
190
179
|
}
|
|
191
|
-
export async function createApp(options, { silent = false,
|
|
180
|
+
export async function createApp(options, { silent = false, environment, }) {
|
|
192
181
|
const templateDirBase = fileURLToPath(new URL(`../templates/${options.framework}/base`, import.meta.url));
|
|
193
182
|
const templateDirRouter = fileURLToPath(new URL(`../templates/${options.framework}/${options.mode}`, import.meta.url));
|
|
194
183
|
const targetDir = resolve(process.cwd(), options.projectName);
|
|
195
|
-
if (
|
|
184
|
+
if (environment.exists(targetDir)) {
|
|
196
185
|
if (!silent) {
|
|
197
186
|
log.error(`Directory "${options.projectName}" already exists`);
|
|
198
187
|
}
|
|
199
188
|
return;
|
|
200
189
|
}
|
|
201
|
-
const copyFiles = createCopyFiles(targetDir);
|
|
202
|
-
const templateFile = createTemplateFile(options.projectName, options, targetDir);
|
|
190
|
+
const copyFiles = createCopyFiles(environment, targetDir);
|
|
191
|
+
const templateFile = createTemplateFile(environment, options.projectName, options, targetDir);
|
|
203
192
|
const isAddOnEnabled = (id) => options.chosenAddOns.find((a) => a.id === id);
|
|
204
|
-
// Make the root directory
|
|
205
|
-
await mkdir(targetDir, { recursive: true });
|
|
206
193
|
// Setup the .vscode directory
|
|
207
|
-
await mkdir(resolve(targetDir, '.vscode'), { recursive: true });
|
|
208
194
|
switch (options.toolchain) {
|
|
209
195
|
case 'biome':
|
|
210
|
-
await copyFile(resolve(templateDirBase, '_dot_vscode/settings.biome.json'), resolve(targetDir, '.vscode/settings.json'));
|
|
196
|
+
await environment.copyFile(resolve(templateDirBase, '_dot_vscode/settings.biome.json'), resolve(targetDir, '.vscode/settings.json'));
|
|
211
197
|
break;
|
|
212
198
|
case 'none':
|
|
213
199
|
default:
|
|
214
|
-
await copyFile(resolve(templateDirBase, '_dot_vscode/settings.json'), resolve(targetDir, '.vscode/settings.json'));
|
|
200
|
+
await environment.copyFile(resolve(templateDirBase, '_dot_vscode/settings.json'), resolve(targetDir, '.vscode/settings.json'));
|
|
215
201
|
}
|
|
216
202
|
// Fill the public directory
|
|
217
|
-
await mkdir(resolve(targetDir, 'public'), { recursive: true });
|
|
218
203
|
copyFiles(templateDirBase, [
|
|
219
204
|
'./public/robots.txt',
|
|
220
205
|
'./public/favicon.ico',
|
|
@@ -222,15 +207,9 @@ export async function createApp(options, { silent = false, } = {}) {
|
|
|
222
207
|
'./public/logo192.png',
|
|
223
208
|
'./public/logo512.png',
|
|
224
209
|
]);
|
|
225
|
-
// Make the src directory
|
|
226
|
-
await mkdir(resolve(targetDir, 'src'), { recursive: true });
|
|
227
|
-
if (options.mode === FILE_ROUTER) {
|
|
228
|
-
await mkdir(resolve(targetDir, 'src/routes'), { recursive: true });
|
|
229
|
-
await mkdir(resolve(targetDir, 'src/components'), { recursive: true });
|
|
230
|
-
}
|
|
231
210
|
// Check for a .cursorrules file
|
|
232
|
-
if (
|
|
233
|
-
await copyFile(resolve(templateDirBase, '.cursorrules'), resolve(targetDir, '.cursorrules'));
|
|
211
|
+
if (environment.exists(resolve(templateDirBase, '.cursorrules'))) {
|
|
212
|
+
await environment.copyFile(resolve(templateDirBase, '.cursorrules'), resolve(targetDir, '.cursorrules'));
|
|
234
213
|
}
|
|
235
214
|
// Copy in Vite and Tailwind config and CSS
|
|
236
215
|
if (!options.tailwind) {
|
|
@@ -259,20 +238,18 @@ export async function createApp(options, { silent = false, } = {}) {
|
|
|
259
238
|
await templateFile(templateDirBase, './tsconfig.json.ejs', './tsconfig.json');
|
|
260
239
|
}
|
|
261
240
|
// Setup the package.json file, optionally with typescript, tailwind and biome
|
|
262
|
-
await createPackageJSON(options.projectName, options, templateDirBase, templateDirRouter, targetDir, options.chosenAddOns.map((addOn) => addOn.packageAdditions));
|
|
241
|
+
await createPackageJSON(environment, options.projectName, options, templateDirBase, templateDirRouter, targetDir, options.chosenAddOns.map((addOn) => addOn.packageAdditions));
|
|
263
242
|
// Copy all the asset files from the addons
|
|
264
243
|
const s = silent ? null : spinner();
|
|
265
244
|
for (const phase of ['setup', 'add-on', 'example']) {
|
|
266
245
|
for (const addOn of options.chosenAddOns.filter((addOn) => addOn.phase === phase)) {
|
|
267
246
|
s?.start(`Setting up ${addOn.name}...`);
|
|
268
247
|
const addOnDir = resolve(addOn.directory, 'assets');
|
|
269
|
-
if (
|
|
270
|
-
await copyFilesRecursively(addOnDir, targetDir,
|
|
248
|
+
if (environment.exists(addOnDir)) {
|
|
249
|
+
await copyFilesRecursively(environment, addOnDir, targetDir, async (file, targetFileName) => templateFile(addOnDir, file, targetFileName));
|
|
271
250
|
}
|
|
272
251
|
if (addOn.command) {
|
|
273
|
-
await
|
|
274
|
-
cwd: targetDir,
|
|
275
|
-
});
|
|
252
|
+
await environment.execute(addOn.command.command, addOn.command.args || [], targetDir);
|
|
276
253
|
}
|
|
277
254
|
s?.stop(`${addOn.name} setup complete`);
|
|
278
255
|
}
|
|
@@ -288,31 +265,29 @@ export async function createApp(options, { silent = false, } = {}) {
|
|
|
288
265
|
}
|
|
289
266
|
if (shadcnComponents.size > 0) {
|
|
290
267
|
s?.start(`Installing shadcn components (${Array.from(shadcnComponents).join(', ')})...`);
|
|
291
|
-
await
|
|
292
|
-
cwd: targetDir,
|
|
293
|
-
});
|
|
268
|
+
await environment.execute('npx', ['shadcn@canary', 'add', ...shadcnComponents], targetDir);
|
|
294
269
|
s?.stop(`Installed shadcn components`);
|
|
295
270
|
}
|
|
296
271
|
}
|
|
297
272
|
const integrations = [];
|
|
298
|
-
if (
|
|
299
|
-
for (const integration of
|
|
273
|
+
if (environment.exists(resolve(targetDir, 'src/integrations'))) {
|
|
274
|
+
for (const integration of environment.readdir(resolve(targetDir, 'src/integrations'))) {
|
|
300
275
|
const integrationName = jsSafeName(integration);
|
|
301
|
-
if (
|
|
276
|
+
if (environment.exists(resolve(targetDir, 'src/integrations', integration, 'layout.tsx'))) {
|
|
302
277
|
integrations.push({
|
|
303
278
|
type: 'layout',
|
|
304
279
|
name: `${integrationName}Layout`,
|
|
305
280
|
path: `integrations/${integration}/layout`,
|
|
306
281
|
});
|
|
307
282
|
}
|
|
308
|
-
if (
|
|
283
|
+
if (environment.exists(resolve(targetDir, 'src/integrations', integration, 'provider.tsx'))) {
|
|
309
284
|
integrations.push({
|
|
310
285
|
type: 'provider',
|
|
311
286
|
name: `${integrationName}Provider`,
|
|
312
287
|
path: `integrations/${integration}/provider`,
|
|
313
288
|
});
|
|
314
289
|
}
|
|
315
|
-
if (
|
|
290
|
+
if (environment.exists(resolve(targetDir, 'src/integrations', integration, 'header-user.tsx'))) {
|
|
316
291
|
integrations.push({
|
|
317
292
|
type: 'header-user',
|
|
318
293
|
name: `${integrationName}Header`,
|
|
@@ -322,8 +297,8 @@ export async function createApp(options, { silent = false, } = {}) {
|
|
|
322
297
|
}
|
|
323
298
|
}
|
|
324
299
|
const routes = [];
|
|
325
|
-
if (
|
|
326
|
-
for (const file of
|
|
300
|
+
if (environment.exists(resolve(targetDir, 'src/routes'))) {
|
|
301
|
+
for (const file of environment.readdir(resolve(targetDir, 'src/routes'))) {
|
|
327
302
|
const name = file.replace(/\.tsx?|\.jsx?/, '');
|
|
328
303
|
const safeRouteName = jsSafeName(name);
|
|
329
304
|
routes.push({
|
|
@@ -374,12 +349,12 @@ export async function createApp(options, { silent = false, } = {}) {
|
|
|
374
349
|
}
|
|
375
350
|
}
|
|
376
351
|
// Add .gitignore
|
|
377
|
-
await copyFile(resolve(templateDirBase, '_dot_gitignore'), resolve(targetDir, '.gitignore'));
|
|
352
|
+
await environment.copyFile(resolve(templateDirBase, '_dot_gitignore'), resolve(targetDir, '.gitignore'));
|
|
378
353
|
// Create the README.md
|
|
379
354
|
await templateFile(templateDirBase, 'README.md.ejs');
|
|
380
355
|
// Install dependencies
|
|
381
356
|
s?.start(`Installing dependencies via ${options.packageManager}...`);
|
|
382
|
-
await
|
|
357
|
+
await environment.execute(options.packageManager, ['install'], targetDir);
|
|
383
358
|
s?.stop(`Installed dependencies`);
|
|
384
359
|
if (warnings.length > 0) {
|
|
385
360
|
if (!silent) {
|
|
@@ -391,21 +366,17 @@ export async function createApp(options, { silent = false, } = {}) {
|
|
|
391
366
|
switch (options.packageManager) {
|
|
392
367
|
case 'pnpm':
|
|
393
368
|
// pnpm automatically forwards extra arguments
|
|
394
|
-
await
|
|
395
|
-
cwd: targetDir,
|
|
396
|
-
});
|
|
369
|
+
await environment.execute(options.packageManager, ['run', 'check', '--fix'], targetDir);
|
|
397
370
|
break;
|
|
398
371
|
default:
|
|
399
|
-
await
|
|
400
|
-
cwd: targetDir,
|
|
401
|
-
});
|
|
372
|
+
await environment.execute(options.packageManager, ['run', 'check', '--', '--fix'], targetDir);
|
|
402
373
|
break;
|
|
403
374
|
}
|
|
404
375
|
s?.stop(`Applied toolchain ${options.toolchain}...`);
|
|
405
376
|
}
|
|
406
377
|
if (options.git) {
|
|
407
378
|
s?.start(`Initializing git repository...`);
|
|
408
|
-
await
|
|
379
|
+
await environment.execute('git', ['init'], targetDir);
|
|
409
380
|
s?.stop(`Initialized git repository`);
|
|
410
381
|
}
|
|
411
382
|
if (!silent) {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { appendFile, copyFile, mkdir, readFile, writeFile, } from 'node:fs/promises';
|
|
2
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { execa } from 'execa';
|
|
5
|
+
export function createDefaultEnvironment() {
|
|
6
|
+
return {
|
|
7
|
+
appendFile: async (path, contents) => {
|
|
8
|
+
await mkdir(dirname(path), { recursive: true });
|
|
9
|
+
return appendFile(path, contents);
|
|
10
|
+
},
|
|
11
|
+
copyFile: async (from, to) => {
|
|
12
|
+
await mkdir(dirname(to), { recursive: true });
|
|
13
|
+
return copyFile(from, to);
|
|
14
|
+
},
|
|
15
|
+
writeFile: async (path, contents) => {
|
|
16
|
+
await mkdir(dirname(path), { recursive: true });
|
|
17
|
+
return writeFile(path, contents);
|
|
18
|
+
},
|
|
19
|
+
execute: async (command, args, cwd) => {
|
|
20
|
+
await execa(command, args, {
|
|
21
|
+
cwd,
|
|
22
|
+
});
|
|
23
|
+
},
|
|
24
|
+
readFile: (path, encoding) => readFile(path, { encoding: encoding || 'utf8' }),
|
|
25
|
+
exists: (path) => existsSync(path),
|
|
26
|
+
readdir: (path) => readdirSync(path),
|
|
27
|
+
isDirectory: (path) => {
|
|
28
|
+
const stat = statSync(path);
|
|
29
|
+
return stat.isDirectory();
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
package/dist/mcp.js
CHANGED
|
@@ -5,6 +5,7 @@ import express from 'express';
|
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import { createApp } from './create-app.js';
|
|
7
7
|
import { finalizeAddOns } from './add-ons.js';
|
|
8
|
+
import { createDefaultEnvironment } from './environment.js';
|
|
8
9
|
const server = new McpServer({
|
|
9
10
|
name: 'Demo',
|
|
10
11
|
version: '1.0.0',
|
|
@@ -93,6 +94,7 @@ server.tool('createTanStackReactApplication', {
|
|
|
93
94
|
variableValues: {},
|
|
94
95
|
}, {
|
|
95
96
|
silent: true,
|
|
97
|
+
environment: createDefaultEnvironment(),
|
|
96
98
|
});
|
|
97
99
|
return {
|
|
98
100
|
content: [{ type: 'text', text: 'Application created successfully' }],
|
|
@@ -170,6 +172,7 @@ server.tool('createTanStackSolidApplication', {
|
|
|
170
172
|
variableValues: {},
|
|
171
173
|
}, {
|
|
172
174
|
silent: true,
|
|
175
|
+
environment: createDefaultEnvironment(),
|
|
173
176
|
});
|
|
174
177
|
return {
|
|
175
178
|
content: [{ type: 'text', text: 'Application created successfully' }],
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-start-app",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Tanstack Application Builder",
|
|
5
5
|
"bin": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"start": "tsc && node dist/index.js",
|
|
10
|
-
"test": "npm run test:lint",
|
|
10
|
+
"test": "npm run test:lint && vitest --run",
|
|
11
|
+
"test:watch": "vitest",
|
|
11
12
|
"cipublish": "node scripts/publish.js",
|
|
12
13
|
"test:lint": "eslint ./src",
|
|
13
14
|
"mcp": "tsc && npx @modelcontextprotocol/inspector dist/index.js --mcp"
|
|
@@ -39,6 +40,7 @@
|
|
|
39
40
|
"execa": "^9.5.2",
|
|
40
41
|
"express": "^4.21.2",
|
|
41
42
|
"prettier": "^3.5.0",
|
|
43
|
+
"vitest": "^3.0.8",
|
|
42
44
|
"zod": "^3.24.2"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
package/src/cli.ts
CHANGED
|
@@ -10,6 +10,8 @@ import runServer from './mcp.js'
|
|
|
10
10
|
import { listAddOns } from './add-ons.js'
|
|
11
11
|
import { DEFAULT_FRAMEWORK, SUPPORTED_FRAMEWORKS } from './constants.js'
|
|
12
12
|
|
|
13
|
+
import { createDefaultEnvironment } from './environment.js'
|
|
14
|
+
|
|
13
15
|
import type { PackageManager } from './package-manager.js'
|
|
14
16
|
import type { ToolChain } from './toolchain.js'
|
|
15
17
|
import type { CliOptions, Framework } from './types.js'
|
|
@@ -115,7 +117,9 @@ export function cli() {
|
|
|
115
117
|
intro("Let's configure your TanStack application")
|
|
116
118
|
finalOptions = await promptForOptions(cliOptions)
|
|
117
119
|
}
|
|
118
|
-
await createApp(finalOptions
|
|
120
|
+
await createApp(finalOptions, {
|
|
121
|
+
environment: createDefaultEnvironment(),
|
|
122
|
+
})
|
|
119
123
|
} catch (error) {
|
|
120
124
|
log.error(
|
|
121
125
|
error instanceof Error
|