@tanstack/cli 0.0.6 → 0.0.8
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/bin.cjs +15 -7
- package/dist/bin.mjs +11 -3
- package/dist/fetch-CbFFGJEw.cjs +3 -0
- package/dist/fetch-DG5dLrsb.cjs +522 -0
- package/dist/fetch-DhlVXS6S.mjs +390 -0
- package/dist/fetch-I_OVg8JX.mjs +3 -0
- package/dist/index.cjs +23 -22
- package/dist/index.mjs +2 -1
- package/dist/{template-CkAkdP8n.mjs → template-Szi7-AZJ.mjs} +53 -396
- package/dist/{template-Cup47s9h.cjs → template-lWrIZhCQ.cjs} +53 -522
- package/package.json +1 -1
- package/src/api/fetch.ts +31 -2
- package/src/commands/create.ts +9 -2
- package/src/commands/mcp.ts +9 -1
- package/src/engine/compile.ts +18 -0
- package/src/templates/base.ts +11 -19
package/dist/bin.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_template = require('./template-
|
|
2
|
+
const require_template = require('./template-lWrIZhCQ.cjs');
|
|
3
|
+
const require_fetch = require('./fetch-DG5dLrsb.cjs');
|
|
3
4
|
let node_fs = require("node:fs");
|
|
4
5
|
let node_path = require("node:path");
|
|
5
6
|
let zod = require("zod");
|
|
@@ -84,7 +85,7 @@ async function runCreate(projectName, options) {
|
|
|
84
85
|
s.start("Fetching available integrations...");
|
|
85
86
|
let manifest;
|
|
86
87
|
try {
|
|
87
|
-
manifest = await
|
|
88
|
+
manifest = await require_fetch.fetchManifest(integrationsPath);
|
|
88
89
|
s.stop("Integrations loaded");
|
|
89
90
|
} catch (error$1) {
|
|
90
91
|
s.stop("Failed to fetch integrations");
|
|
@@ -226,7 +227,7 @@ async function runCreate(projectName, options) {
|
|
|
226
227
|
}
|
|
227
228
|
let chosenIntegrations = [];
|
|
228
229
|
if (resolvedIds.size > 0) try {
|
|
229
|
-
chosenIntegrations = await
|
|
230
|
+
chosenIntegrations = await require_fetch.fetchIntegrations(Array.from(resolvedIds), integrationsPath);
|
|
230
231
|
} catch (error$1) {
|
|
231
232
|
s.stop("Failed to fetch integration details");
|
|
232
233
|
_clack_prompts.log.error("Could not fetch integration definitions.");
|
|
@@ -250,7 +251,10 @@ async function runCreate(projectName, options) {
|
|
|
250
251
|
for (const [filePath, content] of Object.entries(output.files)) {
|
|
251
252
|
const fullPath = (0, node_path.resolve)(targetDir, filePath);
|
|
252
253
|
(0, node_fs.mkdirSync)((0, node_path.resolve)(fullPath, ".."), { recursive: true });
|
|
253
|
-
(
|
|
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");
|
|
254
258
|
}
|
|
255
259
|
await require_template.writeConfigFile(targetDir, compileOptions);
|
|
256
260
|
s.stop("Files written");
|
|
@@ -608,7 +612,7 @@ function createServer() {
|
|
|
608
612
|
});
|
|
609
613
|
server.tool("listTanStackIntegrations", "List available integrations for creating TanStack applications", {}, async () => {
|
|
610
614
|
try {
|
|
611
|
-
const integrations = (await
|
|
615
|
+
const integrations = (await require_fetch.fetchManifest()).integrations.filter((a) => a.modes.includes("file-router")).map((integration) => ({
|
|
612
616
|
id: integration.id,
|
|
613
617
|
name: integration.name,
|
|
614
618
|
description: integration.description,
|
|
@@ -646,9 +650,10 @@ function createServer() {
|
|
|
646
650
|
try {
|
|
647
651
|
const { mkdirSync: mkdirSync$1, writeFileSync: writeFileSync$1 } = await import("node:fs");
|
|
648
652
|
const { resolve: resolve$2 } = await import("node:path");
|
|
653
|
+
const { BINARY_PREFIX: BINARY_PREFIX$1 } = await Promise.resolve().then(() => require("./fetch-CbFFGJEw.cjs"));
|
|
649
654
|
const { execSync } = await import("node:child_process");
|
|
650
655
|
let chosenIntegrations = [];
|
|
651
|
-
if (integrations?.length) chosenIntegrations = await
|
|
656
|
+
if (integrations?.length) chosenIntegrations = await require_fetch.fetchIntegrations(integrations);
|
|
652
657
|
const output = require_template.compile({
|
|
653
658
|
projectName,
|
|
654
659
|
framework: "react",
|
|
@@ -663,7 +668,10 @@ function createServer() {
|
|
|
663
668
|
for (const [filePath, content] of Object.entries(output.files)) {
|
|
664
669
|
const fullPath = resolve$2(targetDir, filePath);
|
|
665
670
|
mkdirSync$1(resolve$2(fullPath, ".."), { recursive: true });
|
|
666
|
-
|
|
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");
|
|
667
675
|
}
|
|
668
676
|
try {
|
|
669
677
|
execSync("git init", {
|
package/dist/bin.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { a as initIntegration, i as compileIntegration, l as writeConfigFile, n as initTemplate, r as loadTemplate, t as compileTemplate, u as compile } from "./template-Szi7-AZJ.mjs";
|
|
3
|
+
import { a as fetchIntegrations, o as fetchManifest, t as BINARY_PREFIX } from "./fetch-DhlVXS6S.mjs";
|
|
3
4
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
4
5
|
import { resolve } from "node:path";
|
|
5
6
|
import { z } from "zod";
|
|
@@ -248,7 +249,10 @@ async function runCreate(projectName, options) {
|
|
|
248
249
|
for (const [filePath, content] of Object.entries(output.files)) {
|
|
249
250
|
const fullPath = resolve(targetDir, filePath);
|
|
250
251
|
mkdirSync(resolve(fullPath, ".."), { recursive: true });
|
|
251
|
-
|
|
252
|
+
if (content.startsWith(BINARY_PREFIX)) {
|
|
253
|
+
const base64Data = content.slice(BINARY_PREFIX.length);
|
|
254
|
+
writeFileSync(fullPath, Buffer.from(base64Data, "base64"));
|
|
255
|
+
} else writeFileSync(fullPath, content, "utf-8");
|
|
252
256
|
}
|
|
253
257
|
await writeConfigFile(targetDir, compileOptions);
|
|
254
258
|
s.stop("Files written");
|
|
@@ -644,6 +648,7 @@ function createServer() {
|
|
|
644
648
|
try {
|
|
645
649
|
const { mkdirSync: mkdirSync$1, writeFileSync: writeFileSync$1 } = await import("node:fs");
|
|
646
650
|
const { resolve: resolve$1 } = await import("node:path");
|
|
651
|
+
const { BINARY_PREFIX: BINARY_PREFIX$1 } = await import("./fetch-I_OVg8JX.mjs");
|
|
647
652
|
const { execSync } = await import("node:child_process");
|
|
648
653
|
let chosenIntegrations = [];
|
|
649
654
|
if (integrations?.length) chosenIntegrations = await fetchIntegrations(integrations);
|
|
@@ -661,7 +666,10 @@ function createServer() {
|
|
|
661
666
|
for (const [filePath, content] of Object.entries(output.files)) {
|
|
662
667
|
const fullPath = resolve$1(targetDir, filePath);
|
|
663
668
|
mkdirSync$1(resolve$1(fullPath, ".."), { recursive: true });
|
|
664
|
-
|
|
669
|
+
if (content.startsWith(BINARY_PREFIX$1)) {
|
|
670
|
+
const base64Data = content.slice(BINARY_PREFIX$1.length);
|
|
671
|
+
writeFileSync$1(fullPath, Buffer.from(base64Data, "base64"));
|
|
672
|
+
} else writeFileSync$1(fullPath, content, "utf-8");
|
|
665
673
|
}
|
|
666
674
|
try {
|
|
667
675
|
execSync("git init", {
|
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
const require_template = require('./template-lWrIZhCQ.cjs');
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
let zod = require("zod");
|
|
5
|
+
let node_os = require("node:os");
|
|
6
|
+
|
|
7
|
+
//#region src/engine/types.ts
|
|
8
|
+
const CategorySchema = zod.z.enum([
|
|
9
|
+
"tanstack",
|
|
10
|
+
"database",
|
|
11
|
+
"orm",
|
|
12
|
+
"auth",
|
|
13
|
+
"deploy",
|
|
14
|
+
"tooling",
|
|
15
|
+
"monitoring",
|
|
16
|
+
"api",
|
|
17
|
+
"i18n",
|
|
18
|
+
"cms",
|
|
19
|
+
"other"
|
|
20
|
+
]);
|
|
21
|
+
const IntegrationTypeSchema = zod.z.enum([
|
|
22
|
+
"integration",
|
|
23
|
+
"example",
|
|
24
|
+
"toolchain",
|
|
25
|
+
"deployment"
|
|
26
|
+
]);
|
|
27
|
+
const IntegrationPhaseSchema = zod.z.enum([
|
|
28
|
+
"setup",
|
|
29
|
+
"integration",
|
|
30
|
+
"example"
|
|
31
|
+
]);
|
|
32
|
+
const RouterModeSchema = zod.z.enum(["file-router", "code-router"]);
|
|
33
|
+
const SelectOptionSchema = zod.z.object({
|
|
34
|
+
type: zod.z.literal("select"),
|
|
35
|
+
label: zod.z.string(),
|
|
36
|
+
description: zod.z.string().optional(),
|
|
37
|
+
default: zod.z.string(),
|
|
38
|
+
options: zod.z.array(zod.z.object({
|
|
39
|
+
value: zod.z.string(),
|
|
40
|
+
label: zod.z.string()
|
|
41
|
+
}))
|
|
42
|
+
});
|
|
43
|
+
const BooleanOptionSchema = zod.z.object({
|
|
44
|
+
type: zod.z.literal("boolean"),
|
|
45
|
+
label: zod.z.string(),
|
|
46
|
+
description: zod.z.string().optional(),
|
|
47
|
+
default: zod.z.boolean()
|
|
48
|
+
});
|
|
49
|
+
const StringOptionSchema = zod.z.object({
|
|
50
|
+
type: zod.z.literal("string"),
|
|
51
|
+
label: zod.z.string(),
|
|
52
|
+
description: zod.z.string().optional(),
|
|
53
|
+
default: zod.z.string()
|
|
54
|
+
});
|
|
55
|
+
const IntegrationOptionSchema = zod.z.discriminatedUnion("type", [
|
|
56
|
+
SelectOptionSchema,
|
|
57
|
+
BooleanOptionSchema,
|
|
58
|
+
StringOptionSchema
|
|
59
|
+
]);
|
|
60
|
+
const IntegrationOptionsSchema = zod.z.record(zod.z.string(), IntegrationOptionSchema);
|
|
61
|
+
const HookTypeSchema = zod.z.enum([
|
|
62
|
+
"header-user",
|
|
63
|
+
"provider",
|
|
64
|
+
"root-provider",
|
|
65
|
+
"layout",
|
|
66
|
+
"vite-plugin",
|
|
67
|
+
"devtools",
|
|
68
|
+
"entry-client"
|
|
69
|
+
]);
|
|
70
|
+
const HookSchema = zod.z.object({
|
|
71
|
+
type: HookTypeSchema.optional(),
|
|
72
|
+
path: zod.z.string().optional(),
|
|
73
|
+
jsName: zod.z.string().optional(),
|
|
74
|
+
import: zod.z.string().optional(),
|
|
75
|
+
code: zod.z.string().optional()
|
|
76
|
+
});
|
|
77
|
+
const RouteSchema = zod.z.object({
|
|
78
|
+
url: zod.z.string().optional(),
|
|
79
|
+
name: zod.z.string().optional(),
|
|
80
|
+
icon: zod.z.string().optional(),
|
|
81
|
+
path: zod.z.string(),
|
|
82
|
+
jsName: zod.z.string(),
|
|
83
|
+
children: zod.z.array(zod.z.lazy(() => RouteSchema)).optional()
|
|
84
|
+
});
|
|
85
|
+
const EnvVarSchema = zod.z.object({
|
|
86
|
+
name: zod.z.string(),
|
|
87
|
+
description: zod.z.string(),
|
|
88
|
+
required: zod.z.boolean().optional(),
|
|
89
|
+
example: zod.z.string().optional()
|
|
90
|
+
});
|
|
91
|
+
const CommandSchema = zod.z.object({
|
|
92
|
+
command: zod.z.string(),
|
|
93
|
+
args: zod.z.array(zod.z.string()).optional()
|
|
94
|
+
});
|
|
95
|
+
const IntegrationInfoSchema = zod.z.object({
|
|
96
|
+
id: zod.z.string().optional(),
|
|
97
|
+
name: zod.z.string(),
|
|
98
|
+
description: zod.z.string(),
|
|
99
|
+
author: zod.z.string().optional(),
|
|
100
|
+
version: zod.z.string().optional(),
|
|
101
|
+
link: zod.z.string().optional(),
|
|
102
|
+
license: zod.z.string().optional(),
|
|
103
|
+
warning: zod.z.string().optional(),
|
|
104
|
+
type: IntegrationTypeSchema,
|
|
105
|
+
phase: IntegrationPhaseSchema,
|
|
106
|
+
category: CategorySchema.optional(),
|
|
107
|
+
modes: zod.z.array(RouterModeSchema),
|
|
108
|
+
priority: zod.z.number().optional(),
|
|
109
|
+
default: zod.z.boolean().optional(),
|
|
110
|
+
requiresTailwind: zod.z.boolean().optional(),
|
|
111
|
+
demoRequiresTailwind: zod.z.boolean().optional(),
|
|
112
|
+
dependsOn: zod.z.array(zod.z.string()).optional(),
|
|
113
|
+
exclusive: zod.z.array(zod.z.string()).optional(),
|
|
114
|
+
partnerId: zod.z.string().optional(),
|
|
115
|
+
options: IntegrationOptionsSchema.optional(),
|
|
116
|
+
hooks: zod.z.array(HookSchema).optional(),
|
|
117
|
+
routes: zod.z.array(RouteSchema).optional(),
|
|
118
|
+
packageAdditions: zod.z.object({
|
|
119
|
+
dependencies: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
120
|
+
devDependencies: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
121
|
+
scripts: zod.z.record(zod.z.string(), zod.z.string()).optional()
|
|
122
|
+
}).optional(),
|
|
123
|
+
shadcnComponents: zod.z.array(zod.z.string()).optional(),
|
|
124
|
+
gitignorePatterns: zod.z.array(zod.z.string()).optional(),
|
|
125
|
+
envVars: zod.z.array(EnvVarSchema).optional(),
|
|
126
|
+
command: CommandSchema.optional(),
|
|
127
|
+
integrationSpecialSteps: zod.z.array(zod.z.string()).optional(),
|
|
128
|
+
createSpecialSteps: zod.z.array(zod.z.string()).optional(),
|
|
129
|
+
postInitSpecialSteps: zod.z.array(zod.z.string()).optional(),
|
|
130
|
+
smallLogo: zod.z.string().optional(),
|
|
131
|
+
logo: zod.z.string().optional(),
|
|
132
|
+
readme: zod.z.string().optional()
|
|
133
|
+
});
|
|
134
|
+
const IntegrationCompiledSchema = IntegrationInfoSchema.extend({
|
|
135
|
+
id: zod.z.string(),
|
|
136
|
+
files: zod.z.record(zod.z.string(), zod.z.string()),
|
|
137
|
+
deletedFiles: zod.z.array(zod.z.string()).optional()
|
|
138
|
+
});
|
|
139
|
+
const CustomTemplateInfoSchema = zod.z.object({
|
|
140
|
+
id: zod.z.string().optional(),
|
|
141
|
+
name: zod.z.string(),
|
|
142
|
+
description: zod.z.string(),
|
|
143
|
+
framework: zod.z.string(),
|
|
144
|
+
mode: RouterModeSchema,
|
|
145
|
+
typescript: zod.z.boolean(),
|
|
146
|
+
tailwind: zod.z.boolean(),
|
|
147
|
+
integrations: zod.z.array(zod.z.string()),
|
|
148
|
+
integrationOptions: zod.z.record(zod.z.string(), zod.z.record(zod.z.string(), zod.z.unknown())).optional(),
|
|
149
|
+
banner: zod.z.string().optional()
|
|
150
|
+
});
|
|
151
|
+
const CustomTemplateCompiledSchema = CustomTemplateInfoSchema.extend({ id: zod.z.string() });
|
|
152
|
+
const ManifestIntegrationSchema = zod.z.object({
|
|
153
|
+
id: zod.z.string(),
|
|
154
|
+
name: zod.z.string(),
|
|
155
|
+
description: zod.z.string(),
|
|
156
|
+
type: IntegrationTypeSchema,
|
|
157
|
+
category: CategorySchema.optional(),
|
|
158
|
+
modes: zod.z.array(RouterModeSchema),
|
|
159
|
+
dependsOn: zod.z.array(zod.z.string()).optional(),
|
|
160
|
+
exclusive: zod.z.array(zod.z.string()).optional(),
|
|
161
|
+
partnerId: zod.z.string().optional(),
|
|
162
|
+
hasOptions: zod.z.boolean().optional(),
|
|
163
|
+
link: zod.z.string().optional(),
|
|
164
|
+
color: zod.z.string().optional(),
|
|
165
|
+
requiresTailwind: zod.z.boolean().optional(),
|
|
166
|
+
demoRequiresTailwind: zod.z.boolean().optional()
|
|
167
|
+
});
|
|
168
|
+
const ManifestCustomTemplateSchema = zod.z.object({
|
|
169
|
+
id: zod.z.string(),
|
|
170
|
+
name: zod.z.string(),
|
|
171
|
+
description: zod.z.string(),
|
|
172
|
+
banner: zod.z.string().optional(),
|
|
173
|
+
icon: zod.z.string().optional(),
|
|
174
|
+
features: zod.z.array(zod.z.string()).optional()
|
|
175
|
+
});
|
|
176
|
+
const ManifestSchema = zod.z.object({
|
|
177
|
+
version: zod.z.string(),
|
|
178
|
+
generated: zod.z.string(),
|
|
179
|
+
integrations: zod.z.array(ManifestIntegrationSchema),
|
|
180
|
+
customTemplates: zod.z.array(ManifestCustomTemplateSchema).optional()
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/cache/index.ts
|
|
185
|
+
const CACHE_DIR = (0, node_path.join)((0, node_os.homedir)(), ".tanstack", "cache");
|
|
186
|
+
const DEFAULT_TTL_MS = 1440 * 60 * 1e3;
|
|
187
|
+
function ensureCacheDir() {
|
|
188
|
+
if (!(0, node_fs.existsSync)(CACHE_DIR)) (0, node_fs.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
189
|
+
}
|
|
190
|
+
function getCachePath(key) {
|
|
191
|
+
return (0, node_path.join)(CACHE_DIR, `${key.replace(/[^a-zA-Z0-9-_]/g, "_")}.json`);
|
|
192
|
+
}
|
|
193
|
+
function getCached(key) {
|
|
194
|
+
const cachePath = getCachePath(key);
|
|
195
|
+
if (!(0, node_fs.existsSync)(cachePath)) return null;
|
|
196
|
+
try {
|
|
197
|
+
const raw = (0, node_fs.readFileSync)(cachePath, "utf-8");
|
|
198
|
+
const entry = JSON.parse(raw);
|
|
199
|
+
if (Date.now() - entry.timestamp > entry.ttl) return null;
|
|
200
|
+
return entry.data;
|
|
201
|
+
} catch {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function setCache(key, data, ttlMs = DEFAULT_TTL_MS) {
|
|
206
|
+
ensureCacheDir();
|
|
207
|
+
const cachePath = getCachePath(key);
|
|
208
|
+
const entry = {
|
|
209
|
+
data,
|
|
210
|
+
timestamp: Date.now(),
|
|
211
|
+
ttl: ttlMs
|
|
212
|
+
};
|
|
213
|
+
(0, node_fs.writeFileSync)(cachePath, JSON.stringify(entry, null, 2), "utf-8");
|
|
214
|
+
}
|
|
215
|
+
async function fetchWithCache(key, fetcher, ttlMs = DEFAULT_TTL_MS) {
|
|
216
|
+
const cached = getCached(key);
|
|
217
|
+
if (cached !== null) return cached;
|
|
218
|
+
const data = await fetcher();
|
|
219
|
+
setCache(key, data, ttlMs);
|
|
220
|
+
return data;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region src/api/fetch.ts
|
|
225
|
+
const GITHUB_RAW_BASE = "https://raw.githubusercontent.com/TanStack/cli/main/integrations";
|
|
226
|
+
const CACHE_TTL_MS = 3600 * 1e3;
|
|
227
|
+
const BINARY_EXTENSIONS = new Set([
|
|
228
|
+
".png",
|
|
229
|
+
".jpg",
|
|
230
|
+
".jpeg",
|
|
231
|
+
".gif",
|
|
232
|
+
".webp",
|
|
233
|
+
".ico",
|
|
234
|
+
".svg",
|
|
235
|
+
".woff",
|
|
236
|
+
".woff2",
|
|
237
|
+
".ttf",
|
|
238
|
+
".eot",
|
|
239
|
+
".otf",
|
|
240
|
+
".pdf",
|
|
241
|
+
".zip",
|
|
242
|
+
".tar",
|
|
243
|
+
".gz",
|
|
244
|
+
".mp3",
|
|
245
|
+
".mp4",
|
|
246
|
+
".wav",
|
|
247
|
+
".ogg",
|
|
248
|
+
".webm"
|
|
249
|
+
]);
|
|
250
|
+
const BINARY_PREFIX = "base64:";
|
|
251
|
+
/**
|
|
252
|
+
* Check if a file should be treated as binary based on extension
|
|
253
|
+
*/
|
|
254
|
+
function isBinaryFile(filePath) {
|
|
255
|
+
return BINARY_EXTENSIONS.has((0, node_path.extname)(filePath).toLowerCase());
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Check if a path is a local directory
|
|
259
|
+
*/
|
|
260
|
+
function isLocalPath(path) {
|
|
261
|
+
return path.startsWith("/") || path.startsWith("./") || path.startsWith("..");
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Fetch the integration manifest from GitHub or local path (with caching for remote)
|
|
265
|
+
*/
|
|
266
|
+
async function fetchManifest(baseUrl = GITHUB_RAW_BASE) {
|
|
267
|
+
if (isLocalPath(baseUrl)) {
|
|
268
|
+
const manifestPath = (0, node_path.join)(baseUrl, "manifest.json");
|
|
269
|
+
if (!(0, node_fs.existsSync)(manifestPath)) throw new Error(`Manifest not found at ${manifestPath}`);
|
|
270
|
+
const data = JSON.parse((0, node_fs.readFileSync)(manifestPath, "utf-8"));
|
|
271
|
+
return ManifestSchema.parse(data);
|
|
272
|
+
}
|
|
273
|
+
return fetchWithCache(`manifest_${baseUrl.replace(/[^a-zA-Z0-9]/g, "_")}`, async () => {
|
|
274
|
+
const url = `${baseUrl}/manifest.json`;
|
|
275
|
+
const response = await fetch(url);
|
|
276
|
+
if (!response.ok) throw new Error(`Failed to fetch manifest: ${response.statusText}`);
|
|
277
|
+
const data = await response.json();
|
|
278
|
+
return ManifestSchema.parse(data);
|
|
279
|
+
}, CACHE_TTL_MS);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Fetch integration info.json from GitHub or local path (with caching for remote)
|
|
283
|
+
*/
|
|
284
|
+
async function fetchIntegrationInfo(integrationId, baseUrl = GITHUB_RAW_BASE) {
|
|
285
|
+
if (isLocalPath(baseUrl)) {
|
|
286
|
+
const infoPath = (0, node_path.join)(baseUrl, integrationId, "info.json");
|
|
287
|
+
if (!(0, node_fs.existsSync)(infoPath)) throw new Error(`Integration info not found at ${infoPath}`);
|
|
288
|
+
const data = JSON.parse((0, node_fs.readFileSync)(infoPath, "utf-8"));
|
|
289
|
+
return IntegrationInfoSchema.parse(data);
|
|
290
|
+
}
|
|
291
|
+
return fetchWithCache(`integration_info_${integrationId}_${baseUrl.replace(/[^a-zA-Z0-9]/g, "_")}`, async () => {
|
|
292
|
+
const url = `${baseUrl}/${integrationId}/info.json`;
|
|
293
|
+
const response = await fetch(url);
|
|
294
|
+
if (!response.ok) throw new Error(`Failed to fetch integration ${integrationId}: ${response.statusText}`);
|
|
295
|
+
const data = await response.json();
|
|
296
|
+
return IntegrationInfoSchema.parse(data);
|
|
297
|
+
}, CACHE_TTL_MS);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Recursively read all files from a directory
|
|
301
|
+
* Binary files are read as base64 with a prefix marker
|
|
302
|
+
*/
|
|
303
|
+
function readDirRecursive(dir, basePath = "") {
|
|
304
|
+
const files = {};
|
|
305
|
+
if (!(0, node_fs.existsSync)(dir)) return files;
|
|
306
|
+
for (const entry of (0, node_fs.readdirSync)(dir)) {
|
|
307
|
+
const fullPath = (0, node_path.join)(dir, entry);
|
|
308
|
+
const relativePath = basePath ? `${basePath}/${entry}` : entry;
|
|
309
|
+
if ((0, node_fs.statSync)(fullPath).isDirectory()) Object.assign(files, readDirRecursive(fullPath, relativePath));
|
|
310
|
+
else if (isBinaryFile(relativePath)) files[relativePath] = BINARY_PREFIX + (0, node_fs.readFileSync)(fullPath).toString("base64");
|
|
311
|
+
else files[relativePath] = (0, node_fs.readFileSync)(fullPath, "utf-8");
|
|
312
|
+
}
|
|
313
|
+
return files;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Fetch all files for an integration from GitHub or local path (with caching for remote)
|
|
317
|
+
*/
|
|
318
|
+
async function fetchIntegrationFiles(integrationId, baseUrl = GITHUB_RAW_BASE) {
|
|
319
|
+
if (isLocalPath(baseUrl)) return readDirRecursive((0, node_path.join)(baseUrl, integrationId, "assets"));
|
|
320
|
+
return fetchWithCache(`integration_files_${integrationId}_${baseUrl.replace(/[^a-zA-Z0-9]/g, "_")}`, async () => {
|
|
321
|
+
const filesUrl = `${baseUrl}/${integrationId}/files.json`;
|
|
322
|
+
const response = await fetch(filesUrl);
|
|
323
|
+
if (!response.ok) return {};
|
|
324
|
+
const fileList = await response.json();
|
|
325
|
+
const files = {};
|
|
326
|
+
await Promise.all(fileList.map(async (filePath) => {
|
|
327
|
+
const fileUrl = `${baseUrl}/${integrationId}/assets/${filePath}`;
|
|
328
|
+
const fileResponse = await fetch(fileUrl);
|
|
329
|
+
if (fileResponse.ok) if (isBinaryFile(filePath)) {
|
|
330
|
+
const buffer = await fileResponse.arrayBuffer();
|
|
331
|
+
files[filePath] = BINARY_PREFIX + Buffer.from(buffer).toString("base64");
|
|
332
|
+
} else files[filePath] = await fileResponse.text();
|
|
333
|
+
}));
|
|
334
|
+
return files;
|
|
335
|
+
}, CACHE_TTL_MS);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Fetch integration package.json if it exists
|
|
339
|
+
*/
|
|
340
|
+
async function fetchIntegrationPackageJson(integrationId, baseUrl) {
|
|
341
|
+
if (isLocalPath(baseUrl)) {
|
|
342
|
+
const pkgPath = (0, node_path.join)(baseUrl, integrationId, "package.json");
|
|
343
|
+
if ((0, node_fs.existsSync)(pkgPath)) return JSON.parse((0, node_fs.readFileSync)(pkgPath, "utf-8"));
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
const url = `${baseUrl}/${integrationId}/package.json`;
|
|
347
|
+
const response = await fetch(url);
|
|
348
|
+
if (!response.ok) return null;
|
|
349
|
+
return response.json();
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Fetch a complete compiled integration from GitHub
|
|
353
|
+
*/
|
|
354
|
+
async function fetchIntegration(integrationId, baseUrl = GITHUB_RAW_BASE) {
|
|
355
|
+
const [info, files, pkgJson] = await Promise.all([
|
|
356
|
+
fetchIntegrationInfo(integrationId, baseUrl),
|
|
357
|
+
fetchIntegrationFiles(integrationId, baseUrl),
|
|
358
|
+
fetchIntegrationPackageJson(integrationId, baseUrl)
|
|
359
|
+
]);
|
|
360
|
+
const packageAdditions = info.packageAdditions ?? {};
|
|
361
|
+
if (pkgJson) {
|
|
362
|
+
if (pkgJson.dependencies) packageAdditions.dependencies = {
|
|
363
|
+
...packageAdditions.dependencies,
|
|
364
|
+
...pkgJson.dependencies
|
|
365
|
+
};
|
|
366
|
+
if (pkgJson.devDependencies) packageAdditions.devDependencies = {
|
|
367
|
+
...packageAdditions.devDependencies,
|
|
368
|
+
...pkgJson.devDependencies
|
|
369
|
+
};
|
|
370
|
+
if (pkgJson.scripts) packageAdditions.scripts = {
|
|
371
|
+
...packageAdditions.scripts,
|
|
372
|
+
...pkgJson.scripts
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
return IntegrationCompiledSchema.parse({
|
|
376
|
+
...info,
|
|
377
|
+
id: integrationId,
|
|
378
|
+
files,
|
|
379
|
+
packageAdditions: Object.keys(packageAdditions).length > 0 ? packageAdditions : void 0,
|
|
380
|
+
deletedFiles: []
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Fetch multiple integrations in parallel
|
|
385
|
+
*/
|
|
386
|
+
async function fetchIntegrations(integrationIds, baseUrl = GITHUB_RAW_BASE) {
|
|
387
|
+
return Promise.all(integrationIds.map((id) => fetchIntegration(id, baseUrl)));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
//#endregion
|
|
391
|
+
Object.defineProperty(exports, 'BINARY_PREFIX', {
|
|
392
|
+
enumerable: true,
|
|
393
|
+
get: function () {
|
|
394
|
+
return BINARY_PREFIX;
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
Object.defineProperty(exports, 'CategorySchema', {
|
|
398
|
+
enumerable: true,
|
|
399
|
+
get: function () {
|
|
400
|
+
return CategorySchema;
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
Object.defineProperty(exports, 'CommandSchema', {
|
|
404
|
+
enumerable: true,
|
|
405
|
+
get: function () {
|
|
406
|
+
return CommandSchema;
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
Object.defineProperty(exports, 'CustomTemplateCompiledSchema', {
|
|
410
|
+
enumerable: true,
|
|
411
|
+
get: function () {
|
|
412
|
+
return CustomTemplateCompiledSchema;
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
Object.defineProperty(exports, 'CustomTemplateInfoSchema', {
|
|
416
|
+
enumerable: true,
|
|
417
|
+
get: function () {
|
|
418
|
+
return CustomTemplateInfoSchema;
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
Object.defineProperty(exports, 'EnvVarSchema', {
|
|
422
|
+
enumerable: true,
|
|
423
|
+
get: function () {
|
|
424
|
+
return EnvVarSchema;
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
Object.defineProperty(exports, 'HookSchema', {
|
|
428
|
+
enumerable: true,
|
|
429
|
+
get: function () {
|
|
430
|
+
return HookSchema;
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
Object.defineProperty(exports, 'IntegrationCompiledSchema', {
|
|
434
|
+
enumerable: true,
|
|
435
|
+
get: function () {
|
|
436
|
+
return IntegrationCompiledSchema;
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
Object.defineProperty(exports, 'IntegrationInfoSchema', {
|
|
440
|
+
enumerable: true,
|
|
441
|
+
get: function () {
|
|
442
|
+
return IntegrationInfoSchema;
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
Object.defineProperty(exports, 'IntegrationOptionSchema', {
|
|
446
|
+
enumerable: true,
|
|
447
|
+
get: function () {
|
|
448
|
+
return IntegrationOptionSchema;
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
Object.defineProperty(exports, 'IntegrationOptionsSchema', {
|
|
452
|
+
enumerable: true,
|
|
453
|
+
get: function () {
|
|
454
|
+
return IntegrationOptionsSchema;
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
Object.defineProperty(exports, 'IntegrationPhaseSchema', {
|
|
458
|
+
enumerable: true,
|
|
459
|
+
get: function () {
|
|
460
|
+
return IntegrationPhaseSchema;
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
Object.defineProperty(exports, 'IntegrationTypeSchema', {
|
|
464
|
+
enumerable: true,
|
|
465
|
+
get: function () {
|
|
466
|
+
return IntegrationTypeSchema;
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
Object.defineProperty(exports, 'ManifestIntegrationSchema', {
|
|
470
|
+
enumerable: true,
|
|
471
|
+
get: function () {
|
|
472
|
+
return ManifestIntegrationSchema;
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
Object.defineProperty(exports, 'ManifestSchema', {
|
|
476
|
+
enumerable: true,
|
|
477
|
+
get: function () {
|
|
478
|
+
return ManifestSchema;
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
Object.defineProperty(exports, 'RouteSchema', {
|
|
482
|
+
enumerable: true,
|
|
483
|
+
get: function () {
|
|
484
|
+
return RouteSchema;
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
Object.defineProperty(exports, 'RouterModeSchema', {
|
|
488
|
+
enumerable: true,
|
|
489
|
+
get: function () {
|
|
490
|
+
return RouterModeSchema;
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
Object.defineProperty(exports, 'fetchIntegration', {
|
|
494
|
+
enumerable: true,
|
|
495
|
+
get: function () {
|
|
496
|
+
return fetchIntegration;
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
Object.defineProperty(exports, 'fetchIntegrationFiles', {
|
|
500
|
+
enumerable: true,
|
|
501
|
+
get: function () {
|
|
502
|
+
return fetchIntegrationFiles;
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
Object.defineProperty(exports, 'fetchIntegrationInfo', {
|
|
506
|
+
enumerable: true,
|
|
507
|
+
get: function () {
|
|
508
|
+
return fetchIntegrationInfo;
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
Object.defineProperty(exports, 'fetchIntegrations', {
|
|
512
|
+
enumerable: true,
|
|
513
|
+
get: function () {
|
|
514
|
+
return fetchIntegrations;
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
Object.defineProperty(exports, 'fetchManifest', {
|
|
518
|
+
enumerable: true,
|
|
519
|
+
get: function () {
|
|
520
|
+
return fetchManifest;
|
|
521
|
+
}
|
|
522
|
+
});
|