@tanstack/cta-cli 0.15.12 → 0.16.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/dist/cli.js +66 -3
- package/package.json +5 -3
- package/src/cli.ts +79 -3
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
1
2
|
import { resolve } from 'node:path';
|
|
2
3
|
import { Command, InvalidArgumentError } from 'commander';
|
|
3
4
|
import { intro, log } from '@clack/prompts';
|
|
4
5
|
import chalk from 'chalk';
|
|
5
|
-
import
|
|
6
|
+
import semver from 'semver';
|
|
7
|
+
import { SUPPORTED_PACKAGE_MANAGERS, addToApp, compileAddOn, compileStarter, createApp, createSerializedOptions, getAllAddOns, getFrameworkById, getFrameworks, initAddOn, initStarter, } from '@tanstack/cta-engine';
|
|
6
8
|
import { launchUI } from '@tanstack/cta-ui';
|
|
7
9
|
import { runMCPServer } from './mcp.js';
|
|
8
10
|
import { promptForAddOns, promptForCreateOptions } from './options.js';
|
|
@@ -36,6 +38,66 @@ export function cli({ name, appName, forcedMode, forcedAddOns = [], defaultTempl
|
|
|
36
38
|
defaultMode = Array.from(supportedModes)[0];
|
|
37
39
|
}
|
|
38
40
|
program.name(name).description(`CLI to create a new ${appName} application`);
|
|
41
|
+
program
|
|
42
|
+
.command('pin-versions')
|
|
43
|
+
.description('Pin versions of the TanStack libraries')
|
|
44
|
+
.action(async () => {
|
|
45
|
+
if (!fs.existsSync('package.json')) {
|
|
46
|
+
console.error('package.json not found');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
50
|
+
const packages = {
|
|
51
|
+
'@tanstack/react-router': '',
|
|
52
|
+
'@tanstack/router-generator': '',
|
|
53
|
+
'@tanstack/react-router-devtools': '',
|
|
54
|
+
'@tanstack/react-start': '',
|
|
55
|
+
'@tanstack/react-start-config': '',
|
|
56
|
+
'@tanstack/router-plugin': '',
|
|
57
|
+
'@tanstack/react-start-client': '',
|
|
58
|
+
'@tanstack/react-start-plugin': '1.115.0',
|
|
59
|
+
'@tanstack/react-start-server': '',
|
|
60
|
+
'@tanstack/start-server-core': '1.115.0',
|
|
61
|
+
};
|
|
62
|
+
function sortObject(obj) {
|
|
63
|
+
return Object.keys(obj)
|
|
64
|
+
.sort()
|
|
65
|
+
.reduce((acc, key) => {
|
|
66
|
+
acc[key] = obj[key];
|
|
67
|
+
return acc;
|
|
68
|
+
}, {});
|
|
69
|
+
}
|
|
70
|
+
if (!packageJson.dependencies['@tanstack/react-start']) {
|
|
71
|
+
console.error('@tanstack/react-start not found in dependencies');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
let changed = 0;
|
|
75
|
+
const startVersion = packageJson.dependencies['@tanstack/react-start'].replace(/^\^/, '');
|
|
76
|
+
for (const pkg of Object.keys(packages)) {
|
|
77
|
+
if (!packageJson.dependencies[pkg]) {
|
|
78
|
+
packageJson.dependencies[pkg] = packages[pkg].length
|
|
79
|
+
? semver.maxSatisfying([startVersion, packages[pkg]], `^${packages[pkg]}`)
|
|
80
|
+
: startVersion;
|
|
81
|
+
changed++;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
if (packageJson.dependencies[pkg].startsWith('^')) {
|
|
85
|
+
packageJson.dependencies[pkg] = packageJson.dependencies[pkg].replace(/^\^/, '');
|
|
86
|
+
changed++;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
packageJson.dependencies = sortObject(packageJson.dependencies);
|
|
91
|
+
if (changed > 0) {
|
|
92
|
+
fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2));
|
|
93
|
+
console.log(`${changed} packages updated.
|
|
94
|
+
|
|
95
|
+
Remove your node_modules directory and package lock file and re-install.`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log('No changes needed. The relevant TanStack packages are already pinned.');
|
|
99
|
+
}
|
|
100
|
+
});
|
|
39
101
|
program
|
|
40
102
|
.command('add')
|
|
41
103
|
.argument('[add-on...]', 'Name of the add-ons (or add-ons separated by spaces or commas)')
|
|
@@ -119,7 +181,7 @@ export function cli({ name, appName, forcedMode, forcedAddOns = [], defaultTempl
|
|
|
119
181
|
throw new InvalidArgumentError(`Invalid framework: ${value}. Only the following are allowed: ${availableFrameworks.join(', ')}`);
|
|
120
182
|
}
|
|
121
183
|
return value;
|
|
122
|
-
}, defaultFramework || '
|
|
184
|
+
}, defaultFramework || 'react-cra');
|
|
123
185
|
}
|
|
124
186
|
program
|
|
125
187
|
.option('--starter [url]', 'initialize this project from a starter URL', false)
|
|
@@ -155,6 +217,7 @@ export function cli({ name, appName, forcedMode, forcedAddOns = [], defaultTempl
|
|
|
155
217
|
.option('--ui', 'Add with the UI');
|
|
156
218
|
program.action(async (projectName, options) => {
|
|
157
219
|
if (options.listAddOns) {
|
|
220
|
+
console.log(options.framework || defaultFramework || 'react-cra');
|
|
158
221
|
const addOns = await getAllAddOns(getFrameworkById(options.framework || defaultFramework || 'react-cra'), defaultMode ||
|
|
159
222
|
convertTemplateToMode(options.template || defaultTemplate));
|
|
160
223
|
for (const addOn of addOns.filter((a) => !forcedAddOns.includes(a.id))) {
|
|
@@ -174,7 +237,7 @@ export function cli({ name, appName, forcedMode, forcedAddOns = [], defaultTempl
|
|
|
174
237
|
projectName,
|
|
175
238
|
...options,
|
|
176
239
|
};
|
|
177
|
-
cliOptions.framework =
|
|
240
|
+
cliOptions.framework = getFrameworkById(options.framework || defaultFramework || 'react-cra').id;
|
|
178
241
|
if (defaultMode) {
|
|
179
242
|
cliOptions.template = defaultMode;
|
|
180
243
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/cta-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "Tanstack Application Builder CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,14 +28,16 @@
|
|
|
28
28
|
"chalk": "^5.4.1",
|
|
29
29
|
"commander": "^13.1.0",
|
|
30
30
|
"express": "^4.21.2",
|
|
31
|
+
"semver": "^7.7.2",
|
|
31
32
|
"zod": "^3.24.2",
|
|
32
|
-
"@tanstack/cta-engine": "0.
|
|
33
|
-
"@tanstack/cta-ui": "0.
|
|
33
|
+
"@tanstack/cta-engine": "0.16.1",
|
|
34
|
+
"@tanstack/cta-ui": "0.16.1"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@tanstack/config": "^0.16.2",
|
|
37
38
|
"@types/express": "^5.0.1",
|
|
38
39
|
"@types/node": "^22.13.4",
|
|
40
|
+
"@types/semver": "^7.7.0",
|
|
39
41
|
"@vitest/coverage-v8": "3.1.1",
|
|
40
42
|
"eslint": "^9.20.0",
|
|
41
43
|
"typescript": "^5.6.3",
|
package/src/cli.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
1
2
|
import { resolve } from 'node:path'
|
|
2
3
|
import { Command, InvalidArgumentError } from 'commander'
|
|
3
4
|
import { intro, log } from '@clack/prompts'
|
|
4
5
|
import chalk from 'chalk'
|
|
6
|
+
import semver from 'semver'
|
|
5
7
|
|
|
6
8
|
import {
|
|
7
9
|
SUPPORTED_PACKAGE_MANAGERS,
|
|
@@ -87,6 +89,79 @@ export function cli({
|
|
|
87
89
|
|
|
88
90
|
program.name(name).description(`CLI to create a new ${appName} application`)
|
|
89
91
|
|
|
92
|
+
program
|
|
93
|
+
.command('pin-versions')
|
|
94
|
+
.description('Pin versions of the TanStack libraries')
|
|
95
|
+
.action(async () => {
|
|
96
|
+
if (!fs.existsSync('package.json')) {
|
|
97
|
+
console.error('package.json not found')
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'))
|
|
101
|
+
|
|
102
|
+
const packages: Record<string, string> = {
|
|
103
|
+
'@tanstack/react-router': '',
|
|
104
|
+
'@tanstack/router-generator': '',
|
|
105
|
+
'@tanstack/react-router-devtools': '',
|
|
106
|
+
'@tanstack/react-start': '',
|
|
107
|
+
'@tanstack/react-start-config': '',
|
|
108
|
+
'@tanstack/router-plugin': '',
|
|
109
|
+
'@tanstack/react-start-client': '',
|
|
110
|
+
'@tanstack/react-start-plugin': '1.115.0',
|
|
111
|
+
'@tanstack/react-start-server': '',
|
|
112
|
+
'@tanstack/start-server-core': '1.115.0',
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function sortObject(obj: Record<string, string>): Record<string, string> {
|
|
116
|
+
return Object.keys(obj)
|
|
117
|
+
.sort()
|
|
118
|
+
.reduce<Record<string, string>>((acc, key) => {
|
|
119
|
+
acc[key] = obj[key]
|
|
120
|
+
return acc
|
|
121
|
+
}, {})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!packageJson.dependencies['@tanstack/react-start']) {
|
|
125
|
+
console.error('@tanstack/react-start not found in dependencies')
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
let changed = 0
|
|
129
|
+
const startVersion = packageJson.dependencies[
|
|
130
|
+
'@tanstack/react-start'
|
|
131
|
+
].replace(/^\^/, '')
|
|
132
|
+
for (const pkg of Object.keys(packages)) {
|
|
133
|
+
if (!packageJson.dependencies[pkg]) {
|
|
134
|
+
packageJson.dependencies[pkg] = packages[pkg].length
|
|
135
|
+
? semver.maxSatisfying(
|
|
136
|
+
[startVersion, packages[pkg]],
|
|
137
|
+
`^${packages[pkg]}`,
|
|
138
|
+
)!
|
|
139
|
+
: startVersion
|
|
140
|
+
changed++
|
|
141
|
+
} else {
|
|
142
|
+
if (packageJson.dependencies[pkg].startsWith('^')) {
|
|
143
|
+
packageJson.dependencies[pkg] = packageJson.dependencies[
|
|
144
|
+
pkg
|
|
145
|
+
].replace(/^\^/, '')
|
|
146
|
+
changed++
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
packageJson.dependencies = sortObject(packageJson.dependencies)
|
|
151
|
+
if (changed > 0) {
|
|
152
|
+
fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2))
|
|
153
|
+
console.log(
|
|
154
|
+
`${changed} packages updated.
|
|
155
|
+
|
|
156
|
+
Remove your node_modules directory and package lock file and re-install.`,
|
|
157
|
+
)
|
|
158
|
+
} else {
|
|
159
|
+
console.log(
|
|
160
|
+
'No changes needed. The relevant TanStack packages are already pinned.',
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
|
|
90
165
|
program
|
|
91
166
|
.command('add')
|
|
92
167
|
.argument(
|
|
@@ -191,7 +266,7 @@ export function cli({
|
|
|
191
266
|
}
|
|
192
267
|
return value
|
|
193
268
|
},
|
|
194
|
-
defaultFramework || '
|
|
269
|
+
defaultFramework || 'react-cra',
|
|
195
270
|
)
|
|
196
271
|
}
|
|
197
272
|
|
|
@@ -259,6 +334,7 @@ export function cli({
|
|
|
259
334
|
|
|
260
335
|
program.action(async (projectName: string, options: CliOptions) => {
|
|
261
336
|
if (options.listAddOns) {
|
|
337
|
+
console.log(options.framework || defaultFramework || 'react-cra')
|
|
262
338
|
const addOns = await getAllAddOns(
|
|
263
339
|
getFrameworkById(options.framework || defaultFramework || 'react-cra')!,
|
|
264
340
|
defaultMode ||
|
|
@@ -280,8 +356,8 @@ export function cli({
|
|
|
280
356
|
...options,
|
|
281
357
|
} as CliOptions
|
|
282
358
|
|
|
283
|
-
cliOptions.framework =
|
|
284
|
-
options.framework || defaultFramework || '
|
|
359
|
+
cliOptions.framework = getFrameworkById(
|
|
360
|
+
options.framework || defaultFramework || 'react-cra',
|
|
285
361
|
)!.id
|
|
286
362
|
|
|
287
363
|
if (defaultMode) {
|