create-tsrouter-app 0.3.0-alpha.6 → 0.3.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/index.js +347 -2
- package/package.json +3 -4
- package/src/index.ts +507 -2
- package/templates/{react/base → base}/README.md.ejs +0 -9
- package/templates/{react/base/tsconfig.json.ejs → base/tsconfig.json} +1 -5
- package/templates/base/vite.config.js.ejs +15 -0
- package/templates/file-router/src/routes/__root.tsx +11 -0
- package/dist/add-ons.js +0 -60
- package/dist/cli.js +0 -58
- package/dist/constants.js +0 -4
- package/dist/create-app.js +0 -293
- package/dist/options.js +0 -245
- package/dist/types.js +0 -1
- package/src/add-ons.ts +0 -158
- package/src/cli.ts +0 -90
- package/src/constants.ts +0 -7
- package/src/create-app.ts +0 -460
- package/src/options.ts +0 -284
- package/src/types.ts +0 -28
- package/templates/react/add-on/clerk/README.md +0 -3
- package/templates/react/add-on/clerk/assets/.env.local.append +0 -2
- package/templates/react/add-on/clerk/assets/src/routes/demo.clerk.tsx +0 -20
- package/templates/react/add-on/clerk/info.json +0 -29
- package/templates/react/add-on/clerk/package.json +0 -5
- package/templates/react/add-on/convex/README.md +0 -4
- package/templates/react/add-on/convex/assets/.cursorrules.append +0 -93
- package/templates/react/add-on/convex/assets/.env.local.append +0 -3
- package/templates/react/add-on/convex/assets/convex/products.ts +0 -8
- package/templates/react/add-on/convex/assets/convex/schema.ts +0 -10
- package/templates/react/add-on/convex/assets/src/routes/demo.convex.tsx +0 -33
- package/templates/react/add-on/convex/info.json +0 -28
- package/templates/react/add-on/convex/package.json +0 -6
- package/templates/react/add-on/form/assets/src/routes/demo.form.tsx +0 -50
- package/templates/react/add-on/form/info.json +0 -13
- package/templates/react/add-on/form/package.json +0 -5
- package/templates/react/add-on/module-federation/assets/module-federation.config.js.ejs +0 -31
- package/templates/react/add-on/module-federation/assets/src/demo-mf-component.tsx +0 -3
- package/templates/react/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +0 -11
- package/templates/react/add-on/module-federation/info.json +0 -7
- package/templates/react/add-on/module-federation/package.json +0 -5
- package/templates/react/add-on/netlify/README.md +0 -11
- package/templates/react/add-on/netlify/info.json +0 -7
- package/templates/react/add-on/sentry/assets/.cursorrules +0 -22
- package/templates/react/add-on/sentry/assets/.env.local.append +0 -2
- package/templates/react/add-on/sentry/assets/src/routes/demo.sentry.bad-server-func.tsx +0 -29
- package/templates/react/add-on/sentry/info.json +0 -14
- package/templates/react/add-on/sentry/package.json +0 -5
- package/templates/react/add-on/shadcn/README.md +0 -7
- package/templates/react/add-on/shadcn/info.json +0 -11
- package/templates/react/add-on/start/assets/app.config.ts +0 -16
- package/templates/react/add-on/start/assets/postcss.config.ts +0 -5
- package/templates/react/add-on/start/assets/src/api.ts +0 -6
- package/templates/react/add-on/start/assets/src/client.tsx +0 -10
- package/templates/react/add-on/start/assets/src/router.tsx.ejs +0 -34
- package/templates/react/add-on/start/assets/src/routes/api.demo-names.ts +0 -11
- package/templates/react/add-on/start/assets/src/routes/demo.start.api-request.tsx.ejs +0 -33
- package/templates/react/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +0 -49
- package/templates/react/add-on/start/assets/src/ssr.tsx +0 -12
- package/templates/react/add-on/start/info.json +0 -19
- package/templates/react/add-on/start/package.json +0 -14
- package/templates/react/add-on/store/assets/src/lib/demo-store.ts +0 -5
- package/templates/react/add-on/store/assets/src/routes/demo.store.page1.tsx +0 -30
- package/templates/react/add-on/store/assets/src/routes/demo.store.page2.tsx +0 -30
- package/templates/react/add-on/store/info.json +0 -17
- package/templates/react/add-on/store/package.json +0 -6
- package/templates/react/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx +0 -30
- package/templates/react/add-on/tanstack-query/info.json +0 -31
- package/templates/react/add-on/tanstack-query/package.json +0 -6
- package/templates/react/base/.vscode/settings.json +0 -11
- package/templates/react/base/vite.config.js.ejs +0 -24
- package/templates/react/example/tanchat/README.md +0 -37
- package/templates/react/example/tanchat/assets/.env.local.append +0 -2
- package/templates/react/example/tanchat/assets/src/components/demo.SettingsDialog.tsx +0 -148
- package/templates/react/example/tanchat/assets/src/demo.index.css +0 -220
- package/templates/react/example/tanchat/assets/src/routes/example.chat.tsx.ejs +0 -375
- package/templates/react/example/tanchat/assets/src/store/demo.hooks.ts +0 -21
- package/templates/react/example/tanchat/assets/src/store/demo.store.ts +0 -133
- package/templates/react/example/tanchat/assets/src/utils/demo.ai.ts +0 -108
- package/templates/react/example/tanchat/info.json +0 -15
- package/templates/react/example/tanchat/package.json +0 -10
- package/templates/react/file-router/src/components/Header.tsx.ejs +0 -27
- package/templates/react/file-router/src/routes/__root.tsx.ejs +0 -80
- package/templates/solid/add-on/form/assets/src/routes/demo.form.tsx +0 -136
- package/templates/solid/add-on/form/info.json +0 -13
- package/templates/solid/add-on/form/package.json +0 -5
- package/templates/solid/add-on/module-federation/assets/module-federation.config.js.ejs +0 -27
- package/templates/solid/add-on/module-federation/assets/src/demo-mf-component.tsx +0 -3
- package/templates/solid/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +0 -9
- package/templates/solid/add-on/module-federation/info.json +0 -7
- package/templates/solid/add-on/module-federation/package.json +0 -5
- package/templates/solid/add-on/sentry/assets/.cursorrules.append +0 -22
- package/templates/solid/add-on/sentry/assets/.env.local.append +0 -2
- package/templates/solid/add-on/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +0 -20
- package/templates/solid/add-on/sentry/info.json +0 -13
- package/templates/solid/add-on/sentry/package.json +0 -5
- package/templates/solid/add-on/solid-ui/README.md +0 -9
- package/templates/solid/add-on/solid-ui/assets/src/lib/utils.ts +0 -6
- package/templates/solid/add-on/solid-ui/assets/src/styles.css +0 -138
- package/templates/solid/add-on/solid-ui/assets/ui.config.json +0 -13
- package/templates/solid/add-on/solid-ui/info.json +0 -11
- package/templates/solid/add-on/solid-ui/package.json +0 -9
- package/templates/solid/add-on/store/assets/src/lib/demo-store.ts +0 -5
- package/templates/solid/add-on/store/assets/src/routes/demo.store.page1.tsx +0 -30
- package/templates/solid/add-on/store/assets/src/routes/demo.store.page2.tsx +0 -30
- package/templates/solid/add-on/store/info.json +0 -17
- package/templates/solid/add-on/store/package.json +0 -6
- package/templates/solid/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx +0 -30
- package/templates/solid/add-on/tanstack-query/info.json +0 -31
- package/templates/solid/add-on/tanstack-query/package.json +0 -6
- package/templates/solid/base/.cursorrules +0 -35
- package/templates/solid/base/.vscode/settings.json +0 -11
- package/templates/solid/base/README.md.ejs +0 -200
- package/templates/solid/base/gitignore +0 -5
- package/templates/solid/base/index.html.ejs +0 -20
- package/templates/solid/base/package.json +0 -22
- package/templates/solid/base/package.ts.json +0 -5
- package/templates/solid/base/package.tw.json +0 -6
- package/templates/solid/base/public/favicon.ico +0 -0
- package/templates/solid/base/public/logo192.png +0 -0
- package/templates/solid/base/public/logo512.png +0 -0
- package/templates/solid/base/public/manifest.json +0 -25
- package/templates/solid/base/public/robots.txt +0 -3
- package/templates/solid/base/src/App.css +0 -0
- package/templates/solid/base/src/App.tsx.ejs +0 -47
- package/templates/solid/base/src/logo.svg +0 -120
- package/templates/solid/base/src/styles.css.ejs +0 -15
- package/templates/solid/base/tsconfig.json.ejs +0 -30
- package/templates/solid/base/vite.config.js.ejs +0 -22
- package/templates/solid/code-router/src/main.tsx.ejs +0 -53
- package/templates/solid/file-router/package.fr.json +0 -5
- package/templates/solid/file-router/src/components/Header.tsx.ejs +0 -24
- package/templates/solid/file-router/src/main.tsx.ejs +0 -44
- package/templates/solid/file-router/src/routes/__root.tsx.ejs +0 -47
- package/templates/solid/file-router/src/routes/index.tsx +0 -43
- /package/dist/{package-manager.js → utils/getPackageManager.js} +0 -0
- /package/src/{package-manager.ts → utils/getPackageManager.ts} +0 -0
- /package/templates/{react/base → base}/gitignore +0 -0
- /package/templates/{react/base → base}/index.html.ejs +0 -0
- /package/templates/{react/base → base}/package.json +0 -0
- /package/templates/{react/base → base}/package.ts.json +0 -0
- /package/templates/{react/base → base}/package.tw.json +0 -0
- /package/templates/{react/base → base}/public/favicon.ico +0 -0
- /package/templates/{react/base → base}/public/logo192.png +0 -0
- /package/templates/{react/base → base}/public/logo512.png +0 -0
- /package/templates/{react/base → base}/public/manifest.json +0 -0
- /package/templates/{react/base → base}/public/robots.txt +0 -0
- /package/templates/{react/base → base}/src/App.css +0 -0
- /package/templates/{react/base → base}/src/App.test.tsx.ejs +0 -0
- /package/templates/{react/base → base}/src/App.tsx.ejs +0 -0
- /package/templates/{react/base → base}/src/logo.svg +0 -0
- /package/templates/{react/base → base}/src/reportWebVitals.ts.ejs +0 -0
- /package/templates/{react/base → base}/src/styles.css.ejs +0 -0
- /package/templates/{react/code-router → code-router}/src/main.tsx.ejs +0 -0
- /package/templates/{react/file-router → file-router}/package.fr.json +0 -0
- /package/templates/{react/file-router → file-router}/src/main.tsx.ejs +0 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,348 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { Command, InvalidArgumentError } from 'commander';
|
|
7
|
+
import { cancel, confirm, intro, isCancel, log, outro, select, spinner, text, } from '@clack/prompts';
|
|
8
|
+
import { execa } from 'execa';
|
|
9
|
+
import { render } from 'ejs';
|
|
10
|
+
import { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, } from './utils/getPackageManager.js';
|
|
11
|
+
const program = new Command();
|
|
12
|
+
const CODE_ROUTER = 'code-router';
|
|
13
|
+
const FILE_ROUTER = 'file-router';
|
|
14
|
+
function sortObject(obj) {
|
|
15
|
+
return Object.keys(obj)
|
|
16
|
+
.sort()
|
|
17
|
+
.reduce((acc, key) => {
|
|
18
|
+
acc[key] = obj[key];
|
|
19
|
+
return acc;
|
|
20
|
+
}, {});
|
|
21
|
+
}
|
|
22
|
+
function createCopyFile(targetDir) {
|
|
23
|
+
return async function copyFiles(templateDir, files) {
|
|
24
|
+
for (const file of files) {
|
|
25
|
+
const targetFileName = file.replace('.tw', '');
|
|
26
|
+
await copyFile(resolve(templateDir, file), resolve(targetDir, targetFileName));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function createTemplateFile(projectName, options, targetDir) {
|
|
31
|
+
return async function templateFile(templateDir, file, targetFileName) {
|
|
32
|
+
const templateValues = {
|
|
33
|
+
packageManager: options.packageManager,
|
|
34
|
+
projectName: projectName,
|
|
35
|
+
typescript: options.typescript,
|
|
36
|
+
tailwind: options.tailwind,
|
|
37
|
+
js: options.typescript ? 'ts' : 'js',
|
|
38
|
+
jsx: options.typescript ? 'tsx' : 'jsx',
|
|
39
|
+
fileRouter: options.mode === FILE_ROUTER,
|
|
40
|
+
codeRouter: options.mode === CODE_ROUTER,
|
|
41
|
+
};
|
|
42
|
+
const template = await readFile(resolve(templateDir, file), 'utf-8');
|
|
43
|
+
const content = render(template, templateValues);
|
|
44
|
+
const target = targetFileName ?? file.replace('.ejs', '');
|
|
45
|
+
await writeFile(resolve(targetDir, target), content);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function createPackageJSON(projectName, options, templateDir, routerDir, targetDir) {
|
|
49
|
+
let packageJSON = JSON.parse(await readFile(resolve(templateDir, 'package.json'), 'utf8'));
|
|
50
|
+
packageJSON.name = projectName;
|
|
51
|
+
if (options.typescript) {
|
|
52
|
+
const tsPackageJSON = JSON.parse(await readFile(resolve(templateDir, 'package.ts.json'), 'utf8'));
|
|
53
|
+
packageJSON = {
|
|
54
|
+
...packageJSON,
|
|
55
|
+
devDependencies: {
|
|
56
|
+
...packageJSON.devDependencies,
|
|
57
|
+
...tsPackageJSON.devDependencies,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (options.tailwind) {
|
|
62
|
+
const twPackageJSON = JSON.parse(await readFile(resolve(templateDir, 'package.tw.json'), 'utf8'));
|
|
63
|
+
packageJSON = {
|
|
64
|
+
...packageJSON,
|
|
65
|
+
dependencies: {
|
|
66
|
+
...packageJSON.dependencies,
|
|
67
|
+
...twPackageJSON.dependencies,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (options.mode === FILE_ROUTER) {
|
|
72
|
+
const frPackageJSON = JSON.parse(await readFile(resolve(routerDir, 'package.fr.json'), 'utf8'));
|
|
73
|
+
packageJSON = {
|
|
74
|
+
...packageJSON,
|
|
75
|
+
dependencies: {
|
|
76
|
+
...packageJSON.dependencies,
|
|
77
|
+
...frPackageJSON.dependencies,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
packageJSON.dependencies = sortObject(packageJSON.dependencies);
|
|
82
|
+
packageJSON.devDependencies = sortObject(packageJSON.devDependencies);
|
|
83
|
+
await writeFile(resolve(targetDir, 'package.json'), JSON.stringify(packageJSON, null, 2));
|
|
84
|
+
}
|
|
85
|
+
async function createApp(options) {
|
|
86
|
+
const templateDirBase = fileURLToPath(new URL('../templates/base', import.meta.url));
|
|
87
|
+
const templateDirRouter = fileURLToPath(new URL(`../templates/${options.mode}`, import.meta.url));
|
|
88
|
+
const targetDir = resolve(process.cwd(), options.projectName);
|
|
89
|
+
if (existsSync(targetDir)) {
|
|
90
|
+
log.error(`Directory "${options.projectName}" already exists`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const copyFiles = createCopyFile(targetDir);
|
|
94
|
+
const templateFile = createTemplateFile(options.projectName, options, targetDir);
|
|
95
|
+
intro(`Creating a new TanStack app in ${targetDir}...`);
|
|
96
|
+
// Make the root directory
|
|
97
|
+
await mkdir(targetDir, { recursive: true });
|
|
98
|
+
// Setup the .vscode directory
|
|
99
|
+
await mkdir(resolve(targetDir, '.vscode'), { recursive: true });
|
|
100
|
+
await copyFile(resolve(templateDirBase, '.vscode/settings.json'), resolve(targetDir, '.vscode/settings.json'));
|
|
101
|
+
// Fill the public directory
|
|
102
|
+
await mkdir(resolve(targetDir, 'public'), { recursive: true });
|
|
103
|
+
copyFiles(templateDirBase, [
|
|
104
|
+
'./public/robots.txt',
|
|
105
|
+
'./public/favicon.ico',
|
|
106
|
+
'./public/manifest.json',
|
|
107
|
+
'./public/logo192.png',
|
|
108
|
+
'./public/logo512.png',
|
|
109
|
+
]);
|
|
110
|
+
// Make the src directory
|
|
111
|
+
await mkdir(resolve(targetDir, 'src'), { recursive: true });
|
|
112
|
+
if (options.mode === FILE_ROUTER) {
|
|
113
|
+
await mkdir(resolve(targetDir, 'src/routes'), { recursive: true });
|
|
114
|
+
}
|
|
115
|
+
// Copy in Vite and Tailwind config and CSS
|
|
116
|
+
if (!options.tailwind) {
|
|
117
|
+
await copyFiles(templateDirBase, ['./src/App.css']);
|
|
118
|
+
}
|
|
119
|
+
await templateFile(templateDirBase, './vite.config.js.ejs');
|
|
120
|
+
await templateFile(templateDirBase, './src/styles.css.ejs');
|
|
121
|
+
copyFiles(templateDirBase, ['./src/logo.svg']);
|
|
122
|
+
// Setup the app component. There are four variations, typescript/javascript and tailwind/non-tailwind.
|
|
123
|
+
if (options.mode === FILE_ROUTER) {
|
|
124
|
+
copyFiles(templateDirRouter, ['./src/routes/__root.tsx']);
|
|
125
|
+
await templateFile(templateDirBase, './src/App.tsx.ejs', './src/routes/index.tsx');
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
await templateFile(templateDirBase, './src/App.tsx.ejs', options.typescript ? undefined : './src/App.jsx');
|
|
129
|
+
await templateFile(templateDirBase, './src/App.test.tsx.ejs', options.typescript ? undefined : './src/App.test.jsx');
|
|
130
|
+
}
|
|
131
|
+
// Create the main entry point
|
|
132
|
+
if (options.typescript) {
|
|
133
|
+
await templateFile(templateDirRouter, './src/main.tsx.ejs');
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
await templateFile(templateDirRouter, './src/main.tsx.ejs', './src/main.jsx');
|
|
137
|
+
}
|
|
138
|
+
// Setup the main, reportWebVitals and index.html files
|
|
139
|
+
if (options.typescript) {
|
|
140
|
+
await templateFile(templateDirBase, './src/reportWebVitals.ts.ejs');
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
await templateFile(templateDirBase, './src/reportWebVitals.ts.ejs', './src/reportWebVitals.js');
|
|
144
|
+
}
|
|
145
|
+
await templateFile(templateDirBase, './index.html.ejs');
|
|
146
|
+
// Setup tsconfig
|
|
147
|
+
if (options.typescript) {
|
|
148
|
+
await copyFiles(templateDirBase, ['./tsconfig.json']);
|
|
149
|
+
}
|
|
150
|
+
// Setup the package.json file, optionally with typescript and tailwind
|
|
151
|
+
await createPackageJSON(options.projectName, options, templateDirBase, templateDirRouter, targetDir);
|
|
152
|
+
// Add .gitignore
|
|
153
|
+
await copyFile(resolve(templateDirBase, 'gitignore'), resolve(targetDir, '.gitignore'));
|
|
154
|
+
// Create the README.md
|
|
155
|
+
await templateFile(templateDirBase, 'README.md.ejs');
|
|
156
|
+
// Install dependencies
|
|
157
|
+
const s = spinner();
|
|
158
|
+
s.start(`Installing dependencies via ${options.packageManager}...`);
|
|
159
|
+
await execa(options.packageManager, ['install'], { cwd: targetDir });
|
|
160
|
+
s.stop(`Installed dependencies`);
|
|
161
|
+
if (options.git) {
|
|
162
|
+
s.start(`Initializing git repository...`);
|
|
163
|
+
await execa('git', ['init'], { cwd: targetDir });
|
|
164
|
+
s.stop(`Initialized git repository`);
|
|
165
|
+
}
|
|
166
|
+
outro(`Created your new TanStack app in ${targetDir}.
|
|
167
|
+
|
|
168
|
+
Use the following commands to start your app:
|
|
169
|
+
|
|
170
|
+
% cd ${options.projectName}
|
|
171
|
+
% ${options.packageManager} start
|
|
172
|
+
|
|
173
|
+
Please read README.md for more information on testing, styling, adding routes, react-query, etc.
|
|
174
|
+
`);
|
|
175
|
+
}
|
|
176
|
+
// If all CLI options are provided, use them directly
|
|
177
|
+
function normalizeOptions(cliOptions) {
|
|
178
|
+
if (cliOptions.projectName) {
|
|
179
|
+
const typescript = cliOptions.template === 'typescript' ||
|
|
180
|
+
cliOptions.template === 'file-router';
|
|
181
|
+
return {
|
|
182
|
+
projectName: cliOptions.projectName,
|
|
183
|
+
typescript,
|
|
184
|
+
tailwind: !!cliOptions.tailwind,
|
|
185
|
+
packageManager: cliOptions.packageManager || DEFAULT_PACKAGE_MANAGER,
|
|
186
|
+
mode: cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER,
|
|
187
|
+
git: !!cliOptions.git,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async function promptForOptions(cliOptions) {
|
|
192
|
+
const options = {};
|
|
193
|
+
if (!cliOptions.projectName) {
|
|
194
|
+
const value = await text({
|
|
195
|
+
message: 'What would you like to name your project?',
|
|
196
|
+
defaultValue: 'my-app',
|
|
197
|
+
validate(value) {
|
|
198
|
+
if (!value) {
|
|
199
|
+
return 'Please enter a name';
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
if (isCancel(value)) {
|
|
204
|
+
cancel('Operation cancelled.');
|
|
205
|
+
process.exit(0);
|
|
206
|
+
}
|
|
207
|
+
options.projectName = value;
|
|
208
|
+
}
|
|
209
|
+
// Router type selection
|
|
210
|
+
if (!cliOptions.template) {
|
|
211
|
+
const routerType = await select({
|
|
212
|
+
message: 'Select the router type:',
|
|
213
|
+
options: [
|
|
214
|
+
{
|
|
215
|
+
value: FILE_ROUTER,
|
|
216
|
+
label: 'File Router - File-based routing structure',
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
value: CODE_ROUTER,
|
|
220
|
+
label: 'Code Router - Traditional code-based routing',
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
initialValue: FILE_ROUTER,
|
|
224
|
+
});
|
|
225
|
+
if (isCancel(routerType)) {
|
|
226
|
+
cancel('Operation cancelled.');
|
|
227
|
+
process.exit(0);
|
|
228
|
+
}
|
|
229
|
+
options.mode = routerType;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
options.mode = cliOptions.template;
|
|
233
|
+
if (options.mode === FILE_ROUTER) {
|
|
234
|
+
options.typescript = true;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// TypeScript selection (if using Code Router)
|
|
238
|
+
if (!options.typescript) {
|
|
239
|
+
if (options.mode === CODE_ROUTER) {
|
|
240
|
+
const typescriptEnable = await confirm({
|
|
241
|
+
message: 'Would you like to use TypeScript?',
|
|
242
|
+
initialValue: true,
|
|
243
|
+
});
|
|
244
|
+
if (isCancel(typescriptEnable)) {
|
|
245
|
+
cancel('Operation cancelled.');
|
|
246
|
+
process.exit(0);
|
|
247
|
+
}
|
|
248
|
+
options.typescript = typescriptEnable;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
options.typescript = true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Tailwind selection
|
|
255
|
+
if (cliOptions.tailwind === undefined) {
|
|
256
|
+
const tailwind = await confirm({
|
|
257
|
+
message: 'Would you like to use Tailwind CSS?',
|
|
258
|
+
initialValue: true,
|
|
259
|
+
});
|
|
260
|
+
if (isCancel(tailwind)) {
|
|
261
|
+
cancel('Operation cancelled.');
|
|
262
|
+
process.exit(0);
|
|
263
|
+
}
|
|
264
|
+
options.tailwind = tailwind;
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
options.tailwind = cliOptions.tailwind;
|
|
268
|
+
}
|
|
269
|
+
// Package manager selection
|
|
270
|
+
if (cliOptions.packageManager === undefined) {
|
|
271
|
+
const detectedPackageManager = getPackageManager();
|
|
272
|
+
if (!detectedPackageManager) {
|
|
273
|
+
const pm = await select({
|
|
274
|
+
message: 'Select package manager:',
|
|
275
|
+
options: SUPPORTED_PACKAGE_MANAGERS.map((pm) => ({
|
|
276
|
+
value: pm,
|
|
277
|
+
label: pm,
|
|
278
|
+
})),
|
|
279
|
+
initialValue: DEFAULT_PACKAGE_MANAGER,
|
|
280
|
+
});
|
|
281
|
+
if (isCancel(pm)) {
|
|
282
|
+
cancel('Operation cancelled.');
|
|
283
|
+
process.exit(0);
|
|
284
|
+
}
|
|
285
|
+
options.packageManager = pm;
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
options.packageManager = detectedPackageManager;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
options.packageManager = cliOptions.packageManager;
|
|
293
|
+
}
|
|
294
|
+
// Git selection
|
|
295
|
+
if (cliOptions.git === undefined) {
|
|
296
|
+
const git = await confirm({
|
|
297
|
+
message: 'Would you like to initialize a new git repository?',
|
|
298
|
+
initialValue: true,
|
|
299
|
+
});
|
|
300
|
+
if (isCancel(git)) {
|
|
301
|
+
cancel('Operation cancelled.');
|
|
302
|
+
process.exit(0);
|
|
303
|
+
}
|
|
304
|
+
options.git = git;
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
options.git = !!cliOptions.git;
|
|
308
|
+
}
|
|
309
|
+
return options;
|
|
310
|
+
}
|
|
311
|
+
program
|
|
312
|
+
.name('create-tsrouter-app')
|
|
313
|
+
.description('CLI to create a new TanStack application')
|
|
314
|
+
.argument('[project-name]', 'name of the project')
|
|
315
|
+
.option('--no-git', 'do not create a git repository')
|
|
316
|
+
.option('--template <type>', 'project template (typescript, javascript, file-router)', (value) => {
|
|
317
|
+
if (value !== 'typescript' &&
|
|
318
|
+
value !== 'javascript' &&
|
|
319
|
+
value !== 'file-router') {
|
|
320
|
+
throw new InvalidArgumentError(`Invalid template: ${value}. Only the following are allowed: typescript, javascript, file-router`);
|
|
321
|
+
}
|
|
322
|
+
return value;
|
|
323
|
+
})
|
|
324
|
+
.option(`--package-manager <${SUPPORTED_PACKAGE_MANAGERS.join('|')}>`, `Explicitly tell the CLI to use this package manager`, (value) => {
|
|
325
|
+
if (!SUPPORTED_PACKAGE_MANAGERS.includes(value)) {
|
|
326
|
+
throw new InvalidArgumentError(`Invalid package manager: ${value}. Only the following are allowed: ${SUPPORTED_PACKAGE_MANAGERS.join(', ')}`);
|
|
327
|
+
}
|
|
328
|
+
return value;
|
|
329
|
+
})
|
|
330
|
+
.option('--tailwind', 'add Tailwind CSS')
|
|
331
|
+
.action(async (projectName, options) => {
|
|
332
|
+
try {
|
|
333
|
+
const cliOptions = {
|
|
334
|
+
projectName,
|
|
335
|
+
...options,
|
|
336
|
+
};
|
|
337
|
+
let finalOptions = normalizeOptions(cliOptions);
|
|
338
|
+
if (!finalOptions) {
|
|
339
|
+
finalOptions = await promptForOptions(cliOptions);
|
|
340
|
+
}
|
|
341
|
+
await createApp(finalOptions);
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
log.error(error instanceof Error ? error.message : 'An unknown error occurred');
|
|
345
|
+
process.exit(1);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-tsrouter-app",
|
|
3
|
-
"version": "0.3.0
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Tanstack Application Builder",
|
|
5
5
|
"bin": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,11 +23,9 @@
|
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@clack/prompts": "^0.10.0",
|
|
26
|
-
"chalk": "^5.4.1",
|
|
27
26
|
"commander": "^13.1.0",
|
|
28
27
|
"ejs": "^3.1.10",
|
|
29
|
-
"execa": "^9.5.2"
|
|
30
|
-
"prettier": "^3.5.0"
|
|
28
|
+
"execa": "^9.5.2"
|
|
31
29
|
},
|
|
32
30
|
"devDependencies": {
|
|
33
31
|
"@tanstack/config": "^0.16.2",
|
|
@@ -36,6 +34,7 @@
|
|
|
36
34
|
"eslint": "^9.20.0",
|
|
37
35
|
"eslint-plugin-react-hooks": "^5.1.0",
|
|
38
36
|
"eslint-plugin-unused-imports": "^4.1.4",
|
|
37
|
+
"prettier": "^3.5.0",
|
|
39
38
|
"typescript": "^5.6.3"
|
|
40
39
|
},
|
|
41
40
|
"scripts": {}
|