@tanstack/cli 0.0.8 → 0.48.3
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/LICENSE +21 -0
- package/dist/bin.js +7 -0
- package/dist/cli.js +481 -0
- package/dist/command-line.js +174 -0
- package/dist/dev-watch.js +290 -0
- package/dist/file-syncer.js +148 -0
- package/dist/index.js +1 -0
- package/dist/mcp/api.js +31 -0
- package/dist/mcp/tools.js +250 -0
- package/dist/mcp/types.js +37 -0
- package/dist/mcp.js +121 -0
- package/dist/options.js +162 -0
- package/dist/types/bin.d.ts +2 -0
- package/dist/types/cli.d.ts +16 -0
- package/dist/types/command-line.d.ts +10 -0
- package/dist/types/dev-watch.d.ts +27 -0
- package/dist/types/file-syncer.d.ts +18 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/mcp/api.d.ts +4 -0
- package/dist/types/mcp/tools.d.ts +2 -0
- package/dist/types/mcp/types.d.ts +217 -0
- package/dist/types/mcp.d.ts +6 -0
- package/dist/types/options.d.ts +8 -0
- package/dist/types/types.d.ts +25 -0
- package/dist/types/ui-environment.d.ts +2 -0
- package/dist/types/ui-prompts.d.ts +12 -0
- package/dist/types/utils.d.ts +8 -0
- package/dist/types.js +1 -0
- package/dist/ui-environment.js +52 -0
- package/dist/ui-prompts.js +244 -0
- package/dist/utils.js +30 -0
- package/package.json +46 -47
- package/src/bin.ts +6 -93
- package/src/cli.ts +692 -0
- package/src/command-line.ts +236 -0
- package/src/dev-watch.ts +430 -0
- package/src/file-syncer.ts +205 -0
- package/src/index.ts +1 -85
- package/src/mcp.ts +190 -0
- package/src/options.ts +260 -0
- package/src/types.ts +27 -0
- package/src/ui-environment.ts +74 -0
- package/src/ui-prompts.ts +322 -0
- package/src/utils.ts +38 -0
- package/tests/command-line.test.ts +304 -0
- package/tests/index.test.ts +9 -0
- package/tests/mcp.test.ts +225 -0
- package/tests/options.test.ts +304 -0
- package/tests/setupVitest.ts +6 -0
- package/tests/ui-environment.test.ts +97 -0
- package/tests/ui-prompts.test.ts +238 -0
- package/tsconfig.json +17 -0
- package/vitest.config.js +7 -0
- package/dist/bin.cjs +0 -769
- package/dist/bin.d.cts +0 -1
- package/dist/bin.d.mts +0 -1
- package/dist/bin.mjs +0 -768
- package/dist/fetch-CbFFGJEw.cjs +0 -3
- package/dist/fetch-DG5dLrsb.cjs +0 -522
- package/dist/fetch-DhlVXS6S.mjs +0 -390
- package/dist/fetch-I_OVg8JX.mjs +0 -3
- package/dist/index.cjs +0 -37
- package/dist/index.d.cts +0 -1172
- package/dist/index.d.mts +0 -1172
- package/dist/index.mjs +0 -4
- package/dist/template-Szi7-AZJ.mjs +0 -2202
- package/dist/template-lWrIZhCQ.cjs +0 -2314
- package/src/api/fetch.test.ts +0 -114
- package/src/api/fetch.ts +0 -278
- package/src/cache/index.ts +0 -89
- package/src/commands/create.ts +0 -470
- package/src/commands/mcp.test.ts +0 -152
- package/src/commands/mcp.ts +0 -211
- package/src/engine/compile-with-addons.test.ts +0 -302
- package/src/engine/compile.test.ts +0 -404
- package/src/engine/compile.ts +0 -569
- package/src/engine/config-file.test.ts +0 -118
- package/src/engine/config-file.ts +0 -61
- package/src/engine/custom-addons/integration.ts +0 -323
- package/src/engine/custom-addons/shared.test.ts +0 -98
- package/src/engine/custom-addons/shared.ts +0 -281
- package/src/engine/custom-addons/template.test.ts +0 -288
- package/src/engine/custom-addons/template.ts +0 -124
- package/src/engine/template.test.ts +0 -256
- package/src/engine/template.ts +0 -269
- package/src/engine/types.ts +0 -336
- package/src/parse-gitignore.d.ts +0 -5
- package/src/templates/base.ts +0 -883
package/dist/bin.cjs
DELETED
|
@@ -1,769 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const require_template = require('./template-lWrIZhCQ.cjs');
|
|
3
|
-
const require_fetch = require('./fetch-DG5dLrsb.cjs');
|
|
4
|
-
let node_fs = require("node:fs");
|
|
5
|
-
let node_path = require("node:path");
|
|
6
|
-
let zod = require("zod");
|
|
7
|
-
let commander = require("commander");
|
|
8
|
-
let _clack_prompts = require("@clack/prompts");
|
|
9
|
-
let chalk = require("chalk");
|
|
10
|
-
chalk = require_template.__toESM(chalk);
|
|
11
|
-
let _modelcontextprotocol_sdk_server_mcp_js = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
12
|
-
let _modelcontextprotocol_sdk_server_stdio_js = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
13
|
-
let _modelcontextprotocol_sdk_server_sse_js = require("@modelcontextprotocol/sdk/server/sse.js");
|
|
14
|
-
let express = require("express");
|
|
15
|
-
express = require_template.__toESM(express);
|
|
16
|
-
|
|
17
|
-
//#region src/commands/create.ts
|
|
18
|
-
const PACKAGE_MANAGERS = [
|
|
19
|
-
"pnpm",
|
|
20
|
-
"npm",
|
|
21
|
-
"yarn",
|
|
22
|
-
"bun",
|
|
23
|
-
"deno"
|
|
24
|
-
];
|
|
25
|
-
function detectPackageManager() {
|
|
26
|
-
const userAgent = process.env.npm_config_user_agent;
|
|
27
|
-
if (userAgent) {
|
|
28
|
-
if (userAgent.includes("pnpm")) return "pnpm";
|
|
29
|
-
if (userAgent.includes("yarn")) return "yarn";
|
|
30
|
-
if (userAgent.includes("bun")) return "bun";
|
|
31
|
-
if (userAgent.includes("deno")) return "deno";
|
|
32
|
-
}
|
|
33
|
-
return "npm";
|
|
34
|
-
}
|
|
35
|
-
function validateProjectName(name) {
|
|
36
|
-
if (!name) return {
|
|
37
|
-
valid: false,
|
|
38
|
-
error: "Project name is required"
|
|
39
|
-
};
|
|
40
|
-
if (!/^[a-z0-9-_]+$/.test(name)) return {
|
|
41
|
-
valid: false,
|
|
42
|
-
error: "Project name can only contain lowercase letters, numbers, hyphens, and underscores"
|
|
43
|
-
};
|
|
44
|
-
return { valid: true };
|
|
45
|
-
}
|
|
46
|
-
function groupIntegrationsByCategory(integrations) {
|
|
47
|
-
const groups = {};
|
|
48
|
-
for (const integration of integrations) {
|
|
49
|
-
const category = integration.category ?? "other";
|
|
50
|
-
groups[category] ??= [];
|
|
51
|
-
groups[category].push(integration);
|
|
52
|
-
}
|
|
53
|
-
return groups;
|
|
54
|
-
}
|
|
55
|
-
const CATEGORY_LABELS = {
|
|
56
|
-
tanstack: "TanStack",
|
|
57
|
-
database: "Database",
|
|
58
|
-
orm: "ORM",
|
|
59
|
-
auth: "Authentication",
|
|
60
|
-
deploy: "Deployment",
|
|
61
|
-
tooling: "Tooling",
|
|
62
|
-
monitoring: "Monitoring",
|
|
63
|
-
api: "API",
|
|
64
|
-
i18n: "Internationalization",
|
|
65
|
-
cms: "CMS",
|
|
66
|
-
other: "Other"
|
|
67
|
-
};
|
|
68
|
-
const CATEGORY_ORDER = [
|
|
69
|
-
"tanstack",
|
|
70
|
-
"database",
|
|
71
|
-
"orm",
|
|
72
|
-
"auth",
|
|
73
|
-
"deploy",
|
|
74
|
-
"api",
|
|
75
|
-
"monitoring",
|
|
76
|
-
"tooling",
|
|
77
|
-
"i18n",
|
|
78
|
-
"cms",
|
|
79
|
-
"other"
|
|
80
|
-
];
|
|
81
|
-
async function runCreate(projectName, options) {
|
|
82
|
-
(0, _clack_prompts.intro)(chalk.default.bgCyan(chalk.default.black(" TanStack Start ")));
|
|
83
|
-
const s = (0, _clack_prompts.spinner)();
|
|
84
|
-
const integrationsPath = options.integrationsPath;
|
|
85
|
-
s.start("Fetching available integrations...");
|
|
86
|
-
let manifest;
|
|
87
|
-
try {
|
|
88
|
-
manifest = await require_fetch.fetchManifest(integrationsPath);
|
|
89
|
-
s.stop("Integrations loaded");
|
|
90
|
-
} catch (error$1) {
|
|
91
|
-
s.stop("Failed to fetch integrations");
|
|
92
|
-
_clack_prompts.log.error("Could not fetch integration manifest. Check your internet connection.");
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
let name = projectName;
|
|
96
|
-
if (!name && !options.yes) {
|
|
97
|
-
const nameInput = await (0, _clack_prompts.text)({
|
|
98
|
-
message: "Project name:",
|
|
99
|
-
placeholder: "my-tanstack-app",
|
|
100
|
-
defaultValue: "my-tanstack-app",
|
|
101
|
-
validate: (value) => {
|
|
102
|
-
const result = validateProjectName(value);
|
|
103
|
-
return result.valid ? void 0 : result.error;
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
if ((0, _clack_prompts.isCancel)(nameInput)) {
|
|
107
|
-
(0, _clack_prompts.cancel)("Operation cancelled.");
|
|
108
|
-
process.exit(0);
|
|
109
|
-
}
|
|
110
|
-
name = nameInput;
|
|
111
|
-
}
|
|
112
|
-
name = name ?? "my-tanstack-app";
|
|
113
|
-
const { valid, error } = validateProjectName(name);
|
|
114
|
-
if (!valid) {
|
|
115
|
-
_clack_prompts.log.error(error ?? "Invalid project name");
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
const targetDir = options.targetDir ? (0, node_path.resolve)(options.targetDir) : (0, node_path.resolve)(process.cwd(), name);
|
|
119
|
-
if ((0, node_fs.existsSync)(targetDir)) {
|
|
120
|
-
if (!options.yes) {
|
|
121
|
-
const overwrite = await (0, _clack_prompts.confirm)({
|
|
122
|
-
message: `Directory ${chalk.default.cyan(name)} already exists. Overwrite?`,
|
|
123
|
-
initialValue: false
|
|
124
|
-
});
|
|
125
|
-
if ((0, _clack_prompts.isCancel)(overwrite) || !overwrite) {
|
|
126
|
-
(0, _clack_prompts.cancel)("Operation cancelled.");
|
|
127
|
-
process.exit(0);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
let packageManager = options.packageManager ?? detectPackageManager();
|
|
132
|
-
if (!options.packageManager && !options.yes) {
|
|
133
|
-
const pmChoice = await (0, _clack_prompts.select)({
|
|
134
|
-
message: "Package manager:",
|
|
135
|
-
options: PACKAGE_MANAGERS.map((pm) => ({
|
|
136
|
-
value: pm,
|
|
137
|
-
label: pm
|
|
138
|
-
})),
|
|
139
|
-
initialValue: packageManager
|
|
140
|
-
});
|
|
141
|
-
if ((0, _clack_prompts.isCancel)(pmChoice)) {
|
|
142
|
-
(0, _clack_prompts.cancel)("Operation cancelled.");
|
|
143
|
-
process.exit(0);
|
|
144
|
-
}
|
|
145
|
-
packageManager = pmChoice;
|
|
146
|
-
}
|
|
147
|
-
let tailwind = options.tailwind ?? true;
|
|
148
|
-
if (options.tailwind === void 0 && !options.yes) {
|
|
149
|
-
const twChoice = await (0, _clack_prompts.confirm)({
|
|
150
|
-
message: "Include Tailwind CSS?",
|
|
151
|
-
initialValue: true
|
|
152
|
-
});
|
|
153
|
-
if ((0, _clack_prompts.isCancel)(twChoice)) {
|
|
154
|
-
(0, _clack_prompts.cancel)("Operation cancelled.");
|
|
155
|
-
process.exit(0);
|
|
156
|
-
}
|
|
157
|
-
tailwind = twChoice;
|
|
158
|
-
}
|
|
159
|
-
let selectedIntegrationIds = [];
|
|
160
|
-
if (options.integrations) selectedIntegrationIds = options.integrations.split(",").map((s$1) => s$1.trim());
|
|
161
|
-
else if (!options.yes) {
|
|
162
|
-
const grouped = groupIntegrationsByCategory(manifest.integrations.filter((a) => a.type === "integration" && a.modes.includes("file-router")));
|
|
163
|
-
const categoryOptions = CATEGORY_ORDER.filter((cat) => grouped[cat]?.length).map((cat) => ({
|
|
164
|
-
value: cat,
|
|
165
|
-
label: CATEGORY_LABELS[cat] ?? cat,
|
|
166
|
-
hint: `${grouped[cat].length} integrations`
|
|
167
|
-
}));
|
|
168
|
-
(0, _clack_prompts.note)("Use arrow keys to navigate, space to select/deselect, enter to confirm.", "Integration Selection");
|
|
169
|
-
const selectedCategories = await (0, _clack_prompts.multiselect)({
|
|
170
|
-
message: "Which categories would you like to explore?",
|
|
171
|
-
options: categoryOptions,
|
|
172
|
-
required: false
|
|
173
|
-
});
|
|
174
|
-
if ((0, _clack_prompts.isCancel)(selectedCategories)) {
|
|
175
|
-
(0, _clack_prompts.cancel)("Operation cancelled.");
|
|
176
|
-
process.exit(0);
|
|
177
|
-
}
|
|
178
|
-
for (const category of selectedCategories) {
|
|
179
|
-
const categoryIntegrations = grouped[category];
|
|
180
|
-
if (!categoryIntegrations?.length) continue;
|
|
181
|
-
const integrationChoices = await (0, _clack_prompts.multiselect)({
|
|
182
|
-
message: `Select ${CATEGORY_LABELS[category]} integrations:`,
|
|
183
|
-
options: categoryIntegrations.map((integration) => ({
|
|
184
|
-
value: integration.id,
|
|
185
|
-
label: integration.name,
|
|
186
|
-
hint: integration.description
|
|
187
|
-
})),
|
|
188
|
-
required: false
|
|
189
|
-
});
|
|
190
|
-
if ((0, _clack_prompts.isCancel)(integrationChoices)) {
|
|
191
|
-
(0, _clack_prompts.cancel)("Operation cancelled.");
|
|
192
|
-
process.exit(0);
|
|
193
|
-
}
|
|
194
|
-
selectedIntegrationIds.push(...integrationChoices);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
const integrationMap = new Map(manifest.integrations.map((a) => [a.id, a]));
|
|
198
|
-
const resolvedIds = new Set(selectedIntegrationIds);
|
|
199
|
-
for (const id of selectedIntegrationIds) {
|
|
200
|
-
const integration = integrationMap.get(id);
|
|
201
|
-
if (integration?.dependsOn) for (const dep of integration.dependsOn) resolvedIds.add(dep);
|
|
202
|
-
}
|
|
203
|
-
if (resolvedIds.size > 0) (0, _clack_prompts.note)(Array.from(resolvedIds).map((id) => {
|
|
204
|
-
const integration = integrationMap.get(id);
|
|
205
|
-
return ` ${!selectedIntegrationIds.includes(id) && resolvedIds.has(id) ? chalk.default.dim("(auto)") : chalk.default.green("+")} ${integration?.name ?? id}`;
|
|
206
|
-
}).join("\n"), "Selected Integrations");
|
|
207
|
-
if (!options.yes) {
|
|
208
|
-
const proceed = await (0, _clack_prompts.confirm)({
|
|
209
|
-
message: "Create project?",
|
|
210
|
-
initialValue: true
|
|
211
|
-
});
|
|
212
|
-
if ((0, _clack_prompts.isCancel)(proceed) || !proceed) {
|
|
213
|
-
(0, _clack_prompts.cancel)("Operation cancelled.");
|
|
214
|
-
process.exit(0);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
s.start("Preparing project...");
|
|
218
|
-
let customTemplate;
|
|
219
|
-
if (options.template) try {
|
|
220
|
-
customTemplate = await require_template.loadTemplate(options.template);
|
|
221
|
-
for (const integrationId of customTemplate.integrations) resolvedIds.add(integrationId);
|
|
222
|
-
tailwind = customTemplate.tailwind;
|
|
223
|
-
} catch (error$1) {
|
|
224
|
-
s.stop("Failed to load template");
|
|
225
|
-
_clack_prompts.log.error(error$1 instanceof Error ? error$1.message : "Could not load template from URL.");
|
|
226
|
-
process.exit(1);
|
|
227
|
-
}
|
|
228
|
-
let chosenIntegrations = [];
|
|
229
|
-
if (resolvedIds.size > 0) try {
|
|
230
|
-
chosenIntegrations = await require_fetch.fetchIntegrations(Array.from(resolvedIds), integrationsPath);
|
|
231
|
-
} catch (error$1) {
|
|
232
|
-
s.stop("Failed to fetch integration details");
|
|
233
|
-
_clack_prompts.log.error("Could not fetch integration definitions.");
|
|
234
|
-
process.exit(1);
|
|
235
|
-
}
|
|
236
|
-
const compileOptions = {
|
|
237
|
-
projectName: name,
|
|
238
|
-
framework: customTemplate?.framework ?? "react",
|
|
239
|
-
mode: customTemplate?.mode ?? "file-router",
|
|
240
|
-
typescript: customTemplate?.typescript ?? true,
|
|
241
|
-
tailwind,
|
|
242
|
-
packageManager,
|
|
243
|
-
chosenIntegrations,
|
|
244
|
-
integrationOptions: customTemplate?.integrationOptions ?? {},
|
|
245
|
-
customTemplate
|
|
246
|
-
};
|
|
247
|
-
const output = require_template.compile(compileOptions);
|
|
248
|
-
s.stop("Project prepared");
|
|
249
|
-
s.start("Writing files...");
|
|
250
|
-
(0, node_fs.mkdirSync)(targetDir, { recursive: true });
|
|
251
|
-
for (const [filePath, content] of Object.entries(output.files)) {
|
|
252
|
-
const fullPath = (0, node_path.resolve)(targetDir, filePath);
|
|
253
|
-
(0, node_fs.mkdirSync)((0, node_path.resolve)(fullPath, ".."), { recursive: true });
|
|
254
|
-
if (content.startsWith(require_fetch.BINARY_PREFIX)) {
|
|
255
|
-
const base64Data = content.slice(require_fetch.BINARY_PREFIX.length);
|
|
256
|
-
(0, node_fs.writeFileSync)(fullPath, Buffer.from(base64Data, "base64"));
|
|
257
|
-
} else (0, node_fs.writeFileSync)(fullPath, content, "utf-8");
|
|
258
|
-
}
|
|
259
|
-
await require_template.writeConfigFile(targetDir, compileOptions);
|
|
260
|
-
s.stop("Files written");
|
|
261
|
-
if (options.git !== false) {
|
|
262
|
-
s.start("Initializing git repository...");
|
|
263
|
-
try {
|
|
264
|
-
const { execSync } = await import("node:child_process");
|
|
265
|
-
execSync("git init", {
|
|
266
|
-
cwd: targetDir,
|
|
267
|
-
stdio: "ignore"
|
|
268
|
-
});
|
|
269
|
-
s.stop("Git initialized");
|
|
270
|
-
} catch {
|
|
271
|
-
s.stop("Git initialization skipped");
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
if (options.install !== false) {
|
|
275
|
-
s.start(`Installing dependencies with ${packageManager}...`);
|
|
276
|
-
const startTime = Date.now();
|
|
277
|
-
const interval = setInterval(() => {
|
|
278
|
-
const elapsed = Math.floor((Date.now() - startTime) / 1e3);
|
|
279
|
-
s.message(`Installing dependencies with ${packageManager}... (${elapsed}s)`);
|
|
280
|
-
}, 1e3);
|
|
281
|
-
try {
|
|
282
|
-
const { execSync } = await import("node:child_process");
|
|
283
|
-
execSync(packageManager === "yarn" ? "yarn" : `${packageManager} install`, {
|
|
284
|
-
cwd: targetDir,
|
|
285
|
-
stdio: "ignore"
|
|
286
|
-
});
|
|
287
|
-
clearInterval(interval);
|
|
288
|
-
const total = Math.floor((Date.now() - startTime) / 1e3);
|
|
289
|
-
s.stop(`Dependencies installed (${total}s)`);
|
|
290
|
-
} catch {
|
|
291
|
-
clearInterval(interval);
|
|
292
|
-
s.stop("Dependency installation failed");
|
|
293
|
-
_clack_prompts.log.warning(`Run "${packageManager} install" manually to install dependencies.`);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
const relativePath = (0, node_path.resolve)(process.cwd()) === targetDir ? "." : name;
|
|
297
|
-
(0, _clack_prompts.outro)(chalk.default.green("Project created successfully!"));
|
|
298
|
-
console.log();
|
|
299
|
-
console.log("Next steps:");
|
|
300
|
-
console.log();
|
|
301
|
-
if (relativePath !== ".") console.log(` ${chalk.default.cyan("cd")} ${relativePath}`);
|
|
302
|
-
if (options.install === false) console.log(` ${chalk.default.cyan(packageManager)} install`);
|
|
303
|
-
console.log(` ${chalk.default.cyan(packageManager)} ${packageManager === "npm" ? "run " : ""}dev`);
|
|
304
|
-
console.log();
|
|
305
|
-
if (output.envVars.length > 0) {
|
|
306
|
-
console.log(chalk.default.yellow("Environment variables needed:"));
|
|
307
|
-
console.log();
|
|
308
|
-
for (const envVar of output.envVars) console.log(` ${chalk.default.cyan(envVar.name)} - ${envVar.description}`);
|
|
309
|
-
console.log();
|
|
310
|
-
console.log(` Add these to your ${chalk.default.cyan(".env.local")} file.`);
|
|
311
|
-
console.log();
|
|
312
|
-
}
|
|
313
|
-
for (const warning of output.warnings) _clack_prompts.log.warning(warning);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
//#endregion
|
|
317
|
-
//#region src/mcp/types.ts
|
|
318
|
-
const LibrarySchema = zod.z.object({
|
|
319
|
-
id: zod.z.string(),
|
|
320
|
-
name: zod.z.string(),
|
|
321
|
-
tagline: zod.z.string(),
|
|
322
|
-
description: zod.z.string().optional(),
|
|
323
|
-
frameworks: zod.z.array(zod.z.string()),
|
|
324
|
-
latestVersion: zod.z.string(),
|
|
325
|
-
latestBranch: zod.z.string().optional(),
|
|
326
|
-
availableVersions: zod.z.array(zod.z.string()),
|
|
327
|
-
repo: zod.z.string(),
|
|
328
|
-
docsRoot: zod.z.string().optional(),
|
|
329
|
-
defaultDocs: zod.z.string().optional(),
|
|
330
|
-
docsUrl: zod.z.string().optional(),
|
|
331
|
-
githubUrl: zod.z.string().optional()
|
|
332
|
-
});
|
|
333
|
-
const LibrariesResponseSchema = zod.z.object({
|
|
334
|
-
libraries: zod.z.array(LibrarySchema),
|
|
335
|
-
groups: zod.z.record(zod.z.array(zod.z.string())),
|
|
336
|
-
groupNames: zod.z.record(zod.z.string())
|
|
337
|
-
});
|
|
338
|
-
const PartnerSchema = zod.z.object({
|
|
339
|
-
id: zod.z.string(),
|
|
340
|
-
name: zod.z.string(),
|
|
341
|
-
tagline: zod.z.string().optional(),
|
|
342
|
-
description: zod.z.string(),
|
|
343
|
-
category: zod.z.string(),
|
|
344
|
-
categoryLabel: zod.z.string(),
|
|
345
|
-
libraries: zod.z.array(zod.z.string()),
|
|
346
|
-
url: zod.z.string()
|
|
347
|
-
});
|
|
348
|
-
const PartnersResponseSchema = zod.z.object({
|
|
349
|
-
partners: zod.z.array(PartnerSchema),
|
|
350
|
-
categories: zod.z.array(zod.z.string()),
|
|
351
|
-
categoryLabels: zod.z.record(zod.z.string())
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
//#endregion
|
|
355
|
-
//#region src/mcp/api.ts
|
|
356
|
-
const TANSTACK_API_BASE = "https://tanstack.com/api/data";
|
|
357
|
-
async function fetchLibraries() {
|
|
358
|
-
const response = await fetch(`${TANSTACK_API_BASE}/libraries`);
|
|
359
|
-
if (!response.ok) throw new Error(`Failed to fetch libraries: ${response.statusText}`);
|
|
360
|
-
const data = await response.json();
|
|
361
|
-
return LibrariesResponseSchema.parse(data);
|
|
362
|
-
}
|
|
363
|
-
async function fetchPartners() {
|
|
364
|
-
const response = await fetch(`${TANSTACK_API_BASE}/partners`);
|
|
365
|
-
if (!response.ok) throw new Error(`Failed to fetch partners: ${response.statusText}`);
|
|
366
|
-
const data = await response.json();
|
|
367
|
-
return PartnersResponseSchema.parse(data);
|
|
368
|
-
}
|
|
369
|
-
async function fetchDocContent(repo, branch, filePath) {
|
|
370
|
-
const url = `https://raw.githubusercontent.com/${repo}/${branch}/${filePath}`;
|
|
371
|
-
const response = await fetch(url, { headers: { "User-Agent": "tanstack-cli" } });
|
|
372
|
-
if (!response.ok) {
|
|
373
|
-
if (response.status === 404) return null;
|
|
374
|
-
throw new Error(`Failed to fetch doc: ${response.statusText}`);
|
|
375
|
-
}
|
|
376
|
-
return response.text();
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
//#endregion
|
|
380
|
-
//#region src/mcp/tools.ts
|
|
381
|
-
const ALGOLIA_APP_ID = "FQ0DQ6MA3C";
|
|
382
|
-
const ALGOLIA_API_KEY = "10c34d6a5c89f6048cf644d601e65172";
|
|
383
|
-
const ALGOLIA_INDEX = "tanstack-test";
|
|
384
|
-
const GROUP_KEYS = [
|
|
385
|
-
"state",
|
|
386
|
-
"headlessUI",
|
|
387
|
-
"performance",
|
|
388
|
-
"tooling"
|
|
389
|
-
];
|
|
390
|
-
function jsonResult(data) {
|
|
391
|
-
return { content: [{
|
|
392
|
-
type: "text",
|
|
393
|
-
text: JSON.stringify(data, null, 2)
|
|
394
|
-
}] };
|
|
395
|
-
}
|
|
396
|
-
function errorResult(error) {
|
|
397
|
-
return {
|
|
398
|
-
content: [{
|
|
399
|
-
type: "text",
|
|
400
|
-
text: `Error: ${error}`
|
|
401
|
-
}],
|
|
402
|
-
isError: true
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
function registerDocTools(server) {
|
|
406
|
-
server.tool("tanstack_list_libraries", "List TanStack libraries with metadata, frameworks, and docs URLs.", { group: zod.z.enum(GROUP_KEYS).optional().describe("Filter libraries by group. Options: state, headlessUI, performance, tooling") }, async ({ group }) => {
|
|
407
|
-
try {
|
|
408
|
-
const data = await fetchLibraries();
|
|
409
|
-
let libraries = data.libraries;
|
|
410
|
-
if (group && data.groups[group]) {
|
|
411
|
-
const groupIds = data.groups[group];
|
|
412
|
-
libraries = libraries.filter((lib) => groupIds.includes(lib.id));
|
|
413
|
-
}
|
|
414
|
-
return jsonResult({
|
|
415
|
-
group: group ? data.groupNames[group] || group : "All Libraries",
|
|
416
|
-
count: libraries.length,
|
|
417
|
-
libraries: libraries.map((lib) => ({
|
|
418
|
-
id: lib.id,
|
|
419
|
-
name: lib.name,
|
|
420
|
-
tagline: lib.tagline,
|
|
421
|
-
description: lib.description,
|
|
422
|
-
frameworks: lib.frameworks,
|
|
423
|
-
latestVersion: lib.latestVersion,
|
|
424
|
-
docsUrl: lib.docsUrl,
|
|
425
|
-
githubUrl: lib.githubUrl
|
|
426
|
-
}))
|
|
427
|
-
});
|
|
428
|
-
} catch (error) {
|
|
429
|
-
return errorResult(String(error));
|
|
430
|
-
}
|
|
431
|
-
});
|
|
432
|
-
server.tool("tanstack_doc", "Fetch a TanStack documentation page by library and path.", {
|
|
433
|
-
library: zod.z.string().describe("Library ID (e.g., query, router, table, form)"),
|
|
434
|
-
path: zod.z.string().describe("Documentation path (e.g., framework/react/overview)"),
|
|
435
|
-
version: zod.z.string().optional().describe("Version (e.g., v5, v1). Defaults to latest")
|
|
436
|
-
}, async ({ library: libraryId, path, version = "latest" }) => {
|
|
437
|
-
try {
|
|
438
|
-
const library = (await fetchLibraries()).libraries.find((l) => l.id === libraryId);
|
|
439
|
-
if (!library) return errorResult(`Library "${libraryId}" not found. Use tanstack_list_libraries to see available libraries.`);
|
|
440
|
-
if (version !== "latest" && !library.availableVersions.includes(version)) return errorResult(`Version "${version}" not found for ${library.name}. Available: ${library.availableVersions.join(", ")}`);
|
|
441
|
-
const branch = version === "latest" || version === library.latestVersion ? library.latestBranch || "main" : version;
|
|
442
|
-
const filePath = `${library.docsRoot || "docs"}/${path}.md`;
|
|
443
|
-
const content = await fetchDocContent(library.repo, branch, filePath);
|
|
444
|
-
if (!content) return errorResult(`Document not found: ${library.name} / ${path} (version: ${version})`);
|
|
445
|
-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
446
|
-
let title = path.split("/").pop() || "Untitled";
|
|
447
|
-
let docContent = content;
|
|
448
|
-
if (frontmatterMatch && frontmatterMatch[1]) {
|
|
449
|
-
const titleMatch = frontmatterMatch[1].match(/title:\s*['"]?([^'"\n]+)['"]?/);
|
|
450
|
-
if (titleMatch && titleMatch[1]) title = titleMatch[1];
|
|
451
|
-
docContent = content.slice(frontmatterMatch[0].length).trim();
|
|
452
|
-
}
|
|
453
|
-
return jsonResult({
|
|
454
|
-
title,
|
|
455
|
-
content: docContent,
|
|
456
|
-
url: `https://tanstack.com/${libraryId}/${version}/docs/${path}`,
|
|
457
|
-
library: library.name,
|
|
458
|
-
version: version === "latest" ? library.latestVersion : version
|
|
459
|
-
});
|
|
460
|
-
} catch (error) {
|
|
461
|
-
return errorResult(String(error));
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
server.tool("tanstack_search_docs", "Search TanStack documentation. Returns matching pages with snippets.", {
|
|
465
|
-
query: zod.z.string().describe("Search query"),
|
|
466
|
-
library: zod.z.string().optional().describe("Filter to specific library (e.g., query, router)"),
|
|
467
|
-
framework: zod.z.string().optional().describe("Filter to specific framework (e.g., react, vue, solid)"),
|
|
468
|
-
limit: zod.z.number().min(1).max(50).optional().describe("Maximum number of results (default: 10, max: 50)")
|
|
469
|
-
}, async ({ query, library, framework, limit = 10 }) => {
|
|
470
|
-
try {
|
|
471
|
-
const ALL_LIBRARIES = [
|
|
472
|
-
"config",
|
|
473
|
-
"form",
|
|
474
|
-
"optimistic",
|
|
475
|
-
"pacer",
|
|
476
|
-
"query",
|
|
477
|
-
"ranger",
|
|
478
|
-
"react-charts",
|
|
479
|
-
"router",
|
|
480
|
-
"start",
|
|
481
|
-
"store",
|
|
482
|
-
"table",
|
|
483
|
-
"virtual",
|
|
484
|
-
"db",
|
|
485
|
-
"devtools"
|
|
486
|
-
];
|
|
487
|
-
const ALL_FRAMEWORKS = [
|
|
488
|
-
"react",
|
|
489
|
-
"vue",
|
|
490
|
-
"solid",
|
|
491
|
-
"svelte",
|
|
492
|
-
"angular"
|
|
493
|
-
];
|
|
494
|
-
const filterParts = ["version:latest"];
|
|
495
|
-
if (library) {
|
|
496
|
-
const exclusions = ALL_LIBRARIES.filter((l) => l !== library).map((l) => `NOT library:${l}`).join(" AND ");
|
|
497
|
-
if (exclusions) filterParts.push(`(${exclusions})`);
|
|
498
|
-
}
|
|
499
|
-
if (framework) {
|
|
500
|
-
const exclusions = ALL_FRAMEWORKS.filter((f) => f !== framework).map((f) => `NOT framework:${f}`).join(" AND ");
|
|
501
|
-
if (exclusions) filterParts.push(`(${exclusions})`);
|
|
502
|
-
}
|
|
503
|
-
const searchParams = { requests: [{
|
|
504
|
-
indexName: ALGOLIA_INDEX,
|
|
505
|
-
query,
|
|
506
|
-
hitsPerPage: Math.min(limit, 50),
|
|
507
|
-
filters: filterParts.join(" AND "),
|
|
508
|
-
attributesToRetrieve: [
|
|
509
|
-
"hierarchy",
|
|
510
|
-
"url",
|
|
511
|
-
"content",
|
|
512
|
-
"library"
|
|
513
|
-
],
|
|
514
|
-
attributesToSnippet: ["content:80"]
|
|
515
|
-
}] };
|
|
516
|
-
const response = await fetch(`https://${ALGOLIA_APP_ID}-dsn.algolia.net/1/indexes/*/queries`, {
|
|
517
|
-
method: "POST",
|
|
518
|
-
headers: {
|
|
519
|
-
"Content-Type": "application/json",
|
|
520
|
-
"X-Algolia-Application-Id": ALGOLIA_APP_ID,
|
|
521
|
-
"X-Algolia-API-Key": ALGOLIA_API_KEY
|
|
522
|
-
},
|
|
523
|
-
body: JSON.stringify(searchParams)
|
|
524
|
-
});
|
|
525
|
-
if (!response.ok) return errorResult(`Algolia search failed: ${response.statusText}`);
|
|
526
|
-
const searchResult = (await response.json()).results[0];
|
|
527
|
-
if (!searchResult) return jsonResult({
|
|
528
|
-
query,
|
|
529
|
-
totalHits: 0,
|
|
530
|
-
results: []
|
|
531
|
-
});
|
|
532
|
-
const results = searchResult.hits.map((hit) => {
|
|
533
|
-
const breadcrumb = Object.values(hit.hierarchy).filter((v) => Boolean(v));
|
|
534
|
-
return {
|
|
535
|
-
title: hit.hierarchy.lvl1 || hit.hierarchy.lvl0 || "Untitled",
|
|
536
|
-
url: hit.url,
|
|
537
|
-
snippet: hit._snippetResult?.content?.value || hit.content || "",
|
|
538
|
-
library: hit.library || "unknown",
|
|
539
|
-
breadcrumb
|
|
540
|
-
};
|
|
541
|
-
});
|
|
542
|
-
return jsonResult({
|
|
543
|
-
query,
|
|
544
|
-
totalHits: searchResult.nbHits || results.length,
|
|
545
|
-
results
|
|
546
|
-
});
|
|
547
|
-
} catch (error) {
|
|
548
|
-
return errorResult(String(error));
|
|
549
|
-
}
|
|
550
|
-
});
|
|
551
|
-
server.tool("tanstack_ecosystem", "Ecosystem partner recommendations. Filter by category (database, auth, deployment, monitoring, cms, api, data-grid) or library.", {
|
|
552
|
-
category: zod.z.string().optional().describe("Filter by category: database, auth, deployment, monitoring, cms, api, data-grid, code-review, learning"),
|
|
553
|
-
library: zod.z.string().optional().describe("Filter by TanStack library (e.g., start, router, query, table)")
|
|
554
|
-
}, async ({ category, library }) => {
|
|
555
|
-
try {
|
|
556
|
-
const data = await fetchPartners();
|
|
557
|
-
const categoryAliases = {
|
|
558
|
-
db: "database",
|
|
559
|
-
postgres: "database",
|
|
560
|
-
sql: "database",
|
|
561
|
-
login: "auth",
|
|
562
|
-
authentication: "auth",
|
|
563
|
-
hosting: "deployment",
|
|
564
|
-
deploy: "deployment",
|
|
565
|
-
serverless: "deployment",
|
|
566
|
-
errors: "monitoring",
|
|
567
|
-
logging: "monitoring",
|
|
568
|
-
content: "cms",
|
|
569
|
-
"api-keys": "api",
|
|
570
|
-
grid: "data-grid",
|
|
571
|
-
review: "code-review",
|
|
572
|
-
courses: "learning"
|
|
573
|
-
};
|
|
574
|
-
let resolvedCategory;
|
|
575
|
-
if (category) {
|
|
576
|
-
const normalized = category.toLowerCase().trim();
|
|
577
|
-
resolvedCategory = categoryAliases[normalized] || normalized;
|
|
578
|
-
if (!data.categories.includes(resolvedCategory)) resolvedCategory = void 0;
|
|
579
|
-
}
|
|
580
|
-
const lib = library?.toLowerCase().trim();
|
|
581
|
-
const partners = data.partners.filter((p) => !resolvedCategory || p.category === resolvedCategory).filter((p) => !lib || p.libraries.some((l) => l === lib)).map((p) => ({
|
|
582
|
-
id: p.id,
|
|
583
|
-
name: p.name,
|
|
584
|
-
tagline: p.tagline,
|
|
585
|
-
description: p.description,
|
|
586
|
-
category: p.category,
|
|
587
|
-
categoryLabel: p.categoryLabel,
|
|
588
|
-
url: p.url,
|
|
589
|
-
libraries: p.libraries
|
|
590
|
-
}));
|
|
591
|
-
return jsonResult({
|
|
592
|
-
query: {
|
|
593
|
-
category,
|
|
594
|
-
categoryResolved: resolvedCategory,
|
|
595
|
-
library
|
|
596
|
-
},
|
|
597
|
-
count: partners.length,
|
|
598
|
-
partners
|
|
599
|
-
});
|
|
600
|
-
} catch (error) {
|
|
601
|
-
return errorResult(String(error));
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
//#endregion
|
|
607
|
-
//#region src/commands/mcp.ts
|
|
608
|
-
function createServer() {
|
|
609
|
-
const server = new _modelcontextprotocol_sdk_server_mcp_js.McpServer({
|
|
610
|
-
name: "TanStack CLI",
|
|
611
|
-
version: "0.0.1"
|
|
612
|
-
});
|
|
613
|
-
server.tool("listTanStackIntegrations", "List available integrations for creating TanStack applications", {}, async () => {
|
|
614
|
-
try {
|
|
615
|
-
const integrations = (await require_fetch.fetchManifest()).integrations.filter((a) => a.modes.includes("file-router")).map((integration) => ({
|
|
616
|
-
id: integration.id,
|
|
617
|
-
name: integration.name,
|
|
618
|
-
description: integration.description,
|
|
619
|
-
category: integration.category,
|
|
620
|
-
dependsOn: integration.dependsOn,
|
|
621
|
-
exclusive: integration.exclusive,
|
|
622
|
-
hasOptions: integration.hasOptions
|
|
623
|
-
}));
|
|
624
|
-
return { content: [{
|
|
625
|
-
type: "text",
|
|
626
|
-
text: JSON.stringify(integrations, null, 2)
|
|
627
|
-
}] };
|
|
628
|
-
} catch (error) {
|
|
629
|
-
return { content: [{
|
|
630
|
-
type: "text",
|
|
631
|
-
text: `Error fetching integrations: ${error}`
|
|
632
|
-
}] };
|
|
633
|
-
}
|
|
634
|
-
});
|
|
635
|
-
registerDocTools(server);
|
|
636
|
-
server.tool("createTanStackApplication", "Create a new TanStack Start application", {
|
|
637
|
-
projectName: zod.z.string().describe("The name of the project (will be the directory name)"),
|
|
638
|
-
targetDir: zod.z.string().describe("Absolute path where the project should be created"),
|
|
639
|
-
integrations: zod.z.array(zod.z.string()).optional().describe("Array of integration IDs to include. Use listTanStackIntegrations to see available options."),
|
|
640
|
-
integrationOptions: zod.z.record(zod.z.record(zod.z.unknown())).optional().describe("Configuration for integrations. Format: {\"integrationId\": {\"optionName\": \"value\"}}"),
|
|
641
|
-
tailwind: zod.z.boolean().optional().describe("Include Tailwind CSS (default: true)"),
|
|
642
|
-
packageManager: zod.z.enum([
|
|
643
|
-
"npm",
|
|
644
|
-
"pnpm",
|
|
645
|
-
"yarn",
|
|
646
|
-
"bun",
|
|
647
|
-
"deno"
|
|
648
|
-
]).optional().describe("Package manager to use (default: pnpm)")
|
|
649
|
-
}, async ({ projectName, targetDir, integrations, integrationOptions, tailwind, packageManager }) => {
|
|
650
|
-
try {
|
|
651
|
-
const { mkdirSync: mkdirSync$1, writeFileSync: writeFileSync$1 } = await import("node:fs");
|
|
652
|
-
const { resolve: resolve$2 } = await import("node:path");
|
|
653
|
-
const { BINARY_PREFIX: BINARY_PREFIX$1 } = await Promise.resolve().then(() => require("./fetch-CbFFGJEw.cjs"));
|
|
654
|
-
const { execSync } = await import("node:child_process");
|
|
655
|
-
let chosenIntegrations = [];
|
|
656
|
-
if (integrations?.length) chosenIntegrations = await require_fetch.fetchIntegrations(integrations);
|
|
657
|
-
const output = require_template.compile({
|
|
658
|
-
projectName,
|
|
659
|
-
framework: "react",
|
|
660
|
-
mode: "file-router",
|
|
661
|
-
typescript: true,
|
|
662
|
-
tailwind: tailwind ?? true,
|
|
663
|
-
packageManager: packageManager ?? "pnpm",
|
|
664
|
-
chosenIntegrations,
|
|
665
|
-
integrationOptions: integrationOptions ?? {}
|
|
666
|
-
});
|
|
667
|
-
mkdirSync$1(targetDir, { recursive: true });
|
|
668
|
-
for (const [filePath, content] of Object.entries(output.files)) {
|
|
669
|
-
const fullPath = resolve$2(targetDir, filePath);
|
|
670
|
-
mkdirSync$1(resolve$2(fullPath, ".."), { recursive: true });
|
|
671
|
-
if (content.startsWith(BINARY_PREFIX$1)) {
|
|
672
|
-
const base64Data = content.slice(BINARY_PREFIX$1.length);
|
|
673
|
-
writeFileSync$1(fullPath, Buffer.from(base64Data, "base64"));
|
|
674
|
-
} else writeFileSync$1(fullPath, content, "utf-8");
|
|
675
|
-
}
|
|
676
|
-
try {
|
|
677
|
-
execSync("git init", {
|
|
678
|
-
cwd: targetDir,
|
|
679
|
-
stdio: "ignore"
|
|
680
|
-
});
|
|
681
|
-
} catch {}
|
|
682
|
-
const envVarList = output.envVars.length > 0 ? `\n\nRequired environment variables:\n${output.envVars.map((e) => `- ${e.name}: ${e.description}`).join("\n")}` : "";
|
|
683
|
-
const warnings = output.warnings.length > 0 ? `\n\nWarnings:\n${output.warnings.map((w) => `- ${w}`).join("\n")}` : "";
|
|
684
|
-
return { content: [{
|
|
685
|
-
type: "text",
|
|
686
|
-
text: `Project "${projectName}" created successfully at ${targetDir}
|
|
687
|
-
|
|
688
|
-
Files created: ${Object.keys(output.files).length}
|
|
689
|
-
Integrations included: ${chosenIntegrations.map((a) => a.name).join(", ") || "none"}${envVarList}${warnings}
|
|
690
|
-
|
|
691
|
-
Next steps:
|
|
692
|
-
1. cd ${targetDir}
|
|
693
|
-
2. ${packageManager ?? "pnpm"} install
|
|
694
|
-
3. ${packageManager ?? "pnpm"} dev`
|
|
695
|
-
}] };
|
|
696
|
-
} catch (error) {
|
|
697
|
-
return { content: [{
|
|
698
|
-
type: "text",
|
|
699
|
-
text: `Error creating application: ${error}`
|
|
700
|
-
}] };
|
|
701
|
-
}
|
|
702
|
-
});
|
|
703
|
-
return server;
|
|
704
|
-
}
|
|
705
|
-
async function runMcp(options) {
|
|
706
|
-
const server = createServer();
|
|
707
|
-
if (options.sse) {
|
|
708
|
-
const app = (0, express.default)();
|
|
709
|
-
let transport = null;
|
|
710
|
-
app.get("/sse", (_req, res) => {
|
|
711
|
-
transport = new _modelcontextprotocol_sdk_server_sse_js.SSEServerTransport("/messages", res);
|
|
712
|
-
server.connect(transport);
|
|
713
|
-
});
|
|
714
|
-
app.post("/messages", (req, res) => {
|
|
715
|
-
if (transport) transport.handlePostMessage(req, res);
|
|
716
|
-
});
|
|
717
|
-
const port = parseInt(options.port ?? "8080", 10);
|
|
718
|
-
app.listen(port, () => {
|
|
719
|
-
console.log(`MCP server running at http://localhost:${port}/sse`);
|
|
720
|
-
});
|
|
721
|
-
} else {
|
|
722
|
-
const transport = new _modelcontextprotocol_sdk_server_stdio_js.StdioServerTransport();
|
|
723
|
-
await server.connect(transport);
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
//#endregion
|
|
728
|
-
//#region src/bin.ts
|
|
729
|
-
const program = new commander.Command();
|
|
730
|
-
program.name("tanstack").description("TanStack CLI for scaffolding and tooling").version("0.0.1");
|
|
731
|
-
program.command("create").argument("[project-name]", "name of the project").option("--template <template>", "URL to a custom template JSON file").option("--package-manager <pm>", "package manager (npm, pnpm, yarn, bun)").option("--integrations <integrations>", "comma-separated list of integration IDs").option("--no-install", "skip installing dependencies").option("--no-git", "skip initializing git repository").option("--no-tailwind", "skip tailwind CSS").option("-y, --yes", "skip prompts and use defaults").option("--target-dir <path>", "target directory for the project").option("--integrations-path <path>", "local path to integrations directory (for development)").description("Create a new TanStack Start project").action(runCreate);
|
|
732
|
-
program.command("mcp").option("--sse", "run in SSE mode (for HTTP transport)").option("--port <port>", "port for SSE server", "8080").description("Start the MCP server for AI agents").action(runMcp);
|
|
733
|
-
const integrationCommand = program.command("integration");
|
|
734
|
-
integrationCommand.command("init").option("--integrations-path <path>", "local path to integrations directory (for development)").description("Initialize an integration from the current project").action(async (options) => {
|
|
735
|
-
try {
|
|
736
|
-
await require_template.initIntegration((0, node_path.resolve)(process.cwd()), options.integrationsPath);
|
|
737
|
-
} catch (error) {
|
|
738
|
-
console.error(error instanceof Error ? error.message : "An error occurred");
|
|
739
|
-
process.exit(1);
|
|
740
|
-
}
|
|
741
|
-
});
|
|
742
|
-
integrationCommand.command("compile").option("--integrations-path <path>", "local path to integrations directory (for development)").description("Compile/update the integration from the current project").action(async (options) => {
|
|
743
|
-
try {
|
|
744
|
-
await require_template.compileIntegration((0, node_path.resolve)(process.cwd()), options.integrationsPath);
|
|
745
|
-
} catch (error) {
|
|
746
|
-
console.error(error instanceof Error ? error.message : "An error occurred");
|
|
747
|
-
process.exit(1);
|
|
748
|
-
}
|
|
749
|
-
});
|
|
750
|
-
const templateCommand = program.command("template");
|
|
751
|
-
templateCommand.command("init").description("Initialize a custom template from the current project").action(async () => {
|
|
752
|
-
try {
|
|
753
|
-
await require_template.initTemplate((0, node_path.resolve)(process.cwd()));
|
|
754
|
-
} catch (error) {
|
|
755
|
-
console.error(error instanceof Error ? error.message : "An error occurred");
|
|
756
|
-
process.exit(1);
|
|
757
|
-
}
|
|
758
|
-
});
|
|
759
|
-
templateCommand.command("compile").description("Compile/update the custom template from the current project").action(async () => {
|
|
760
|
-
try {
|
|
761
|
-
await require_template.compileTemplate((0, node_path.resolve)(process.cwd()));
|
|
762
|
-
} catch (error) {
|
|
763
|
-
console.error(error instanceof Error ? error.message : "An error occurred");
|
|
764
|
-
process.exit(1);
|
|
765
|
-
}
|
|
766
|
-
});
|
|
767
|
-
program.parse();
|
|
768
|
-
|
|
769
|
-
//#endregion
|