zitejs 0.9.12 → 0.9.14
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/cjs/bundle/index.js +476 -0
- package/dist/cjs/cli.js +7 -1
- package/dist/cjs/dev/index.js +9 -1
- package/dist/esm/bundle/index.d.ts +1 -0
- package/dist/esm/bundle/index.js +440 -0
- package/dist/esm/cli.js +7 -1
- package/dist/esm/dev/index.js +10 -2
- package/package.json +4 -2
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runBundle = runBundle;
|
|
37
|
+
/**
|
|
38
|
+
* `npx zitejs bundle` — Bundle endpoint files for cloudflare-lambda deployment.
|
|
39
|
+
*
|
|
40
|
+
* Replaces the legacy `scripts/bundle-endpoints.js` from zitejs-starter.
|
|
41
|
+
* Reads endpoints from src/api/*.ts, resolves SDK imports via .zite/backend.ts
|
|
42
|
+
* (monorepo) or src/__zite__/integrations.ts (legacy), and outputs bundled ESM
|
|
43
|
+
* code suitable for the cloudflare-lambda worker runtime.
|
|
44
|
+
*
|
|
45
|
+
* Usage:
|
|
46
|
+
* npx zitejs bundle # bundle all endpoints
|
|
47
|
+
* npx zitejs bundle --app admin-panel # bundle endpoints for a specific app
|
|
48
|
+
* npx zitejs bundle --script <path> # bundle a one-off script
|
|
49
|
+
*
|
|
50
|
+
* Output: JSON to stdout
|
|
51
|
+
* { bundledEndpoints: Record<string, string>, endpointErrors?: Record<string, string> }
|
|
52
|
+
* or for --script: { bundledCode: string } or { error: string }
|
|
53
|
+
*
|
|
54
|
+
* Dependencies (add to zitejs package.json):
|
|
55
|
+
* "esbuild": "^0.25.0"
|
|
56
|
+
* "@babel/parser": "^7.26.0"
|
|
57
|
+
*/
|
|
58
|
+
const esbuild = __importStar(require("esbuild"));
|
|
59
|
+
const path = __importStar(require("path"));
|
|
60
|
+
const fs = __importStar(require("fs"));
|
|
61
|
+
const parser_1 = require("@babel/parser");
|
|
62
|
+
const _NODE_BUILTIN_NAMES = [
|
|
63
|
+
'http', 'https', 'http2', 'stream', 'buffer', 'util', 'events', 'crypto',
|
|
64
|
+
'path', 'fs', 'url', 'querystring', 'zlib', 'net', 'tls', 'os', 'assert',
|
|
65
|
+
'process', 'child_process', 'cluster', 'dgram', 'dns', 'inspector', 'module',
|
|
66
|
+
'perf_hooks', 'readline', 'repl', 'string_decoder', 'timers', 'tty', 'v8',
|
|
67
|
+
'vm', 'worker_threads', 'async_hooks', 'trace_events', 'punycode',
|
|
68
|
+
];
|
|
69
|
+
const NODE_BUILTINS = _NODE_BUILTIN_NAMES.flatMap(m => [m, `node:${m}`]);
|
|
70
|
+
const PREBUNDLED_LIBS = {
|
|
71
|
+
'@zite/endpoints-runtime-sdk': '__zite-runtime__.js',
|
|
72
|
+
'zod': '__zod__.js',
|
|
73
|
+
'openai': '__openai__.js',
|
|
74
|
+
'@anthropic-ai/sdk': '__anthropic__.js',
|
|
75
|
+
'stripe': '__stripe__.js',
|
|
76
|
+
'airtable': '__airtable__.js',
|
|
77
|
+
'@notionhq/client': '__notion__.js',
|
|
78
|
+
'@slack/web-api': '__slack__.js',
|
|
79
|
+
'googleapis': '__googleapis__.js',
|
|
80
|
+
'@mailchimp/mailchimp_marketing': '__mailchimp__.js',
|
|
81
|
+
'@hubspot/api-client': '__hubspot__.js',
|
|
82
|
+
'jsforce': '__jsforce__.js',
|
|
83
|
+
'@linear/sdk': '__linear__.js',
|
|
84
|
+
'@microsoft/microsoft-graph-client': '__microsoft-graph__.js',
|
|
85
|
+
'twilio': '__twilio__.js',
|
|
86
|
+
'intercom-client': '__intercom__.js',
|
|
87
|
+
'@google/generative-ai': '__gemini__.js',
|
|
88
|
+
};
|
|
89
|
+
const BASE_BUILD_OPTIONS = {
|
|
90
|
+
bundle: true,
|
|
91
|
+
write: false,
|
|
92
|
+
format: 'esm',
|
|
93
|
+
platform: 'neutral',
|
|
94
|
+
target: 'es2022',
|
|
95
|
+
treeShaking: true,
|
|
96
|
+
external: NODE_BUILTINS,
|
|
97
|
+
mainFields: ['module', 'main'],
|
|
98
|
+
conditions: ['worker', 'browser', 'import', 'default'],
|
|
99
|
+
};
|
|
100
|
+
function getUsedSdkImports(endpointCode) {
|
|
101
|
+
try {
|
|
102
|
+
const ast = (0, parser_1.parse)(endpointCode, {
|
|
103
|
+
sourceType: 'module',
|
|
104
|
+
plugins: ['typescript'],
|
|
105
|
+
});
|
|
106
|
+
const usedImports = new Set();
|
|
107
|
+
const sdkSources = [
|
|
108
|
+
'zite-integrations-backend-sdk',
|
|
109
|
+
'zitejs/backend',
|
|
110
|
+
'zitejs/backend/base',
|
|
111
|
+
];
|
|
112
|
+
for (const node of ast.program.body) {
|
|
113
|
+
if (node.type === 'ImportDeclaration' &&
|
|
114
|
+
sdkSources.includes(node.source.value)) {
|
|
115
|
+
if (node.importKind === 'type')
|
|
116
|
+
continue;
|
|
117
|
+
for (const spec of node.specifiers) {
|
|
118
|
+
if (spec.type === 'ImportSpecifier') {
|
|
119
|
+
if (spec.importKind === 'type')
|
|
120
|
+
continue;
|
|
121
|
+
const importedName = spec.imported.type === 'Identifier'
|
|
122
|
+
? spec.imported.name
|
|
123
|
+
: spec.imported.value;
|
|
124
|
+
usedImports.add(importedName);
|
|
125
|
+
}
|
|
126
|
+
else if (spec.type === 'ImportNamespaceSpecifier') {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return Array.from(usedImports);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function getSdkExportKinds(sdkCode) {
|
|
139
|
+
try {
|
|
140
|
+
const ast = (0, parser_1.parse)(sdkCode, {
|
|
141
|
+
sourceType: 'module',
|
|
142
|
+
plugins: ['typescript'],
|
|
143
|
+
});
|
|
144
|
+
const typeExports = new Set();
|
|
145
|
+
const valueExports = new Set();
|
|
146
|
+
for (const node of ast.program.body) {
|
|
147
|
+
if (node.type === 'ExportNamedDeclaration') {
|
|
148
|
+
if (node.declaration?.type === 'TSTypeAliasDeclaration') {
|
|
149
|
+
typeExports.add(node.declaration.id.name);
|
|
150
|
+
}
|
|
151
|
+
else if (node.declaration?.type === 'TSInterfaceDeclaration') {
|
|
152
|
+
typeExports.add(node.declaration.id.name);
|
|
153
|
+
}
|
|
154
|
+
else if (node.declaration?.type === 'ClassDeclaration' && node.declaration.id) {
|
|
155
|
+
valueExports.add(node.declaration.id.name);
|
|
156
|
+
}
|
|
157
|
+
else if (node.declaration?.type === 'FunctionDeclaration' && node.declaration.id) {
|
|
158
|
+
valueExports.add(node.declaration.id.name);
|
|
159
|
+
}
|
|
160
|
+
else if (node.declaration?.type === 'VariableDeclaration') {
|
|
161
|
+
for (const decl of node.declaration.declarations) {
|
|
162
|
+
if (decl.id.type === 'Identifier') {
|
|
163
|
+
valueExports.add(decl.id.name);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else if (node.specifiers && node.specifiers.length > 0) {
|
|
168
|
+
for (const spec of node.specifiers) {
|
|
169
|
+
if (spec.type === 'ExportSpecifier') {
|
|
170
|
+
const name = spec.exported.type === 'Identifier'
|
|
171
|
+
? spec.exported.name
|
|
172
|
+
: spec.exported.value;
|
|
173
|
+
if (spec.exportKind === 'type') {
|
|
174
|
+
typeExports.add(name);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
valueExports.add(name);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return { typeExports, valueExports };
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Resolve the backend SDK file path. Tries monorepo layout first
|
|
192
|
+
* (.zite/backend.ts), falls back to legacy (__zite__/integrations.ts).
|
|
193
|
+
*/
|
|
194
|
+
function findSdkPath(baseDir) {
|
|
195
|
+
const monorepoPath = path.resolve(baseDir, '.zite/backend.ts');
|
|
196
|
+
if (fs.existsSync(monorepoPath))
|
|
197
|
+
return monorepoPath;
|
|
198
|
+
const legacyPath = path.resolve(baseDir, 'src/__zite__/integrations.ts');
|
|
199
|
+
if (fs.existsSync(legacyPath))
|
|
200
|
+
return legacyPath;
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Determine which import source the endpoint uses for the SDK.
|
|
205
|
+
* Returns the source string so we can generate the correct wrapper.
|
|
206
|
+
*/
|
|
207
|
+
function getSdkImportSource(baseDir) {
|
|
208
|
+
if (fs.existsSync(path.resolve(baseDir, '.zite/backend.ts'))) {
|
|
209
|
+
return 'zitejs/backend';
|
|
210
|
+
}
|
|
211
|
+
return 'zite-integrations-backend-sdk';
|
|
212
|
+
}
|
|
213
|
+
function createAliasPlugin(opts) {
|
|
214
|
+
return {
|
|
215
|
+
name: 'zite-alias',
|
|
216
|
+
setup(build) {
|
|
217
|
+
const sdkSources = [
|
|
218
|
+
/^zite-integrations-backend-sdk$/,
|
|
219
|
+
/^zitejs\/backend$/,
|
|
220
|
+
/^zitejs\/backend\/base$/,
|
|
221
|
+
];
|
|
222
|
+
for (const filter of sdkSources) {
|
|
223
|
+
build.onResolve({ filter }, () => {
|
|
224
|
+
if (opts.sdkPath)
|
|
225
|
+
return { path: path.resolve(opts.sdkPath) };
|
|
226
|
+
if (opts.baseDir) {
|
|
227
|
+
const sdkPath = findSdkPath(opts.baseDir);
|
|
228
|
+
if (sdkPath)
|
|
229
|
+
return { path: sdkPath };
|
|
230
|
+
}
|
|
231
|
+
return { path: 'zitejs/backend', external: true };
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
// Resolve zitejs/db to .zite/db.ts
|
|
235
|
+
build.onResolve({ filter: /^zitejs\/db$/ }, () => {
|
|
236
|
+
if (opts.baseDir) {
|
|
237
|
+
const dbPath = path.resolve(opts.baseDir, '.zite/db.ts');
|
|
238
|
+
if (fs.existsSync(dbPath))
|
|
239
|
+
return { path: dbPath };
|
|
240
|
+
}
|
|
241
|
+
return { path: 'zitejs/db', external: true };
|
|
242
|
+
});
|
|
243
|
+
// Resolve zitejs/runtime
|
|
244
|
+
build.onResolve({ filter: /^zitejs\/runtime$/ }, () => {
|
|
245
|
+
return { path: 'zitejs/runtime', external: true };
|
|
246
|
+
});
|
|
247
|
+
for (const [pkgName, modulePath] of Object.entries(PREBUNDLED_LIBS)) {
|
|
248
|
+
const escapedName = pkgName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
249
|
+
const filter = new RegExp(`^${escapedName}$`);
|
|
250
|
+
build.onResolve({ filter }, () => ({
|
|
251
|
+
path: `./${modulePath}`,
|
|
252
|
+
external: true,
|
|
253
|
+
}));
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
function generateEndpointWrapper(endpointName, usedImports, sdkExportKinds, sdkSource) {
|
|
259
|
+
if (usedImports === null) {
|
|
260
|
+
return `
|
|
261
|
+
import * as sdk from '${sdkSource}';
|
|
262
|
+
Object.assign(globalThis, sdk);
|
|
263
|
+
import endpoint from './api/${endpointName}';
|
|
264
|
+
globalThis.__endpoint = endpoint;
|
|
265
|
+
`;
|
|
266
|
+
}
|
|
267
|
+
if (usedImports.length === 0) {
|
|
268
|
+
return `
|
|
269
|
+
import endpoint from './api/${endpointName}';
|
|
270
|
+
globalThis.__endpoint = endpoint;
|
|
271
|
+
`;
|
|
272
|
+
}
|
|
273
|
+
const typeImports = [];
|
|
274
|
+
const valueImports = [];
|
|
275
|
+
for (const name of usedImports) {
|
|
276
|
+
if (sdkExportKinds?.typeExports.has(name)) {
|
|
277
|
+
typeImports.push(name);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
valueImports.push(name);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const importStatements = [];
|
|
284
|
+
if (typeImports.length > 0) {
|
|
285
|
+
importStatements.push(`import type { ${typeImports.join(', ')} } from '${sdkSource}';`);
|
|
286
|
+
}
|
|
287
|
+
if (valueImports.length > 0) {
|
|
288
|
+
importStatements.push(`import { ${valueImports.join(', ')} } from '${sdkSource}';`);
|
|
289
|
+
}
|
|
290
|
+
const globalAssign = valueImports.length > 0
|
|
291
|
+
? `Object.assign(globalThis, { ${valueImports.join(', ')} });`
|
|
292
|
+
: '';
|
|
293
|
+
return `
|
|
294
|
+
${importStatements.join('\n')}
|
|
295
|
+
${globalAssign}
|
|
296
|
+
import endpoint from './api/${endpointName}';
|
|
297
|
+
globalThis.__endpoint = endpoint;
|
|
298
|
+
`;
|
|
299
|
+
}
|
|
300
|
+
async function bundleEndpointsImpl(baseDir, endpointNames) {
|
|
301
|
+
const bundledEndpoints = {};
|
|
302
|
+
const endpointErrors = {};
|
|
303
|
+
const aliasPlugin = createAliasPlugin({ baseDir });
|
|
304
|
+
const sdkSource = getSdkImportSource(baseDir);
|
|
305
|
+
let sdkExportKinds = null;
|
|
306
|
+
try {
|
|
307
|
+
const sdkPath = findSdkPath(baseDir);
|
|
308
|
+
if (sdkPath) {
|
|
309
|
+
const sdkCode = fs.readFileSync(sdkPath, 'utf-8');
|
|
310
|
+
sdkExportKinds = getSdkExportKinds(sdkCode);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch { }
|
|
314
|
+
for (const name of endpointNames) {
|
|
315
|
+
let usedImports = null;
|
|
316
|
+
try {
|
|
317
|
+
const endpointPath = path.join(baseDir, 'src', 'api', `${name}.ts`);
|
|
318
|
+
const endpointCode = fs.readFileSync(endpointPath, 'utf-8');
|
|
319
|
+
usedImports = getUsedSdkImports(endpointCode);
|
|
320
|
+
}
|
|
321
|
+
catch { }
|
|
322
|
+
const wrapperCode = generateEndpointWrapper(name, usedImports, sdkExportKinds, sdkSource);
|
|
323
|
+
try {
|
|
324
|
+
const result = await esbuild.build({
|
|
325
|
+
...BASE_BUILD_OPTIONS,
|
|
326
|
+
stdin: {
|
|
327
|
+
contents: wrapperCode,
|
|
328
|
+
resolveDir: `${baseDir}/src`,
|
|
329
|
+
loader: 'ts',
|
|
330
|
+
},
|
|
331
|
+
logLevel: 'warning',
|
|
332
|
+
plugins: [aliasPlugin],
|
|
333
|
+
});
|
|
334
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
335
|
+
const msgs = result.warnings.map(w => `${w.location?.file || 'unknown'}:${w.location?.line || '?'} - ${w.text}`);
|
|
336
|
+
endpointErrors[name] = `Warnings: ${msgs.join('; ')}`;
|
|
337
|
+
}
|
|
338
|
+
if (result.outputFiles && result.outputFiles.length > 0) {
|
|
339
|
+
bundledEndpoints[name] = result.outputFiles[0].text;
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
endpointErrors[name] = 'No output generated';
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch (err) {
|
|
346
|
+
const e = err;
|
|
347
|
+
if (e.errors && Array.isArray(e.errors)) {
|
|
348
|
+
const msgs = e.errors.map(er => {
|
|
349
|
+
const loc = er.location
|
|
350
|
+
? `${er.location.file || 'unknown'}:${er.location.line || '?'}:${er.location.column || '?'}`
|
|
351
|
+
: 'unknown';
|
|
352
|
+
return `${loc} - ${er.text}`;
|
|
353
|
+
});
|
|
354
|
+
endpointErrors[name] = msgs.join('\n');
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
endpointErrors[name] = e.message || String(err);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
console.log(JSON.stringify({
|
|
362
|
+
bundledEndpoints,
|
|
363
|
+
endpointErrors: Object.keys(endpointErrors).length > 0 ? endpointErrors : undefined,
|
|
364
|
+
}));
|
|
365
|
+
}
|
|
366
|
+
async function bundleOneOffScriptImpl(scriptPath, sdkPath) {
|
|
367
|
+
const rawScript = fs.readFileSync(scriptPath, 'utf-8');
|
|
368
|
+
const plugin = createAliasPlugin({ sdkPath });
|
|
369
|
+
let importSection = '';
|
|
370
|
+
let bodySection = rawScript;
|
|
371
|
+
try {
|
|
372
|
+
const ast = (0, parser_1.parse)(rawScript, {
|
|
373
|
+
sourceType: 'module',
|
|
374
|
+
plugins: ['typescript'],
|
|
375
|
+
allowReturnOutsideFunction: true,
|
|
376
|
+
});
|
|
377
|
+
let lastImportEnd = 0;
|
|
378
|
+
for (const node of ast.program.body) {
|
|
379
|
+
if (node.type === 'ImportDeclaration' && node.end) {
|
|
380
|
+
lastImportEnd = node.end;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (lastImportEnd > 0) {
|
|
384
|
+
importSection = rawScript.slice(0, lastImportEnd);
|
|
385
|
+
bodySection = rawScript.slice(lastImportEnd);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
catch { }
|
|
389
|
+
const wrappedScript = `${importSection}
|
|
390
|
+
export async function execute() {
|
|
391
|
+
${bodySection}
|
|
392
|
+
}`;
|
|
393
|
+
try {
|
|
394
|
+
const result = await esbuild.build({
|
|
395
|
+
...BASE_BUILD_OPTIONS,
|
|
396
|
+
stdin: {
|
|
397
|
+
contents: wrappedScript,
|
|
398
|
+
loader: 'ts',
|
|
399
|
+
resolveDir: process.cwd(),
|
|
400
|
+
},
|
|
401
|
+
minify: false,
|
|
402
|
+
logLevel: 'silent',
|
|
403
|
+
plugins: [plugin],
|
|
404
|
+
});
|
|
405
|
+
if (result.errors.length > 0) {
|
|
406
|
+
console.log(JSON.stringify({ error: result.errors.map(e => e.text).join('\n') }));
|
|
407
|
+
process.exit(1);
|
|
408
|
+
}
|
|
409
|
+
if (!result.outputFiles || result.outputFiles.length === 0) {
|
|
410
|
+
console.log(JSON.stringify({ error: 'esbuild produced no output' }));
|
|
411
|
+
process.exit(1);
|
|
412
|
+
}
|
|
413
|
+
const esbuildOutput = result.outputFiles[0].text;
|
|
414
|
+
console.log(JSON.stringify({
|
|
415
|
+
bundledCode: `${esbuildOutput}\nglobalThis.__endpoint = { execute };\n`,
|
|
416
|
+
}));
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
const e = err;
|
|
420
|
+
if (e.errors && Array.isArray(e.errors)) {
|
|
421
|
+
const msgs = e.errors.map(er => {
|
|
422
|
+
const loc = er.location
|
|
423
|
+
? `${er.location.file || 'unknown'}:${er.location.line || '?'}`
|
|
424
|
+
: 'unknown';
|
|
425
|
+
return `${loc} - ${er.text}`;
|
|
426
|
+
});
|
|
427
|
+
console.log(JSON.stringify({ error: msgs.join('\n') }));
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
console.log(JSON.stringify({ error: e.message || String(err) }));
|
|
431
|
+
}
|
|
432
|
+
process.exit(1);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
async function runBundle() {
|
|
436
|
+
const args = process.argv.slice(3); // skip 'node', 'zitejs', 'bundle'
|
|
437
|
+
const scriptFlagIndex = args.indexOf('--script');
|
|
438
|
+
if (scriptFlagIndex !== -1) {
|
|
439
|
+
const scriptPath = args[scriptFlagIndex + 1];
|
|
440
|
+
if (!scriptPath) {
|
|
441
|
+
console.log(JSON.stringify({ error: 'Usage: zitejs bundle --script <path> [--sdk <path>]' }));
|
|
442
|
+
process.exit(1);
|
|
443
|
+
}
|
|
444
|
+
const sdkFlagIndex = args.indexOf('--sdk');
|
|
445
|
+
const sdkPath = sdkFlagIndex !== -1 ? args[sdkFlagIndex + 1] : undefined;
|
|
446
|
+
return bundleOneOffScriptImpl(scriptPath, sdkPath);
|
|
447
|
+
}
|
|
448
|
+
// Endpoint mode: find all endpoints and bundle them
|
|
449
|
+
const appFlag = args.indexOf('--app');
|
|
450
|
+
let baseDir = process.cwd();
|
|
451
|
+
if (appFlag !== -1 && args[appFlag + 1]) {
|
|
452
|
+
baseDir = path.resolve(baseDir, 'apps', args[appFlag + 1]);
|
|
453
|
+
}
|
|
454
|
+
// If explicit endpoint names passed, use those; otherwise find all
|
|
455
|
+
const explicitNames = args.filter(a => !a.startsWith('--'));
|
|
456
|
+
let endpointNames;
|
|
457
|
+
if (explicitNames.length > 0) {
|
|
458
|
+
endpointNames = explicitNames;
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
const apiDir = path.join(baseDir, 'src', 'api');
|
|
462
|
+
if (!fs.existsSync(apiDir)) {
|
|
463
|
+
console.log(JSON.stringify({ bundledEndpoints: {} }));
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
endpointNames = fs
|
|
467
|
+
.readdirSync(apiDir)
|
|
468
|
+
.filter(f => f.endsWith('.ts'))
|
|
469
|
+
.map(f => f.replace('.ts', ''));
|
|
470
|
+
}
|
|
471
|
+
if (endpointNames.length === 0) {
|
|
472
|
+
console.log(JSON.stringify({ bundledEndpoints: {} }));
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
return bundleEndpointsImpl(baseDir, endpointNames);
|
|
476
|
+
}
|
package/dist/cjs/cli.js
CHANGED
|
@@ -55,15 +55,21 @@ async function main() {
|
|
|
55
55
|
await runCheck();
|
|
56
56
|
break;
|
|
57
57
|
}
|
|
58
|
+
case 'bundle': {
|
|
59
|
+
const { runBundle } = await Promise.resolve().then(() => __importStar(require('./bundle/index.js')));
|
|
60
|
+
await runBundle();
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
58
63
|
default:
|
|
59
64
|
console.error(command
|
|
60
65
|
? `Unknown command: ${command}`
|
|
61
|
-
: 'Usage: zitejs <sync|dev|check>');
|
|
66
|
+
: 'Usage: zitejs <sync|dev|check|bundle>');
|
|
62
67
|
console.error('');
|
|
63
68
|
console.error('Commands:');
|
|
64
69
|
console.error(' sync Generate .zite/db.ts and .zite/api.ts from your database schema');
|
|
65
70
|
console.error(' dev Run sync then watch for changes (like npx convex dev)');
|
|
66
71
|
console.error(' check Run tsc --noEmit and vite build for all apps');
|
|
72
|
+
console.error(' bundle Bundle src/api/*.ts endpoints for cloudflare-lambda');
|
|
67
73
|
process.exit(1);
|
|
68
74
|
}
|
|
69
75
|
}
|
package/dist/cjs/dev/index.js
CHANGED
|
@@ -32,6 +32,13 @@ function getFlowId(appDir) {
|
|
|
32
32
|
catch { }
|
|
33
33
|
return undefined;
|
|
34
34
|
}
|
|
35
|
+
function regenerateAppTypedWrappers(appDir) {
|
|
36
|
+
const outDir = (0, path_1.join)('apps', appDir, '.zite');
|
|
37
|
+
(0, fs_2.mkdirSync)(outDir, { recursive: true });
|
|
38
|
+
(0, fs_2.writeFileSync)((0, path_1.join)(outDir, 'user.ts'), (0, lib_js_1.generateUserTs)());
|
|
39
|
+
(0, fs_2.writeFileSync)((0, path_1.join)(outDir, 'auth.ts'), (0, lib_js_1.generateAuthWrapperTs)());
|
|
40
|
+
(0, fs_2.writeFileSync)((0, path_1.join)(outDir, 'backend.ts'), (0, lib_js_1.generateBackendWrapperTs)());
|
|
41
|
+
}
|
|
35
42
|
function regenerateAppApiTs(appDir) {
|
|
36
43
|
const apiDir = (0, path_1.join)('apps', appDir, 'src', 'api');
|
|
37
44
|
if (!(0, fs_2.existsSync)(apiDir))
|
|
@@ -57,10 +64,11 @@ async function runDev() {
|
|
|
57
64
|
console.warn('Initial sync failed (continuing with watcher):', err instanceof Error ? err.message : err);
|
|
58
65
|
}
|
|
59
66
|
console.log('');
|
|
60
|
-
// 2. Find all apps and regenerate their .zite/
|
|
67
|
+
// 2. Find all apps and regenerate their .zite/ files
|
|
61
68
|
const appDirs = findAppDirs();
|
|
62
69
|
for (const app of appDirs) {
|
|
63
70
|
regenerateAppApiTs(app);
|
|
71
|
+
regenerateAppTypedWrappers(app);
|
|
64
72
|
}
|
|
65
73
|
// 3. Watch each app's src/api/ for endpoint changes
|
|
66
74
|
let watchingAny = false;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runBundle(): Promise<void>;
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `npx zitejs bundle` — Bundle endpoint files for cloudflare-lambda deployment.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the legacy `scripts/bundle-endpoints.js` from zitejs-starter.
|
|
5
|
+
* Reads endpoints from src/api/*.ts, resolves SDK imports via .zite/backend.ts
|
|
6
|
+
* (monorepo) or src/__zite__/integrations.ts (legacy), and outputs bundled ESM
|
|
7
|
+
* code suitable for the cloudflare-lambda worker runtime.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* npx zitejs bundle # bundle all endpoints
|
|
11
|
+
* npx zitejs bundle --app admin-panel # bundle endpoints for a specific app
|
|
12
|
+
* npx zitejs bundle --script <path> # bundle a one-off script
|
|
13
|
+
*
|
|
14
|
+
* Output: JSON to stdout
|
|
15
|
+
* { bundledEndpoints: Record<string, string>, endpointErrors?: Record<string, string> }
|
|
16
|
+
* or for --script: { bundledCode: string } or { error: string }
|
|
17
|
+
*
|
|
18
|
+
* Dependencies (add to zitejs package.json):
|
|
19
|
+
* "esbuild": "^0.25.0"
|
|
20
|
+
* "@babel/parser": "^7.26.0"
|
|
21
|
+
*/
|
|
22
|
+
import * as esbuild from 'esbuild';
|
|
23
|
+
import * as path from 'path';
|
|
24
|
+
import * as fs from 'fs';
|
|
25
|
+
import { parse } from '@babel/parser';
|
|
26
|
+
const _NODE_BUILTIN_NAMES = [
|
|
27
|
+
'http', 'https', 'http2', 'stream', 'buffer', 'util', 'events', 'crypto',
|
|
28
|
+
'path', 'fs', 'url', 'querystring', 'zlib', 'net', 'tls', 'os', 'assert',
|
|
29
|
+
'process', 'child_process', 'cluster', 'dgram', 'dns', 'inspector', 'module',
|
|
30
|
+
'perf_hooks', 'readline', 'repl', 'string_decoder', 'timers', 'tty', 'v8',
|
|
31
|
+
'vm', 'worker_threads', 'async_hooks', 'trace_events', 'punycode',
|
|
32
|
+
];
|
|
33
|
+
const NODE_BUILTINS = _NODE_BUILTIN_NAMES.flatMap(m => [m, `node:${m}`]);
|
|
34
|
+
const PREBUNDLED_LIBS = {
|
|
35
|
+
'@zite/endpoints-runtime-sdk': '__zite-runtime__.js',
|
|
36
|
+
'zod': '__zod__.js',
|
|
37
|
+
'openai': '__openai__.js',
|
|
38
|
+
'@anthropic-ai/sdk': '__anthropic__.js',
|
|
39
|
+
'stripe': '__stripe__.js',
|
|
40
|
+
'airtable': '__airtable__.js',
|
|
41
|
+
'@notionhq/client': '__notion__.js',
|
|
42
|
+
'@slack/web-api': '__slack__.js',
|
|
43
|
+
'googleapis': '__googleapis__.js',
|
|
44
|
+
'@mailchimp/mailchimp_marketing': '__mailchimp__.js',
|
|
45
|
+
'@hubspot/api-client': '__hubspot__.js',
|
|
46
|
+
'jsforce': '__jsforce__.js',
|
|
47
|
+
'@linear/sdk': '__linear__.js',
|
|
48
|
+
'@microsoft/microsoft-graph-client': '__microsoft-graph__.js',
|
|
49
|
+
'twilio': '__twilio__.js',
|
|
50
|
+
'intercom-client': '__intercom__.js',
|
|
51
|
+
'@google/generative-ai': '__gemini__.js',
|
|
52
|
+
};
|
|
53
|
+
const BASE_BUILD_OPTIONS = {
|
|
54
|
+
bundle: true,
|
|
55
|
+
write: false,
|
|
56
|
+
format: 'esm',
|
|
57
|
+
platform: 'neutral',
|
|
58
|
+
target: 'es2022',
|
|
59
|
+
treeShaking: true,
|
|
60
|
+
external: NODE_BUILTINS,
|
|
61
|
+
mainFields: ['module', 'main'],
|
|
62
|
+
conditions: ['worker', 'browser', 'import', 'default'],
|
|
63
|
+
};
|
|
64
|
+
function getUsedSdkImports(endpointCode) {
|
|
65
|
+
try {
|
|
66
|
+
const ast = parse(endpointCode, {
|
|
67
|
+
sourceType: 'module',
|
|
68
|
+
plugins: ['typescript'],
|
|
69
|
+
});
|
|
70
|
+
const usedImports = new Set();
|
|
71
|
+
const sdkSources = [
|
|
72
|
+
'zite-integrations-backend-sdk',
|
|
73
|
+
'zitejs/backend',
|
|
74
|
+
'zitejs/backend/base',
|
|
75
|
+
];
|
|
76
|
+
for (const node of ast.program.body) {
|
|
77
|
+
if (node.type === 'ImportDeclaration' &&
|
|
78
|
+
sdkSources.includes(node.source.value)) {
|
|
79
|
+
if (node.importKind === 'type')
|
|
80
|
+
continue;
|
|
81
|
+
for (const spec of node.specifiers) {
|
|
82
|
+
if (spec.type === 'ImportSpecifier') {
|
|
83
|
+
if (spec.importKind === 'type')
|
|
84
|
+
continue;
|
|
85
|
+
const importedName = spec.imported.type === 'Identifier'
|
|
86
|
+
? spec.imported.name
|
|
87
|
+
: spec.imported.value;
|
|
88
|
+
usedImports.add(importedName);
|
|
89
|
+
}
|
|
90
|
+
else if (spec.type === 'ImportNamespaceSpecifier') {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return Array.from(usedImports);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function getSdkExportKinds(sdkCode) {
|
|
103
|
+
try {
|
|
104
|
+
const ast = parse(sdkCode, {
|
|
105
|
+
sourceType: 'module',
|
|
106
|
+
plugins: ['typescript'],
|
|
107
|
+
});
|
|
108
|
+
const typeExports = new Set();
|
|
109
|
+
const valueExports = new Set();
|
|
110
|
+
for (const node of ast.program.body) {
|
|
111
|
+
if (node.type === 'ExportNamedDeclaration') {
|
|
112
|
+
if (node.declaration?.type === 'TSTypeAliasDeclaration') {
|
|
113
|
+
typeExports.add(node.declaration.id.name);
|
|
114
|
+
}
|
|
115
|
+
else if (node.declaration?.type === 'TSInterfaceDeclaration') {
|
|
116
|
+
typeExports.add(node.declaration.id.name);
|
|
117
|
+
}
|
|
118
|
+
else if (node.declaration?.type === 'ClassDeclaration' && node.declaration.id) {
|
|
119
|
+
valueExports.add(node.declaration.id.name);
|
|
120
|
+
}
|
|
121
|
+
else if (node.declaration?.type === 'FunctionDeclaration' && node.declaration.id) {
|
|
122
|
+
valueExports.add(node.declaration.id.name);
|
|
123
|
+
}
|
|
124
|
+
else if (node.declaration?.type === 'VariableDeclaration') {
|
|
125
|
+
for (const decl of node.declaration.declarations) {
|
|
126
|
+
if (decl.id.type === 'Identifier') {
|
|
127
|
+
valueExports.add(decl.id.name);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else if (node.specifiers && node.specifiers.length > 0) {
|
|
132
|
+
for (const spec of node.specifiers) {
|
|
133
|
+
if (spec.type === 'ExportSpecifier') {
|
|
134
|
+
const name = spec.exported.type === 'Identifier'
|
|
135
|
+
? spec.exported.name
|
|
136
|
+
: spec.exported.value;
|
|
137
|
+
if (spec.exportKind === 'type') {
|
|
138
|
+
typeExports.add(name);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
valueExports.add(name);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { typeExports, valueExports };
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Resolve the backend SDK file path. Tries monorepo layout first
|
|
156
|
+
* (.zite/backend.ts), falls back to legacy (__zite__/integrations.ts).
|
|
157
|
+
*/
|
|
158
|
+
function findSdkPath(baseDir) {
|
|
159
|
+
const monorepoPath = path.resolve(baseDir, '.zite/backend.ts');
|
|
160
|
+
if (fs.existsSync(monorepoPath))
|
|
161
|
+
return monorepoPath;
|
|
162
|
+
const legacyPath = path.resolve(baseDir, 'src/__zite__/integrations.ts');
|
|
163
|
+
if (fs.existsSync(legacyPath))
|
|
164
|
+
return legacyPath;
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Determine which import source the endpoint uses for the SDK.
|
|
169
|
+
* Returns the source string so we can generate the correct wrapper.
|
|
170
|
+
*/
|
|
171
|
+
function getSdkImportSource(baseDir) {
|
|
172
|
+
if (fs.existsSync(path.resolve(baseDir, '.zite/backend.ts'))) {
|
|
173
|
+
return 'zitejs/backend';
|
|
174
|
+
}
|
|
175
|
+
return 'zite-integrations-backend-sdk';
|
|
176
|
+
}
|
|
177
|
+
function createAliasPlugin(opts) {
|
|
178
|
+
return {
|
|
179
|
+
name: 'zite-alias',
|
|
180
|
+
setup(build) {
|
|
181
|
+
const sdkSources = [
|
|
182
|
+
/^zite-integrations-backend-sdk$/,
|
|
183
|
+
/^zitejs\/backend$/,
|
|
184
|
+
/^zitejs\/backend\/base$/,
|
|
185
|
+
];
|
|
186
|
+
for (const filter of sdkSources) {
|
|
187
|
+
build.onResolve({ filter }, () => {
|
|
188
|
+
if (opts.sdkPath)
|
|
189
|
+
return { path: path.resolve(opts.sdkPath) };
|
|
190
|
+
if (opts.baseDir) {
|
|
191
|
+
const sdkPath = findSdkPath(opts.baseDir);
|
|
192
|
+
if (sdkPath)
|
|
193
|
+
return { path: sdkPath };
|
|
194
|
+
}
|
|
195
|
+
return { path: 'zitejs/backend', external: true };
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
// Resolve zitejs/db to .zite/db.ts
|
|
199
|
+
build.onResolve({ filter: /^zitejs\/db$/ }, () => {
|
|
200
|
+
if (opts.baseDir) {
|
|
201
|
+
const dbPath = path.resolve(opts.baseDir, '.zite/db.ts');
|
|
202
|
+
if (fs.existsSync(dbPath))
|
|
203
|
+
return { path: dbPath };
|
|
204
|
+
}
|
|
205
|
+
return { path: 'zitejs/db', external: true };
|
|
206
|
+
});
|
|
207
|
+
// Resolve zitejs/runtime
|
|
208
|
+
build.onResolve({ filter: /^zitejs\/runtime$/ }, () => {
|
|
209
|
+
return { path: 'zitejs/runtime', external: true };
|
|
210
|
+
});
|
|
211
|
+
for (const [pkgName, modulePath] of Object.entries(PREBUNDLED_LIBS)) {
|
|
212
|
+
const escapedName = pkgName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
213
|
+
const filter = new RegExp(`^${escapedName}$`);
|
|
214
|
+
build.onResolve({ filter }, () => ({
|
|
215
|
+
path: `./${modulePath}`,
|
|
216
|
+
external: true,
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function generateEndpointWrapper(endpointName, usedImports, sdkExportKinds, sdkSource) {
|
|
223
|
+
if (usedImports === null) {
|
|
224
|
+
return `
|
|
225
|
+
import * as sdk from '${sdkSource}';
|
|
226
|
+
Object.assign(globalThis, sdk);
|
|
227
|
+
import endpoint from './api/${endpointName}';
|
|
228
|
+
globalThis.__endpoint = endpoint;
|
|
229
|
+
`;
|
|
230
|
+
}
|
|
231
|
+
if (usedImports.length === 0) {
|
|
232
|
+
return `
|
|
233
|
+
import endpoint from './api/${endpointName}';
|
|
234
|
+
globalThis.__endpoint = endpoint;
|
|
235
|
+
`;
|
|
236
|
+
}
|
|
237
|
+
const typeImports = [];
|
|
238
|
+
const valueImports = [];
|
|
239
|
+
for (const name of usedImports) {
|
|
240
|
+
if (sdkExportKinds?.typeExports.has(name)) {
|
|
241
|
+
typeImports.push(name);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
valueImports.push(name);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const importStatements = [];
|
|
248
|
+
if (typeImports.length > 0) {
|
|
249
|
+
importStatements.push(`import type { ${typeImports.join(', ')} } from '${sdkSource}';`);
|
|
250
|
+
}
|
|
251
|
+
if (valueImports.length > 0) {
|
|
252
|
+
importStatements.push(`import { ${valueImports.join(', ')} } from '${sdkSource}';`);
|
|
253
|
+
}
|
|
254
|
+
const globalAssign = valueImports.length > 0
|
|
255
|
+
? `Object.assign(globalThis, { ${valueImports.join(', ')} });`
|
|
256
|
+
: '';
|
|
257
|
+
return `
|
|
258
|
+
${importStatements.join('\n')}
|
|
259
|
+
${globalAssign}
|
|
260
|
+
import endpoint from './api/${endpointName}';
|
|
261
|
+
globalThis.__endpoint = endpoint;
|
|
262
|
+
`;
|
|
263
|
+
}
|
|
264
|
+
async function bundleEndpointsImpl(baseDir, endpointNames) {
|
|
265
|
+
const bundledEndpoints = {};
|
|
266
|
+
const endpointErrors = {};
|
|
267
|
+
const aliasPlugin = createAliasPlugin({ baseDir });
|
|
268
|
+
const sdkSource = getSdkImportSource(baseDir);
|
|
269
|
+
let sdkExportKinds = null;
|
|
270
|
+
try {
|
|
271
|
+
const sdkPath = findSdkPath(baseDir);
|
|
272
|
+
if (sdkPath) {
|
|
273
|
+
const sdkCode = fs.readFileSync(sdkPath, 'utf-8');
|
|
274
|
+
sdkExportKinds = getSdkExportKinds(sdkCode);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
catch { }
|
|
278
|
+
for (const name of endpointNames) {
|
|
279
|
+
let usedImports = null;
|
|
280
|
+
try {
|
|
281
|
+
const endpointPath = path.join(baseDir, 'src', 'api', `${name}.ts`);
|
|
282
|
+
const endpointCode = fs.readFileSync(endpointPath, 'utf-8');
|
|
283
|
+
usedImports = getUsedSdkImports(endpointCode);
|
|
284
|
+
}
|
|
285
|
+
catch { }
|
|
286
|
+
const wrapperCode = generateEndpointWrapper(name, usedImports, sdkExportKinds, sdkSource);
|
|
287
|
+
try {
|
|
288
|
+
const result = await esbuild.build({
|
|
289
|
+
...BASE_BUILD_OPTIONS,
|
|
290
|
+
stdin: {
|
|
291
|
+
contents: wrapperCode,
|
|
292
|
+
resolveDir: `${baseDir}/src`,
|
|
293
|
+
loader: 'ts',
|
|
294
|
+
},
|
|
295
|
+
logLevel: 'warning',
|
|
296
|
+
plugins: [aliasPlugin],
|
|
297
|
+
});
|
|
298
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
299
|
+
const msgs = result.warnings.map(w => `${w.location?.file || 'unknown'}:${w.location?.line || '?'} - ${w.text}`);
|
|
300
|
+
endpointErrors[name] = `Warnings: ${msgs.join('; ')}`;
|
|
301
|
+
}
|
|
302
|
+
if (result.outputFiles && result.outputFiles.length > 0) {
|
|
303
|
+
bundledEndpoints[name] = result.outputFiles[0].text;
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
endpointErrors[name] = 'No output generated';
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
const e = err;
|
|
311
|
+
if (e.errors && Array.isArray(e.errors)) {
|
|
312
|
+
const msgs = e.errors.map(er => {
|
|
313
|
+
const loc = er.location
|
|
314
|
+
? `${er.location.file || 'unknown'}:${er.location.line || '?'}:${er.location.column || '?'}`
|
|
315
|
+
: 'unknown';
|
|
316
|
+
return `${loc} - ${er.text}`;
|
|
317
|
+
});
|
|
318
|
+
endpointErrors[name] = msgs.join('\n');
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
endpointErrors[name] = e.message || String(err);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
console.log(JSON.stringify({
|
|
326
|
+
bundledEndpoints,
|
|
327
|
+
endpointErrors: Object.keys(endpointErrors).length > 0 ? endpointErrors : undefined,
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
async function bundleOneOffScriptImpl(scriptPath, sdkPath) {
|
|
331
|
+
const rawScript = fs.readFileSync(scriptPath, 'utf-8');
|
|
332
|
+
const plugin = createAliasPlugin({ sdkPath });
|
|
333
|
+
let importSection = '';
|
|
334
|
+
let bodySection = rawScript;
|
|
335
|
+
try {
|
|
336
|
+
const ast = parse(rawScript, {
|
|
337
|
+
sourceType: 'module',
|
|
338
|
+
plugins: ['typescript'],
|
|
339
|
+
allowReturnOutsideFunction: true,
|
|
340
|
+
});
|
|
341
|
+
let lastImportEnd = 0;
|
|
342
|
+
for (const node of ast.program.body) {
|
|
343
|
+
if (node.type === 'ImportDeclaration' && node.end) {
|
|
344
|
+
lastImportEnd = node.end;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (lastImportEnd > 0) {
|
|
348
|
+
importSection = rawScript.slice(0, lastImportEnd);
|
|
349
|
+
bodySection = rawScript.slice(lastImportEnd);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
catch { }
|
|
353
|
+
const wrappedScript = `${importSection}
|
|
354
|
+
export async function execute() {
|
|
355
|
+
${bodySection}
|
|
356
|
+
}`;
|
|
357
|
+
try {
|
|
358
|
+
const result = await esbuild.build({
|
|
359
|
+
...BASE_BUILD_OPTIONS,
|
|
360
|
+
stdin: {
|
|
361
|
+
contents: wrappedScript,
|
|
362
|
+
loader: 'ts',
|
|
363
|
+
resolveDir: process.cwd(),
|
|
364
|
+
},
|
|
365
|
+
minify: false,
|
|
366
|
+
logLevel: 'silent',
|
|
367
|
+
plugins: [plugin],
|
|
368
|
+
});
|
|
369
|
+
if (result.errors.length > 0) {
|
|
370
|
+
console.log(JSON.stringify({ error: result.errors.map(e => e.text).join('\n') }));
|
|
371
|
+
process.exit(1);
|
|
372
|
+
}
|
|
373
|
+
if (!result.outputFiles || result.outputFiles.length === 0) {
|
|
374
|
+
console.log(JSON.stringify({ error: 'esbuild produced no output' }));
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
const esbuildOutput = result.outputFiles[0].text;
|
|
378
|
+
console.log(JSON.stringify({
|
|
379
|
+
bundledCode: `${esbuildOutput}\nglobalThis.__endpoint = { execute };\n`,
|
|
380
|
+
}));
|
|
381
|
+
}
|
|
382
|
+
catch (err) {
|
|
383
|
+
const e = err;
|
|
384
|
+
if (e.errors && Array.isArray(e.errors)) {
|
|
385
|
+
const msgs = e.errors.map(er => {
|
|
386
|
+
const loc = er.location
|
|
387
|
+
? `${er.location.file || 'unknown'}:${er.location.line || '?'}`
|
|
388
|
+
: 'unknown';
|
|
389
|
+
return `${loc} - ${er.text}`;
|
|
390
|
+
});
|
|
391
|
+
console.log(JSON.stringify({ error: msgs.join('\n') }));
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
console.log(JSON.stringify({ error: e.message || String(err) }));
|
|
395
|
+
}
|
|
396
|
+
process.exit(1);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
export async function runBundle() {
|
|
400
|
+
const args = process.argv.slice(3); // skip 'node', 'zitejs', 'bundle'
|
|
401
|
+
const scriptFlagIndex = args.indexOf('--script');
|
|
402
|
+
if (scriptFlagIndex !== -1) {
|
|
403
|
+
const scriptPath = args[scriptFlagIndex + 1];
|
|
404
|
+
if (!scriptPath) {
|
|
405
|
+
console.log(JSON.stringify({ error: 'Usage: zitejs bundle --script <path> [--sdk <path>]' }));
|
|
406
|
+
process.exit(1);
|
|
407
|
+
}
|
|
408
|
+
const sdkFlagIndex = args.indexOf('--sdk');
|
|
409
|
+
const sdkPath = sdkFlagIndex !== -1 ? args[sdkFlagIndex + 1] : undefined;
|
|
410
|
+
return bundleOneOffScriptImpl(scriptPath, sdkPath);
|
|
411
|
+
}
|
|
412
|
+
// Endpoint mode: find all endpoints and bundle them
|
|
413
|
+
const appFlag = args.indexOf('--app');
|
|
414
|
+
let baseDir = process.cwd();
|
|
415
|
+
if (appFlag !== -1 && args[appFlag + 1]) {
|
|
416
|
+
baseDir = path.resolve(baseDir, 'apps', args[appFlag + 1]);
|
|
417
|
+
}
|
|
418
|
+
// If explicit endpoint names passed, use those; otherwise find all
|
|
419
|
+
const explicitNames = args.filter(a => !a.startsWith('--'));
|
|
420
|
+
let endpointNames;
|
|
421
|
+
if (explicitNames.length > 0) {
|
|
422
|
+
endpointNames = explicitNames;
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
const apiDir = path.join(baseDir, 'src', 'api');
|
|
426
|
+
if (!fs.existsSync(apiDir)) {
|
|
427
|
+
console.log(JSON.stringify({ bundledEndpoints: {} }));
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
endpointNames = fs
|
|
431
|
+
.readdirSync(apiDir)
|
|
432
|
+
.filter(f => f.endsWith('.ts'))
|
|
433
|
+
.map(f => f.replace('.ts', ''));
|
|
434
|
+
}
|
|
435
|
+
if (endpointNames.length === 0) {
|
|
436
|
+
console.log(JSON.stringify({ bundledEndpoints: {} }));
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
return bundleEndpointsImpl(baseDir, endpointNames);
|
|
440
|
+
}
|
package/dist/esm/cli.js
CHANGED
|
@@ -20,15 +20,21 @@ async function main() {
|
|
|
20
20
|
await runCheck();
|
|
21
21
|
break;
|
|
22
22
|
}
|
|
23
|
+
case 'bundle': {
|
|
24
|
+
const { runBundle } = await import('./bundle/index.js');
|
|
25
|
+
await runBundle();
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
23
28
|
default:
|
|
24
29
|
console.error(command
|
|
25
30
|
? `Unknown command: ${command}`
|
|
26
|
-
: 'Usage: zitejs <sync|dev|check>');
|
|
31
|
+
: 'Usage: zitejs <sync|dev|check|bundle>');
|
|
27
32
|
console.error('');
|
|
28
33
|
console.error('Commands:');
|
|
29
34
|
console.error(' sync Generate .zite/db.ts and .zite/api.ts from your database schema');
|
|
30
35
|
console.error(' dev Run sync then watch for changes (like npx convex dev)');
|
|
31
36
|
console.error(' check Run tsc --noEmit and vite build for all apps');
|
|
37
|
+
console.error(' bundle Bundle src/api/*.ts endpoints for cloudflare-lambda');
|
|
32
38
|
process.exit(1);
|
|
33
39
|
}
|
|
34
40
|
}
|
package/dist/esm/dev/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { watch } from 'fs';
|
|
|
2
2
|
import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { runSync } from '../sync/index.js';
|
|
5
|
-
import { generateApiTs } from '../sync/lib.js';
|
|
5
|
+
import { generateApiTs, generateUserTs, generateAuthWrapperTs, generateBackendWrapperTs, } from '../sync/lib.js';
|
|
6
6
|
const debounceTimers = new Map();
|
|
7
7
|
function debounce(key, fn, ms) {
|
|
8
8
|
const existing = debounceTimers.get(key);
|
|
@@ -29,6 +29,13 @@ function getFlowId(appDir) {
|
|
|
29
29
|
catch { }
|
|
30
30
|
return undefined;
|
|
31
31
|
}
|
|
32
|
+
function regenerateAppTypedWrappers(appDir) {
|
|
33
|
+
const outDir = join('apps', appDir, '.zite');
|
|
34
|
+
mkdirSync(outDir, { recursive: true });
|
|
35
|
+
writeFileSync(join(outDir, 'user.ts'), generateUserTs());
|
|
36
|
+
writeFileSync(join(outDir, 'auth.ts'), generateAuthWrapperTs());
|
|
37
|
+
writeFileSync(join(outDir, 'backend.ts'), generateBackendWrapperTs());
|
|
38
|
+
}
|
|
32
39
|
function regenerateAppApiTs(appDir) {
|
|
33
40
|
const apiDir = join('apps', appDir, 'src', 'api');
|
|
34
41
|
if (!existsSync(apiDir))
|
|
@@ -54,10 +61,11 @@ export async function runDev() {
|
|
|
54
61
|
console.warn('Initial sync failed (continuing with watcher):', err instanceof Error ? err.message : err);
|
|
55
62
|
}
|
|
56
63
|
console.log('');
|
|
57
|
-
// 2. Find all apps and regenerate their .zite/
|
|
64
|
+
// 2. Find all apps and regenerate their .zite/ files
|
|
58
65
|
const appDirs = findAppDirs();
|
|
59
66
|
for (const app of appDirs) {
|
|
60
67
|
regenerateAppApiTs(app);
|
|
68
|
+
regenerateAppTypedWrappers(app);
|
|
61
69
|
}
|
|
62
70
|
// 3. Watch each app's src/api/ for endpoint changes
|
|
63
71
|
let watchingAny = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zitejs",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.14",
|
|
4
4
|
"description": "The Zite framework — build apps on Zite Database",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/runtime/index.js",
|
|
@@ -111,6 +111,8 @@
|
|
|
111
111
|
"url": "https://github.com/zite/zitejs"
|
|
112
112
|
},
|
|
113
113
|
"dependencies": {
|
|
114
|
-
"
|
|
114
|
+
"@babel/parser": "^7.29.7",
|
|
115
|
+
"dotenv": "^17.4.2",
|
|
116
|
+
"esbuild": "^0.28.0"
|
|
115
117
|
}
|
|
116
118
|
}
|