@adep/cli 0.0.5 → 0.0.7
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/README.md +45 -50
- package/dist/index.js +1518 -1706
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -9,6 +9,20 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// packages/cli/src/config.ts
|
|
13
|
+
function resolvePaths(env = process.env) {
|
|
14
|
+
const home = env["ADEP_HOME"] ?? `${env["HOME"] ?? ""}/.adep`;
|
|
15
|
+
return { home, credentialsFile: `${home}/credentials` };
|
|
16
|
+
}
|
|
17
|
+
function resolveServer(env = process.env) {
|
|
18
|
+
return (env["ADEP_SERVER"] ?? "https://adep.jajabjbj.top").replace(/\/+$/, "");
|
|
19
|
+
}
|
|
20
|
+
var init_config = __esm({
|
|
21
|
+
"packages/cli/src/config.ts"() {
|
|
22
|
+
"use strict";
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
12
26
|
// packages/cli/src/credentials.ts
|
|
13
27
|
import { mkdir, open, readFile, rm, stat } from "node:fs/promises";
|
|
14
28
|
import { dirname } from "node:path";
|
|
@@ -218,327 +232,45 @@ var init_auth = __esm({
|
|
|
218
232
|
}
|
|
219
233
|
});
|
|
220
234
|
|
|
221
|
-
// packages/cli/src/
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
function resolveServer(env = process.env) {
|
|
227
|
-
return (env["ADEP_SERVER"] ?? "https://adep.jajabjbj.top").replace(/\/+$/, "");
|
|
228
|
-
}
|
|
229
|
-
var init_config = __esm({
|
|
230
|
-
"packages/cli/src/config.ts"() {
|
|
231
|
-
"use strict";
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// packages/cli/src/widget/build.ts
|
|
236
|
-
import { createHash } from "node:crypto";
|
|
237
|
-
import { join as join2, resolve as resolve2 } from "node:path";
|
|
238
|
-
import { build as esbuildBuild } from "esbuild";
|
|
239
|
-
async function buildWidget(options) {
|
|
240
|
-
const root = resolve2(options.cwd);
|
|
241
|
-
const entry = join2(root, options.entry ?? "src/index.ts");
|
|
242
|
-
const result = await esbuildBuild({
|
|
243
|
-
entryPoints: [entry],
|
|
244
|
-
bundle: true,
|
|
245
|
-
write: false,
|
|
246
|
-
format: "esm",
|
|
247
|
-
target: ["es2020"],
|
|
248
|
-
logLevel: "error",
|
|
249
|
-
loader: { ".ts": "ts", ".tsx": "tsx", ".js": "js", ".jsx": "jsx" },
|
|
250
|
-
...options.framework === "react" ? { jsx: "automatic", jsxImportSource: "react" } : {}
|
|
251
|
-
});
|
|
252
|
-
const text = result.outputFiles?.[0]?.text ?? "";
|
|
253
|
-
if (text.length === 0) {
|
|
254
|
-
throw new WidgetError("EMPTY_BUILD", "\u6784\u5EFA\u4EA7\u7269\u4E3A\u7A7A\uFF1A\u8BF7\u68C0\u67E5 widget \u5165\u53E3\u662F\u5426\u6B63\u786E");
|
|
255
|
-
}
|
|
256
|
-
const hash = createHash("sha256").update(text).digest("hex");
|
|
257
|
-
return { text, hash };
|
|
258
|
-
}
|
|
259
|
-
var WidgetError;
|
|
260
|
-
var init_build = __esm({
|
|
261
|
-
"packages/cli/src/widget/build.ts"() {
|
|
262
|
-
"use strict";
|
|
263
|
-
WidgetError = class extends Error {
|
|
264
|
-
constructor(code, message) {
|
|
265
|
-
super(message);
|
|
266
|
-
this.code = code;
|
|
267
|
-
this.name = "WidgetError";
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
}
|
|
235
|
+
// packages/cli/src/prompt.ts
|
|
236
|
+
var prompt_exports = {};
|
|
237
|
+
__export(prompt_exports, {
|
|
238
|
+
createPrompt: () => createPrompt
|
|
271
239
|
});
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
function
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
"manifest.json": MANIFEST(name, "vue3"),
|
|
278
|
-
"package.json": `{
|
|
279
|
-
"name": "${name}",
|
|
280
|
-
"version": "0.1.0",
|
|
281
|
-
"private": true,
|
|
282
|
-
"type": "module",
|
|
283
|
-
"scripts": {
|
|
284
|
-
"typecheck": "tsc --noEmit",
|
|
285
|
-
"dev": "adep widget dev",
|
|
286
|
-
"widget:publish": "adep widget publish -p"
|
|
287
|
-
},
|
|
288
|
-
"dependencies": {
|
|
289
|
-
"vue": "^3.5.0",
|
|
290
|
-
"@adep/types": "workspace:*"
|
|
291
|
-
},
|
|
292
|
-
"devDependencies": {
|
|
293
|
-
"typescript": "^5.5.0"
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
`,
|
|
297
|
-
"src/theme.css": THEME_CSS,
|
|
298
|
-
"src/App.ts": `import { defineComponent, h } from 'vue'
|
|
299
|
-
|
|
300
|
-
/** \u7EC4\u4EF6 props \u4E0E manifest.json \u7684 props schema \u5BF9\u9F50\uFF08contracts/ \u6821\u9A8C\u5B57\u6BB5\u5B50\u96C6\uFF09\u3002 */
|
|
301
|
-
export const App = defineComponent({
|
|
302
|
-
name: 'HelloVue',
|
|
303
|
-
props: {
|
|
304
|
-
title: { type: String, default: 'Hello' },
|
|
305
|
-
},
|
|
306
|
-
setup(props) {
|
|
307
|
-
return () =>
|
|
308
|
-
h('div', { style: { padding: 'var(--adep-space-4)' } }, [
|
|
309
|
-
h('h2', { style: { color: 'var(--adep-color-accent)' } }, props.title),
|
|
310
|
-
h(
|
|
311
|
-
'p',
|
|
312
|
-
{ style: { color: 'var(--adep-color-text-secondary)' } },
|
|
313
|
-
'Vue 3 \u6E32\u67D3\u51FD\u6570\u7EC4\u4EF6\u3002\u4E3B\u9898\u53D8\u91CF\u4E0E\u9274\u6743 token \u7531\u5BBF\u4E3B\u6CE8\u5165\u3002'
|
|
314
|
-
),
|
|
315
|
-
])
|
|
316
|
-
},
|
|
317
|
-
})
|
|
318
|
-
`,
|
|
319
|
-
"src/index.ts": `// Widget \u8FD0\u884C\u65F6\u5165\u53E3\uFF08FE-002\uFF09\u3002\u5BFC\u51FA HarnessWidgetRuntime \u4E09\u4EF6\u5957\uFF1A
|
|
320
|
-
// __harness / mount(host, ctx) / unmount(host)\u3002
|
|
321
|
-
// \u7EC4\u4EF6\u4EE5\u6E32\u67D3\u51FD\u6570\u7F16\u5199\uFF08\u975E SFC\uFF09\uFF0Cesbuild \u514D\u63D2\u4EF6\u76F4\u7F16\uFF08M3 MVP\uFF1B.vue SFC \u8D70 Vite \u5C5E\u4E8C\u671F\uFF09\u3002
|
|
322
|
-
import { createApp, type App as VueApp } from 'vue'
|
|
323
|
-
import type { HarnessMountHost, HarnessWidgetContext } from '@adep/types'
|
|
324
|
-
import { App } from './App'
|
|
325
|
-
|
|
326
|
-
// \u5BBF\u4E3B \u2192 \u6302\u8F7D\u7684 app \u5F15\u7528\uFF0Cunmount \u65F6\u7528\u5B8C\u91CA\u653E\uFF08WeakMap \u4E0D\u963B\u6B62\u5BBF\u4E3B\u56DE\u6536\uFF09\u3002
|
|
327
|
-
const mounted = new WeakMap<object, { app: VueApp; root: HTMLElement }>()
|
|
328
|
-
|
|
329
|
-
export const __harness = true as const
|
|
330
|
-
|
|
331
|
-
export function mount(host: HarnessMountHost, ctx: HarnessWidgetContext): void {
|
|
332
|
-
const root = document.createElement('div')
|
|
333
|
-
host.appendChild(root)
|
|
334
|
-
const app = createApp(App, ctx.props as never)
|
|
335
|
-
app.mount(root)
|
|
336
|
-
mounted.set(host, { app, root })
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
export function unmount(host: HarnessMountHost): void {
|
|
340
|
-
const entry = mounted.get(host)
|
|
341
|
-
if (entry === undefined) return
|
|
342
|
-
entry.app.unmount()
|
|
343
|
-
host.removeChild(entry.root)
|
|
344
|
-
mounted.delete(host)
|
|
345
|
-
}
|
|
346
|
-
`,
|
|
347
|
-
"src/mock-props.json": MOCK_PROPS
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
function reactFiles(name) {
|
|
240
|
+
import { createInterface } from "node:readline/promises";
|
|
241
|
+
import { Writable } from "node:stream";
|
|
242
|
+
function createPrompt(input = process.stdin) {
|
|
243
|
+
const rl = createInterface({ input, output: process.stdout, terminal: true });
|
|
244
|
+
let muted = null;
|
|
351
245
|
return {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
"name": "${name}",
|
|
356
|
-
"version": "0.1.0",
|
|
357
|
-
"private": true,
|
|
358
|
-
"type": "module",
|
|
359
|
-
"scripts": {
|
|
360
|
-
"typecheck": "tsc --noEmit",
|
|
361
|
-
"dev": "adep widget dev",
|
|
362
|
-
"widget:publish": "adep widget publish -p"
|
|
363
|
-
},
|
|
364
|
-
"dependencies": {
|
|
365
|
-
"react": "^18.3.0",
|
|
366
|
-
"react-dom": "^18.3.0",
|
|
367
|
-
"@adep/types": "workspace:*"
|
|
368
|
-
},
|
|
369
|
-
"devDependencies": {
|
|
370
|
-
"@types/react": "^18.3.0",
|
|
371
|
-
"@types/react-dom": "^18.3.0",
|
|
372
|
-
"typescript": "^5.5.0"
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
`,
|
|
376
|
-
"src/theme.css": THEME_CSS,
|
|
377
|
-
"src/App.tsx": `import type { CSSProperties } from 'react'
|
|
378
|
-
|
|
379
|
-
/** \u7EC4\u4EF6 props \u4E0E manifest.json \u7684 props schema \u5BF9\u9F50\uFF08contracts/ \u6821\u9A8C\u5B57\u6BB5\u5B50\u96C6\uFF09\u3002 */
|
|
380
|
-
export interface WidgetProps {
|
|
381
|
-
title: string
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
const styleRoot: CSSProperties = { padding: 'var(--adep-space-4)' }
|
|
385
|
-
const styleTitle: CSSProperties = { color: 'var(--adep-color-accent)', margin: 0 }
|
|
386
|
-
const styleDesc: CSSProperties = { color: 'var(--adep-color-text-secondary)' }
|
|
387
|
-
|
|
388
|
-
export default function App(props: WidgetProps): React.JSX.Element {
|
|
389
|
-
return (
|
|
390
|
-
<div style={styleRoot}>
|
|
391
|
-
<h2 style={styleTitle}>{props.title}</h2>
|
|
392
|
-
<p style={styleDesc}>React 18 \u7EC4\u4EF6\u3002\u4E3B\u9898\u53D8\u91CF\u4E0E\u9274\u6743 token \u7531\u5BBF\u4E3B\u6CE8\u5165\u3002</p>
|
|
393
|
-
</div>
|
|
394
|
-
)
|
|
395
|
-
}
|
|
396
|
-
`,
|
|
397
|
-
"src/index.tsx": `// Widget \u8FD0\u884C\u65F6\u5165\u53E3\uFF08FE-002\uFF09\u3002\u5BFC\u51FA HarnessWidgetRuntime \u4E09\u4EF6\u5957\uFF1A
|
|
398
|
-
// __harness / mount(host, ctx) / unmount(host)\u3002
|
|
399
|
-
import { createRoot, type Root } from 'react-dom/client'
|
|
400
|
-
import type { HarnessMountHost, HarnessWidgetContext } from '@adep/types'
|
|
401
|
-
import App from './App'
|
|
402
|
-
|
|
403
|
-
const mounted = new WeakMap<object, { root: Root; host: HTMLElement }>()
|
|
404
|
-
|
|
405
|
-
export const __harness = true as const
|
|
406
|
-
|
|
407
|
-
export function mount(host: HarnessMountHost, ctx: HarnessWidgetContext): void {
|
|
408
|
-
const container = document.createElement('div')
|
|
409
|
-
host.appendChild(container)
|
|
410
|
-
const root = createRoot(container)
|
|
411
|
-
root.render(<App {...(ctx.props as never)} />)
|
|
412
|
-
mounted.set(host, { root, host: container })
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
export function unmount(host: HarnessMountHost): void {
|
|
416
|
-
const entry = mounted.get(host)
|
|
417
|
-
if (entry === undefined) return
|
|
418
|
-
entry.root.unmount()
|
|
419
|
-
host.removeChild(entry.host)
|
|
420
|
-
mounted.delete(host)
|
|
421
|
-
}
|
|
422
|
-
`,
|
|
423
|
-
"src/mock-props.json": MOCK_PROPS
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
function widgetTemplateFiles(name, template) {
|
|
427
|
-
return template === "react-ts" ? reactFiles(name) : vue3Files(name);
|
|
428
|
-
}
|
|
429
|
-
var WIDGET_TEMPLATES, TS_BASE, MANIFEST, THEME_CSS, MOCK_PROPS;
|
|
430
|
-
var init_templates = __esm({
|
|
431
|
-
"packages/cli/src/widget/templates.ts"() {
|
|
432
|
-
"use strict";
|
|
433
|
-
WIDGET_TEMPLATES = ["vue3-ts", "react-ts"];
|
|
434
|
-
TS_BASE = () => ({
|
|
435
|
-
"tsconfig.json": `{
|
|
436
|
-
"compilerOptions": {
|
|
437
|
-
"target": "ES2020",
|
|
438
|
-
"module": "ESNext",
|
|
439
|
-
"moduleResolution": "Bundler",
|
|
440
|
-
"strict": true,
|
|
441
|
-
"jsx": "react-jsx",
|
|
442
|
-
"skipLibCheck": true,
|
|
443
|
-
"noEmit": true
|
|
444
|
-
},
|
|
445
|
-
"include": ["src"]
|
|
446
|
-
}
|
|
447
|
-
`,
|
|
448
|
-
"README.md": `# <widget>
|
|
449
|
-
|
|
450
|
-
AgentDeploy \u5FAE\u524D\u7AEF\u7EC4\u4EF6\uFF08widget\uFF09\u3002
|
|
451
|
-
|
|
452
|
-
- \`adep widget dev\`\uFF1A\u672C\u5730\u5BBF\u4E3B\u6C99\u7BB1\uFF08\u4E3B\u9898\u53D8\u91CF + mock props + token \u6CE8\u5165 + \u70ED\u66F4\u65B0\uFF09
|
|
453
|
-
- \`adep widget publish -p <project-slug>\`\uFF1A\u6309\u6846\u67B6\u6784\u5EFA \u2192 \u4E0A\u4F20\u5E73\u53F0\u9759\u6001\u8D44\u6E90 \u2192 \u7248\u672C\u5316\u8F93\u51FA URL
|
|
454
|
-
|
|
455
|
-
> \u7EC4\u4EF6\u5165\u53E3\u5BFC\u51FA \`__harness\` / \`mount(host, ctx)\` / \`unmount(host)\`\uFF0C\u5951\u7EA6\u89C1
|
|
456
|
-
> \`@adep/types\` \u7684 HarnessWidgetRuntime\uFF1B\u5BBF\u4E3B\u7528 \`<RemoteWidget>\` \u6309\u9700\u62C9\u53D6\u3002
|
|
457
|
-
`,
|
|
458
|
-
".gitignore": "node_modules/\n.adep/\ndist/\n"
|
|
459
|
-
});
|
|
460
|
-
MANIFEST = (name, framework) => `{
|
|
461
|
-
"name": "${name}",
|
|
462
|
-
"framework": "${framework}",
|
|
463
|
-
"props": {
|
|
464
|
-
"type": "object",
|
|
465
|
-
"properties": {
|
|
466
|
-
"title": { "type": "string" }
|
|
246
|
+
async ask(question) {
|
|
247
|
+
const answer = await rl.question(question);
|
|
248
|
+
return answer.trim();
|
|
467
249
|
},
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
481
|
-
`;
|
|
482
|
-
MOCK_PROPS = `{
|
|
483
|
-
"title": "Hello from mock props"
|
|
484
|
-
}
|
|
485
|
-
`;
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
// packages/cli/src/widget/init.ts
|
|
490
|
-
var init_exports = {};
|
|
491
|
-
__export(init_exports, {
|
|
492
|
-
WIDGET_TEMPLATES: () => WIDGET_TEMPLATES,
|
|
493
|
-
WidgetInitError: () => WidgetInitError,
|
|
494
|
-
initWidget: () => initWidget
|
|
495
|
-
});
|
|
496
|
-
import { mkdir as mkdir3, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
|
|
497
|
-
import { dirname as dirname3, join as join3, resolve as resolve3 } from "node:path";
|
|
498
|
-
async function initWidget(cwd, name, template) {
|
|
499
|
-
if (!WIDGET_NAME_RE.test(name)) {
|
|
500
|
-
throw new WidgetInitError(
|
|
501
|
-
"INVALID_NAME",
|
|
502
|
-
`widget \u540D "${name}" \u4E0D\u5408\u6CD5\uFF1A\u9700\u4EE5\u5C0F\u5199\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u542B\u5C0F\u5199\u5B57\u6BCD / \u6570\u5B57 / \u8FDE\u5B57\u7B26`
|
|
503
|
-
);
|
|
504
|
-
}
|
|
505
|
-
if (!WIDGET_TEMPLATES.includes(template)) {
|
|
506
|
-
throw new WidgetInitError("INVALID_TEMPLATE", `\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 vue3-ts | react-ts`);
|
|
507
|
-
}
|
|
508
|
-
const projectPath = resolve3(cwd, name);
|
|
509
|
-
let existing;
|
|
510
|
-
try {
|
|
511
|
-
existing = await stat3(projectPath);
|
|
512
|
-
} catch {
|
|
513
|
-
existing = null;
|
|
514
|
-
}
|
|
515
|
-
if (existing !== null) {
|
|
516
|
-
throw new WidgetInitError("DIR_EXISTS", `\u76EE\u5F55 ${projectPath} \u5DF2\u5B58\u5728\uFF1A\u8BF7\u6362\u4E00\u4E2A\u540D\u5B57\u6216\u5148\u5220\u9664`);
|
|
517
|
-
}
|
|
518
|
-
const files = widgetTemplateFiles(name, template);
|
|
519
|
-
await mkdir3(projectPath, { recursive: true });
|
|
520
|
-
await Promise.all(
|
|
521
|
-
Object.entries(files).map(async ([rel, content]) => {
|
|
522
|
-
const target = join3(projectPath, rel);
|
|
523
|
-
await mkdir3(dirname3(target), { recursive: true });
|
|
524
|
-
await writeFile2(target, content);
|
|
525
|
-
})
|
|
526
|
-
);
|
|
527
|
-
return { projectPath, files: Object.keys(files).toSorted() };
|
|
250
|
+
async askHidden(question) {
|
|
251
|
+
muted = createInterface({ input, output: new MutedStream(), terminal: true });
|
|
252
|
+
const answer = await muted.question(question);
|
|
253
|
+
muted.close();
|
|
254
|
+
muted = null;
|
|
255
|
+
process.stdout.write("\n");
|
|
256
|
+
return answer.trim();
|
|
257
|
+
},
|
|
258
|
+
close() {
|
|
259
|
+
muted?.close();
|
|
260
|
+
rl.close();
|
|
261
|
+
}
|
|
262
|
+
};
|
|
528
263
|
}
|
|
529
|
-
var
|
|
530
|
-
var
|
|
531
|
-
"packages/cli/src/
|
|
264
|
+
var MutedStream;
|
|
265
|
+
var init_prompt = __esm({
|
|
266
|
+
"packages/cli/src/prompt.ts"() {
|
|
532
267
|
"use strict";
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
this.code = code;
|
|
538
|
-
this.name = "WidgetInitError";
|
|
268
|
+
MutedStream = class extends Writable {
|
|
269
|
+
write(_chunk, ...rest) {
|
|
270
|
+
void rest;
|
|
271
|
+
return true;
|
|
539
272
|
}
|
|
540
273
|
};
|
|
541
|
-
WIDGET_NAME_RE = /^[a-z][a-z0-9-]{0,62}$/;
|
|
542
274
|
}
|
|
543
275
|
});
|
|
544
276
|
|
|
@@ -634,7 +366,7 @@ var init_domain = __esm({
|
|
|
634
366
|
});
|
|
635
367
|
|
|
636
368
|
// packages/runtime/src/functions/deps/manifest.ts
|
|
637
|
-
import { createHash
|
|
369
|
+
import { createHash } from "node:crypto";
|
|
638
370
|
function isVersionRangeSpec(spec) {
|
|
639
371
|
if (spec === "*" || spec === "latest") return true;
|
|
640
372
|
const unions = spec.split("||");
|
|
@@ -710,7 +442,7 @@ function classifyDependencies(dependencies, builtin) {
|
|
|
710
442
|
}
|
|
711
443
|
function depsKeyOf(dependencies) {
|
|
712
444
|
const canonical = Object.entries(dependencies).map(([name, version]) => `${name}@${version}`).toSorted().join("\n");
|
|
713
|
-
return
|
|
445
|
+
return createHash("sha256").update(canonical).digest("hex").slice(0, 16);
|
|
714
446
|
}
|
|
715
447
|
var PACKAGE_NAME_PATTERN, COMPARATOR_PATTERN, MANIFEST_MAX_DEPS;
|
|
716
448
|
var init_manifest = __esm({
|
|
@@ -724,14 +456,14 @@ var init_manifest = __esm({
|
|
|
724
456
|
});
|
|
725
457
|
|
|
726
458
|
// packages/runtime/src/functions/deps/resolve.ts
|
|
727
|
-
import { resolve as
|
|
459
|
+
import { resolve as resolve2 } from "node:path";
|
|
728
460
|
function resolveExecutionDeps(config, projectId, manifestContent) {
|
|
729
461
|
const manifest = tryParseManifestDependencies(manifestContent);
|
|
730
462
|
const { customDeps } = classifyDependencies(manifest, config.builtin);
|
|
731
463
|
const custom = Object.keys(customDeps);
|
|
732
464
|
return {
|
|
733
465
|
// 绝对化(相对进程 cwd,与 installer 侧 resolve(rootDir) 同基准):worker 的 createRequire 需要确定路径
|
|
734
|
-
dir: custom.length === 0 ? null :
|
|
466
|
+
dir: custom.length === 0 ? null : resolve2(config.rootDir, projectId, depsKeyOf(customDeps)),
|
|
735
467
|
builtin: [...config.builtin],
|
|
736
468
|
custom
|
|
737
469
|
};
|
|
@@ -746,22 +478,22 @@ var init_resolve = __esm({
|
|
|
746
478
|
// packages/runtime/src/functions/runtime/worker-executor.ts
|
|
747
479
|
import { readFileSync } from "node:fs";
|
|
748
480
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
749
|
-
import { dirname as
|
|
481
|
+
import { dirname as dirname3, join as join2 } from "node:path";
|
|
750
482
|
import { Worker } from "node:worker_threads";
|
|
751
483
|
function resolveWorkerEntry(baseDir = fileURLToPath(new URL(".", import.meta.url))) {
|
|
752
484
|
const candidates = [
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
485
|
+
join2(baseDir, "worker-entry.js"),
|
|
486
|
+
join2(baseDir, "worker-entry.ts"),
|
|
487
|
+
join2(baseDir, "domains/functions/runtime/worker-entry.js"),
|
|
488
|
+
join2(baseDir, "domains/functions/runtime/worker-entry.ts")
|
|
757
489
|
];
|
|
758
490
|
let current = baseDir;
|
|
759
491
|
for (let depth = 0; depth < 8; depth += 1) {
|
|
760
492
|
candidates.push(
|
|
761
|
-
|
|
762
|
-
|
|
493
|
+
join2(current, "packages/runtime/src/functions/runtime/worker-entry.js"),
|
|
494
|
+
join2(current, "packages/runtime/src/functions/runtime/worker-entry.ts")
|
|
763
495
|
);
|
|
764
|
-
const parent =
|
|
496
|
+
const parent = dirname3(current);
|
|
765
497
|
if (parent === current) break;
|
|
766
498
|
current = parent;
|
|
767
499
|
}
|
|
@@ -803,7 +535,7 @@ var init_worker_executor = __esm({
|
|
|
803
535
|
const entry = input.entry ?? "index.ts";
|
|
804
536
|
const deps = this.depsConfig === void 0 ? void 0 : resolveExecutionDeps(this.depsConfig, input.project.id, input.files["package.json"]);
|
|
805
537
|
const logs = [];
|
|
806
|
-
return new Promise((
|
|
538
|
+
return new Promise((resolve11, reject) => {
|
|
807
539
|
let worker;
|
|
808
540
|
try {
|
|
809
541
|
worker = new Worker(resolveWorkerEntry(), {
|
|
@@ -865,7 +597,7 @@ var init_worker_executor = __esm({
|
|
|
865
597
|
if (message.type === "result") {
|
|
866
598
|
clearTimeout(timer);
|
|
867
599
|
void worker.terminate();
|
|
868
|
-
|
|
600
|
+
resolve11({ body: message.body, logs });
|
|
869
601
|
return;
|
|
870
602
|
}
|
|
871
603
|
if (message.type === "error") {
|
|
@@ -2441,13 +2173,13 @@ var init_cloud2 = __esm({
|
|
|
2441
2173
|
});
|
|
2442
2174
|
|
|
2443
2175
|
// packages/runtime/src/storage/driver/local.ts
|
|
2444
|
-
import { mkdir as
|
|
2445
|
-
import { dirname as
|
|
2176
|
+
import { mkdir as mkdir3, readFile as readFile2, readdir, rm as rm2, stat as stat3, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
2177
|
+
import { dirname as dirname4, join as join3 } from "node:path";
|
|
2446
2178
|
function createLocalStorageDriver(options) {
|
|
2447
2179
|
const quotaBytes = options.quotaBytes ?? PROJECT_QUOTA_BYTES;
|
|
2448
|
-
const bucketDir = (projectId) =>
|
|
2449
|
-
const objectPath = (projectId, path) =>
|
|
2450
|
-
const metaPath = (projectId, path) =>
|
|
2180
|
+
const bucketDir = (projectId) => join3(options.dir, projectId);
|
|
2181
|
+
const objectPath = (projectId, path) => join3(bucketDir(projectId), path);
|
|
2182
|
+
const metaPath = (projectId, path) => join3(dirname4(objectPath(projectId, path)), `${path.split("/").pop() ?? ""}${META_SUFFIX}`);
|
|
2451
2183
|
const readStoredMeta = async (projectId, path) => {
|
|
2452
2184
|
const raw = await readFile2(metaPath(projectId, path), "utf8");
|
|
2453
2185
|
return JSON.parse(raw);
|
|
@@ -2459,7 +2191,7 @@ function createLocalStorageDriver(options) {
|
|
|
2459
2191
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2460
2192
|
...meta.contentType === void 0 ? {} : { contentType: meta.contentType }
|
|
2461
2193
|
};
|
|
2462
|
-
await
|
|
2194
|
+
await writeFile2(metaPath(projectId, path), JSON.stringify(payload), "utf8");
|
|
2463
2195
|
};
|
|
2464
2196
|
const totalSize = async (projectId) => {
|
|
2465
2197
|
const root = bucketDir(projectId);
|
|
@@ -2473,14 +2205,14 @@ function createLocalStorageDriver(options) {
|
|
|
2473
2205
|
}
|
|
2474
2206
|
const tasks = [];
|
|
2475
2207
|
for (const entry of entries) {
|
|
2476
|
-
const full =
|
|
2208
|
+
const full = join3(dir, entry.name);
|
|
2477
2209
|
if (entry.isDirectory()) {
|
|
2478
2210
|
tasks.push(walk(full));
|
|
2479
2211
|
} else if (entry.isFile() && !entry.name.endsWith(META_SUFFIX)) {
|
|
2480
2212
|
tasks.push(
|
|
2481
2213
|
(async () => {
|
|
2482
2214
|
try {
|
|
2483
|
-
const info = await
|
|
2215
|
+
const info = await stat3(full);
|
|
2484
2216
|
total += info.size;
|
|
2485
2217
|
} catch {
|
|
2486
2218
|
}
|
|
@@ -2502,7 +2234,7 @@ function createLocalStorageDriver(options) {
|
|
|
2502
2234
|
const used = await totalSize(projectId);
|
|
2503
2235
|
let existingSize = 0;
|
|
2504
2236
|
try {
|
|
2505
|
-
existingSize = (await
|
|
2237
|
+
existingSize = (await stat3(objectPath(projectId, path))).size;
|
|
2506
2238
|
} catch {
|
|
2507
2239
|
existingSize = 0;
|
|
2508
2240
|
}
|
|
@@ -2517,8 +2249,8 @@ function createLocalStorageDriver(options) {
|
|
|
2517
2249
|
);
|
|
2518
2250
|
}
|
|
2519
2251
|
const dest = objectPath(projectId, path);
|
|
2520
|
-
await
|
|
2521
|
-
await
|
|
2252
|
+
await mkdir3(dirname4(dest), { recursive: true });
|
|
2253
|
+
await writeFile2(dest, data);
|
|
2522
2254
|
await writeStoredMeta(projectId, path, {
|
|
2523
2255
|
visibility: putOptions.visibility,
|
|
2524
2256
|
size: data.byteLength,
|
|
@@ -2572,7 +2304,7 @@ function createLocalStorageDriver(options) {
|
|
|
2572
2304
|
assertSafeStoragePath(path);
|
|
2573
2305
|
let exists = true;
|
|
2574
2306
|
try {
|
|
2575
|
-
await
|
|
2307
|
+
await stat3(objectPath(projectId, path));
|
|
2576
2308
|
} catch {
|
|
2577
2309
|
exists = false;
|
|
2578
2310
|
}
|
|
@@ -2605,7 +2337,7 @@ function createLocalStorageDriver(options) {
|
|
|
2605
2337
|
const tasks = [];
|
|
2606
2338
|
for (const entry of entries) {
|
|
2607
2339
|
if (entry.name.endsWith(META_SUFFIX)) continue;
|
|
2608
|
-
const full =
|
|
2340
|
+
const full = join3(dir, entry.name);
|
|
2609
2341
|
const rel = relative3 === "" ? entry.name : `${relative3}/${entry.name}`;
|
|
2610
2342
|
if (entry.isFile()) {
|
|
2611
2343
|
if (prefix !== void 0 && !rel.startsWith(prefix)) continue;
|
|
@@ -2655,9 +2387,9 @@ var init_local = __esm({
|
|
|
2655
2387
|
});
|
|
2656
2388
|
|
|
2657
2389
|
// packages/cli/src/sim/storage.ts
|
|
2658
|
-
import { join as
|
|
2390
|
+
import { join as join4 } from "node:path";
|
|
2659
2391
|
function createSimStorageCapability(options) {
|
|
2660
|
-
const dir =
|
|
2392
|
+
const dir = join4(options.cwd, ".adep", "sim", "storage");
|
|
2661
2393
|
const driver = createLocalStorageDriver({ dir });
|
|
2662
2394
|
const signer = {
|
|
2663
2395
|
secret: options.secret ?? "adep-sim-secret",
|
|
@@ -2804,10 +2536,10 @@ var init_realtime = __esm({
|
|
|
2804
2536
|
});
|
|
2805
2537
|
|
|
2806
2538
|
// packages/cli/src/sim/runtime.ts
|
|
2807
|
-
import { mkdir as
|
|
2808
|
-
import { dirname as
|
|
2539
|
+
import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
2540
|
+
import { dirname as dirname5, join as join5 } from "node:path";
|
|
2809
2541
|
function simDir(cwd) {
|
|
2810
|
-
return
|
|
2542
|
+
return join5(cwd, ".adep", "sim");
|
|
2811
2543
|
}
|
|
2812
2544
|
function mergeBundles(bundles) {
|
|
2813
2545
|
const capabilities = [];
|
|
@@ -2829,7 +2561,7 @@ function mergeBundles(bundles) {
|
|
|
2829
2561
|
return { capabilities, rpcHandlers };
|
|
2830
2562
|
}
|
|
2831
2563
|
function jsonStorage(cwd) {
|
|
2832
|
-
const file =
|
|
2564
|
+
const file = join5(simDir(cwd), "db.json");
|
|
2833
2565
|
return {
|
|
2834
2566
|
async load() {
|
|
2835
2567
|
try {
|
|
@@ -2840,8 +2572,8 @@ function jsonStorage(cwd) {
|
|
|
2840
2572
|
}
|
|
2841
2573
|
},
|
|
2842
2574
|
async save(tables) {
|
|
2843
|
-
await
|
|
2844
|
-
await
|
|
2575
|
+
await mkdir4(dirname5(file), { recursive: true });
|
|
2576
|
+
await writeFile3(file, JSON.stringify(tables), "utf8");
|
|
2845
2577
|
}
|
|
2846
2578
|
};
|
|
2847
2579
|
}
|
|
@@ -2878,7 +2610,7 @@ var init_runtime = __esm({
|
|
|
2878
2610
|
|
|
2879
2611
|
// packages/cli/src/sim/env.ts
|
|
2880
2612
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
2881
|
-
import { join as
|
|
2613
|
+
import { join as join6 } from "node:path";
|
|
2882
2614
|
function parseEnv(content) {
|
|
2883
2615
|
const env = {};
|
|
2884
2616
|
for (const raw of content.split(/\r?\n/)) {
|
|
@@ -2893,8 +2625,8 @@ function parseEnv(content) {
|
|
|
2893
2625
|
return env;
|
|
2894
2626
|
}
|
|
2895
2627
|
async function loadSimEnv(cwd, config = {}) {
|
|
2896
|
-
const envRoot = await readFile4(
|
|
2897
|
-
const envLocal = await readFile4(
|
|
2628
|
+
const envRoot = await readFile4(join6(cwd, ".env"), "utf8").catch(() => "");
|
|
2629
|
+
const envLocal = await readFile4(join6(cwd, ".env.local"), "utf8").catch(() => "");
|
|
2898
2630
|
const merged = { ...parseEnv(envRoot), ...parseEnv(envLocal) };
|
|
2899
2631
|
for (const secret of config.secrets ?? []) {
|
|
2900
2632
|
if (merged[secret] !== void 0) continue;
|
|
@@ -2926,9 +2658,9 @@ function listFunctionNames(files) {
|
|
|
2926
2658
|
const names = /* @__PURE__ */ new Set();
|
|
2927
2659
|
for (const key of Object.keys(files)) {
|
|
2928
2660
|
const parts = key.split("/");
|
|
2929
|
-
if (parts.length === 1 && parts[0]
|
|
2661
|
+
if (parts.length === 1 && parts[0] !== void 0 && parts[0].endsWith(".ts")) {
|
|
2930
2662
|
names.add(parts[0].slice(0, -3));
|
|
2931
|
-
} else if (parts.length === 2 && parts[1] === "index.ts") {
|
|
2663
|
+
} else if (parts.length === 2 && parts[1] === "index.ts" && parts[0] !== void 0) {
|
|
2932
2664
|
names.add(parts[0]);
|
|
2933
2665
|
}
|
|
2934
2666
|
}
|
|
@@ -3016,13 +2748,13 @@ __export(dev_exports, {
|
|
|
3016
2748
|
});
|
|
3017
2749
|
import { createServer } from "node:http";
|
|
3018
2750
|
import { watch } from "node:fs";
|
|
3019
|
-
import { mkdir as
|
|
3020
|
-
import { basename, join as
|
|
2751
|
+
import { mkdir as mkdir5, readdir as readdir2, readFile as readFile5, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
|
|
2752
|
+
import { basename, join as join7, resolve as resolve3 } from "node:path";
|
|
3021
2753
|
async function loadConfig(cwd) {
|
|
3022
|
-
const name = basename(
|
|
3023
|
-
const configPath =
|
|
2754
|
+
const name = basename(resolve3(cwd));
|
|
2755
|
+
const configPath = join7(cwd, "adep.config.ts");
|
|
3024
2756
|
try {
|
|
3025
|
-
await
|
|
2757
|
+
await stat4(configPath);
|
|
3026
2758
|
} catch {
|
|
3027
2759
|
return { name, functionsDir: "functions" };
|
|
3028
2760
|
}
|
|
@@ -3062,7 +2794,7 @@ async function collectFunctions(dir) {
|
|
|
3062
2794
|
}
|
|
3063
2795
|
for (const entry of entries) {
|
|
3064
2796
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
3065
|
-
const full =
|
|
2797
|
+
const full = join7(sub, entry.name);
|
|
3066
2798
|
if (entry.isDirectory()) {
|
|
3067
2799
|
await walk(full, rel);
|
|
3068
2800
|
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
@@ -3103,22 +2835,22 @@ function printBoundaries(log) {
|
|
|
3103
2835
|
}
|
|
3104
2836
|
}
|
|
3105
2837
|
async function ensureGitignore(cwd) {
|
|
3106
|
-
const gitignorePath =
|
|
2838
|
+
const gitignorePath = join7(cwd, ".gitignore");
|
|
3107
2839
|
const existing = await readFile5(gitignorePath, "utf8").catch(() => "");
|
|
3108
2840
|
if (existing.split(/\r?\n/).includes(".adep/")) return;
|
|
3109
|
-
await
|
|
2841
|
+
await writeFile4(gitignorePath, `${existing.replace(/\n+$/, "")}
|
|
3110
2842
|
.adep/
|
|
3111
2843
|
`, "utf8");
|
|
3112
2844
|
}
|
|
3113
2845
|
async function startDevServer(options) {
|
|
3114
|
-
const cwd =
|
|
2846
|
+
const cwd = resolve3(options.cwd);
|
|
3115
2847
|
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
3116
2848
|
`));
|
|
3117
2849
|
const config = await loadConfig(cwd);
|
|
3118
|
-
const functionsDir =
|
|
2850
|
+
const functionsDir = join7(cwd, config.functionsDir);
|
|
3119
2851
|
const coldStartAt = Date.now();
|
|
3120
2852
|
const executor = new WorkerFunctionExecutor();
|
|
3121
|
-
await
|
|
2853
|
+
await mkdir5(functionsDir, { recursive: true });
|
|
3122
2854
|
const runtime = await createSimRuntime({
|
|
3123
2855
|
cwd,
|
|
3124
2856
|
projectId: "local",
|
|
@@ -3133,12 +2865,12 @@ async function startDevServer(options) {
|
|
|
3133
2865
|
const reload = async () => {
|
|
3134
2866
|
const [nextFiles, envText2] = await Promise.all([
|
|
3135
2867
|
collectFunctions(functionsDir),
|
|
3136
|
-
readFile5(
|
|
2868
|
+
readFile5(join7(cwd, ".env.local"), "utf8").catch(() => "")
|
|
3137
2869
|
]);
|
|
3138
2870
|
files = nextFiles;
|
|
3139
2871
|
env = parseEnvFile(envText2);
|
|
3140
2872
|
};
|
|
3141
|
-
const envText = await readFile5(
|
|
2873
|
+
const envText = await readFile5(join7(cwd, ".env.local"), "utf8").catch(() => "");
|
|
3142
2874
|
env = parseEnvFile(envText);
|
|
3143
2875
|
let debounceTimer;
|
|
3144
2876
|
let watcher;
|
|
@@ -3270,321 +3002,68 @@ var init_dev = __esm({
|
|
|
3270
3002
|
}
|
|
3271
3003
|
});
|
|
3272
3004
|
|
|
3273
|
-
// packages/cli/src/
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
createClient: () => createClient,
|
|
3277
|
-
resolveSlug: () => resolveSlug
|
|
3278
|
-
});
|
|
3279
|
-
async function envelopeError(response, fallbackCode, parsed) {
|
|
3280
|
-
const payload = parsed ?? null;
|
|
3281
|
-
return new CliError(
|
|
3282
|
-
payload?.error?.code ?? fallbackCode,
|
|
3283
|
-
payload?.error?.message ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`
|
|
3284
|
-
);
|
|
3005
|
+
// packages/cli/src/serve/banner.ts
|
|
3006
|
+
function isLoopback(host) {
|
|
3007
|
+
return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]";
|
|
3285
3008
|
}
|
|
3286
|
-
|
|
3287
|
-
const
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3009
|
+
function renderBanner(options) {
|
|
3010
|
+
const { host, port, projectName, functions, hasStatic, staticDir = "public/" } = options;
|
|
3011
|
+
const baseUrl = `http://${host}:${port}`;
|
|
3012
|
+
const loopback = isLoopback(host);
|
|
3013
|
+
const lines = [];
|
|
3014
|
+
lines.push("");
|
|
3015
|
+
lines.push("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
|
|
3016
|
+
lines.push("\u2551 adep serve \u2014 \u5F00\u53D1\u6001\u670D\u52A1\u5668 \u2551");
|
|
3017
|
+
lines.push("\u2551 \u26A0 \u8FD9\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668\uFF0C\u4E0D\u63D0\u4F9B TLS / \u96C6\u7FA4 / \u4F18\u96C5\u91CD\u542F \u2551");
|
|
3018
|
+
lines.push("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
|
|
3019
|
+
lines.push("");
|
|
3020
|
+
lines.push(` \u9879\u76EE: ${projectName}`);
|
|
3021
|
+
lines.push(` \u5730\u5740: ${baseUrl}`);
|
|
3022
|
+
lines.push(` \u7ED1\u5B9A: ${host}${loopback ? "\uFF08\u4EC5\u672C\u673A\u53EF\u8BBF\u95EE\uFF09" : "\uFF08\u26A0 \u5BF9\u5916\u66B4\u9732\uFF09"}`);
|
|
3023
|
+
lines.push("");
|
|
3024
|
+
lines.push(" \u80FD\u529B:");
|
|
3025
|
+
if (functions.length > 0) {
|
|
3026
|
+
lines.push(
|
|
3027
|
+
` - \u51FD\u6570\u8DEF\u7531: ${baseUrl}/api/{fn}\uFF08${functions.length} \u4E2A\u51FD\u6570: ${functions.join(", ")}\uFF09`
|
|
3028
|
+
);
|
|
3029
|
+
} else {
|
|
3030
|
+
lines.push(" - \u51FD\u6570\u8DEF\u7531: \u65E0\uFF08functions/ \u76EE\u5F55\u4E3A\u7A7A\uFF09");
|
|
3031
|
+
}
|
|
3032
|
+
if (hasStatic) {
|
|
3033
|
+
lines.push(` - \u9759\u6001\u6258\u7BA1: ${baseUrl}/ \u2192 ${staticDir}`);
|
|
3034
|
+
} else {
|
|
3035
|
+
lines.push(` - \u9759\u6001\u6258\u7BA1: \u65E0\uFF08${staticDir} \u76EE\u5F55\u4E0D\u5B58\u5728\uFF09`);
|
|
3036
|
+
}
|
|
3037
|
+
lines.push(" - \u7EC4\u4EF6\u9884\u89C8: Widget / Page \u4EA7\u7269\uFF08\u5982\u5DF2\u6784\u5EFA\uFF09");
|
|
3038
|
+
lines.push(` - \u5065\u5EB7\u68C0\u67E5: ${baseUrl}/healthz`);
|
|
3039
|
+
lines.push("");
|
|
3040
|
+
lines.push(" \u8FB9\u754C\uFF08\u5F00\u53D1\u6001\u9ED8\u8BA4\u503C\uFF0C\u4E0D\u53EF\u5728\u6B64\u6A21\u5F0F\u4E0B\u5F00\u542F\uFF09:");
|
|
3041
|
+
lines.push(" - \u65E0\u9274\u6743\uFF1A\u4EFB\u4F55\u4EBA\u53EF\u8C03\u7528\u6240\u6709\u51FD\u6570");
|
|
3042
|
+
lines.push(" - \u65E0\u9650\u6D41\uFF1A\u65E0 QPS / \u5E76\u53D1\u9650\u5236");
|
|
3043
|
+
lines.push(" - \u65E0\u914D\u989D\uFF1A\u65E0\u8C03\u7528\u6B21\u6570 / \u8D44\u6E90\u7528\u91CF\u9650\u5236");
|
|
3044
|
+
lines.push(" - \u65E0 TLS\uFF1A\u660E\u6587 HTTP\uFF0C\u4E0D\u652F\u6301 HTTPS");
|
|
3045
|
+
lines.push(" - \u65E0\u96C6\u7FA4\uFF1A\u5355\u8FDB\u7A0B\uFF0C\u4E0D\u652F\u6301\u591A\u5B9E\u4F8B");
|
|
3046
|
+
lines.push(" - \u65E0\u4F18\u96C5\u91CD\u542F\uFF1A\u8FDB\u7A0B\u9000\u51FA\u5373\u4E2D\u65AD");
|
|
3047
|
+
lines.push("");
|
|
3048
|
+
if (!loopback) {
|
|
3049
|
+
lines.push(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
3050
|
+
lines.push(" \u2502 \u26A0\u26A0\u26A0 \u5BF9\u5916\u66B4\u9732\u8B66\u544A \u2502");
|
|
3051
|
+
lines.push(" \u2502 \u2502");
|
|
3052
|
+
lines.push(` \u2502 \u5F53\u524D\u7ED1\u5B9A ${host.padEnd(43)}\u2502`);
|
|
3053
|
+
lines.push(" \u2502 \u5C40\u57DF\u7F51/\u516C\u7F51\u5185\u4EFB\u4F55\u4EBA\u90FD\u53EF\u8BBF\u95EE\u4F60\u7684\u51FD\u6570\u4E0E\u6570\u636E\u3002 \u2502");
|
|
3054
|
+
lines.push(" \u2502 \u65E0\u9274\u6743\u3001\u65E0\u9650\u6D41\u3001\u65E0\u914D\u989D\u2014\u2014\u8BF7\u52FF\u5728\u4E0D\u53EF\u4FE1\u7F51\u7EDC\u4E2D\u4F7F\u7528\u3002 \u2502");
|
|
3055
|
+
lines.push(" \u2502 \u2502");
|
|
3056
|
+
lines.push(" \u2502 \u9700\u8981\u751F\u4EA7\u90E8\u7F72\uFF1F\u4F7F\u7528 `adep deploy` \u90E8\u7F72\u5230\u5E73\u53F0\u3002 \u2502");
|
|
3057
|
+
lines.push(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
|
3058
|
+
lines.push("");
|
|
3293
3059
|
}
|
|
3060
|
+
lines.push(" \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668\u3002");
|
|
3061
|
+
lines.push("");
|
|
3062
|
+
return lines.join("\n");
|
|
3294
3063
|
}
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
throw new CliError("NOT_LOGGED_IN", "\u672A\u767B\u5F55\uFF1A\u8BF7\u5148\u6267\u884C adep login");
|
|
3299
|
-
}
|
|
3300
|
-
const server = credentials.server;
|
|
3301
|
-
const cookie = `better-auth.session_token=${decodeToken(credentials.encodedToken)}`;
|
|
3302
|
-
const request = async (path, init = {}, fallbackCode = "API_REQUEST_FAILED") => {
|
|
3303
|
-
const method = init.method ?? (init.body === void 0 ? "GET" : "POST");
|
|
3304
|
-
let response;
|
|
3305
|
-
try {
|
|
3306
|
-
response = await fetch(`${server}${path}`, {
|
|
3307
|
-
method,
|
|
3308
|
-
headers: { "content-type": "application/json", cookie },
|
|
3309
|
-
...init.body === void 0 ? {} : { body: JSON.stringify(init.body) }
|
|
3310
|
-
});
|
|
3311
|
-
} catch (error) {
|
|
3312
|
-
throw new CliError(
|
|
3313
|
-
"SERVER_UNREACHABLE",
|
|
3314
|
-
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
3315
|
-
);
|
|
3316
|
-
}
|
|
3317
|
-
const parsed = await parseBody(response);
|
|
3318
|
-
if (response.status < 200 || response.status >= 300) {
|
|
3319
|
-
throw await envelopeError(response, fallbackCode, parsed);
|
|
3320
|
-
}
|
|
3321
|
-
return parsed;
|
|
3322
|
-
};
|
|
3323
|
-
const upload = async (path, form, fallbackCode = "UPLOAD_FAILED") => {
|
|
3324
|
-
let response;
|
|
3325
|
-
try {
|
|
3326
|
-
response = await fetch(`${server}${path}`, {
|
|
3327
|
-
method: "POST",
|
|
3328
|
-
headers: { cookie },
|
|
3329
|
-
body: form
|
|
3330
|
-
});
|
|
3331
|
-
} catch (error) {
|
|
3332
|
-
throw new CliError(
|
|
3333
|
-
"SERVER_UNREACHABLE",
|
|
3334
|
-
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
3335
|
-
);
|
|
3336
|
-
}
|
|
3337
|
-
if (response.status < 200 || response.status >= 300) {
|
|
3338
|
-
throw await envelopeError(response, fallbackCode, await parseBody(response));
|
|
3339
|
-
}
|
|
3340
|
-
return response;
|
|
3341
|
-
};
|
|
3342
|
-
const download = async (url, fallbackCode = "DOWNLOAD_FAILED") => {
|
|
3343
|
-
const target = url.startsWith("http") ? url : `${server}${url}`;
|
|
3344
|
-
let response;
|
|
3345
|
-
try {
|
|
3346
|
-
response = await fetch(target, { headers: { cookie } });
|
|
3347
|
-
} catch (error) {
|
|
3348
|
-
throw new CliError(
|
|
3349
|
-
"SERVER_UNREACHABLE",
|
|
3350
|
-
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
3351
|
-
);
|
|
3352
|
-
}
|
|
3353
|
-
if (response.status < 200 || response.status >= 300) {
|
|
3354
|
-
throw await envelopeError(response, fallbackCode, await parseBody(response));
|
|
3355
|
-
}
|
|
3356
|
-
return response;
|
|
3357
|
-
};
|
|
3358
|
-
return { server, cookie, request, upload, download };
|
|
3359
|
-
}
|
|
3360
|
-
async function resolveSlug(cwd, slug) {
|
|
3361
|
-
if (slug !== void 0 && slug.length > 0) return slug;
|
|
3362
|
-
const config = await loadConfig(cwd);
|
|
3363
|
-
return config.name;
|
|
3364
|
-
}
|
|
3365
|
-
var init_client = __esm({
|
|
3366
|
-
"packages/cli/src/client.ts"() {
|
|
3367
|
-
"use strict";
|
|
3368
|
-
init_auth();
|
|
3369
|
-
init_credentials();
|
|
3370
|
-
init_dev();
|
|
3371
|
-
}
|
|
3372
|
-
});
|
|
3373
|
-
|
|
3374
|
-
// packages/cli/src/deploy.ts
|
|
3375
|
-
var deploy_exports = {};
|
|
3376
|
-
__export(deploy_exports, {
|
|
3377
|
-
collectEntries: () => collectEntries,
|
|
3378
|
-
deploy: () => deploy
|
|
3379
|
-
});
|
|
3380
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
3381
|
-
import { readdir as readdir3, readFile as readFile6 } from "node:fs/promises";
|
|
3382
|
-
import { join as join10, resolve as resolve6, basename as basename2 } from "node:path";
|
|
3383
|
-
async function collectEntries(functionsDir) {
|
|
3384
|
-
const entries = {};
|
|
3385
|
-
let names;
|
|
3386
|
-
try {
|
|
3387
|
-
const dirents = await readdir3(functionsDir, { withFileTypes: true });
|
|
3388
|
-
names = dirents.filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => basename2(entry.name, ".ts")).toSorted();
|
|
3389
|
-
} catch {
|
|
3390
|
-
return entries;
|
|
3391
|
-
}
|
|
3392
|
-
for (const name of names) {
|
|
3393
|
-
entries[name] = await readFile6(join10(functionsDir, `${name}.ts`), "utf8");
|
|
3394
|
-
}
|
|
3395
|
-
return entries;
|
|
3396
|
-
}
|
|
3397
|
-
function sha256Hex(content) {
|
|
3398
|
-
return createHash3("sha256").update(content).digest("hex");
|
|
3399
|
-
}
|
|
3400
|
-
async function deploy(paths, options) {
|
|
3401
|
-
await requireNetwork("adep deploy");
|
|
3402
|
-
const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
|
|
3403
|
-
`));
|
|
3404
|
-
const client = await createClient(paths);
|
|
3405
|
-
const cwd = resolve6(options.cwd);
|
|
3406
|
-
const config = await loadConfig(cwd);
|
|
3407
|
-
const slug = options.slug ?? config.name;
|
|
3408
|
-
const functionsDir = options.functionsDir === void 0 ? join10(cwd, config.functionsDir) : resolve6(cwd, options.functionsDir);
|
|
3409
|
-
const local = await collectEntries(functionsDir);
|
|
3410
|
-
if (Object.keys(local).length === 0) {
|
|
3411
|
-
throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
|
|
3412
|
-
}
|
|
3413
|
-
const remote = await client.request(
|
|
3414
|
-
"/api/v1/deploy/diff",
|
|
3415
|
-
{
|
|
3416
|
-
body: {
|
|
3417
|
-
slug,
|
|
3418
|
-
functions: Object.entries(local).map(([name, content]) => ({
|
|
3419
|
-
name,
|
|
3420
|
-
files: { "index.ts": sha256Hex(content) }
|
|
3421
|
-
}))
|
|
3422
|
-
}
|
|
3423
|
-
},
|
|
3424
|
-
"DEPLOY_FAILED"
|
|
3425
|
-
);
|
|
3426
|
-
const baseUrl = `${remote.scheme}://${remote.slug}.${remote.domain}`;
|
|
3427
|
-
const deployed = [];
|
|
3428
|
-
for (const item of remote.functions) {
|
|
3429
|
-
const content = local[item.name];
|
|
3430
|
-
if (item.action === "none") {
|
|
3431
|
-
deployed.push({
|
|
3432
|
-
name: item.name,
|
|
3433
|
-
action: "none",
|
|
3434
|
-
version: item.version ?? 0,
|
|
3435
|
-
url: `${baseUrl}/${item.name}`
|
|
3436
|
-
});
|
|
3437
|
-
continue;
|
|
3438
|
-
}
|
|
3439
|
-
log(`[adep] \u90E8\u7F72 ${item.name}\uFF08${item.action === "create" ? "\u65B0\u5EFA" : "\u53D8\u66F4"}\uFF09`);
|
|
3440
|
-
let functionId = item.id;
|
|
3441
|
-
if (functionId === null) {
|
|
3442
|
-
const created = await client.request(
|
|
3443
|
-
`/api/v1/projects/${remote.projectId}/functions`,
|
|
3444
|
-
{
|
|
3445
|
-
body: { name: item.name, files: { "index.ts": content } }
|
|
3446
|
-
}
|
|
3447
|
-
);
|
|
3448
|
-
functionId = created.id;
|
|
3449
|
-
} else {
|
|
3450
|
-
await client.request(`/api/v1/projects/${remote.projectId}/functions/${item.name}`, {
|
|
3451
|
-
method: "PATCH",
|
|
3452
|
-
body: { files: { "index.ts": content } }
|
|
3453
|
-
});
|
|
3454
|
-
}
|
|
3455
|
-
const published = await client.request(
|
|
3456
|
-
`/api/v1/functions/${functionId}/publish`,
|
|
3457
|
-
{ method: "POST" }
|
|
3458
|
-
);
|
|
3459
|
-
deployed.push({
|
|
3460
|
-
name: item.name,
|
|
3461
|
-
action: item.action,
|
|
3462
|
-
version: published.version,
|
|
3463
|
-
url: `${baseUrl}/${item.name}`
|
|
3464
|
-
});
|
|
3465
|
-
}
|
|
3466
|
-
return {
|
|
3467
|
-
projectId: remote.projectId,
|
|
3468
|
-
slug: remote.slug,
|
|
3469
|
-
baseUrl,
|
|
3470
|
-
noChanges: deployed.every((function_) => function_.action === "none"),
|
|
3471
|
-
functions: deployed
|
|
3472
|
-
};
|
|
3473
|
-
}
|
|
3474
|
-
var init_deploy = __esm({
|
|
3475
|
-
"packages/cli/src/deploy.ts"() {
|
|
3476
|
-
"use strict";
|
|
3477
|
-
init_auth();
|
|
3478
|
-
init_client();
|
|
3479
|
-
init_dev();
|
|
3480
|
-
init_net();
|
|
3481
|
-
}
|
|
3482
|
-
});
|
|
3483
|
-
|
|
3484
|
-
// packages/cli/src/prompt.ts
|
|
3485
|
-
var prompt_exports = {};
|
|
3486
|
-
__export(prompt_exports, {
|
|
3487
|
-
createPrompt: () => createPrompt
|
|
3488
|
-
});
|
|
3489
|
-
import { createInterface } from "node:readline/promises";
|
|
3490
|
-
import { Writable } from "node:stream";
|
|
3491
|
-
function createPrompt(input = process.stdin) {
|
|
3492
|
-
const rl = createInterface({ input, output: process.stdout, terminal: true });
|
|
3493
|
-
let muted = null;
|
|
3494
|
-
return {
|
|
3495
|
-
async ask(question) {
|
|
3496
|
-
const answer = await rl.question(question);
|
|
3497
|
-
return answer.trim();
|
|
3498
|
-
},
|
|
3499
|
-
async askHidden(question) {
|
|
3500
|
-
muted = createInterface({ input, output: new MutedStream(), terminal: true });
|
|
3501
|
-
const answer = await muted.question(question);
|
|
3502
|
-
muted.close();
|
|
3503
|
-
muted = null;
|
|
3504
|
-
process.stdout.write("\n");
|
|
3505
|
-
return answer.trim();
|
|
3506
|
-
},
|
|
3507
|
-
close() {
|
|
3508
|
-
muted?.close();
|
|
3509
|
-
rl.close();
|
|
3510
|
-
}
|
|
3511
|
-
};
|
|
3512
|
-
}
|
|
3513
|
-
var MutedStream;
|
|
3514
|
-
var init_prompt = __esm({
|
|
3515
|
-
"packages/cli/src/prompt.ts"() {
|
|
3516
|
-
"use strict";
|
|
3517
|
-
MutedStream = class extends Writable {
|
|
3518
|
-
write(_chunk, ...rest) {
|
|
3519
|
-
void rest;
|
|
3520
|
-
return true;
|
|
3521
|
-
}
|
|
3522
|
-
};
|
|
3523
|
-
}
|
|
3524
|
-
});
|
|
3525
|
-
|
|
3526
|
-
// packages/cli/src/serve/banner.ts
|
|
3527
|
-
function isLoopback(host) {
|
|
3528
|
-
return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]";
|
|
3529
|
-
}
|
|
3530
|
-
function renderBanner(options) {
|
|
3531
|
-
const { host, port, projectName, functions, hasStatic, staticDir = "public/" } = options;
|
|
3532
|
-
const baseUrl = `http://${host}:${port}`;
|
|
3533
|
-
const loopback = isLoopback(host);
|
|
3534
|
-
const lines = [];
|
|
3535
|
-
lines.push("");
|
|
3536
|
-
lines.push("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
|
|
3537
|
-
lines.push("\u2551 adep serve \u2014 \u5F00\u53D1\u6001\u670D\u52A1\u5668 \u2551");
|
|
3538
|
-
lines.push("\u2551 \u26A0 \u8FD9\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668\uFF0C\u4E0D\u63D0\u4F9B TLS / \u96C6\u7FA4 / \u4F18\u96C5\u91CD\u542F \u2551");
|
|
3539
|
-
lines.push("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
|
|
3540
|
-
lines.push("");
|
|
3541
|
-
lines.push(` \u9879\u76EE: ${projectName}`);
|
|
3542
|
-
lines.push(` \u5730\u5740: ${baseUrl}`);
|
|
3543
|
-
lines.push(` \u7ED1\u5B9A: ${host}${loopback ? "\uFF08\u4EC5\u672C\u673A\u53EF\u8BBF\u95EE\uFF09" : "\uFF08\u26A0 \u5BF9\u5916\u66B4\u9732\uFF09"}`);
|
|
3544
|
-
lines.push("");
|
|
3545
|
-
lines.push(" \u80FD\u529B:");
|
|
3546
|
-
if (functions.length > 0) {
|
|
3547
|
-
lines.push(
|
|
3548
|
-
` - \u51FD\u6570\u8DEF\u7531: ${baseUrl}/api/{fn}\uFF08${functions.length} \u4E2A\u51FD\u6570: ${functions.join(", ")}\uFF09`
|
|
3549
|
-
);
|
|
3550
|
-
} else {
|
|
3551
|
-
lines.push(" - \u51FD\u6570\u8DEF\u7531: \u65E0\uFF08functions/ \u76EE\u5F55\u4E3A\u7A7A\uFF09");
|
|
3552
|
-
}
|
|
3553
|
-
if (hasStatic) {
|
|
3554
|
-
lines.push(` - \u9759\u6001\u6258\u7BA1: ${baseUrl}/ \u2192 ${staticDir}`);
|
|
3555
|
-
} else {
|
|
3556
|
-
lines.push(` - \u9759\u6001\u6258\u7BA1: \u65E0\uFF08${staticDir} \u76EE\u5F55\u4E0D\u5B58\u5728\uFF09`);
|
|
3557
|
-
}
|
|
3558
|
-
lines.push(" - \u7EC4\u4EF6\u9884\u89C8: Widget / Page \u4EA7\u7269\uFF08\u5982\u5DF2\u6784\u5EFA\uFF09");
|
|
3559
|
-
lines.push(` - \u5065\u5EB7\u68C0\u67E5: ${baseUrl}/healthz`);
|
|
3560
|
-
lines.push("");
|
|
3561
|
-
lines.push(" \u8FB9\u754C\uFF08\u5F00\u53D1\u6001\u9ED8\u8BA4\u503C\uFF0C\u4E0D\u53EF\u5728\u6B64\u6A21\u5F0F\u4E0B\u5F00\u542F\uFF09:");
|
|
3562
|
-
lines.push(" - \u65E0\u9274\u6743\uFF1A\u4EFB\u4F55\u4EBA\u53EF\u8C03\u7528\u6240\u6709\u51FD\u6570");
|
|
3563
|
-
lines.push(" - \u65E0\u9650\u6D41\uFF1A\u65E0 QPS / \u5E76\u53D1\u9650\u5236");
|
|
3564
|
-
lines.push(" - \u65E0\u914D\u989D\uFF1A\u65E0\u8C03\u7528\u6B21\u6570 / \u8D44\u6E90\u7528\u91CF\u9650\u5236");
|
|
3565
|
-
lines.push(" - \u65E0 TLS\uFF1A\u660E\u6587 HTTP\uFF0C\u4E0D\u652F\u6301 HTTPS");
|
|
3566
|
-
lines.push(" - \u65E0\u96C6\u7FA4\uFF1A\u5355\u8FDB\u7A0B\uFF0C\u4E0D\u652F\u6301\u591A\u5B9E\u4F8B");
|
|
3567
|
-
lines.push(" - \u65E0\u4F18\u96C5\u91CD\u542F\uFF1A\u8FDB\u7A0B\u9000\u51FA\u5373\u4E2D\u65AD");
|
|
3568
|
-
lines.push("");
|
|
3569
|
-
if (!loopback) {
|
|
3570
|
-
lines.push(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
3571
|
-
lines.push(" \u2502 \u26A0\u26A0\u26A0 \u5BF9\u5916\u66B4\u9732\u8B66\u544A \u2502");
|
|
3572
|
-
lines.push(" \u2502 \u2502");
|
|
3573
|
-
lines.push(` \u2502 \u5F53\u524D\u7ED1\u5B9A ${host.padEnd(43)}\u2502`);
|
|
3574
|
-
lines.push(" \u2502 \u5C40\u57DF\u7F51/\u516C\u7F51\u5185\u4EFB\u4F55\u4EBA\u90FD\u53EF\u8BBF\u95EE\u4F60\u7684\u51FD\u6570\u4E0E\u6570\u636E\u3002 \u2502");
|
|
3575
|
-
lines.push(" \u2502 \u65E0\u9274\u6743\u3001\u65E0\u9650\u6D41\u3001\u65E0\u914D\u989D\u2014\u2014\u8BF7\u52FF\u5728\u4E0D\u53EF\u4FE1\u7F51\u7EDC\u4E2D\u4F7F\u7528\u3002 \u2502");
|
|
3576
|
-
lines.push(" \u2502 \u2502");
|
|
3577
|
-
lines.push(" \u2502 \u9700\u8981\u751F\u4EA7\u90E8\u7F72\uFF1F\u4F7F\u7528 `adep deploy` \u90E8\u7F72\u5230\u5E73\u53F0\u3002 \u2502");
|
|
3578
|
-
lines.push(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
|
3579
|
-
lines.push("");
|
|
3580
|
-
}
|
|
3581
|
-
lines.push(" \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668\u3002");
|
|
3582
|
-
lines.push("");
|
|
3583
|
-
return lines.join("\n");
|
|
3584
|
-
}
|
|
3585
|
-
var init_banner = __esm({
|
|
3586
|
-
"packages/cli/src/serve/banner.ts"() {
|
|
3587
|
-
"use strict";
|
|
3064
|
+
var init_banner = __esm({
|
|
3065
|
+
"packages/cli/src/serve/banner.ts"() {
|
|
3066
|
+
"use strict";
|
|
3588
3067
|
}
|
|
3589
3068
|
});
|
|
3590
3069
|
|
|
@@ -3595,8 +3074,9 @@ __export(server_exports, {
|
|
|
3595
3074
|
startServeServer: () => startServeServer
|
|
3596
3075
|
});
|
|
3597
3076
|
import { createServer as createServer2 } from "node:http";
|
|
3598
|
-
import {
|
|
3599
|
-
import {
|
|
3077
|
+
import { watch as watch2 } from "node:fs";
|
|
3078
|
+
import { mkdir as mkdir6, readdir as readdir3, readFile as readFile6, stat as stat5 } from "node:fs/promises";
|
|
3079
|
+
import { join as join8, relative, resolve as resolve4 } from "node:path";
|
|
3600
3080
|
function envNumber(name) {
|
|
3601
3081
|
const raw = process.env[name];
|
|
3602
3082
|
if (raw === void 0 || raw.trim() === "") return void 0;
|
|
@@ -3612,17 +3092,17 @@ async function collectFunctions2(dir) {
|
|
|
3612
3092
|
const walk = async (sub, prefix) => {
|
|
3613
3093
|
let entries;
|
|
3614
3094
|
try {
|
|
3615
|
-
entries = await
|
|
3095
|
+
entries = await readdir3(sub, { withFileTypes: true });
|
|
3616
3096
|
} catch {
|
|
3617
3097
|
return;
|
|
3618
3098
|
}
|
|
3619
3099
|
for (const entry of entries) {
|
|
3620
3100
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
3621
|
-
const full =
|
|
3101
|
+
const full = join8(sub, entry.name);
|
|
3622
3102
|
if (entry.isDirectory()) {
|
|
3623
3103
|
await walk(full, rel);
|
|
3624
3104
|
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
3625
|
-
files[rel] = await
|
|
3105
|
+
files[rel] = await readFile6(full, "utf8");
|
|
3626
3106
|
}
|
|
3627
3107
|
}
|
|
3628
3108
|
};
|
|
@@ -3657,29 +3137,29 @@ function contentTypeFor(path) {
|
|
|
3657
3137
|
return MIME_TYPES[ext] ?? "application/octet-stream";
|
|
3658
3138
|
}
|
|
3659
3139
|
async function startServeServer(options) {
|
|
3660
|
-
const cwd =
|
|
3140
|
+
const cwd = resolve4(options.cwd);
|
|
3661
3141
|
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
3662
3142
|
`));
|
|
3663
3143
|
const host = options.host ?? envString("HOST") ?? "127.0.0.1";
|
|
3664
3144
|
const port = options.port ?? envNumber("PORT") ?? 8787;
|
|
3665
|
-
const staticDir =
|
|
3145
|
+
const staticDir = resolve4(
|
|
3666
3146
|
cwd,
|
|
3667
3147
|
options.staticDir ?? envString("ADEP_SERVE_STATIC_DIR") ?? "public"
|
|
3668
3148
|
);
|
|
3669
3149
|
const config = await loadConfig(cwd);
|
|
3670
|
-
const functionsDir =
|
|
3150
|
+
const functionsDir = join8(cwd, config.functionsDir);
|
|
3671
3151
|
let hasStatic = false;
|
|
3672
3152
|
try {
|
|
3673
|
-
const publicStat = await
|
|
3153
|
+
const publicStat = await stat5(staticDir);
|
|
3674
3154
|
hasStatic = publicStat.isDirectory();
|
|
3675
3155
|
} catch {
|
|
3676
3156
|
hasStatic = false;
|
|
3677
3157
|
}
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
const envText = await
|
|
3681
|
-
|
|
3682
|
-
|
|
3158
|
+
let files = await collectFunctions2(functionsDir);
|
|
3159
|
+
let functionNames = listFunctionNames(files);
|
|
3160
|
+
const envText = await readFile6(join8(cwd, ".env.local"), "utf8").catch(() => "");
|
|
3161
|
+
let env = parseEnvFile(envText);
|
|
3162
|
+
let simEnv = await loadSimEnv(cwd).catch(() => ({}));
|
|
3683
3163
|
const runtime = await createSimRuntime({
|
|
3684
3164
|
cwd,
|
|
3685
3165
|
projectId: "local",
|
|
@@ -3688,7 +3168,44 @@ async function startServeServer(options) {
|
|
|
3688
3168
|
});
|
|
3689
3169
|
const executor = new WorkerFunctionExecutor();
|
|
3690
3170
|
const dbBundle = runtime.bundle;
|
|
3691
|
-
|
|
3171
|
+
let invokeHandler = createSimInvokeHandler({ executor, files });
|
|
3172
|
+
let stopWatch;
|
|
3173
|
+
if (options.watch === true) {
|
|
3174
|
+
const reload = async () => {
|
|
3175
|
+
const [nextFiles, envLocalText] = await Promise.all([
|
|
3176
|
+
collectFunctions2(functionsDir),
|
|
3177
|
+
readFile6(join8(cwd, ".env.local"), "utf8").catch(() => "")
|
|
3178
|
+
]);
|
|
3179
|
+
files = nextFiles;
|
|
3180
|
+
env = parseEnvFile(envLocalText);
|
|
3181
|
+
simEnv = await loadSimEnv(cwd).catch(() => ({}));
|
|
3182
|
+
invokeHandler = createSimInvokeHandler({ executor, files });
|
|
3183
|
+
functionNames = listFunctionNames(files);
|
|
3184
|
+
log(`[serve] \u70ED\u91CD\u8F7D\uFF1A\u68C0\u6D4B\u5230\u53D8\u66F4\uFF0C\u5DF2\u91CD\u65B0\u52A0\u8F7D ${functionNames.length} \u4E2A\u51FD\u6570`);
|
|
3185
|
+
};
|
|
3186
|
+
let debounceTimer;
|
|
3187
|
+
const watchers = [];
|
|
3188
|
+
const scheduleReload = () => {
|
|
3189
|
+
if (debounceTimer !== void 0) clearTimeout(debounceTimer);
|
|
3190
|
+
debounceTimer = setTimeout(() => {
|
|
3191
|
+
void reload();
|
|
3192
|
+
}, 120);
|
|
3193
|
+
};
|
|
3194
|
+
await mkdir6(functionsDir, { recursive: true }).catch(() => void 0);
|
|
3195
|
+
try {
|
|
3196
|
+
watchers.push(watch2(functionsDir, { recursive: true }, scheduleReload));
|
|
3197
|
+
} catch {
|
|
3198
|
+
log("[serve] \u8B66\u544A\uFF1Afunctions/ \u9012\u5F52\u76D1\u542C\u4E0D\u53EF\u7528\uFF0C\u70ED\u91CD\u8F7D\u5173\u95ED\uFF08\u670D\u52A1\u6B63\u5E38\u8FD0\u884C\uFF09");
|
|
3199
|
+
}
|
|
3200
|
+
try {
|
|
3201
|
+
watchers.push(watch2(cwd, scheduleReload));
|
|
3202
|
+
} catch {
|
|
3203
|
+
}
|
|
3204
|
+
stopWatch = () => {
|
|
3205
|
+
if (debounceTimer !== void 0) clearTimeout(debounceTimer);
|
|
3206
|
+
for (const watcher of watchers) watcher.close();
|
|
3207
|
+
};
|
|
3208
|
+
}
|
|
3692
3209
|
const buildInput = async (fnName, entry, url, req) => {
|
|
3693
3210
|
const query = {};
|
|
3694
3211
|
for (const key of new Set(url.searchParams.keys())) {
|
|
@@ -3726,16 +3243,16 @@ async function startServeServer(options) {
|
|
|
3726
3243
|
const serveStatic = async (pathname, res) => {
|
|
3727
3244
|
if (!hasStatic) return false;
|
|
3728
3245
|
const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
|
|
3729
|
-
const filePath =
|
|
3730
|
-
const resolvedPath = safePath === "" || safePath === "/" ?
|
|
3246
|
+
const filePath = join8(staticDir, safePath);
|
|
3247
|
+
const resolvedPath = safePath === "" || safePath === "/" ? join8(filePath, "index.html") : filePath;
|
|
3731
3248
|
try {
|
|
3732
|
-
const fileStat = await
|
|
3249
|
+
const fileStat = await stat5(resolvedPath);
|
|
3733
3250
|
if (fileStat.isDirectory()) {
|
|
3734
|
-
const indexPath =
|
|
3251
|
+
const indexPath = join8(resolvedPath, "index.html");
|
|
3735
3252
|
try {
|
|
3736
|
-
const indexStat = await
|
|
3253
|
+
const indexStat = await stat5(indexPath);
|
|
3737
3254
|
if (indexStat.isFile()) {
|
|
3738
|
-
const content2 = await
|
|
3255
|
+
const content2 = await readFile6(indexPath);
|
|
3739
3256
|
res.writeHead(200, { "content-type": contentTypeFor(indexPath) });
|
|
3740
3257
|
res.end(content2);
|
|
3741
3258
|
return true;
|
|
@@ -3744,7 +3261,7 @@ async function startServeServer(options) {
|
|
|
3744
3261
|
}
|
|
3745
3262
|
return false;
|
|
3746
3263
|
}
|
|
3747
|
-
const content = await
|
|
3264
|
+
const content = await readFile6(resolvedPath);
|
|
3748
3265
|
res.writeHead(200, { "content-type": contentTypeFor(resolvedPath) });
|
|
3749
3266
|
res.end(content);
|
|
3750
3267
|
return true;
|
|
@@ -3775,6 +3292,9 @@ async function startServeServer(options) {
|
|
|
3775
3292
|
const result = await executor.execute(input);
|
|
3776
3293
|
const durationMs = Math.round(performance.now() - startedAt);
|
|
3777
3294
|
log(`[serve] ${req.method ?? "GET"} ${pathname} -> 200 ${durationMs}ms`);
|
|
3295
|
+
if (options.watch === true) {
|
|
3296
|
+
for (const line of result.logs) log(`[serve] ${line}`);
|
|
3297
|
+
}
|
|
3778
3298
|
writeJson2(res, 200, result.body === void 0 ? null : result.body);
|
|
3779
3299
|
} catch (error) {
|
|
3780
3300
|
const durationMs = Math.round(performance.now() - startedAt);
|
|
@@ -3801,123 +3321,322 @@ async function startServeServer(options) {
|
|
|
3801
3321
|
service: "adep-serve",
|
|
3802
3322
|
project: config.name
|
|
3803
3323
|
});
|
|
3804
|
-
return;
|
|
3324
|
+
return;
|
|
3325
|
+
}
|
|
3326
|
+
const served = await serveStatic(pathname, res);
|
|
3327
|
+
if (served) return;
|
|
3328
|
+
if (pathname === "/" || pathname === "") {
|
|
3329
|
+
writeJson2(res, 200, {
|
|
3330
|
+
service: "adep-serve",
|
|
3331
|
+
mode: "development",
|
|
3332
|
+
project: config.name,
|
|
3333
|
+
functions: functionNames,
|
|
3334
|
+
static: hasStatic,
|
|
3335
|
+
endpoints: {
|
|
3336
|
+
functions: "/api/{fn}",
|
|
3337
|
+
static: `/ \u2192 ${staticDir}`,
|
|
3338
|
+
healthz: "/healthz"
|
|
3339
|
+
},
|
|
3340
|
+
warning: "\u8FD9\u662F\u5F00\u53D1\u6001\u670D\u52A1\u5668\uFF0C\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668"
|
|
3341
|
+
});
|
|
3342
|
+
return;
|
|
3343
|
+
}
|
|
3344
|
+
writeJson2(res, 404, { error: { code: "NOT_FOUND", message: `\u8DEF\u5F84 "${pathname}" \u4E0D\u5B58\u5728` } });
|
|
3345
|
+
};
|
|
3346
|
+
const server = createServer2((req, res) => {
|
|
3347
|
+
void handle(req, res).catch((error) => {
|
|
3348
|
+
log(`[serve] \u672A\u5904\u7406\u9519\u8BEF: ${error instanceof Error ? error.message : String(error)}`);
|
|
3349
|
+
if (!res.headersSent) {
|
|
3350
|
+
writeJson2(res, 500, { error: { code: "INTERNAL_ERROR", message: "\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF" } });
|
|
3351
|
+
}
|
|
3352
|
+
});
|
|
3353
|
+
});
|
|
3354
|
+
const actualPort = await new Promise((resolveListen, rejectListen) => {
|
|
3355
|
+
server.once("error", rejectListen);
|
|
3356
|
+
server.listen(port, host, () => {
|
|
3357
|
+
server.off("error", rejectListen);
|
|
3358
|
+
const addr = server.address();
|
|
3359
|
+
if (addr === null || typeof addr === "string") {
|
|
3360
|
+
resolveListen(port);
|
|
3361
|
+
} else {
|
|
3362
|
+
resolveListen(addr.port);
|
|
3363
|
+
}
|
|
3364
|
+
});
|
|
3365
|
+
});
|
|
3366
|
+
const banner = renderBanner({
|
|
3367
|
+
host,
|
|
3368
|
+
port: actualPort,
|
|
3369
|
+
projectName: config.name,
|
|
3370
|
+
functions: functionNames,
|
|
3371
|
+
hasStatic,
|
|
3372
|
+
staticDir: relative(cwd, staticDir).length > 0 ? relative(cwd, staticDir) : staticDir
|
|
3373
|
+
});
|
|
3374
|
+
log(banner);
|
|
3375
|
+
if (options.watch === true) {
|
|
3376
|
+
log(`[serve] \u70ED\u91CD\u8F7D\u5DF2\u5F00\u542F\uFF1A\u6539 functions/ \u4E0E .env* \u5373\u751F\u6548\uFF0C\u51FD\u6570 console \u8F93\u51FA\u76F4\u8FBE\u7EC8\u7AEF\uFF08--watch\uFF09`);
|
|
3377
|
+
}
|
|
3378
|
+
return {
|
|
3379
|
+
port: actualPort,
|
|
3380
|
+
host,
|
|
3381
|
+
baseUrl: `http://${host}:${actualPort}`,
|
|
3382
|
+
close: async () => {
|
|
3383
|
+
stopWatch?.();
|
|
3384
|
+
await new Promise((resolveClose) => {
|
|
3385
|
+
server.close(() => resolveClose());
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
};
|
|
3389
|
+
}
|
|
3390
|
+
var MIME_TYPES;
|
|
3391
|
+
var init_server = __esm({
|
|
3392
|
+
"packages/cli/src/serve/server.ts"() {
|
|
3393
|
+
"use strict";
|
|
3394
|
+
init_executor();
|
|
3395
|
+
init_worker_executor();
|
|
3396
|
+
init_runtime();
|
|
3397
|
+
init_env();
|
|
3398
|
+
init_invoke();
|
|
3399
|
+
init_dev();
|
|
3400
|
+
init_banner();
|
|
3401
|
+
MIME_TYPES = {
|
|
3402
|
+
".html": "text/html; charset=utf-8",
|
|
3403
|
+
".htm": "text/html; charset=utf-8",
|
|
3404
|
+
".css": "text/css; charset=utf-8",
|
|
3405
|
+
".js": "application/javascript; charset=utf-8",
|
|
3406
|
+
".mjs": "application/javascript; charset=utf-8",
|
|
3407
|
+
".json": "application/json; charset=utf-8",
|
|
3408
|
+
".png": "image/png",
|
|
3409
|
+
".jpg": "image/jpeg",
|
|
3410
|
+
".jpeg": "image/jpeg",
|
|
3411
|
+
".gif": "image/gif",
|
|
3412
|
+
".svg": "image/svg+xml",
|
|
3413
|
+
".ico": "image/x-icon",
|
|
3414
|
+
".woff": "font/woff",
|
|
3415
|
+
".woff2": "font/woff2",
|
|
3416
|
+
".ttf": "font/ttf",
|
|
3417
|
+
".txt": "text/plain; charset=utf-8",
|
|
3418
|
+
".md": "text/markdown; charset=utf-8",
|
|
3419
|
+
".pdf": "application/pdf",
|
|
3420
|
+
".map": "application/json"
|
|
3421
|
+
};
|
|
3422
|
+
}
|
|
3423
|
+
});
|
|
3424
|
+
|
|
3425
|
+
// packages/cli/src/client.ts
|
|
3426
|
+
var client_exports = {};
|
|
3427
|
+
__export(client_exports, {
|
|
3428
|
+
createClient: () => createClient,
|
|
3429
|
+
resolveSlug: () => resolveSlug
|
|
3430
|
+
});
|
|
3431
|
+
async function envelopeError(response, fallbackCode, parsed) {
|
|
3432
|
+
const payload = parsed ?? null;
|
|
3433
|
+
return new CliError(
|
|
3434
|
+
payload?.error?.code ?? fallbackCode,
|
|
3435
|
+
payload?.error?.message ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`
|
|
3436
|
+
);
|
|
3437
|
+
}
|
|
3438
|
+
async function parseBody(response) {
|
|
3439
|
+
const text = await response.text();
|
|
3440
|
+
if (text.length === 0) return null;
|
|
3441
|
+
try {
|
|
3442
|
+
return JSON.parse(text);
|
|
3443
|
+
} catch {
|
|
3444
|
+
return null;
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
async function createClient(paths) {
|
|
3448
|
+
const credentials = await loadCredentials(paths);
|
|
3449
|
+
if (credentials === null) {
|
|
3450
|
+
throw new CliError("NOT_LOGGED_IN", "\u672A\u767B\u5F55\uFF1A\u8BF7\u5148\u6267\u884C adep login");
|
|
3451
|
+
}
|
|
3452
|
+
const server = credentials.server;
|
|
3453
|
+
const cookie = `better-auth.session_token=${decodeToken(credentials.encodedToken)}`;
|
|
3454
|
+
const request = async (path, init = {}, fallbackCode = "API_REQUEST_FAILED") => {
|
|
3455
|
+
const method = init.method ?? (init.body === void 0 ? "GET" : "POST");
|
|
3456
|
+
let response;
|
|
3457
|
+
try {
|
|
3458
|
+
response = await fetch(`${server}${path}`, {
|
|
3459
|
+
method,
|
|
3460
|
+
headers: { "content-type": "application/json", cookie },
|
|
3461
|
+
...init.body === void 0 ? {} : { body: JSON.stringify(init.body) }
|
|
3462
|
+
});
|
|
3463
|
+
} catch (error) {
|
|
3464
|
+
throw new CliError(
|
|
3465
|
+
"SERVER_UNREACHABLE",
|
|
3466
|
+
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
3467
|
+
);
|
|
3468
|
+
}
|
|
3469
|
+
const parsed = await parseBody(response);
|
|
3470
|
+
if (response.status < 200 || response.status >= 300) {
|
|
3471
|
+
throw await envelopeError(response, fallbackCode, parsed);
|
|
3472
|
+
}
|
|
3473
|
+
return parsed;
|
|
3474
|
+
};
|
|
3475
|
+
const upload = async (path, form, fallbackCode = "UPLOAD_FAILED") => {
|
|
3476
|
+
let response;
|
|
3477
|
+
try {
|
|
3478
|
+
response = await fetch(`${server}${path}`, {
|
|
3479
|
+
method: "POST",
|
|
3480
|
+
headers: { cookie },
|
|
3481
|
+
body: form
|
|
3482
|
+
});
|
|
3483
|
+
} catch (error) {
|
|
3484
|
+
throw new CliError(
|
|
3485
|
+
"SERVER_UNREACHABLE",
|
|
3486
|
+
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
3487
|
+
);
|
|
3488
|
+
}
|
|
3489
|
+
if (response.status < 200 || response.status >= 300) {
|
|
3490
|
+
throw await envelopeError(response, fallbackCode, await parseBody(response));
|
|
3491
|
+
}
|
|
3492
|
+
return response;
|
|
3493
|
+
};
|
|
3494
|
+
const download = async (url, fallbackCode = "DOWNLOAD_FAILED") => {
|
|
3495
|
+
const target = url.startsWith("http") ? url : `${server}${url}`;
|
|
3496
|
+
let response;
|
|
3497
|
+
try {
|
|
3498
|
+
response = await fetch(target, { headers: { cookie } });
|
|
3499
|
+
} catch (error) {
|
|
3500
|
+
throw new CliError(
|
|
3501
|
+
"SERVER_UNREACHABLE",
|
|
3502
|
+
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
3503
|
+
);
|
|
3504
|
+
}
|
|
3505
|
+
if (response.status < 200 || response.status >= 300) {
|
|
3506
|
+
throw await envelopeError(response, fallbackCode, await parseBody(response));
|
|
3507
|
+
}
|
|
3508
|
+
return response;
|
|
3509
|
+
};
|
|
3510
|
+
return { server, cookie, request, upload, download };
|
|
3511
|
+
}
|
|
3512
|
+
async function resolveSlug(cwd, slug) {
|
|
3513
|
+
if (slug !== void 0 && slug.length > 0) return slug;
|
|
3514
|
+
const config = await loadConfig(cwd);
|
|
3515
|
+
return config.name;
|
|
3516
|
+
}
|
|
3517
|
+
var init_client = __esm({
|
|
3518
|
+
"packages/cli/src/client.ts"() {
|
|
3519
|
+
"use strict";
|
|
3520
|
+
init_auth();
|
|
3521
|
+
init_credentials();
|
|
3522
|
+
init_dev();
|
|
3523
|
+
}
|
|
3524
|
+
});
|
|
3525
|
+
|
|
3526
|
+
// packages/cli/src/deploy.ts
|
|
3527
|
+
var deploy_exports = {};
|
|
3528
|
+
__export(deploy_exports, {
|
|
3529
|
+
collectEntries: () => collectEntries,
|
|
3530
|
+
deploy: () => deploy
|
|
3531
|
+
});
|
|
3532
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
3533
|
+
import { readdir as readdir4, readFile as readFile7 } from "node:fs/promises";
|
|
3534
|
+
import { join as join9, resolve as resolve5, basename as basename2 } from "node:path";
|
|
3535
|
+
function functionUrlBase(prefix) {
|
|
3536
|
+
const raw = (prefix ?? "/api").trim();
|
|
3537
|
+
const normalized = raw === "/" ? "/" : raw.replace(/\/+$/, "");
|
|
3538
|
+
return normalized === "/" ? "" : normalized;
|
|
3539
|
+
}
|
|
3540
|
+
async function collectEntries(functionsDir) {
|
|
3541
|
+
const entries = {};
|
|
3542
|
+
let names;
|
|
3543
|
+
try {
|
|
3544
|
+
const dirents = await readdir4(functionsDir, { withFileTypes: true });
|
|
3545
|
+
names = dirents.filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => basename2(entry.name, ".ts")).toSorted();
|
|
3546
|
+
} catch {
|
|
3547
|
+
return entries;
|
|
3548
|
+
}
|
|
3549
|
+
for (const name of names) {
|
|
3550
|
+
entries[name] = await readFile7(join9(functionsDir, `${name}.ts`), "utf8");
|
|
3551
|
+
}
|
|
3552
|
+
return entries;
|
|
3553
|
+
}
|
|
3554
|
+
function sha256Hex(content) {
|
|
3555
|
+
return createHash2("sha256").update(content).digest("hex");
|
|
3556
|
+
}
|
|
3557
|
+
async function deploy(paths, options) {
|
|
3558
|
+
await requireNetwork("adep deploy");
|
|
3559
|
+
const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
|
|
3560
|
+
`));
|
|
3561
|
+
const client = await createClient(paths);
|
|
3562
|
+
const cwd = resolve5(options.cwd);
|
|
3563
|
+
const config = await loadConfig(cwd);
|
|
3564
|
+
const slug = options.slug ?? config.name;
|
|
3565
|
+
const functionsDir = options.functionsDir === void 0 ? join9(cwd, config.functionsDir) : resolve5(cwd, options.functionsDir);
|
|
3566
|
+
const local = await collectEntries(functionsDir);
|
|
3567
|
+
if (Object.keys(local).length === 0) {
|
|
3568
|
+
throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
|
|
3569
|
+
}
|
|
3570
|
+
const remote = await client.request(
|
|
3571
|
+
"/api/v1/deploy/diff",
|
|
3572
|
+
{
|
|
3573
|
+
body: {
|
|
3574
|
+
slug,
|
|
3575
|
+
functions: Object.entries(local).map(([name, content]) => ({
|
|
3576
|
+
name,
|
|
3577
|
+
files: { "index.ts": sha256Hex(content) }
|
|
3578
|
+
}))
|
|
3579
|
+
}
|
|
3580
|
+
},
|
|
3581
|
+
"DEPLOY_FAILED"
|
|
3582
|
+
);
|
|
3583
|
+
const baseUrl = `${remote.scheme}://${remote.slug}.${remote.domain}`;
|
|
3584
|
+
const prefixBase = functionUrlBase(remote.functionsPrefix);
|
|
3585
|
+
const functionUrl = (name) => `${baseUrl}${prefixBase}/${name}`;
|
|
3586
|
+
const deployed = [];
|
|
3587
|
+
for (const item of remote.functions) {
|
|
3588
|
+
const content = local[item.name];
|
|
3589
|
+
if (item.action === "none") {
|
|
3590
|
+
deployed.push({
|
|
3591
|
+
name: item.name,
|
|
3592
|
+
action: "none",
|
|
3593
|
+
version: item.version ?? 0,
|
|
3594
|
+
url: functionUrl(item.name)
|
|
3595
|
+
});
|
|
3596
|
+
continue;
|
|
3805
3597
|
}
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
if (
|
|
3809
|
-
const
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
const widgetStat = await stat6(widgetDir);
|
|
3814
|
-
if (widgetStat.isDirectory()) {
|
|
3815
|
-
const indexPath = join11(widgetDir, "index.html");
|
|
3816
|
-
try {
|
|
3817
|
-
const content = await readFile7(indexPath, "utf8");
|
|
3818
|
-
res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
3819
|
-
res.end(content);
|
|
3820
|
-
return;
|
|
3821
|
-
} catch {
|
|
3822
|
-
}
|
|
3823
|
-
}
|
|
3824
|
-
} catch {
|
|
3598
|
+
log(`[adep] \u90E8\u7F72 ${item.name}\uFF08${item.action === "create" ? "\u65B0\u5EFA" : "\u53D8\u66F4"}\uFF09`);
|
|
3599
|
+
let functionId = item.id;
|
|
3600
|
+
if (functionId === null) {
|
|
3601
|
+
const created = await client.request(
|
|
3602
|
+
`/api/v1/projects/${remote.projectId}/functions`,
|
|
3603
|
+
{
|
|
3604
|
+
body: { name: item.name, files: { "index.ts": content } }
|
|
3825
3605
|
}
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
service: "adep-serve",
|
|
3833
|
-
mode: "development",
|
|
3834
|
-
project: config.name,
|
|
3835
|
-
functions: functionNames,
|
|
3836
|
-
static: hasStatic,
|
|
3837
|
-
endpoints: {
|
|
3838
|
-
functions: "/api/{fn}",
|
|
3839
|
-
static: `/ \u2192 ${staticDir}`,
|
|
3840
|
-
preview: "/_preview/{widget}",
|
|
3841
|
-
healthz: "/healthz"
|
|
3842
|
-
},
|
|
3843
|
-
warning: "\u8FD9\u662F\u5F00\u53D1\u6001\u670D\u52A1\u5668\uFF0C\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668"
|
|
3606
|
+
);
|
|
3607
|
+
functionId = created.id;
|
|
3608
|
+
} else {
|
|
3609
|
+
await client.request(`/api/v1/projects/${remote.projectId}/functions/${item.name}`, {
|
|
3610
|
+
method: "PATCH",
|
|
3611
|
+
body: { files: { "index.ts": content } }
|
|
3844
3612
|
});
|
|
3845
|
-
return;
|
|
3846
3613
|
}
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
});
|
|
3857
|
-
const actualPort = await new Promise((resolveListen, rejectListen) => {
|
|
3858
|
-
server.once("error", rejectListen);
|
|
3859
|
-
server.listen(port, host, () => {
|
|
3860
|
-
server.off("error", rejectListen);
|
|
3861
|
-
const addr = server.address();
|
|
3862
|
-
if (addr === null || typeof addr === "string") {
|
|
3863
|
-
resolveListen(port);
|
|
3864
|
-
} else {
|
|
3865
|
-
resolveListen(addr.port);
|
|
3866
|
-
}
|
|
3614
|
+
const published = await client.request(
|
|
3615
|
+
`/api/v1/functions/${functionId}/publish`,
|
|
3616
|
+
{ method: "POST" }
|
|
3617
|
+
);
|
|
3618
|
+
deployed.push({
|
|
3619
|
+
name: item.name,
|
|
3620
|
+
action: item.action,
|
|
3621
|
+
version: published.version,
|
|
3622
|
+
url: functionUrl(item.name)
|
|
3867
3623
|
});
|
|
3868
|
-
}
|
|
3869
|
-
const banner = renderBanner({
|
|
3870
|
-
host,
|
|
3871
|
-
port: actualPort,
|
|
3872
|
-
projectName: config.name,
|
|
3873
|
-
functions: functionNames,
|
|
3874
|
-
hasStatic,
|
|
3875
|
-
staticDir: relative(cwd, staticDir).length > 0 ? relative(cwd, staticDir) : staticDir
|
|
3876
|
-
});
|
|
3877
|
-
log(banner);
|
|
3624
|
+
}
|
|
3878
3625
|
return {
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
baseUrl
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
server.close(() => resolveClose());
|
|
3885
|
-
});
|
|
3886
|
-
}
|
|
3626
|
+
projectId: remote.projectId,
|
|
3627
|
+
slug: remote.slug,
|
|
3628
|
+
baseUrl,
|
|
3629
|
+
noChanges: deployed.every((function_) => function_.action === "none"),
|
|
3630
|
+
functions: deployed
|
|
3887
3631
|
};
|
|
3888
3632
|
}
|
|
3889
|
-
var
|
|
3890
|
-
|
|
3891
|
-
"packages/cli/src/serve/server.ts"() {
|
|
3633
|
+
var init_deploy = __esm({
|
|
3634
|
+
"packages/cli/src/deploy.ts"() {
|
|
3892
3635
|
"use strict";
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
init_runtime();
|
|
3896
|
-
init_env();
|
|
3897
|
-
init_invoke();
|
|
3636
|
+
init_auth();
|
|
3637
|
+
init_client();
|
|
3898
3638
|
init_dev();
|
|
3899
|
-
|
|
3900
|
-
MIME_TYPES = {
|
|
3901
|
-
".html": "text/html; charset=utf-8",
|
|
3902
|
-
".htm": "text/html; charset=utf-8",
|
|
3903
|
-
".css": "text/css; charset=utf-8",
|
|
3904
|
-
".js": "application/javascript; charset=utf-8",
|
|
3905
|
-
".mjs": "application/javascript; charset=utf-8",
|
|
3906
|
-
".json": "application/json; charset=utf-8",
|
|
3907
|
-
".png": "image/png",
|
|
3908
|
-
".jpg": "image/jpeg",
|
|
3909
|
-
".jpeg": "image/jpeg",
|
|
3910
|
-
".gif": "image/gif",
|
|
3911
|
-
".svg": "image/svg+xml",
|
|
3912
|
-
".ico": "image/x-icon",
|
|
3913
|
-
".woff": "font/woff",
|
|
3914
|
-
".woff2": "font/woff2",
|
|
3915
|
-
".ttf": "font/ttf",
|
|
3916
|
-
".txt": "text/plain; charset=utf-8",
|
|
3917
|
-
".md": "text/markdown; charset=utf-8",
|
|
3918
|
-
".pdf": "application/pdf",
|
|
3919
|
-
".map": "application/json"
|
|
3920
|
-
};
|
|
3639
|
+
init_net();
|
|
3921
3640
|
}
|
|
3922
3641
|
});
|
|
3923
3642
|
|
|
@@ -3990,13 +3709,13 @@ __export(functions_exports, {
|
|
|
3990
3709
|
functionsList: () => functionsList,
|
|
3991
3710
|
functionsLogs: () => functionsLogs
|
|
3992
3711
|
});
|
|
3993
|
-
import { resolve as
|
|
3712
|
+
import { resolve as resolve6 } from "node:path";
|
|
3994
3713
|
async function functionsDeploy(paths, options) {
|
|
3995
3714
|
const startedAt = Date.now();
|
|
3996
3715
|
const result = await deploy(paths, {
|
|
3997
3716
|
cwd: options.cwd,
|
|
3998
3717
|
...options.slug === void 0 ? {} : { slug: options.slug },
|
|
3999
|
-
...options.dir === void 0 ? {} : { functionsDir:
|
|
3718
|
+
...options.dir === void 0 ? {} : { functionsDir: resolve6(options.cwd, options.dir) },
|
|
4000
3719
|
silent: true
|
|
4001
3720
|
});
|
|
4002
3721
|
return { ...result, elapsedSeconds: (Date.now() - startedAt) / 1e3 };
|
|
@@ -4009,10 +3728,12 @@ async function functionsList(paths, options) {
|
|
|
4009
3728
|
{},
|
|
4010
3729
|
"FUNCTION_LIST_FAILED"
|
|
4011
3730
|
);
|
|
3731
|
+
const prefix = project2.functionsPrefix ?? "/api";
|
|
3732
|
+
const prefixBase = prefix.trim() === "/" ? "" : prefix.trim().replace(/\/+$/, "");
|
|
4012
3733
|
return {
|
|
4013
3734
|
projectId: project2.id,
|
|
4014
3735
|
slug: project2.slug,
|
|
4015
|
-
baseUrl: project2.url
|
|
3736
|
+
baseUrl: `${project2.url.replace(/\/+$/, "")}${prefixBase}`,
|
|
4016
3737
|
functions: result.functions
|
|
4017
3738
|
};
|
|
4018
3739
|
}
|
|
@@ -4040,7 +3761,7 @@ async function functionsLogs(paths, options) {
|
|
|
4040
3761
|
return { functionId: target.id, name: target.name, logs: result.logs };
|
|
4041
3762
|
}
|
|
4042
3763
|
async function resolveProject(client, options) {
|
|
4043
|
-
const slug = await resolveSlug(
|
|
3764
|
+
const slug = await resolveSlug(resolve6(options.cwd), options.slug);
|
|
4044
3765
|
const projects = await projectsListFrom(client);
|
|
4045
3766
|
const match = projects.find((project2) => project2.slug === slug);
|
|
4046
3767
|
if (match === void 0) {
|
|
@@ -4071,7 +3792,7 @@ __export(mcp_exports, {
|
|
|
4071
3792
|
mcpPublish: () => mcpPublish,
|
|
4072
3793
|
mcpUnpublish: () => mcpUnpublish
|
|
4073
3794
|
});
|
|
4074
|
-
import { resolve as
|
|
3795
|
+
import { resolve as resolve7 } from "node:path";
|
|
4075
3796
|
async function mcpPublish(paths, options) {
|
|
4076
3797
|
const fn = requireFunctionName(options.fn);
|
|
4077
3798
|
const client = await createClient(paths);
|
|
@@ -4107,7 +3828,9 @@ async function mcpUnpublish(paths, options) {
|
|
|
4107
3828
|
async function mcpList(paths, options) {
|
|
4108
3829
|
const client = await createClient(paths);
|
|
4109
3830
|
const project2 = await resolveProject2(client, options);
|
|
4110
|
-
const
|
|
3831
|
+
const prefix = project2.functionsPrefix ?? "/api";
|
|
3832
|
+
const prefixBase = prefix.trim() === "/" ? "" : prefix.trim().replace(/\/+$/, "");
|
|
3833
|
+
const endpoint = `${project2.url.replace(/\/+$/, "")}${prefixBase}/mcp`;
|
|
4111
3834
|
let response;
|
|
4112
3835
|
try {
|
|
4113
3836
|
response = await fetch(endpoint, {
|
|
@@ -4150,7 +3873,7 @@ function requireFunctionName(fn) {
|
|
|
4150
3873
|
return fn.trim();
|
|
4151
3874
|
}
|
|
4152
3875
|
async function resolveProject2(client, options) {
|
|
4153
|
-
const slug = await resolveSlug(
|
|
3876
|
+
const slug = await resolveSlug(resolve7(options.cwd), options.slug);
|
|
4154
3877
|
const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
4155
3878
|
const match = listed.projects.find((project2) => project2.slug === slug);
|
|
4156
3879
|
if (match === void 0) {
|
|
@@ -4159,7 +3882,12 @@ async function resolveProject2(client, options) {
|
|
|
4159
3882
|
`\u5E73\u53F0\u9879\u76EE "${slug}" \u4E0D\u5B58\u5728\u6216\u4F60\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\uFF1A\u5148\u6267\u884C adep projects create ${slug}`
|
|
4160
3883
|
);
|
|
4161
3884
|
}
|
|
4162
|
-
return {
|
|
3885
|
+
return {
|
|
3886
|
+
id: match.id,
|
|
3887
|
+
slug: match.slug,
|
|
3888
|
+
url: match.url,
|
|
3889
|
+
...match.functionsPrefix === void 0 ? {} : { functionsPrefix: match.functionsPrefix }
|
|
3890
|
+
};
|
|
4163
3891
|
}
|
|
4164
3892
|
async function resolveFunction(client, project2, name) {
|
|
4165
3893
|
const listed = await client.request(`/api/v1/projects/${project2.id}/functions`, {}, "FUNCTION_LIST_FAILED");
|
|
@@ -4183,7 +3911,7 @@ __export(doctor_exports, {
|
|
|
4183
3911
|
formatDoctorReport: () => formatDoctorReport,
|
|
4184
3912
|
runDoctor: () => runDoctor
|
|
4185
3913
|
});
|
|
4186
|
-
import { stat as
|
|
3914
|
+
import { stat as stat6 } from "node:fs/promises";
|
|
4187
3915
|
async function probeServer(server) {
|
|
4188
3916
|
const controller = new AbortController();
|
|
4189
3917
|
const timer = setTimeout(() => controller.abort(), SERVER_PROBE_TIMEOUT_MS);
|
|
@@ -4201,7 +3929,7 @@ async function probeServer(server) {
|
|
|
4201
3929
|
}
|
|
4202
3930
|
async function credentialMode(file) {
|
|
4203
3931
|
try {
|
|
4204
|
-
const info = await
|
|
3932
|
+
const info = await stat6(file);
|
|
4205
3933
|
return (info.mode & 511).toString(8).padStart(3, "0");
|
|
4206
3934
|
} catch {
|
|
4207
3935
|
return void 0;
|
|
@@ -4277,8 +4005,6 @@ var init_doctor = __esm({
|
|
|
4277
4005
|
"adep init",
|
|
4278
4006
|
"adep dev",
|
|
4279
4007
|
"adep serve",
|
|
4280
|
-
"adep widget init",
|
|
4281
|
-
"adep widget dev",
|
|
4282
4008
|
"adep db\uFF08\u672C\u5730\u6A21\u62DF\uFF09",
|
|
4283
4009
|
"adep doctor"
|
|
4284
4010
|
];
|
|
@@ -4297,10 +4023,10 @@ __export(db_exports, {
|
|
|
4297
4023
|
dbStatus: () => dbStatus,
|
|
4298
4024
|
dbStop: () => dbStop
|
|
4299
4025
|
});
|
|
4300
|
-
import { resolve as
|
|
4026
|
+
import { resolve as resolve8 } from "node:path";
|
|
4301
4027
|
async function open2(paths, options) {
|
|
4302
4028
|
const client = await createClient(paths);
|
|
4303
|
-
const project2 = await resolveSlug(
|
|
4029
|
+
const project2 = await resolveSlug(resolve8(options.cwd), options.slug);
|
|
4304
4030
|
return { client, project: project2 };
|
|
4305
4031
|
}
|
|
4306
4032
|
async function dbStart(paths, options) {
|
|
@@ -4374,11 +4100,11 @@ __export(storage_exports, {
|
|
|
4374
4100
|
storageRemove: () => storageRemove,
|
|
4375
4101
|
storageUpload: () => storageUpload
|
|
4376
4102
|
});
|
|
4377
|
-
import { mkdir as mkdir7, readFile as readFile8, stat as
|
|
4378
|
-
import { basename as basename3, dirname as
|
|
4103
|
+
import { mkdir as mkdir7, readFile as readFile8, stat as stat7, writeFile as writeFile5 } from "node:fs/promises";
|
|
4104
|
+
import { basename as basename3, dirname as dirname6, extname, join as join10, resolve as resolve9 } from "node:path";
|
|
4379
4105
|
async function open3(paths, options) {
|
|
4380
4106
|
const client = await createClient(paths);
|
|
4381
|
-
const project2 = await resolveSlug(
|
|
4107
|
+
const project2 = await resolveSlug(resolve9(options.cwd), options.slug);
|
|
4382
4108
|
return { client, project: project2 };
|
|
4383
4109
|
}
|
|
4384
4110
|
function contentTypeOf(path) {
|
|
@@ -4411,8 +4137,8 @@ function contentTypeOf(path) {
|
|
|
4411
4137
|
}
|
|
4412
4138
|
async function storageUpload(paths, options) {
|
|
4413
4139
|
const { client, project: project2 } = await open3(paths, options);
|
|
4414
|
-
const local =
|
|
4415
|
-
const info = await
|
|
4140
|
+
const local = resolve9(options.file);
|
|
4141
|
+
const info = await stat7(local).catch(() => null);
|
|
4416
4142
|
if (info === null || !info.isFile()) {
|
|
4417
4143
|
throw new CliError("FILE_NOT_FOUND", `\u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${local}`);
|
|
4418
4144
|
}
|
|
@@ -4458,9 +4184,9 @@ async function storageDownload(paths, options) {
|
|
|
4458
4184
|
const url = await resolveDownloadUrl(client, project2, options.path);
|
|
4459
4185
|
const response = await client.download(url, "STORAGE_DOWNLOAD_FAILED");
|
|
4460
4186
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
4461
|
-
const output =
|
|
4462
|
-
await mkdir7(
|
|
4463
|
-
await
|
|
4187
|
+
const output = resolve9(options.output ?? join10(resolve9(options.cwd), basename3(options.path)));
|
|
4188
|
+
await mkdir7(dirname6(output), { recursive: true });
|
|
4189
|
+
await writeFile5(output, bytes);
|
|
4464
4190
|
return { path: options.path, output, size: bytes.length };
|
|
4465
4191
|
}
|
|
4466
4192
|
async function storageRemove(paths, options) {
|
|
@@ -4486,11 +4212,11 @@ __export(hosting_exports, {
|
|
|
4486
4212
|
hostingInfo: () => hostingInfo,
|
|
4487
4213
|
hostingPull: () => hostingPull
|
|
4488
4214
|
});
|
|
4489
|
-
import { readdir as readdir5, readFile as readFile9, stat as
|
|
4490
|
-
import { dirname as
|
|
4215
|
+
import { readdir as readdir5, readFile as readFile9, stat as stat8 } from "node:fs/promises";
|
|
4216
|
+
import { dirname as dirname7, join as join11, relative as relative2, resolve as resolve10, sep } from "node:path";
|
|
4491
4217
|
async function open4(paths, options) {
|
|
4492
4218
|
const client = await createClient(paths);
|
|
4493
|
-
const project2 = await resolveSlug(
|
|
4219
|
+
const project2 = await resolveSlug(resolve10(options.cwd), options.slug);
|
|
4494
4220
|
return { client, project: project2 };
|
|
4495
4221
|
}
|
|
4496
4222
|
async function hostingInfo(paths, options) {
|
|
@@ -4503,7 +4229,7 @@ async function hostingInfo(paths, options) {
|
|
|
4503
4229
|
};
|
|
4504
4230
|
}
|
|
4505
4231
|
async function collectSiteFiles(dir) {
|
|
4506
|
-
const root =
|
|
4232
|
+
const root = resolve10(dir);
|
|
4507
4233
|
const files = /* @__PURE__ */ new Map();
|
|
4508
4234
|
const walk = async (sub) => {
|
|
4509
4235
|
let entries;
|
|
@@ -4513,7 +4239,7 @@ async function collectSiteFiles(dir) {
|
|
|
4513
4239
|
return;
|
|
4514
4240
|
}
|
|
4515
4241
|
for (const entry of entries) {
|
|
4516
|
-
const full =
|
|
4242
|
+
const full = join11(sub, entry.name);
|
|
4517
4243
|
if (entry.isDirectory()) {
|
|
4518
4244
|
await walk(full);
|
|
4519
4245
|
} else if (entry.isFile()) {
|
|
@@ -4531,12 +4257,12 @@ async function hostingDeploy(paths, options) {
|
|
|
4531
4257
|
`));
|
|
4532
4258
|
const files = await collectSiteFiles(options.dir);
|
|
4533
4259
|
if (files.size === 0) {
|
|
4534
|
-
throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${
|
|
4260
|
+
throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${resolve10(options.dir)}`);
|
|
4535
4261
|
}
|
|
4536
4262
|
const uploaded = [];
|
|
4537
4263
|
for (const [rel, full] of files) {
|
|
4538
4264
|
log(`[adep] \u4E0A\u4F20 site/${rel}`);
|
|
4539
|
-
const info2 = await
|
|
4265
|
+
const info2 = await stat8(full);
|
|
4540
4266
|
const bytes = await readFile9(full);
|
|
4541
4267
|
const form = new FormData();
|
|
4542
4268
|
form.set("path", `site/${rel}`);
|
|
@@ -4564,8 +4290,8 @@ async function hostingPull(paths, options) {
|
|
|
4564
4290
|
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
4565
4291
|
`));
|
|
4566
4292
|
const info = await hostingInfo(paths, options);
|
|
4567
|
-
const outputDir =
|
|
4568
|
-
const { mkdir: mkdir9, writeFile:
|
|
4293
|
+
const outputDir = resolve10(options.output ?? resolve10(options.cwd));
|
|
4294
|
+
const { mkdir: mkdir9, writeFile: writeFile8 } = await import("node:fs/promises");
|
|
4569
4295
|
const files = [];
|
|
4570
4296
|
for (const entry of info.files) {
|
|
4571
4297
|
if (entry.visibility !== "public" || entry.path === HOSTING_CONFIG_PATH) continue;
|
|
@@ -4575,9 +4301,9 @@ async function hostingPull(paths, options) {
|
|
|
4575
4301
|
const response = await client.download(url, "HOSTING_DOWNLOAD_FAILED");
|
|
4576
4302
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
4577
4303
|
const rel = entry.path.replace(/^site\//, "");
|
|
4578
|
-
const target =
|
|
4579
|
-
await mkdir9(
|
|
4580
|
-
await
|
|
4304
|
+
const target = join11(outputDir, ...rel.split("/"));
|
|
4305
|
+
await mkdir9(dirname7(target), { recursive: true });
|
|
4306
|
+
await writeFile8(target, bytes);
|
|
4581
4307
|
files.push({ path: entry.path, size: bytes.length });
|
|
4582
4308
|
}
|
|
4583
4309
|
return { siteUrl: info.siteUrl, outputDir, files };
|
|
@@ -4609,7 +4335,7 @@ var client_exports2 = {};
|
|
|
4609
4335
|
__export(client_exports2, {
|
|
4610
4336
|
createExportApiClient: () => createExportApiClient
|
|
4611
4337
|
});
|
|
4612
|
-
import { writeFile as
|
|
4338
|
+
import { writeFile as writeFile6 } from "node:fs/promises";
|
|
4613
4339
|
function toExportJob(view) {
|
|
4614
4340
|
return {
|
|
4615
4341
|
id: view.id,
|
|
@@ -4653,7 +4379,7 @@ async function createExportApiClient(paths) {
|
|
|
4653
4379
|
}
|
|
4654
4380
|
const response = await client.download(download.downloadUrl, "EXPORT_DOWNLOAD_FAILED");
|
|
4655
4381
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
4656
|
-
await
|
|
4382
|
+
await writeFile6(outputPath, bytes);
|
|
4657
4383
|
return { path: outputPath, size: bytes.length };
|
|
4658
4384
|
}
|
|
4659
4385
|
};
|
|
@@ -4750,19 +4476,19 @@ var fs_exports = {};
|
|
|
4750
4476
|
__export(fs_exports, {
|
|
4751
4477
|
createExportFileSystem: () => createExportFileSystem
|
|
4752
4478
|
});
|
|
4753
|
-
import { mkdir as mkdir8, readFile as readFile10, rm as rm3, stat as
|
|
4754
|
-
import { dirname as
|
|
4479
|
+
import { mkdir as mkdir8, readFile as readFile10, rm as rm3, stat as stat9, writeFile as writeFile7 } from "node:fs/promises";
|
|
4480
|
+
import { dirname as dirname8, join as join12 } from "node:path";
|
|
4755
4481
|
function createExportFileSystem() {
|
|
4756
4482
|
return {
|
|
4757
4483
|
readFile: (path) => readFile10(path),
|
|
4758
|
-
writeFile: (path, content) =>
|
|
4484
|
+
writeFile: (path, content) => writeFile7(path, content),
|
|
4759
4485
|
// 同时用于清理解压临时目录(${zip}.tmp 是个目录)——递归强制删除,缺失不报错。
|
|
4760
4486
|
deleteFile: async (path) => {
|
|
4761
4487
|
await rm3(path, { recursive: true, force: true });
|
|
4762
4488
|
},
|
|
4763
4489
|
fileExists: async (path) => {
|
|
4764
4490
|
try {
|
|
4765
|
-
await
|
|
4491
|
+
await stat9(path);
|
|
4766
4492
|
return true;
|
|
4767
4493
|
} catch {
|
|
4768
4494
|
return false;
|
|
@@ -4774,9 +4500,9 @@ function createExportFileSystem() {
|
|
|
4774
4500
|
unzip: async (zipPath, targetDir) => {
|
|
4775
4501
|
const entries = zipRead(await readFile10(zipPath));
|
|
4776
4502
|
for (const [name, data] of entries) {
|
|
4777
|
-
const dest =
|
|
4778
|
-
await mkdir8(
|
|
4779
|
-
await
|
|
4503
|
+
const dest = join12(targetDir, name);
|
|
4504
|
+
await mkdir8(dirname8(dest), { recursive: true });
|
|
4505
|
+
await writeFile7(dest, data);
|
|
4780
4506
|
}
|
|
4781
4507
|
}
|
|
4782
4508
|
};
|
|
@@ -5057,7 +4783,7 @@ var command_exports = {};
|
|
|
5057
4783
|
__export(command_exports, {
|
|
5058
4784
|
ExportCommand: () => ExportCommand
|
|
5059
4785
|
});
|
|
5060
|
-
import { createHash as
|
|
4786
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
5061
4787
|
var ExportCommand;
|
|
5062
4788
|
var init_command = __esm({
|
|
5063
4789
|
"packages/cli/src/export/command.ts"() {
|
|
@@ -5205,7 +4931,7 @@ ${errors}`);
|
|
|
5205
4931
|
const contentResult = verifyContents(
|
|
5206
4932
|
manifest.contents,
|
|
5207
4933
|
actual,
|
|
5208
|
-
(text) =>
|
|
4934
|
+
(text) => createHash3("sha256").update(Buffer.from(text, "latin1")).digest("hex")
|
|
5209
4935
|
);
|
|
5210
4936
|
if (!contentResult.valid) {
|
|
5211
4937
|
const detail = contentResult.errors.map((e) => e.message).join("\n");
|
|
@@ -5276,311 +5002,405 @@ ${detail}`);
|
|
|
5276
5002
|
* @param ms 毫秒数
|
|
5277
5003
|
*/
|
|
5278
5004
|
sleep(ms) {
|
|
5279
|
-
return new Promise((
|
|
5005
|
+
return new Promise((resolve11) => setTimeout(resolve11, ms));
|
|
5280
5006
|
}
|
|
5281
5007
|
};
|
|
5282
5008
|
}
|
|
5283
5009
|
});
|
|
5284
5010
|
|
|
5285
|
-
// packages/cli/src/
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
startWidgetDev: () => startWidgetDev
|
|
5290
|
-
});
|
|
5291
|
-
import { createServer as createServer3 } from "node:http";
|
|
5292
|
-
import { watch as watch2 } from "node:fs";
|
|
5293
|
-
import { readFile as readFile11, stat as stat11 } from "node:fs/promises";
|
|
5294
|
-
import { join as join15, resolve as resolve13 } from "node:path";
|
|
5295
|
-
async function loadWidgetProject(cwd) {
|
|
5296
|
-
const fallback = {
|
|
5297
|
-
name: "widget",
|
|
5298
|
-
framework: "vue3"
|
|
5299
|
-
};
|
|
5300
|
-
const manifestPath = join15(resolve13(cwd), "manifest.json");
|
|
5301
|
-
try {
|
|
5302
|
-
await stat11(manifestPath);
|
|
5303
|
-
} catch {
|
|
5304
|
-
return fallback;
|
|
5305
|
-
}
|
|
5306
|
-
try {
|
|
5307
|
-
const raw = await readFile11(manifestPath, "utf8");
|
|
5308
|
-
const parsed = JSON.parse(raw);
|
|
5309
|
-
return {
|
|
5310
|
-
name: typeof parsed["name"] === "string" ? parsed["name"] : fallback.name,
|
|
5311
|
-
framework: parsed["framework"] === "react" ? "react" : "vue3"
|
|
5312
|
-
};
|
|
5313
|
-
} catch {
|
|
5314
|
-
return fallback;
|
|
5315
|
-
}
|
|
5316
|
-
}
|
|
5317
|
-
function sandboxHtml(name, framework) {
|
|
5318
|
-
return `<!doctype html>
|
|
5319
|
-
<html>
|
|
5320
|
-
<head>
|
|
5321
|
-
<meta charset="utf-8" />
|
|
5322
|
-
<title>adep widget dev \u2014 ${name}</title>
|
|
5323
|
-
<link rel="stylesheet" href="/__widget/theme.css" />
|
|
5324
|
-
<style>
|
|
5325
|
-
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #f5f6f7; margin: 0; padding: 24px; }
|
|
5326
|
-
#toolbar { display: flex; gap: 12px; align-items: center; font-size: 13px; color: #4c5561; margin-bottom: 16px; }
|
|
5327
|
-
#toolbar .dot { width: 8px; height: 8px; border-radius: 50%; background: #99a2ad; }
|
|
5328
|
-
#toolbar .dot.on { background: #16a34a; }
|
|
5329
|
-
#sandbox { background: #fff; border: 1px solid #e5e6eb; border-radius: 8px; min-height: 120px; }
|
|
5330
|
-
code { background: #eef0f3; padding: 2px 6px; border-radius: 4px; }
|
|
5331
|
-
</style>
|
|
5332
|
-
</head>
|
|
5333
|
-
<body>
|
|
5334
|
-
<div id="toolbar"><span id="status"><span class="dot" id="dot"></span> sandbox connecting\u2026</span></div>
|
|
5335
|
-
<div id="sandbox"></div>
|
|
5336
|
-
<script type="module">
|
|
5337
|
-
const q = new URLSearchParams(location.search)
|
|
5338
|
-
const token = q.get('token') ?? ''
|
|
5339
|
-
document.getElementById('status').textContent = 'token: ' + (token ? 'injected' : '(none)')
|
|
5340
|
-
const hostEl = document.getElementById('sandbox')
|
|
5341
|
-
const host = hostEl.attachShadow({ mode: 'open' })
|
|
5342
|
-
let version = 0
|
|
5011
|
+
// packages/cli/src/cli.ts
|
|
5012
|
+
init_config();
|
|
5013
|
+
import { Command } from "commander";
|
|
5014
|
+
import { createRequire } from "node:module";
|
|
5343
5015
|
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
let props = {}
|
|
5347
|
-
try { props = await (await fetch('/__widget/mock-props')).json() } catch { props = {} }
|
|
5348
|
-
const mod = await import('/__widget/index.js?v=' + v)
|
|
5349
|
-
mod.mount(host, {
|
|
5350
|
-
widgetName: '${name}',
|
|
5351
|
-
framework: '${framework}',
|
|
5352
|
-
props,
|
|
5353
|
-
host: {
|
|
5354
|
-
getProjectId: () => 'local-dev',
|
|
5355
|
-
invokeFunction: async () => ({})
|
|
5356
|
-
}
|
|
5357
|
-
})
|
|
5358
|
-
}
|
|
5016
|
+
// packages/cli/src/output.ts
|
|
5017
|
+
init_auth();
|
|
5359
5018
|
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
document.getElementById('status').firstChild.textContent = 'sandbox live \u2014 watch src/\uFF0C\u4FDD\u5B58\u540E\u81EA\u52A8\u70ED\u66F4\u65B0 '
|
|
5364
|
-
}
|
|
5019
|
+
// packages/cli/src/init.ts
|
|
5020
|
+
import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises";
|
|
5021
|
+
import { dirname as dirname2, join, resolve } from "node:path";
|
|
5365
5022
|
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5023
|
+
// shared/sdk/adep-env.ts
|
|
5024
|
+
var ADEP_ENV_DTS = `/**
|
|
5025
|
+
* AgentDeploy \u4E91\u51FD\u6570\u5F00\u53D1\u73AF\u5883\u7C7B\u578B\u58F0\u660E\uFF08\u90E8\u7F72\u5305 / adep init \u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u6539\uFF09\u3002
|
|
5026
|
+
*
|
|
5027
|
+
* \u672C\u6587\u4EF6\u662F @adep/types \u7684\u6E90\u7801\u6587\u672C\u955C\u50CF\uFF1A\u4E3A\u51FD\u6570\u6E90\u7801\u91CC\u7684 ctx \u63D0\u4F9B method/path/query/
|
|
5028
|
+
* headers/body/files/user \u4E0E cloud.db / cloud.storage / cloud.fetch / cloud.realtime \u7684\u5B8C\u6574\u8865\u5168\u3002
|
|
5029
|
+
* \u5168\u5C40 ctx \u4E0E AdepContext \u662F\u5F00\u53D1\u671F\u4E0A\u4E0B\u6587\uFF08\u7F16\u8F91\u5668\u8865\u5168\u7528\uFF09\uFF1B\u51FD\u6570\u8FD0\u884C\u671F\u7ECF\u53C2\u6570\u6CE8\u5165\uFF0C\u4E0D\u8BFB\u53D6\u5168\u5C40\u3002
|
|
5030
|
+
* \u7C7B\u578B\u5951\u7EA6\u7684\u5355\u4E00\u771F\u76F8\u6E90\u89C1 packages/types\uFF08\u4EFB\u52A1\u5355 CORE-006\uFF09\u3002
|
|
5031
|
+
*/
|
|
5032
|
+
|
|
5033
|
+
/* ---------- HTTP \u89E6\u53D1\u4E0A\u4E0B\u6587\uFF08FunctionContext \u955C\u50CF\uFF09 ---------- */
|
|
5034
|
+
|
|
5035
|
+
type AdepHttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'
|
|
5036
|
+
|
|
5037
|
+
/* ---------- \u6587\u4EF6\u4E0E\u5B58\u50A8\uFF08CloudStorage \u955C\u50CF\uFF09 ---------- */
|
|
5038
|
+
|
|
5039
|
+
/** multipart \u4E0A\u4F20\u7684\u6587\u4EF6\uFF08\u51FD\u6570 HTTP \u89E6\u53D1\u65F6 ctx.files \u4E2D\u7684\u5355\u4E2A\u6587\u4EF6\uFF09\u3002 */
|
|
5040
|
+
interface AdepFunctionFile {
|
|
5041
|
+
/** \u5BA2\u6237\u7AEF\u63D0\u4F9B\u7684\u6587\u4EF6\u540D\uFF08\u542B\u6269\u5C55\u540D\uFF09\u3002 */
|
|
5042
|
+
name: string
|
|
5043
|
+
/** MIME \u7C7B\u578B\u3002 */
|
|
5044
|
+
type: string
|
|
5045
|
+
/** \u5B57\u8282\u6570\u3002 */
|
|
5046
|
+
size: number
|
|
5047
|
+
data: Uint8Array
|
|
5380
5048
|
}
|
|
5381
|
-
async function startWidgetDev(options) {
|
|
5382
|
-
const cwd = resolve13(options.cwd);
|
|
5383
|
-
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
5384
|
-
`));
|
|
5385
|
-
const project2 = await loadWidgetProject(cwd);
|
|
5386
|
-
const framework = options.framework ?? project2.framework;
|
|
5387
|
-
let state = { text: "", version: 0 };
|
|
5388
|
-
const rebuild = async () => {
|
|
5389
|
-
const built = await buildWidget({ cwd, framework });
|
|
5390
|
-
const next = { text: built.text, version: state.version + 1 };
|
|
5391
|
-
state = next;
|
|
5392
|
-
return next;
|
|
5393
|
-
};
|
|
5394
|
-
try {
|
|
5395
|
-
await rebuild();
|
|
5396
|
-
} catch (error) {
|
|
5397
|
-
throw new WidgetError(
|
|
5398
|
-
"BUILD_FAILED",
|
|
5399
|
-
`widget \u6784\u5EFA\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
5400
|
-
);
|
|
5401
|
-
}
|
|
5402
|
-
const clients = /* @__PURE__ */ new Set();
|
|
5403
|
-
const broadcast = (version) => {
|
|
5404
|
-
for (const res of clients) {
|
|
5405
|
-
res.write(`event: rebuild
|
|
5406
|
-
data: ${version}
|
|
5407
5049
|
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5050
|
+
/** \u4E0A\u4F20\u6570\u636E\uFF1A\u6587\u672C\u3001\u4E8C\u8FDB\u5236\u3001\u6216\u76F4\u63A5\u900F\u4F20\u8BF7\u6C42\u91CC\u7684\u6587\u4EF6\u5BF9\u8C61\u3002 */
|
|
5051
|
+
type AdepStorageUploadData = string | Uint8Array | ArrayBuffer | AdepFunctionFile
|
|
5052
|
+
|
|
5053
|
+
type AdepFileVisibility = 'public' | 'private'
|
|
5054
|
+
|
|
5055
|
+
/** \u4E0A\u4F20 / \u5217\u4E3E\u8FD4\u56DE\u7684\u6587\u4EF6\u5143\u6570\u636E\uFF08\u4E0D\u542B\u5185\u5BB9\uFF09\u3002 */
|
|
5056
|
+
interface AdepStoredFile {
|
|
5057
|
+
/** \u6876\u5185\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u5982 avatars/avatar.png\u3002 */
|
|
5058
|
+
path: string
|
|
5059
|
+
size: number
|
|
5060
|
+
contentType?: string
|
|
5061
|
+
visibility: AdepFileVisibility
|
|
5062
|
+
/** ISO 8601 \u65F6\u95F4\u6233\u3002 */
|
|
5063
|
+
updatedAt?: string
|
|
5064
|
+
}
|
|
5065
|
+
|
|
5066
|
+
interface AdepCloudStorage {
|
|
5067
|
+
/** \u4E0A\u4F20 / \u8986\u76D6\u6587\u4EF6\uFF1B\u8DEF\u5F84\u975E\u6CD5\uFF08\u7A7F\u8D8A\u3001\u8D85\u9650\uFF09\u7531\u5B9E\u73B0\u629B\u9519\u3002 */
|
|
5068
|
+
upload(path: string, data: AdepStorageUploadData): Promise<AdepStoredFile>
|
|
5069
|
+
/** \u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\uFF1B\u4E0D\u5B58\u5728\u65F6\u629B STORAGE_NOT_FOUND\u3002 */
|
|
5070
|
+
get(path: string): Promise<Uint8Array>
|
|
5071
|
+
/** \u5220\u9664\u6587\u4EF6\uFF1B\u4E0D\u5B58\u5728\u65F6\u629B STORAGE_NOT_FOUND\u3002 */
|
|
5072
|
+
remove(path: string): Promise<void>
|
|
5073
|
+
/** \u6309\u524D\u7F00\u5217\u4E3E\uFF08\u7F3A\u7701\u5168\u6876\uFF09\u3002 */
|
|
5074
|
+
list(prefix?: string): Promise<AdepStoredFile[]>
|
|
5075
|
+
/** \u751F\u6210\u7B7E\u540D URL\uFF08private \u6587\u4EF6\u7684\u5916\u53D1\u901A\u9053\uFF09\uFF1B\u7F3A\u7701 TTL 15 \u5206\u949F\u3002 */
|
|
5076
|
+
getSignedUrl(path: string, ttlSeconds?: number): Promise<string>
|
|
5077
|
+
}
|
|
5078
|
+
|
|
5079
|
+
/* ---------- \u6570\u636E\u5E93\uFF08CloudDb \u955C\u50CF\uFF09 ---------- */
|
|
5080
|
+
|
|
5081
|
+
/** \u53EF\u7ED1\u5B9A\u5230 SQLite \u7684\u53C2\u6570\u503C\u3002 */
|
|
5082
|
+
type AdepSqlValue = string | number | bigint | boolean | null | Uint8Array
|
|
5083
|
+
|
|
5084
|
+
/** where(col, op, value) \u652F\u6301\u7684\u6BD4\u8F83\u7B26\u3002 */
|
|
5085
|
+
type AdepSqlOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'like' | 'in' | 'not in'
|
|
5086
|
+
|
|
5087
|
+
/** \u4E00\u884C\u67E5\u8BE2\u7ED3\u679C\u3002\u5217\u7C7B\u578B\u7F16\u8BD1\u671F\u672A\u77E5\uFF08\u8FD0\u884C\u65F6\u5EFA\u8868\uFF09\uFF0C\u7531\u7528\u6237\u4EE3\u7801\u81EA\u884C\u6536\u7A84\u3002 */
|
|
5088
|
+
type AdepRow = Record<string, unknown>
|
|
5089
|
+
|
|
5090
|
+
/** owned \u8868\u53D8\u66F4\u64CD\u4F5C\u7C7B\u578B\u3002 */
|
|
5091
|
+
type AdepChangeOp = 'insert' | 'update' | 'delete'
|
|
5092
|
+
|
|
5093
|
+
/** owned \u8868 __changes \u53D8\u66F4\u6D41\u8BB0\u5F55\uFF08\u8FFD\u52A0\u5F0F\u3001\u53EF\u91CD\u653E\uFF1Bbefore/after \u4E3A\u6574\u884C\uFF0C\u672A\u6D89\u53CA\u4FA7\u4E3A null\uFF09\u3002 */
|
|
5094
|
+
interface AdepChangeRecord {
|
|
5095
|
+
/** \u8868\u5185\u81EA\u589E\u5E8F\u53F7\uFF08\u65F6\u95F4\u5347\u5E8F\uFF0C\u91CD\u653E\u987A\u5E8F\u4F9D\u636E\uFF09\u3002 */
|
|
5096
|
+
seq: number
|
|
5097
|
+
/** \u53D8\u66F4\u65F6\u95F4\uFF08ISO 8601\uFF09\u3002 */
|
|
5098
|
+
ts: string
|
|
5099
|
+
op: AdepChangeOp
|
|
5100
|
+
/** \u884C\u4E3B\u952E\uFF08ULID\uFF09\u3002 */
|
|
5101
|
+
id: string
|
|
5102
|
+
/** \u884C\u5F52\u5C5E\u5206\u533A\uFF08null = \u672A\u5F52\u5C5E\uFF09\u3002 */
|
|
5103
|
+
ownerKey: string | null
|
|
5104
|
+
/** \u53D8\u66F4\u524D\u6574\u884C\uFF08insert \u4E3A null\uFF09\u3002 */
|
|
5105
|
+
before: AdepRow | null
|
|
5106
|
+
/** \u53D8\u66F4\u540E\u6574\u884C\uFF08delete \u4E3A null\uFF09\u3002 */
|
|
5107
|
+
after: AdepRow | null
|
|
5108
|
+
}
|
|
5109
|
+
|
|
5110
|
+
/** cloud.db.changes(table, query) \u7684\u8FC7\u6EE4\u6761\u4EF6\uFF08\u5168\u90E8\u53EF\u9009\uFF09\u3002 */
|
|
5111
|
+
interface AdepChangeQuery {
|
|
5112
|
+
/** \u53EA\u53D6 seq > afterSeq\uFF08\u589E\u91CF\u62C9\u53D6 / \u6536\u4EF6\u6279\u6B21\uFF09\u3002 */
|
|
5113
|
+
afterSeq?: number
|
|
5114
|
+
/** \u53EA\u53D6\u67D0\u5206\u533A\u884C\uFF1Bnull = \u53EA\u53D6\u672A\u5F52\u5C5E\u884C\uFF08\u7F3A\u7701\u4E0D\u8FC7\u6EE4\uFF09\u3002 */
|
|
5115
|
+
ownerKey?: string | null
|
|
5116
|
+
/** \u6700\u591A\u8FD4\u56DE\u6761\u6570\uFF08\u914D\u5408 afterSeq \u505A\u5206\u9875\uFF09\u3002 */
|
|
5117
|
+
limit?: number
|
|
5118
|
+
}
|
|
5119
|
+
|
|
5120
|
+
/**
|
|
5121
|
+
* \u5355\u8868\u94FE\u5F0F Builder\u3002\u6240\u6709\u94FE\u5F0F\u65B9\u6CD5\u8FD4\u56DE\u65B0 Builder\uFF08\u4E0D\u53EF\u53D8\uFF09\uFF0C\u7EC8\u503C\u65B9\u6CD5
|
|
5122
|
+
* \uFF08get/first/count/insert/update/delete\uFF09\u8FD4\u56DE Promise\u3002\u590D\u7528\u540C\u4E00 Builder
|
|
5123
|
+
* \u5B9E\u4F8B\u6D3E\u751F\u591A\u4E2A\u67E5\u8BE2\u662F\u5B89\u5168\u7684\uFF08\u5B9E\u73B0\u4E0D\u5F97\u6709\u5171\u4EAB\u53EF\u53D8\u72B6\u6001\uFF09\u3002
|
|
5124
|
+
*/
|
|
5125
|
+
interface AdepCloudDbTable {
|
|
5126
|
+
/** \u9650\u5B9A\u8FD4\u56DE\u5217\uFF1B\u4E0D\u8C03\u5373 select *\u3002 */
|
|
5127
|
+
select(...columns: string[]): AdepCloudDbTable
|
|
5128
|
+
/** \u58F0\u660E\u4E3A owned \u8868\uFF08DB-006\uFF09\uFF1A\u5199\u5165\u81EA\u52A8\u751F\u6210 ULID \u4E3B\u952E + \u8FFD\u52A0 __changes \u53D8\u66F4\u6D41\u3002 */
|
|
5129
|
+
owned(): AdepCloudDbTable
|
|
5130
|
+
/** \u7B49\u503C\u8FC7\u6EE4\uFF1Awhere('status', 'active')\u3002 */
|
|
5131
|
+
where(column: string, value: AdepSqlValue): AdepCloudDbTable
|
|
5132
|
+
/** \u5E26\u64CD\u4F5C\u7B26\u8FC7\u6EE4\uFF1Awhere('age', '>', 18)\u3002 */
|
|
5133
|
+
where(
|
|
5134
|
+
column: string,
|
|
5135
|
+
operator: AdepSqlOperator,
|
|
5136
|
+
value: AdepSqlValue | readonly AdepSqlValue[]
|
|
5137
|
+
): AdepCloudDbTable
|
|
5138
|
+
orderBy(column: string, direction?: 'asc' | 'desc'): AdepCloudDbTable
|
|
5139
|
+
limit(n: number): AdepCloudDbTable
|
|
5140
|
+
offset(n: number): AdepCloudDbTable
|
|
5141
|
+
/** \u7ED3\u679C\u6570\u7EC4\uFF08\u53EF\u80FD\u4E3A\u7A7A\uFF09\u3002 */
|
|
5142
|
+
get(): Promise<AdepRow[]>
|
|
5143
|
+
/** \u9996\u884C\u6216 null\u3002 */
|
|
5144
|
+
first(): Promise<AdepRow | null>
|
|
5145
|
+
/** \u884C\u6570\uFF08\u5FFD\u7565 select/orderBy\uFF09\u3002 */
|
|
5146
|
+
count(): Promise<number>
|
|
5147
|
+
/** \u63D2\u5165\u4E00\u884C\uFF1Bwhere \u5BF9\u63D2\u5165\u65E0\u610F\u4E49\u3002 */
|
|
5148
|
+
insert(row: Record<string, AdepSqlValue>): Promise<void>
|
|
5149
|
+
/** \u6279\u91CF\u63D2\u5165\u3002 */
|
|
5150
|
+
insertMany(rows: ReadonlyArray<Record<string, AdepSqlValue>>): Promise<void>
|
|
5151
|
+
/** \u66F4\u65B0\uFF08\u5FC5\u987B\u5148 where\uFF0C\u5426\u5219 DB_UNSAFE_OP\uFF09\uFF1B\u8FD4\u56DE\u53D7\u5F71\u54CD\u884C\u6570\u3002 */
|
|
5152
|
+
update(values: Record<string, AdepSqlValue>): Promise<number>
|
|
5153
|
+
/** \u5220\u9664\uFF08\u5FC5\u987B\u5148 where\uFF0C\u5426\u5219 DB_UNSAFE_OP\uFF09\uFF1B\u8FD4\u56DE\u53D7\u5F71\u54CD\u884C\u6570\u3002 */
|
|
5154
|
+
delete(): Promise<number>
|
|
5155
|
+
}
|
|
5156
|
+
|
|
5157
|
+
/** \u9879\u76EE\u6570\u636E\u5E93\u53E5\u67C4\uFF08\u95ED\u5305\u5C01\u88C5\uFF1A\u4E0D\u66B4\u9732\u8FDE\u63A5\u4E32\u3001schema \u540D\uFF09\u3002 */
|
|
5158
|
+
interface AdepCloudDb {
|
|
5159
|
+
/** \u6253\u5F00\u5355\u8868 Builder\u3002\u8868\u540D\u7531\u8FD0\u884C\u65F6\u767D\u540D\u5355\u6821\u9A8C\u3002 */
|
|
5160
|
+
table(name: string): AdepCloudDbTable
|
|
5161
|
+
/** \u4E8B\u52A1\uFF1Afn \u6536\u5230\u540C\u5F62\u72B6\u7684\u53D7\u63A7\u4E8B\u52A1\u53E5\u67C4\uFF1B\u629B\u9519\u5373\u6574\u4F53\u56DE\u6EDA\u3002\u4E8B\u52A1\u5185\u7981\u6B62\u4E8B\u52A1\u5916\u53E5\u67C4\u5199\u672C\u5E93\u3002 */
|
|
5162
|
+
transaction<T>(fn: (tx: AdepCloudDb) => Promise<T>): Promise<T>
|
|
5163
|
+
/** \u53D7\u63A7\u88F8 SQL\uFF1Bparams \u5FC5\u586B\uFF08\u65E0\u53C2\u4F20 []\uFF09\uFF0C\u5355\u8BED\u53E5\uFF0C\u7981\u591A\u8BED\u53E5\u5806\u53E0\u3002 */
|
|
5164
|
+
query(sql: string, params: readonly AdepSqlValue[]): Promise<AdepRow[]>
|
|
5165
|
+
/** \u8BFB\u53D6 owned \u8868 __changes \u53D8\u66F4\u6D41\uFF08\u6309 seq \u5347\u5E8F\uFF0C\u53EF\u91CD\u653E\uFF09\u3002 */
|
|
5166
|
+
changes(table: string, query?: AdepChangeQuery): Promise<AdepChangeRecord[]>
|
|
5167
|
+
}
|
|
5168
|
+
|
|
5169
|
+
/* ---------- \u53D7\u63A7\u7F51\u7EDC\uFF08CloudFetch \u955C\u50CF\uFF09 ---------- */
|
|
5170
|
+
|
|
5171
|
+
/** cloud.fetch \u8BF7\u6C42\u9009\u9879\uFF08\u53D7\u63A7\u5B50\u96C6\uFF0Cbody \u9650\u5236\u4E3A\u5B57\u7B26\u4E32/JSON\uFF0C\u4E8C\u8FDB\u5236\u4E0A\u4F20\u4E0D\u5728\u672C\u80FD\u529B\u8303\u56F4\uFF09\u3002 */
|
|
5172
|
+
interface AdepCloudFetchInit {
|
|
5173
|
+
method?: string
|
|
5174
|
+
/** \u8BF7\u6C42\u5934\uFF08\u5C0F\u5199\u5316\u540E\u9010\u6761\u900F\u4F20\uFF09\u3002 */
|
|
5175
|
+
headers?: Record<string, string>
|
|
5176
|
+
body?: string
|
|
5177
|
+
/** \u8C03\u7528\u65B9\u4E2D\u6B62\u4FE1\u53F7\uFF08\u4E0E\u5E73\u53F0\u8D85\u65F6\u53E0\u52A0\uFF0C\u4E8C\u8005\u4EFB\u4E00\u89E6\u53D1\u5373\u4E2D\u6B62\uFF09\u3002 */
|
|
5178
|
+
signal?: AbortSignal
|
|
5179
|
+
}
|
|
5180
|
+
|
|
5181
|
+
/** cloud.fetch \u7684\u7ED3\u6784\u5316\u54CD\u5E94\uFF08\u6587\u672C/JSON/\u4E8C\u8FDB\u5236\u8BFB\u53D6\u53D7\u54CD\u5E94\u4F53\u4E0A\u9650\u7EA6\u675F\uFF09\u3002 */
|
|
5182
|
+
interface AdepCloudFetchResponse {
|
|
5183
|
+
ok: boolean
|
|
5184
|
+
status: number
|
|
5185
|
+
statusText: string
|
|
5186
|
+
/** \u5F52\u4E00\u5316\u54CD\u5E94\u5934\uFF08\u952E\u5C0F\u5199\uFF09\u3002 */
|
|
5187
|
+
headers: Record<string, string>
|
|
5188
|
+
text(): Promise<string>
|
|
5189
|
+
json(): Promise<unknown>
|
|
5190
|
+
arrayBuffer(): Promise<ArrayBuffer>
|
|
5191
|
+
}
|
|
5192
|
+
|
|
5193
|
+
/** cloud.fetch\uFF1A\u53D7\u63A7\u7684 HTTPS \u8BF7\u6C42\u3002URL \u4E3B\u673A\u4E0D\u5728\u767D\u540D\u5355\u5219\u629B FN_FETCH_FORBIDDEN\u3002 */
|
|
5194
|
+
type AdepCloudFetch = (url: string, init?: AdepCloudFetchInit) => Promise<AdepCloudFetchResponse>
|
|
5195
|
+
|
|
5196
|
+
/* ---------- \u5B9E\u65F6\u901A\u9053\uFF08CloudRealtime \u955C\u50CF\uFF09 ---------- */
|
|
5197
|
+
|
|
5198
|
+
/** \u4E00\u6761\u901A\u9053\u6D88\u606F\uFF08\u4E0E @adep/types \u7684 RealtimeChannelMessage \u5BF9\u9F50\uFF09\u3002 */
|
|
5199
|
+
interface AdepRealtimeChannelMessage {
|
|
5200
|
+
channel: string
|
|
5201
|
+
seq: number
|
|
5202
|
+
data: unknown
|
|
5203
|
+
publishedAt: string
|
|
5204
|
+
publisher?: string
|
|
5516
5205
|
}
|
|
5517
|
-
var init_dev2 = __esm({
|
|
5518
|
-
"packages/cli/src/widget/dev.ts"() {
|
|
5519
|
-
"use strict";
|
|
5520
|
-
init_build();
|
|
5521
|
-
}
|
|
5522
|
-
});
|
|
5523
5206
|
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
publishWidget: () => publishWidget
|
|
5528
|
-
});
|
|
5529
|
-
import { readFile as readFile12 } from "node:fs/promises";
|
|
5530
|
-
import { basename as basename4, join as join16, resolve as resolve14 } from "node:path";
|
|
5531
|
-
async function publishWidget(paths, options) {
|
|
5532
|
-
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
5533
|
-
`));
|
|
5534
|
-
const client = await createClient(paths);
|
|
5535
|
-
const root = resolve14(options.cwd);
|
|
5536
|
-
const project2 = await loadWidgetProject(root);
|
|
5537
|
-
const framework = options.framework ?? project2.framework;
|
|
5538
|
-
let version = "0.1.0";
|
|
5539
|
-
try {
|
|
5540
|
-
const pkg = JSON.parse(await readFile12(join16(root, "package.json"), "utf8"));
|
|
5541
|
-
if (typeof pkg["version"] === "string" && pkg["version"].length > 0) version = pkg["version"];
|
|
5542
|
-
} catch {
|
|
5543
|
-
version = "0.1.0";
|
|
5544
|
-
}
|
|
5545
|
-
const name = project2.name === "widget" ? basename4(root) : project2.name;
|
|
5546
|
-
log(`[adep] \u6784\u5EFA ${name}\uFF08${framework}\uFF09v${version} \u2026`);
|
|
5547
|
-
const built = await buildWidget({ cwd: root, framework });
|
|
5548
|
-
const path = `widgets/${name}/${version}/index.js`;
|
|
5549
|
-
const form = new FormData();
|
|
5550
|
-
form.set("path", path);
|
|
5551
|
-
form.set("visibility", "public");
|
|
5552
|
-
form.set("file", new Blob([built.text], { type: "text/javascript" }), "index.js");
|
|
5553
|
-
await client.upload(`/api/v1/projects/${options.project}/files`, form, "PUBLISH_UPLOAD_FAILED");
|
|
5554
|
-
const prefix = encodeURIComponent(`widgets/${name}/${version}/`);
|
|
5555
|
-
const listing = await client.request(
|
|
5556
|
-
`/api/v1/projects/${options.project}/files?prefix=${prefix}`
|
|
5557
|
-
);
|
|
5558
|
-
const entry = (listing.files ?? []).find((file) => file.path?.endsWith("index.js"));
|
|
5559
|
-
const url = entry?.url;
|
|
5560
|
-
if (typeof url !== "string" || url.length === 0) {
|
|
5561
|
-
throw new WidgetError("URL_MISSING", "\u4E0A\u4F20\u6210\u529F\u4F46\u65E0\u6CD5\u89E3\u6790\u4EA7\u7269 URL\uFF0C\u8BF7\u68C0\u67E5\u5E73\u53F0\u5B58\u50A8\u914D\u7F6E");
|
|
5562
|
-
}
|
|
5563
|
-
log(`[adep] \u5DF2\u53D1\u5E03 ${name} v${version}\uFF08hash ${built.hash.slice(0, 8)}\u2026\uFF09`);
|
|
5564
|
-
return { name, version, framework, url, hash: built.hash };
|
|
5207
|
+
/** publish \u56DE\u6267\uFF1Adelivered = \u5B9E\u9645\u547D\u4E2D\u7684\u8BA2\u9605\u8FDE\u63A5\u6570\uFF08\u5C3D\u529B\u6295\u9012\uFF0C0 \u662F\u5408\u6CD5\u7ED3\u679C\uFF09\u3002 */
|
|
5208
|
+
interface AdepCloudRealtimeReceipt {
|
|
5209
|
+
delivered: number
|
|
5565
5210
|
}
|
|
5566
|
-
var init_publish = __esm({
|
|
5567
|
-
"packages/cli/src/widget/publish.ts"() {
|
|
5568
|
-
"use strict";
|
|
5569
|
-
init_client();
|
|
5570
|
-
init_build();
|
|
5571
|
-
init_dev2();
|
|
5572
|
-
}
|
|
5573
|
-
});
|
|
5574
5211
|
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5212
|
+
/** subscribe \u56DE\u6267\uFF1Asubscription \u662F\u540E\u7EED receive / unsubscribe \u7684\u53E5\u67C4\u3002 */
|
|
5213
|
+
interface AdepCloudRealtimeSubscription {
|
|
5214
|
+
subscription: string
|
|
5215
|
+
channel: string
|
|
5216
|
+
}
|
|
5217
|
+
|
|
5218
|
+
/**
|
|
5219
|
+
* cloud.realtime\uFF1A\u51FD\u6570\u5185\u6536\u53D1\u5B9E\u65F6\u901A\u9053\u6D88\u606F\u3002
|
|
5220
|
+
* \u26A0\uFE0F subscribe / receive \u662F\u8F6E\u8BE2\u53D6\u4EF6\u800C\u975E\u56DE\u8C03\u8BA2\u9605\uFF08RPC \u53C2\u6570\u8D70\u7ED3\u6784\u5316\u514B\u9686\uFF0C\u4F20\u4E0D\u4E86\u51FD\u6570\uFF09\u3002
|
|
5221
|
+
*/
|
|
5222
|
+
interface AdepCloudRealtime {
|
|
5223
|
+
/** except \u4EC5\u7EBF\u4E0A\u652F\u6301\uFF08\u4E0D\u56DE\u53D1\u7ED9\u8BE5\u8FDE\u63A5\uFF09\uFF1B\u672C\u5730 adep dev \u4F20\u7B2C\u4E09\u53C2\u4F1A fail loud\u3002 */
|
|
5224
|
+
publish(channel: string, data: unknown, except?: string): Promise<AdepCloudRealtimeReceipt>
|
|
5225
|
+
subscribe(channel: string): Promise<AdepCloudRealtimeSubscription>
|
|
5226
|
+
receive(subscription: string): Promise<AdepRealtimeChannelMessage[]>
|
|
5227
|
+
unsubscribe(subscription: string): Promise<{ removed: true }>
|
|
5228
|
+
}
|
|
5229
|
+
|
|
5230
|
+
/* ---------- \u80FD\u529B\u6302\u8F7D\u70B9\uFF08Cloud / CapabilityRegistry \u955C\u50CF\uFF09 ---------- */
|
|
5231
|
+
|
|
5232
|
+
/** \u5DF2\u6CE8\u518C\u80FD\u529B\u540D \u2192 \u5B9E\u73B0\u5951\u7EA6\u7684\u6620\u5C04\u3002\u8BBF\u95EE\u672A\u6CE8\u518C\u80FD\u529B\u8FD0\u884C\u65F6\u629B\u5E26\u53EF\u64CD\u4F5C\u63D0\u793A\u7684\u9519\u8BEF\u3002 */
|
|
5233
|
+
interface AdepCapabilityRegistry {
|
|
5234
|
+
db: AdepCloudDb
|
|
5235
|
+
storage: AdepCloudStorage
|
|
5236
|
+
/** \u6C99\u7BB1\u53D7\u63A7\u7F51\u7EDC\uFF08GAME-007\uFF09\uFF1A\u672A\u914D\u7F6E\u767D\u540D\u5355\u65F6\u4E0D\u6CE8\u5165\uFF08\u65E0\u7F51\u7EDC\u5B89\u5168\u9ED8\u8BA4\uFF09\u3002 */
|
|
5237
|
+
fetch: AdepCloudFetch
|
|
5238
|
+
/** \u5B9E\u65F6\u901A\u9053\uFF08FN-020\uFF09\uFF1A\u9879\u76EE\u88C5\u914D realtime \u57DF\u5373\u6CE8\u5165\uFF1B\u8F6E\u8BE2\u8BED\u4E49\u89C1 AdepCloudRealtime\u3002 */
|
|
5239
|
+
realtime: AdepCloudRealtime
|
|
5240
|
+
}
|
|
5241
|
+
|
|
5242
|
+
/** \u7528\u6237\u51FD\u6570\u4FA7\u7684 ctx.cloud\uFF1A\u53EA\u80FD\u8BBF\u95EE\u80FD\u529B\u3002\u5DF2\u77E5\u80FD\u529B\u6709\u7CBE\u786E\u8865\u5168\uFF1B\u81EA\u5B9A\u4E49\u80FD\u529B\u7ECF\u7D22\u5F15\u7B7E\u540D\u8BBF\u95EE\u3002 */
|
|
5243
|
+
type AdepCloud = {
|
|
5244
|
+
readonly [K in keyof AdepCapabilityRegistry]: AdepCapabilityRegistry[K]
|
|
5245
|
+
} & {
|
|
5246
|
+
// \u547D\u540D\u5C5E\u6027\u7ED9\u51FA\u7CBE\u786E\u8865\u5168\uFF1B\u7D22\u5F15\u7B7E\u540D\u653E\u884C\u81EA\u5B9A\u4E49\u80FD\u529B\u8BBF\u95EE\uFF08\u8FD0\u884C\u65F6\u672A\u6CE8\u518C\u5373\u629B\u9519\uFF09\u3002
|
|
5247
|
+
readonly [capability: string]: unknown
|
|
5248
|
+
}
|
|
5249
|
+
|
|
5250
|
+
/* ---------- \u8C03\u7528\u8005\u8EAB\u4EFD\uFF08ExecutorUser \u955C\u50CF\uFF09 ---------- */
|
|
5251
|
+
|
|
5252
|
+
/** \u6267\u884C\u8005\u8EAB\u4EFD\u6295\u5F71\uFF1A\u7F51\u5173\u89E3\u6790\u4F1A\u8BDD\u540E\u6CE8\u5165\uFF1Bnull = \u533F\u540D / \u672A\u6CE8\u5165\uFF08\u900F\u4F20\u4FE1\u606F\uFF0C\u975E\u5F3A\u5236\u95E8\uFF09\u3002 */
|
|
5253
|
+
interface AdepExecutorUser {
|
|
5254
|
+
/** \u5E73\u53F0\u7528\u6237 id\uFF08= better-auth session.user.id\uFF09\u3002 */
|
|
5255
|
+
id: string
|
|
5256
|
+
email?: string
|
|
5257
|
+
name?: string
|
|
5258
|
+
}
|
|
5259
|
+
|
|
5260
|
+
/* ---------- \u5168\u5C40 ctx\uFF08FunctionContext \u955C\u50CF\uFF09 ---------- */
|
|
5261
|
+
|
|
5262
|
+
interface AdepContext {
|
|
5263
|
+
/** \u8BF7\u6C42\u65B9\u6CD5\u3002 */
|
|
5264
|
+
readonly method: AdepHttpMethod
|
|
5265
|
+
/** \u89E6\u53D1\u8DEF\u5F84\uFF08\u4E0D\u542B host\uFF09\uFF0C\u5982 /hello\u3002 */
|
|
5266
|
+
readonly path: string
|
|
5267
|
+
/** \u89E3\u6790\u540E\u7684 query\uFF1B\u540C\u540D\u591A\u503C\u6536\u4E3A\u6570\u7EC4\u3002 */
|
|
5268
|
+
readonly query: Readonly<Record<string, string | readonly string[]>>
|
|
5269
|
+
/** \u8BF7\u6C42\u5934\uFF08\u952E\u4E3A\u5C0F\u5199\uFF09\u3002 */
|
|
5270
|
+
readonly headers: Readonly<Record<string, string>>
|
|
5271
|
+
/** \u8BF7\u6C42\u4F53\uFF1B\u5F62\u72B6\u7531\u7528\u6237\u7528\u7C7B\u578B\u65AD\u8A00\u6536\u7A84\uFF08\u5982 ctx.body as { name: string }\uFF09\u3002 */
|
|
5272
|
+
readonly body: unknown
|
|
5273
|
+
/** multipart \u4E0A\u4F20\u7684\u6587\u4EF6\uFF08\u65E0\u6587\u4EF6\u65F6\u4E3A\u7A7A\u6570\u7EC4\uFF09\u3002 */
|
|
5274
|
+
readonly files: readonly AdepFunctionFile[]
|
|
5275
|
+
/** \u5E73\u53F0\u80FD\u529B\u6302\u8F7D\u70B9\uFF1Acloud.db / cloud.storage / cloud.fetch / cloud.realtime\u3002 */
|
|
5276
|
+
readonly cloud: AdepCloud
|
|
5277
|
+
/** \u8C03\u7528\u8005\u8EAB\u4EFD\u6295\u5F71\uFF1Bnull = \u533F\u540D / \u672A\u6CE8\u5165\u3002 */
|
|
5278
|
+
readonly user: AdepExecutorUser | null
|
|
5279
|
+
}
|
|
5280
|
+
|
|
5281
|
+
/** \u5168\u5C40\u5F00\u53D1\u671F\u4E0A\u4E0B\u6587\uFF08\u7F16\u8F91\u5668\u8865\u5168\u7528\uFF1B\u51FD\u6570\u8FD0\u884C\u671F\u7ECF\u53C2\u6570\u6CE8\u5165\uFF0C\u4E0D\u8BFB\u53D6\u5168\u5C40\uFF09\u3002 */
|
|
5282
|
+
declare const ctx: AdepContext
|
|
5283
|
+
`;
|
|
5284
|
+
var ADEP_TSCONFIG_JSON = `{
|
|
5285
|
+
"compilerOptions": {
|
|
5286
|
+
"target": "ES2021",
|
|
5287
|
+
"module": "ESNext",
|
|
5288
|
+
"moduleResolution": "Bundler",
|
|
5289
|
+
"strict": true,
|
|
5290
|
+
"noEmit": true,
|
|
5291
|
+
"skipLibCheck": true,
|
|
5292
|
+
"types": [],
|
|
5293
|
+
"lib": ["ES2021", "DOM"]
|
|
5294
|
+
},
|
|
5295
|
+
"include": ["**/*.ts", "**/*.d.ts"]
|
|
5296
|
+
}
|
|
5297
|
+
`;
|
|
5298
|
+
|
|
5299
|
+
// shared/sdk/web-project-template.ts
|
|
5300
|
+
function webProjectFiles() {
|
|
5301
|
+
return [
|
|
5302
|
+
{
|
|
5303
|
+
path: "package.json",
|
|
5304
|
+
content: JSON.stringify(
|
|
5305
|
+
{
|
|
5306
|
+
name: "adep-web",
|
|
5307
|
+
version: "0.0.0",
|
|
5308
|
+
type: "module",
|
|
5309
|
+
scripts: { dev: "vite" },
|
|
5310
|
+
dependencies: { vue: "^3.3.4" },
|
|
5311
|
+
devDependencies: {
|
|
5312
|
+
vite: "^4.4.0",
|
|
5313
|
+
"@vitejs/plugin-vue": "^4.3.0",
|
|
5314
|
+
// vite 内部动态 import('esbuild-wasm'),必须在 package.json 显式声明才能被 Nodebox 解析
|
|
5315
|
+
"esbuild-wasm": "0.18.20"
|
|
5316
|
+
}
|
|
5317
|
+
},
|
|
5318
|
+
null,
|
|
5319
|
+
2
|
|
5320
|
+
)
|
|
5321
|
+
},
|
|
5322
|
+
{
|
|
5323
|
+
path: "index.html",
|
|
5324
|
+
content: [
|
|
5325
|
+
`<!doctype html>`,
|
|
5326
|
+
`<html lang="zh-CN">`,
|
|
5327
|
+
`<head>`,
|
|
5328
|
+
` <meta charset="utf-8" />`,
|
|
5329
|
+
` <meta name="viewport" content="width=device-width, initial-scale=1" />`,
|
|
5330
|
+
` <title>adep web</title>`,
|
|
5331
|
+
`</head>`,
|
|
5332
|
+
`<body>`,
|
|
5333
|
+
` <div id="app"></div>`,
|
|
5334
|
+
` <script type="module" src="/src/main.ts"></script>`,
|
|
5335
|
+
`</body>`,
|
|
5336
|
+
`</html>`,
|
|
5337
|
+
``
|
|
5338
|
+
].join("\n")
|
|
5339
|
+
},
|
|
5340
|
+
{
|
|
5341
|
+
path: "vite.config.ts",
|
|
5342
|
+
content: [
|
|
5343
|
+
`// web/vite.config.ts \u2014\u2014 \u6807\u51C6 Vite \u914D\u7F6E\uFF08Vue 3 \u63D2\u4EF6\uFF09\u3002`,
|
|
5344
|
+
`import { defineConfig } from 'vite'`,
|
|
5345
|
+
`import vue from '@vitejs/plugin-vue'`,
|
|
5346
|
+
``,
|
|
5347
|
+
`export default defineConfig({`,
|
|
5348
|
+
` plugins: [vue()],`,
|
|
5349
|
+
`})`,
|
|
5350
|
+
``
|
|
5351
|
+
].join("\n")
|
|
5352
|
+
},
|
|
5353
|
+
{
|
|
5354
|
+
path: "src/main.ts",
|
|
5355
|
+
content: [
|
|
5356
|
+
`// web/src/main.ts \u2014\u2014 \u5E94\u7528\u5165\u53E3\uFF08Vue 3 + Vite\uFF09\u3002`,
|
|
5357
|
+
`// \u5F00\u53D1\uFF1A\u5E95\u90E8\u300C\u6D4F\u89C8\u5668\u7EC8\u7AEF\u300D\u8FD0\u884C npm run dev\uFF08\u6216\u7B49 Nodebox \u81EA\u52A8\u62C9\u8D77\uFF09\uFF0C\u4FDD\u5B58\u540E\u9884\u89C8 HMR \u5237\u65B0\u3002`,
|
|
5358
|
+
`import { createApp } from 'vue'`,
|
|
5359
|
+
`import App from './App.vue'`,
|
|
5360
|
+
``,
|
|
5361
|
+
`createApp(App).mount('#app')`,
|
|
5362
|
+
``
|
|
5363
|
+
].join("\n")
|
|
5364
|
+
},
|
|
5365
|
+
{
|
|
5366
|
+
path: "src/App.vue",
|
|
5367
|
+
content: [
|
|
5368
|
+
`<script setup lang="ts">`,
|
|
5369
|
+
`import { ref } from 'vue'`,
|
|
5370
|
+
``,
|
|
5371
|
+
`const title = ref('adep web')`,
|
|
5372
|
+
`const clicks = ref(0)`,
|
|
5373
|
+
`</script>`,
|
|
5374
|
+
``,
|
|
5375
|
+
`<template>`,
|
|
5376
|
+
` <main>`,
|
|
5377
|
+
` <h1>{{ title }}</h1>`,
|
|
5378
|
+
` <p>\u5728 web/src/App.vue \u91CC\u7F16\u8F91\uFF0C\u4FDD\u5B58\u540E\u9884\u89C8\u81EA\u52A8\u5237\u65B0\uFF08HMR\uFF09\u3002</p>`,
|
|
5379
|
+
` <button @click="clicks++">clicks: {{ clicks }}</button>`,
|
|
5380
|
+
` </main>`,
|
|
5381
|
+
`</template>`,
|
|
5382
|
+
``,
|
|
5383
|
+
`<style scoped>`,
|
|
5384
|
+
`main {`,
|
|
5385
|
+
` margin: 24px;`,
|
|
5386
|
+
` font-family: system-ui, -apple-system, sans-serif;`,
|
|
5387
|
+
`}`,
|
|
5388
|
+
`button {`,
|
|
5389
|
+
` padding: 6px 14px;`,
|
|
5390
|
+
` border: 1px solid #6366f1;`,
|
|
5391
|
+
` border-radius: 6px;`,
|
|
5392
|
+
` background: #eef2ff;`,
|
|
5393
|
+
` cursor: pointer;`,
|
|
5394
|
+
`}`,
|
|
5395
|
+
`</style>`,
|
|
5396
|
+
``
|
|
5397
|
+
].join("\n")
|
|
5398
|
+
}
|
|
5399
|
+
];
|
|
5400
|
+
}
|
|
5580
5401
|
|
|
5581
5402
|
// packages/cli/src/init.ts
|
|
5582
|
-
|
|
5583
|
-
import { dirname as dirname2, join, resolve } from "node:path";
|
|
5403
|
+
var TEMPLATE_NAMES = ["empty", "function", "fullstack"];
|
|
5584
5404
|
var InitError = class extends Error {
|
|
5585
5405
|
constructor(code, message) {
|
|
5586
5406
|
super(message);
|
|
@@ -5596,23 +5416,58 @@ export default {
|
|
|
5596
5416
|
`;
|
|
5597
5417
|
var README = (name, template) => `# ${name}
|
|
5598
5418
|
|
|
5599
|
-
AgentDeploy \u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u3002
|
|
5419
|
+
AgentDeploy \u5168\u6808\u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u3002
|
|
5600
5420
|
|
|
5601
|
-
|
|
5602
|
-
|
|
5421
|
+
## \u5E38\u7528\u547D\u4EE4
|
|
5422
|
+
|
|
5423
|
+
- \`adep dev\`\uFF1A\u672C\u5730\u8C03\u8BD5\uFF08\u76D1\u542C functions/\uFF0C\u652F\u6301\u70ED\u91CD\u8F7D\uFF0C\u9ED8\u8BA4 http://127.0.0.1:8787/<fnName>\uFF09
|
|
5424
|
+
- \`adep deploy\`\uFF1A\u589E\u91CF\u90E8\u7F72\uFF08\u5BF9\u6BD4\u8FDC\u7AEF\u54C8\u5E0C \u2192 \u4EC5\u4E0A\u4F20\u53D8\u66F4 \u2192 \u53D1\u5E03 \u2192 \u8F93\u51FA\u8BBF\u95EE\u57DF\u540D\uFF09
|
|
5425
|
+
- \`adep serve\`\uFF1A\u5F00\u53D1\u6001\u670D\u52A1\u5668\uFF08\u51FD\u6570 /api/{fn} + /healthz + \u9759\u6001\u6258\u7BA1 + \u524D\u7AEF\u9884\u89C8\uFF09
|
|
5426
|
+
|
|
5427
|
+
## \u76EE\u5F55\u7ED3\u6784
|
|
5428
|
+
|
|
5429
|
+
- \`adep.config.ts\`\uFF1A\u9879\u76EE\u6807\u8BC6\uFF08dev / deploy \u6309\u6B64\u8BC6\u522B\uFF09
|
|
5430
|
+
- \`functions/\`\uFF1A\u4E91\u51FD\u6570\u76EE\u5F55\uFF08\u6BCF\u4E2A\u6587\u4EF6 = \u4E00\u4E2A\u51FD\u6570\uFF0C\u9ED8\u8BA4\u5BFC\u51FA \`(ctx: AdepContext) => Response\`\uFF09
|
|
5431
|
+
- \`web/\`\uFF1A\u524D\u7AEF\u5DE5\u7A0B\uFF08\u6807\u51C6 Vite + Vue 3\uFF1B\u4E0E Web IDE \u9879\u76EE\u540C\u6784\uFF0C\u53EF\u6574\u76EE\u5F55\u5BFC\u51FA\u4E8C\u6B21\u5F00\u53D1\uFF09
|
|
5432
|
+
- \`database/schema.sql\`\uFF1A\u6570\u636E\u5E93\u7ED3\u6784\uFF08\u8868\u7531\u5E73\u53F0\u63A7\u5236\u53F0 / \`adep db\` \u7BA1\u7406\uFF0C\u6B64\u5904\u4E3A\u7ED3\u6784\u8BB0\u5F55\uFF09
|
|
5433
|
+
- \`tsconfig.json\`\uFF1A\u4E91\u51FD\u6570 TypeScript \u7F16\u8F91\u5668\u914D\u7F6E\uFF08strict + noEmit\uFF09
|
|
5434
|
+
- \`adep.d.ts\`\uFF1A\u4E91\u51FD\u6570\u4E0A\u4E0B\u6587\u73AF\u5883\u7C7B\u578B\u58F0\u660E\uFF08\`ctx: AdepContext\` \u8865\u5168\uFF0C\u65E0\u9700\u88C5\u4F9D\u8D56\uFF09
|
|
5435
|
+
|
|
5436
|
+
## \u4E91\u51FD\u6570\u7C7B\u578B\u63D0\u793A
|
|
5437
|
+
|
|
5438
|
+
\u7528 VSCode \u6253\u5F00\u672C\u76EE\u5F55\uFF0C\u4EFB\u610F \`functions/**\` \u4E0B\u7684 TS \u6587\u4EF6\u5373\u53EF\u83B7\u5F97 \`AdepContext\` / \`ctx.cloud.*\` \u8865\u5168\uFF1A
|
|
5439
|
+
\`tsconfig.json\` \u4F1A\u628A \`adep.d.ts\` \u7EB3\u5165 include\uFF0C\u51FD\u6570\u53C2\u6570\u5199 \`ctx: AdepContext\` \u5373\u53EF\u3002
|
|
5440
|
+
\`ctx\` \u4E0E \`AdepContext\` \u662F\u5168\u5C40\u5F00\u53D1\u671F\u58F0\u660E\uFF0C\u51FD\u6570\u8FD0\u884C\u671F\u7ECF\u53C2\u6570\u6CE8\u5165\uFF08\u4E0D\u8BFB\u53D6\u5168\u5C40\uFF09\u3002
|
|
5441
|
+
|
|
5442
|
+
## \u6A21\u677F\u8BF4\u660E\uFF08adep init\uFF09
|
|
5443
|
+
|
|
5444
|
+
- \`adep init <name>\`\uFF1A\u9ED8\u8BA4 \`fullstack\` \u6A21\u677F\uFF08functions/ + web/ \u524D\u7AEF\u5DE5\u7A0B + database/\uFF0C\u4E0E Web IDE \u9879\u76EE\u540C\u6784\uFF09
|
|
5445
|
+
- \`adep init <name> -t function\`\uFF1A\u4EC5\u4E91\u51FD\u6570\uFF08\u5355\u4E2A\u793A\u4F8B\u51FD\u6570\uFF09
|
|
5446
|
+
- \`adep init <name> -t empty\`\uFF1A\u7A7A\u6A21\u677F\uFF08\u4EC5\u9879\u76EE\u9AA8\u67B6\uFF09
|
|
5447
|
+
- \`adep init --list\`\uFF1A\u4ECE\u5E73\u53F0 /api/v1/templates \u5217\u51FA\u53EF\u7528\u6A21\u677F
|
|
5448
|
+
- \`adep init --list -s <server>\`\uFF1A\u6307\u5B9A\u5E73\u53F0\u5730\u5740
|
|
5449
|
+
|
|
5450
|
+
## \u524D\u7AEF\u5DE5\u7A0B\uFF08web/\uFF09
|
|
5451
|
+
|
|
5452
|
+
\`web/\` \u662F\u6807\u51C6 Vite + Vue 3 \u5DE5\u7A0B\uFF0C\u4E0E Web IDE \u5185\u521B\u5EFA\u7684\u9879\u76EE\u5B8C\u5168\u540C\u6784\uFF1A
|
|
5453
|
+
\`index.html\` / \`package.json\` / \`vite.config.ts\` / \`src/main.ts\` / \`src/App.vue\`\u3002
|
|
5454
|
+
\u672C\u5730\u5F00\u53D1\uFF1A\`cd web && npm install && npm run dev\`\uFF1B\u90E8\u7F72\u7531 \`adep deploy\` \u7EDF\u4E00\u6784\u5EFA\u53D1\u5E03\u3002
|
|
5603
5455
|
`;
|
|
5604
5456
|
var HELLO_FUNCTION = `// \u793A\u4F8B\u51FD\u6570\uFF1Aadep deploy \u540E\u7ECF https://<project-slug>.<platform-domain>/hello \u89E6\u53D1\u3002
|
|
5605
|
-
// \u7528\u6237\u51FD\u6570\u5373 functions/ \u4E0B\u7684\u72EC\u7ACB\u6587\u4EF6\uFF0C\u9ED8\u8BA4\u5BFC\u51FA (ctx) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668
|
|
5606
|
-
//\uFF08ctx \u5951\u7EA6\u89C1
|
|
5607
|
-
export default async (ctx) => {
|
|
5457
|
+
// \u7528\u6237\u51FD\u6570\u5373 functions/ \u4E0B\u7684\u72EC\u7ACB\u6587\u4EF6\uFF0C\u9ED8\u8BA4\u5BFC\u51FA (ctx: AdepContext) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668
|
|
5458
|
+
//\uFF08ctx \u5951\u7EA6\u89C1 adep.d.ts\uFF1Amethod / path / query / headers / body / files / user / cloud.*\uFF09\u3002
|
|
5459
|
+
export default async (ctx: AdepContext) => {
|
|
5608
5460
|
const name = (ctx.query['name'] as string | undefined) ?? 'world'
|
|
5609
5461
|
return { message: \`hello \${name}\` }
|
|
5610
5462
|
}
|
|
5611
5463
|
`;
|
|
5612
5464
|
var FUNCTION_INDEX = `// \u51FD\u6570\u6A21\u5757\u5165\u53E3\uFF1A\u9879\u76EE\u91CC\u7684\u6BCF\u4E2A\u51FD\u6570\u662F functions/ \u4E0B\u7684\u72EC\u7ACB\u6587\u4EF6\uFF0C
|
|
5613
|
-
// \u9ED8\u8BA4\u5BFC\u51FA (ctx) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668\uFF08\u5951\u7EA6\u89C1
|
|
5465
|
+
// \u9ED8\u8BA4\u5BFC\u51FA (ctx: AdepContext) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668\uFF08\u5951\u7EA6\u89C1 adep.d.ts\uFF09\u3002
|
|
5466
|
+
`;
|
|
5467
|
+
var EMPTY_INDEX = `// AgentDeploy \u9879\u76EE\u5165\u53E3\u3002\u6A21\u677F\u6682\u65E0\u66F4\u591A\u5185\u5BB9\u2014\u2014\u51FD\u6570\u653E functions/\uFF0C\u524D\u7AEF\u653E web/\uFF0C\u914D\u7F6E\u89C1 adep.config.ts\u3002
|
|
5614
5468
|
`;
|
|
5615
|
-
var
|
|
5469
|
+
var SCHEMA_SQL = `-- AgentDeploy \u9879\u76EE\u6570\u636E\u5E93\u7ED3\u6784\uFF08\u5360\u4F4D\uFF09\u3002
|
|
5470
|
+
-- \u8868\u7ED3\u6784\u8BF7\u5728\u5E73\u53F0\u63A7\u5236\u53F0\u300C\u6570\u636E\u5E93\u300D\u6216\u672C\u5730 \`adep db\` \u4E2D\u521B\u5EFA\u540E\u56DE\u586B\uFF0C\u4FDD\u6301\u4E0E\u7EBF\u4E0A schema \u4E00\u81F4\u3002
|
|
5616
5471
|
`;
|
|
5617
5472
|
async function initProject(cwd, name, template) {
|
|
5618
5473
|
if (!/^[a-z][a-z0-9-]{0,62}$/.test(name)) {
|
|
@@ -5621,6 +5476,12 @@ async function initProject(cwd, name, template) {
|
|
|
5621
5476
|
`\u9879\u76EE\u540D "${name}" \u4E0D\u5408\u6CD5\uFF1A\u9700\u4EE5\u5C0F\u5199\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u542B\u5C0F\u5199\u5B57\u6BCD / \u6570\u5B57 / \u8FDE\u5B57\u7B26`
|
|
5622
5477
|
);
|
|
5623
5478
|
}
|
|
5479
|
+
if (!TEMPLATE_NAMES.includes(template)) {
|
|
5480
|
+
throw new InitError(
|
|
5481
|
+
"INVALID_TEMPLATE",
|
|
5482
|
+
`\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 ${TEMPLATE_NAMES.join(" | ")}`
|
|
5483
|
+
);
|
|
5484
|
+
}
|
|
5624
5485
|
const projectPath = resolve(cwd, name);
|
|
5625
5486
|
let existing;
|
|
5626
5487
|
try {
|
|
@@ -5633,14 +5494,23 @@ async function initProject(cwd, name, template) {
|
|
|
5633
5494
|
}
|
|
5634
5495
|
const files = [
|
|
5635
5496
|
{ path: "adep.config.ts", content: ADEP_CONFIG(name, template) },
|
|
5636
|
-
|
|
5497
|
+
// 云函数 TypeScript 类型提示:tsconfig 把 adep.d.ts 纳入 include,写 ctx: AdepContext 即有补全。
|
|
5498
|
+
{ path: "tsconfig.json", content: ADEP_TSCONFIG_JSON },
|
|
5499
|
+
{ path: "adep.d.ts", content: ADEP_ENV_DTS },
|
|
5500
|
+
{ path: "README.md", content: README(name, template) },
|
|
5501
|
+
{ path: ".gitignore", content: "node_modules/\ndata/\n.adep/\nweb/node_modules/\n" }
|
|
5637
5502
|
];
|
|
5638
5503
|
if (template === "function") {
|
|
5639
5504
|
files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION });
|
|
5640
5505
|
files.push({ path: "functions/README.md", content: FUNCTION_INDEX });
|
|
5641
|
-
|
|
5506
|
+
} else if (template === "fullstack") {
|
|
5507
|
+
files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION });
|
|
5508
|
+
files.push({ path: "functions/README.md", content: FUNCTION_INDEX });
|
|
5509
|
+
files.push({ path: "database/schema.sql", content: SCHEMA_SQL });
|
|
5510
|
+
for (const file of webProjectFiles()) {
|
|
5511
|
+
files.push({ path: `web/${file.path}`, content: file.content });
|
|
5512
|
+
}
|
|
5642
5513
|
} else {
|
|
5643
|
-
files.push({ path: ".gitignore", content: "node_modules/\ndata/\n.adep/\n" });
|
|
5644
5514
|
files.push({ path: "README-EMPTY.md", content: EMPTY_INDEX });
|
|
5645
5515
|
}
|
|
5646
5516
|
await mkdir2(projectPath, { recursive: true });
|
|
@@ -5654,62 +5524,56 @@ async function initProject(cwd, name, template) {
|
|
|
5654
5524
|
return { projectPath, files: files.map((file) => file.path) };
|
|
5655
5525
|
}
|
|
5656
5526
|
|
|
5657
|
-
// packages/cli/src/
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
let response;
|
|
5661
|
-
try {
|
|
5662
|
-
response = await fetch(`${server}/api/v1/templates`);
|
|
5663
|
-
} catch (error) {
|
|
5664
|
-
throw new CliError(
|
|
5665
|
-
"SERVER_UNREACHABLE",
|
|
5666
|
-
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
5667
|
-
);
|
|
5668
|
-
}
|
|
5669
|
-
const text = await response.text();
|
|
5670
|
-
let parsed = null;
|
|
5671
|
-
try {
|
|
5672
|
-
parsed = text.length === 0 ? null : JSON.parse(text);
|
|
5673
|
-
} catch {
|
|
5674
|
-
parsed = null;
|
|
5675
|
-
}
|
|
5676
|
-
if (response.status < 200 || response.status >= 300) {
|
|
5677
|
-
const msg = parsed?.error;
|
|
5678
|
-
throw new CliError("TEMPLATE_LIST_FAILED", msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`);
|
|
5679
|
-
}
|
|
5680
|
-
const templates = parsed?.templates;
|
|
5681
|
-
return templates ?? [];
|
|
5527
|
+
// packages/cli/src/output.ts
|
|
5528
|
+
function isCommandError(error) {
|
|
5529
|
+
return error instanceof CliError || error instanceof InitError;
|
|
5682
5530
|
}
|
|
5683
|
-
|
|
5684
|
-
// packages/cli/src/cli.ts
|
|
5685
|
-
init_build();
|
|
5686
|
-
init_init();
|
|
5687
|
-
var requireJson = createRequire(import.meta.url);
|
|
5688
|
-
var APP_VERSION = requireJson("../package.json").version;
|
|
5689
5531
|
function needsRelogin(error) {
|
|
5690
5532
|
return error.code === "NOT_LOGGED_IN" || error.code === "AUTH_UNAUTHORIZED";
|
|
5691
5533
|
}
|
|
5692
|
-
function
|
|
5693
|
-
|
|
5534
|
+
function toLines(value) {
|
|
5535
|
+
return Array.isArray(value) ? value : [value];
|
|
5536
|
+
}
|
|
5537
|
+
function createCommandIO(command, output, json) {
|
|
5538
|
+
const ok = (data, render) => {
|
|
5539
|
+
if (json) {
|
|
5540
|
+
output(JSON.stringify({ ok: true, command, data }));
|
|
5541
|
+
return;
|
|
5542
|
+
}
|
|
5543
|
+
if (render !== void 0) for (const lineValue of toLines(render(data))) output(lineValue);
|
|
5544
|
+
};
|
|
5545
|
+
const line = (text) => {
|
|
5546
|
+
if (!json) output(text);
|
|
5547
|
+
};
|
|
5548
|
+
const raw = (text) => {
|
|
5549
|
+
output(text);
|
|
5550
|
+
};
|
|
5551
|
+
const fail = (code, message) => {
|
|
5552
|
+
if (json) output(JSON.stringify({ ok: false, command, error: { code, message } }));
|
|
5553
|
+
else output(`\u9519\u8BEF\uFF1A${message}`);
|
|
5554
|
+
process.exitCode = 1;
|
|
5555
|
+
};
|
|
5556
|
+
const err = (error) => {
|
|
5557
|
+
if (!isCommandError(error)) throw error;
|
|
5694
5558
|
if (json) {
|
|
5695
5559
|
output(
|
|
5696
|
-
JSON.stringify({
|
|
5697
|
-
ok: false,
|
|
5698
|
-
command,
|
|
5699
|
-
error: { code: error.code, message: error.message }
|
|
5700
|
-
})
|
|
5560
|
+
JSON.stringify({ ok: false, command, error: { code: error.code, message: error.message } })
|
|
5701
5561
|
);
|
|
5702
5562
|
} else {
|
|
5703
5563
|
const withCode = error.message.includes(error.code) || error.code.length === 0 ? error.message : `${error.message}\uFF08${error.code}\uFF09`;
|
|
5704
5564
|
output(`\u9519\u8BEF\uFF1A${withCode}`);
|
|
5705
|
-
if (error instanceof CliError && needsRelogin(error))
|
|
5706
|
-
output("\u63D0\u793A\uFF1A\u5148\u6267\u884C adep login");
|
|
5707
|
-
}
|
|
5565
|
+
if (error instanceof CliError && needsRelogin(error)) output("\u63D0\u793A\uFF1A\u5148\u6267\u884C adep login");
|
|
5708
5566
|
}
|
|
5709
5567
|
process.exitCode = 1;
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5568
|
+
};
|
|
5569
|
+
const run = async (fn) => {
|
|
5570
|
+
try {
|
|
5571
|
+
await fn();
|
|
5572
|
+
} catch (error) {
|
|
5573
|
+
err(error);
|
|
5574
|
+
}
|
|
5575
|
+
};
|
|
5576
|
+
return { json, ok, line, raw, fail, err, run };
|
|
5713
5577
|
}
|
|
5714
5578
|
function formatBytes(bytes) {
|
|
5715
5579
|
if (bytes < 1024) return `${bytes} B`;
|
|
@@ -5730,69 +5594,35 @@ function formatTable(columns, rows) {
|
|
|
5730
5594
|
widths[index] = Math.max(widths[index], cell.length);
|
|
5731
5595
|
});
|
|
5732
5596
|
}
|
|
5733
|
-
const
|
|
5597
|
+
const contentLine = (cells) => cells.map((cell, index) => cell.padEnd(widths[index] ?? 0)).join(" ").trimEnd();
|
|
5734
5598
|
const parts = [
|
|
5735
|
-
|
|
5736
|
-
...rows.map((row) =>
|
|
5599
|
+
contentLine(columns),
|
|
5600
|
+
...rows.map((row) => contentLine(columns.map((c) => String(row[c] ?? ""))))
|
|
5737
5601
|
];
|
|
5738
5602
|
return parts.join("\n");
|
|
5739
5603
|
}
|
|
5740
|
-
function parseBool(raw) {
|
|
5741
|
-
if (raw === void 0) return void 0;
|
|
5742
|
-
if (raw === "true") return true;
|
|
5743
|
-
if (raw === "false") return false;
|
|
5744
|
-
throw new CliError("INVALID_BOOLEAN", `\u5E03\u5C14\u53C2\u6570\u987B\u4E3A true \u6216 false\uFF0C\u6536\u5230 "${raw}"`);
|
|
5745
|
-
}
|
|
5746
5604
|
function formatSeconds(seconds) {
|
|
5747
5605
|
return `${Math.max(0.1, Math.round(seconds * 10) / 10)}s`;
|
|
5748
5606
|
}
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
const
|
|
5607
|
+
|
|
5608
|
+
// packages/cli/src/commands/context.ts
|
|
5609
|
+
function createCliContext(deps) {
|
|
5610
|
+
const { output, paths, cwd, json } = deps;
|
|
5611
|
+
return {
|
|
5612
|
+
output,
|
|
5613
|
+
paths,
|
|
5753
5614
|
cwd,
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
// --json 下逐函数进度会破坏「stdout 恰好一个 JSON 对象」的信封约定(PRD §2.5.3)。
|
|
5757
|
-
silent: json,
|
|
5758
|
-
// 人读模式的进度也走注入的 output:deploy 内部缺省会直写 process.stdout,
|
|
5759
|
-
// 那会让带 sink 的调用方漏收这部分行。
|
|
5760
|
-
log: (line) => output(line)
|
|
5761
|
-
});
|
|
5762
|
-
const elapsedSeconds = (Date.now() - startedAt) / 1e3;
|
|
5763
|
-
const deployedCount = result.functions.filter((fn) => fn.action !== "none").length;
|
|
5764
|
-
if (json) {
|
|
5765
|
-
output(
|
|
5766
|
-
JSON.stringify({
|
|
5767
|
-
ok: true,
|
|
5768
|
-
command: "deploy",
|
|
5769
|
-
data: { ...result, elapsedSeconds, deployedCount }
|
|
5770
|
-
})
|
|
5771
|
-
);
|
|
5772
|
-
return;
|
|
5773
|
-
}
|
|
5774
|
-
for (const fn of result.functions) {
|
|
5775
|
-
output(`${fn.name} v${fn.version} ${fn.url}`);
|
|
5776
|
-
}
|
|
5777
|
-
if (result.noChanges) {
|
|
5778
|
-
output(
|
|
5779
|
-
`\u2713 no changes \xB7 ${result.functions.length} functions up to date in ${formatSeconds(elapsedSeconds)}`
|
|
5780
|
-
);
|
|
5781
|
-
return;
|
|
5782
|
-
}
|
|
5783
|
-
output(`\u2713 ${deployedCount} functions deployed in ${formatSeconds(elapsedSeconds)}`);
|
|
5615
|
+
io: (command) => createCommandIO(command, output, json())
|
|
5616
|
+
};
|
|
5784
5617
|
}
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
const program2 = new Command();
|
|
5791
|
-
program2.name("adep").description("AgentDeploy CLI").version(APP_VERSION);
|
|
5792
|
-
program2.option("--json", "\u4EE5\u673A\u5668\u53EF\u8BFB JSON \u8F93\u51FA\uFF08Agent / \u811A\u672C\u8C03\u7528\uFF09", false);
|
|
5793
|
-
const jsonMode = () => program2.opts()["json"] === true;
|
|
5618
|
+
|
|
5619
|
+
// packages/cli/src/commands/auth.ts
|
|
5620
|
+
init_auth();
|
|
5621
|
+
init_config();
|
|
5622
|
+
function registerAuth(program2, ctx) {
|
|
5794
5623
|
program2.command("login").description("\u767B\u5F55\u5E73\u53F0\uFF08better-auth \u90AE\u7BB1\u5BC6\u7801\u767B\u5F55\uFF1B\u8BBE\u5907\u6388\u6743\u6D41\u5F52 CORE \u57DF\u540E\u7EED\u4EFB\u52A1\uFF09").option("-s, --server <url>", "\u5E73\u53F0\u5730\u5740\uFF08\u7F3A\u7701\u8BFB\u53D6 ADEP_SERVER \u6216 http://localhost:3000\uFF09").option("-e, --email <email>", "\u767B\u5F55\u90AE\u7BB1").option("-p, --password <password>", "\u767B\u5F55\u5BC6\u7801\uFF08\u6CE8\u610F shell \u5386\u53F2\uFF1B\u7F3A\u7701\u4EA4\u4E92\u8F93\u5165\uFF09").action(async (flags) => {
|
|
5795
|
-
|
|
5624
|
+
const command = ctx.io("login");
|
|
5625
|
+
await command.run(async () => {
|
|
5796
5626
|
const server = flags.server ?? resolveServer();
|
|
5797
5627
|
let email = flags.email;
|
|
5798
5628
|
let password = flags.password;
|
|
@@ -5803,89 +5633,113 @@ function buildProgram(options = {}) {
|
|
|
5803
5633
|
password = password ?? await prompt.askHidden("\u5BC6\u7801\uFF1A");
|
|
5804
5634
|
prompt.close();
|
|
5805
5635
|
}
|
|
5806
|
-
const result = await login(paths, {
|
|
5636
|
+
const result = await login(ctx.paths, {
|
|
5807
5637
|
server,
|
|
5808
5638
|
email,
|
|
5809
5639
|
password
|
|
5810
5640
|
});
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
} catch (error) {
|
|
5817
|
-
emitError(output, "login", jsonMode(), error);
|
|
5818
|
-
}
|
|
5641
|
+
command.ok(result, (data) => {
|
|
5642
|
+
const d = data;
|
|
5643
|
+
return `\u5DF2\u767B\u5F55\uFF1A${d.email}\uFF08\u51ED\u636E\u5DF2\u5199\u5165 ${ctx.paths.credentialsFile}\uFF0C\u6743\u9650 0600\uFF09`;
|
|
5644
|
+
});
|
|
5645
|
+
});
|
|
5819
5646
|
});
|
|
5820
5647
|
program2.command("whoami").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u8EAB\u4EFD").action(async () => {
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
}
|
|
5828
|
-
}
|
|
5829
|
-
emitError(output, "whoami", jsonMode(), error);
|
|
5830
|
-
}
|
|
5648
|
+
const command = ctx.io("whoami");
|
|
5649
|
+
await command.run(async () => {
|
|
5650
|
+
const result = await whoami(ctx.paths);
|
|
5651
|
+
command.ok(result, (data) => {
|
|
5652
|
+
const d = data;
|
|
5653
|
+
return `${d.email} @ ${d.server}`;
|
|
5654
|
+
});
|
|
5655
|
+
});
|
|
5831
5656
|
});
|
|
5832
5657
|
program2.command("logout").description("\u767B\u51FA\u5E76\u6E05\u9664\u672C\u5730\u51ED\u636E").action(async () => {
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
output("\u5DF2\u767B\u51FA");
|
|
5839
|
-
}
|
|
5840
|
-
} catch (error) {
|
|
5841
|
-
emitError(output, "logout", jsonMode(), error);
|
|
5842
|
-
}
|
|
5658
|
+
const command = ctx.io("logout");
|
|
5659
|
+
await command.run(async () => {
|
|
5660
|
+
await logout(ctx.paths);
|
|
5661
|
+
command.ok({ done: true }, () => "\u5DF2\u767B\u51FA");
|
|
5662
|
+
});
|
|
5843
5663
|
});
|
|
5844
|
-
|
|
5664
|
+
}
|
|
5665
|
+
|
|
5666
|
+
// packages/cli/src/commands/init.ts
|
|
5667
|
+
init_config();
|
|
5668
|
+
|
|
5669
|
+
// packages/cli/src/templates.ts
|
|
5670
|
+
init_auth();
|
|
5671
|
+
async function fetchTemplates(server) {
|
|
5672
|
+
let response;
|
|
5673
|
+
try {
|
|
5674
|
+
response = await fetch(`${server}/api/v1/templates`);
|
|
5675
|
+
} catch (error) {
|
|
5676
|
+
throw new CliError(
|
|
5677
|
+
"SERVER_UNREACHABLE",
|
|
5678
|
+
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
5679
|
+
);
|
|
5680
|
+
}
|
|
5681
|
+
const text = await response.text();
|
|
5682
|
+
let parsed = null;
|
|
5683
|
+
try {
|
|
5684
|
+
parsed = text.length === 0 ? null : JSON.parse(text);
|
|
5685
|
+
} catch {
|
|
5686
|
+
parsed = null;
|
|
5687
|
+
}
|
|
5688
|
+
if (response.status < 200 || response.status >= 300) {
|
|
5689
|
+
const msg = parsed?.error;
|
|
5690
|
+
throw new CliError("TEMPLATE_LIST_FAILED", msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`);
|
|
5691
|
+
}
|
|
5692
|
+
const templates = parsed?.templates;
|
|
5693
|
+
return templates ?? [];
|
|
5694
|
+
}
|
|
5695
|
+
|
|
5696
|
+
// packages/cli/src/commands/init.ts
|
|
5697
|
+
function registerInit(program2, ctx) {
|
|
5698
|
+
program2.command("init").description("\u521D\u59CB\u5316\u9879\u76EE\uFF08\u6A21\u677F\uFF1Aempty / function / fullstack\uFF09\uFF0C\u6216 --list \u4ECE\u5E73\u53F0\u53D6\u6A21\u677F\u6E05\u5355").argument("[name]", "\u9879\u76EE\u76EE\u5F55\u540D\uFF08\u914D\u5408 --list \u65F6\u53EF\u7701\u7565\uFF09").option("-t, --template <template>", "\u6A21\u677F\uFF1Aempty | function | fullstack", "fullstack").option("-l, --list", "\u4ECE\u5E73\u53F0 /api/v1/templates \u5217\u51FA\u53EF\u7528\u6A21\u677F\uFF08\u4E0D\u811A\u624B\u67B6\uFF09", false).option(
|
|
5845
5699
|
"-s, --server <url>",
|
|
5846
5700
|
"\u5E73\u53F0\u5730\u5740\uFF08--list \u7528\uFF1B\u7F3A\u7701\u8BFB ADEP_SERVER \u6216 http://localhost:3000\uFF09"
|
|
5847
5701
|
).action(
|
|
5848
5702
|
async (name, flags) => {
|
|
5849
|
-
|
|
5703
|
+
const command = ctx.io("init");
|
|
5704
|
+
await command.run(async () => {
|
|
5850
5705
|
if (flags.list === true) {
|
|
5851
5706
|
const server = flags.server ?? resolveServer();
|
|
5852
5707
|
const templates = await fetchTemplates(server);
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
}
|
|
5708
|
+
command.ok(
|
|
5709
|
+
{ templates },
|
|
5710
|
+
(data) => data.templates.map(
|
|
5711
|
+
(tpl) => `${tpl.code} ${tpl.name} ${tpl.description ?? ""}`
|
|
5712
|
+
)
|
|
5713
|
+
);
|
|
5860
5714
|
return;
|
|
5861
5715
|
}
|
|
5862
5716
|
if (name === void 0) {
|
|
5863
5717
|
throw new InitError("MISSING_NAME", "\u9700\u7ED9\u51FA\u9879\u76EE\u540D\uFF0C\u6216\u4F7F\u7528 --list \u5217\u51FA\u5E73\u53F0\u53EF\u7528\u6A21\u677F");
|
|
5864
5718
|
}
|
|
5865
5719
|
const template = flags.template;
|
|
5866
|
-
if (!
|
|
5867
|
-
throw new InitError(
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
output(JSON.stringify({ ok: true, command: "init", data: result }));
|
|
5872
|
-
} else {
|
|
5873
|
-
output(`\u5DF2\u521B\u5EFA ${result.projectPath}`);
|
|
5720
|
+
if (!TEMPLATE_NAMES.includes(template)) {
|
|
5721
|
+
throw new InitError(
|
|
5722
|
+
"INVALID_TEMPLATE",
|
|
5723
|
+
`\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 ${TEMPLATE_NAMES.join(" | ")}`
|
|
5724
|
+
);
|
|
5874
5725
|
}
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
}
|
|
5726
|
+
const result = await initProject(ctx.cwd, name, template);
|
|
5727
|
+
command.ok(result, (data) => `\u5DF2\u521B\u5EFA ${data.projectPath}`);
|
|
5728
|
+
});
|
|
5878
5729
|
}
|
|
5879
5730
|
);
|
|
5731
|
+
}
|
|
5732
|
+
|
|
5733
|
+
// packages/cli/src/commands/dev.ts
|
|
5734
|
+
function registerDevServers(program2, ctx) {
|
|
5880
5735
|
program2.command("dev").description("\u672C\u5730\u8C03\u8BD5\uFF1A\u76D1\u542C functions/ \u70ED\u91CD\u8F7D\uFF0Chttp://localhost:<port>/<fnName>").option("-p, --port <port>", "\u76D1\u542C\u7AEF\u53E3\uFF08\u7F3A\u7701 8787\uFF09", "8787").action(async (flags) => {
|
|
5881
|
-
|
|
5736
|
+
const command = ctx.io("dev");
|
|
5737
|
+
await command.run(async () => {
|
|
5882
5738
|
const { startDevServer: startDevServer2 } = await Promise.resolve().then(() => (init_dev(), dev_exports));
|
|
5883
|
-
const started = await startDevServer2({ cwd, port: Number(flags.port ?? "8787") });
|
|
5884
|
-
|
|
5739
|
+
const started = await startDevServer2({ cwd: ctx.cwd, port: Number(flags.port ?? "8787") });
|
|
5740
|
+
command.raw(`[adep] dev server listening on ${started.baseUrl}\uFF08Ctrl-C \u9000\u51FA\uFF09`);
|
|
5885
5741
|
await new Promise(() => void 0);
|
|
5886
|
-
}
|
|
5887
|
-
emitError(output, "dev", jsonMode(), error);
|
|
5888
|
-
}
|
|
5742
|
+
});
|
|
5889
5743
|
});
|
|
5890
5744
|
program2.command("serve").description(
|
|
5891
5745
|
"\u5F00\u53D1\u6001\u670D\u52A1\u5668\uFF1A\u51FD\u6570 /api/{fn} + /healthz + \u9759\u6001\u6258\u7BA1 + \u7EC4\u4EF6\u9884\u89C8\uFF08\u9ED8\u8BA4\u4EC5\u56DE\u73AF\uFF0C\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668\uFF09"
|
|
@@ -5895,605 +5749,563 @@ function buildProgram(options = {}) {
|
|
|
5895
5749
|
).option(
|
|
5896
5750
|
"--static <dir>",
|
|
5897
5751
|
"\u9759\u6001\u6258\u7BA1\u76EE\u5F55\uFF08\u7F3A\u7701\u53D6 ADEP_SERVE_STATIC_DIR\uFF0C\u518D\u7F3A\u7701 public/\uFF1B\u81EA\u6258\u7BA1\u90E8\u7F72\u5305\u6307\u5411\u5305\u5185 web/\uFF09"
|
|
5752
|
+
).option(
|
|
5753
|
+
"--watch",
|
|
5754
|
+
"\u70ED\u91CD\u8F7D\uFF1A\u76D1\u542C functions/ \u4E0E .env* \u53D8\u66F4\u81EA\u52A8\u751F\u6548\uFF0C\u51FD\u6570 console \u8F93\u51FA\u76F4\u8FBE\u7EC8\u7AEF\uFF08\u5F00\u53D1\u6001\u8C03\u8BD5\u7528\uFF09"
|
|
5898
5755
|
).action(async (flags) => {
|
|
5899
|
-
|
|
5756
|
+
const command = ctx.io("serve");
|
|
5757
|
+
await command.run(async () => {
|
|
5900
5758
|
const { startServeServer: startServeServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
5901
5759
|
await startServeServer2({
|
|
5902
|
-
cwd,
|
|
5760
|
+
cwd: ctx.cwd,
|
|
5903
5761
|
...flags.port === void 0 ? {} : { port: Number(flags.port) },
|
|
5904
5762
|
...flags.host === void 0 ? {} : { host: flags.host },
|
|
5905
|
-
...flags.static === void 0 ? {} : { staticDir: flags.static }
|
|
5763
|
+
...flags.static === void 0 ? {} : { staticDir: flags.static },
|
|
5764
|
+
...flags.watch === void 0 ? {} : { watch: true }
|
|
5906
5765
|
});
|
|
5907
5766
|
await new Promise(() => void 0);
|
|
5908
|
-
}
|
|
5909
|
-
emitError(output, "serve", jsonMode(), error);
|
|
5910
|
-
}
|
|
5767
|
+
});
|
|
5911
5768
|
});
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5769
|
+
}
|
|
5770
|
+
|
|
5771
|
+
// packages/cli/src/commands/deploy.ts
|
|
5772
|
+
async function runDeploy(paths, io, cwd, slug, dir) {
|
|
5773
|
+
const { deploy: deploy2 } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
|
|
5774
|
+
const startedAt = Date.now();
|
|
5775
|
+
const result = await deploy2(paths, {
|
|
5776
|
+
cwd,
|
|
5777
|
+
...slug === void 0 ? {} : { slug },
|
|
5778
|
+
...dir === void 0 ? {} : { functionsDir: dir },
|
|
5779
|
+
// --json 下逐函数进度会破坏「stdout 恰好一个 JSON 对象」的信封约定(PRD §2.5.3)。
|
|
5780
|
+
silent: io.json,
|
|
5781
|
+
// 人读模式的进度也走注入的 io:deploy 内部缺省会直写 process.stdout,
|
|
5782
|
+
// 那会让带 sink 的调用方漏收这部分行。
|
|
5783
|
+
log: (line) => io.line(line)
|
|
5784
|
+
});
|
|
5785
|
+
const elapsedSeconds = (Date.now() - startedAt) / 1e3;
|
|
5786
|
+
const deployedCount = result.functions.filter((fn) => fn.action !== "none").length;
|
|
5787
|
+
io.ok({ ...result, elapsedSeconds, deployedCount }, (data) => {
|
|
5788
|
+
const r = data;
|
|
5789
|
+
const lines = r.functions.map((fn) => `${fn.name} v${fn.version} ${fn.url}`);
|
|
5790
|
+
if (r.noChanges) {
|
|
5791
|
+
lines.push(
|
|
5792
|
+
`\u2713 no changes \xB7 ${r.functions.length} functions up to date in ${formatSeconds(r.elapsedSeconds)}`
|
|
5793
|
+
);
|
|
5794
|
+
} else {
|
|
5795
|
+
lines.push(`\u2713 ${r.deployedCount} functions deployed in ${formatSeconds(r.elapsedSeconds)}`);
|
|
5917
5796
|
}
|
|
5797
|
+
return lines;
|
|
5798
|
+
});
|
|
5799
|
+
}
|
|
5800
|
+
function registerDeploy(program2, ctx) {
|
|
5801
|
+
program2.command("deploy").description("\u589E\u91CF\u90E8\u7F72\uFF1A\u5BF9\u6BD4\u8FDC\u7AEF\u54C8\u5E0C \u2192 \u4EC5\u4E0A\u4F20\u53D8\u66F4 \u2192 \u53D1\u5E03 \u2192 \u8F93\u51FA\u8BBF\u95EE\u57DF\u540D").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
5802
|
+
const command = ctx.io("deploy");
|
|
5803
|
+
await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project));
|
|
5918
5804
|
});
|
|
5805
|
+
}
|
|
5806
|
+
|
|
5807
|
+
// packages/cli/src/commands/projects.ts
|
|
5808
|
+
function registerProjects(program2, ctx) {
|
|
5919
5809
|
const projects = program2.command("projects").description("\u9879\u76EE\uFF1A\u521B\u5EFA / \u5217\u51FA / \u67E5\u770B\uFF08\u5B50\u57DF\u5730\u5740\u7531\u5E73\u53F0\u56DE\u663E\uFF0C\u4E0D\u5728 CLI \u4FA7\u62FC\uFF09");
|
|
5920
5810
|
projects.command("create").description("\u521B\u5EFA\u9879\u76EE\u5E76\u8F93\u51FA\u5B50\u57DF\u5730\u5740").argument("<slug>", "\u9879\u76EE slug\uFF08\u5168\u5C40\u552F\u4E00\uFF0C\u5373\u5B50\u57DF\u540D\uFF09").option("-n, --name <name>", "\u9879\u76EE\u5C55\u793A\u540D\uFF08\u7F3A\u7701\u53D6 slug\uFF09").option("--space <spaceId>", "\u5F52\u5C5E\u7A7A\u95F4\uFF08\u7F3A\u7701\u4E2A\u4EBA\u7A7A\u95F4\uFF09").action(async (slug, flags) => {
|
|
5921
|
-
|
|
5811
|
+
const command = ctx.io("projects create");
|
|
5812
|
+
await command.run(async () => {
|
|
5922
5813
|
const { projectsCreate: projectsCreate2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
5923
|
-
const created = await projectsCreate2(paths, {
|
|
5814
|
+
const created = await projectsCreate2(ctx.paths, {
|
|
5924
5815
|
slug,
|
|
5925
5816
|
...flags.name === void 0 ? {} : { name: flags.name },
|
|
5926
5817
|
...flags.space === void 0 ? {} : { spaceId: flags.space }
|
|
5927
5818
|
});
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
} else {
|
|
5931
|
-
output(`\u2713 Project created \xB7 ${created.url}`);
|
|
5932
|
-
}
|
|
5933
|
-
} catch (error) {
|
|
5934
|
-
emitError(output, "projects create", jsonMode(), error);
|
|
5935
|
-
}
|
|
5819
|
+
command.ok(created, (data) => `\u2713 Project created \xB7 ${data.url}`);
|
|
5820
|
+
});
|
|
5936
5821
|
});
|
|
5937
5822
|
projects.command("list").description("\u5217\u51FA\u5F53\u524D\u7528\u6237\u53EF\u8BBF\u95EE\u7684\u9879\u76EE").action(async () => {
|
|
5938
|
-
|
|
5823
|
+
const command = ctx.io("projects list");
|
|
5824
|
+
await command.run(async () => {
|
|
5939
5825
|
const { projectsList: projectsList2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
5940
|
-
const list = await projectsList2(paths);
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
} catch (error) {
|
|
5948
|
-
emitError(output, "projects list", jsonMode(), error);
|
|
5949
|
-
}
|
|
5826
|
+
const list = await projectsList2(ctx.paths);
|
|
5827
|
+
command.ok({ projects: list }, (data) => {
|
|
5828
|
+
const projectsData = data.projects;
|
|
5829
|
+
if (projectsData.length === 0) return "\uFF08\u8FD8\u6CA1\u6709\u9879\u76EE\uFF1Aadep projects create <slug>\uFF09";
|
|
5830
|
+
return projectsData.map((p) => `${p.slug} ${p.name} ${p.url}`);
|
|
5831
|
+
});
|
|
5832
|
+
});
|
|
5950
5833
|
});
|
|
5951
5834
|
projects.command("info").description("\u67E5\u770B\u5355\u4E2A\u9879\u76EE\u7684 id / slug / \u5B50\u57DF\u5730\u5740").argument("<slug>", "\u9879\u76EE slug").action(async (slug) => {
|
|
5952
|
-
|
|
5835
|
+
const command = ctx.io("projects info");
|
|
5836
|
+
await command.run(async () => {
|
|
5953
5837
|
const { projectsInfo: projectsInfo2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
5954
|
-
const project2 = await projectsInfo2(paths, { slug });
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
} catch (error) {
|
|
5961
|
-
emitError(output, "projects info", jsonMode(), error);
|
|
5962
|
-
}
|
|
5838
|
+
const project2 = await projectsInfo2(ctx.paths, { slug });
|
|
5839
|
+
command.ok(project2, (data) => {
|
|
5840
|
+
const p = data;
|
|
5841
|
+
return `${p.id} ${p.slug} ${p.name} ${p.url}`;
|
|
5842
|
+
});
|
|
5843
|
+
});
|
|
5963
5844
|
});
|
|
5845
|
+
}
|
|
5846
|
+
|
|
5847
|
+
// packages/cli/src/commands/functions.ts
|
|
5848
|
+
init_auth();
|
|
5849
|
+
function registerFunctions(program2, ctx) {
|
|
5964
5850
|
const functions = program2.command("functions").description("\u4E91\u51FD\u6570\uFF1A\u90E8\u7F72\uFF08\u53EF\u6307\u5B9A\u76EE\u5F55\uFF09/ \u5217\u51FA / \u67E5\u65E5\u5FD7");
|
|
5965
5851
|
functions.command("deploy").description(
|
|
5966
5852
|
"\u90E8\u7F72\u51FD\u6570\u76EE\u5F55\uFF08`adep deploy` \u7684\u547D\u4EE4\u65CF\u5165\u53E3\uFF1Bdir \u8986\u76D6 adep.config.ts \u7684 functionsDir\uFF09"
|
|
5967
5853
|
).argument("[dir]", "\u51FD\u6570\u76EE\u5F55\uFF08\u76F8\u5BF9\u9879\u76EE\u6839\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u7F3A\u7701\u53D6\u914D\u7F6E\u91CC\u7684 functionsDir\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (dir, flags) => {
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
} catch (error) {
|
|
5971
|
-
emitError(output, "functions deploy", jsonMode(), error);
|
|
5972
|
-
}
|
|
5854
|
+
const command = ctx.io("functions deploy");
|
|
5855
|
+
await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project, dir));
|
|
5973
5856
|
});
|
|
5974
5857
|
functions.command("list").description("\u5217\u51FA\u9879\u76EE\u4E0B\u7684\u4E91\u51FD\u6570\uFF08\u542B\u516C\u7F51\u8BBF\u95EE\u524D\u7F00\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
5975
|
-
|
|
5858
|
+
const command = ctx.io("functions list");
|
|
5859
|
+
await command.run(async () => {
|
|
5976
5860
|
const { functionsList: functionsList2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
5977
|
-
const result = await functionsList2(paths, {
|
|
5978
|
-
cwd,
|
|
5861
|
+
const result = await functionsList2(ctx.paths, {
|
|
5862
|
+
cwd: ctx.cwd,
|
|
5979
5863
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
5980
5864
|
});
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
}
|
|
5988
|
-
}
|
|
5989
|
-
} catch (error) {
|
|
5990
|
-
emitError(output, "functions list", jsonMode(), error);
|
|
5991
|
-
}
|
|
5865
|
+
command.ok(result, (data) => {
|
|
5866
|
+
const r = data;
|
|
5867
|
+
if (r.functions.length === 0) return "\uFF08\u8BE5\u9879\u76EE\u4E0B\u8FD8\u6CA1\u6709\u51FD\u6570\uFF09";
|
|
5868
|
+
return r.functions.map((fn) => `${fn.name} ${r.baseUrl}/${fn.name}`);
|
|
5869
|
+
});
|
|
5870
|
+
});
|
|
5992
5871
|
});
|
|
5993
5872
|
functions.command("logs").description("\u67E5\u8BE2\u51FD\u6570\u6700\u8FD1\u6267\u884C\u65E5\u5FD7\uFF08\u7F13\u51B2\u5728\u5E73\u53F0\u8FDB\u7A0B\u5185\uFF0C\u672A\u6267\u884C\u8FC7\u7684\u51FD\u6570\u4E3A\u7A7A\uFF09").argument("<name>", "\u51FD\u6570\u540D").option("--tail <count>", "\u53D6\u6700\u8FD1\u591A\u5C11\u6761\uFF08\u7F3A\u7701 100\uFF0C\u670D\u52A1\u7AEF\u6709\u4E0A\u9650\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (name, flags) => {
|
|
5994
|
-
|
|
5873
|
+
const command = ctx.io("functions logs");
|
|
5874
|
+
await command.run(async () => {
|
|
5995
5875
|
const { functionsLogs: functionsLogs2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
5996
5876
|
const tail = flags.tail === void 0 ? void 0 : Number(flags.tail);
|
|
5997
5877
|
if (tail !== void 0 && (!Number.isFinite(tail) || tail <= 0)) {
|
|
5998
5878
|
throw new CliError("INVALID_TAIL", `--tail \u987B\u4E3A\u6B63\u6574\u6570\uFF0C\u6536\u5230 "${flags.tail}"`);
|
|
5999
5879
|
}
|
|
6000
|
-
const result = await functionsLogs2(paths, {
|
|
6001
|
-
cwd,
|
|
5880
|
+
const result = await functionsLogs2(ctx.paths, {
|
|
5881
|
+
cwd: ctx.cwd,
|
|
6002
5882
|
name,
|
|
6003
5883
|
...tail === void 0 ? {} : { tail },
|
|
6004
5884
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6005
5885
|
});
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
output(`\uFF08\u51FD\u6570 ${name} \u6682\u65E0\u6267\u884C\u65E5\u5FD7\uFF1A\u5148\u7528 adep deploy \u53D1\u5E03\u5E76\u7ECF\u7F51\u5173\u6216\u8C03\u8BD5\u9762\u677F\u6267\u884C\u4E00\u6B21\uFF09`);
|
|
5886
|
+
command.ok(result, (data) => {
|
|
5887
|
+
const r = data;
|
|
5888
|
+
if (r.logs.length === 0) {
|
|
5889
|
+
return `\uFF08\u51FD\u6570 ${name} \u6682\u65E0\u6267\u884C\u65E5\u5FD7\uFF1A\u5148\u7528 adep deploy \u53D1\u5E03\u5E76\u7ECF\u7F51\u5173\u6216\u8C03\u8BD5\u9762\u677F\u6267\u884C\u4E00\u6B21\uFF09`;
|
|
6011
5890
|
}
|
|
6012
|
-
|
|
6013
|
-
}
|
|
6014
|
-
}
|
|
6015
|
-
emitError(output, "functions logs", jsonMode(), error);
|
|
6016
|
-
}
|
|
5891
|
+
return r.logs.map((log) => `${log.at} [${log.level}] ${log.message}`);
|
|
5892
|
+
});
|
|
5893
|
+
});
|
|
6017
5894
|
});
|
|
5895
|
+
}
|
|
5896
|
+
|
|
5897
|
+
// packages/cli/src/commands/mcp.ts
|
|
5898
|
+
function registerMcp(program2, ctx) {
|
|
6018
5899
|
const mcp = program2.command("mcp").description("MCP Tool\uFF1A\u628A\u4E91\u51FD\u6570\u53D1\u5E03\u4E3A\u5DE5\u5177 / \u53D6\u6D88\u53D1\u5E03 / \u5217\u51FA");
|
|
6019
5900
|
mcp.command("publish").description("\u53D1\u5E03\u4E91\u51FD\u6570\u4E3A\u9879\u76EE MCP Tool\uFF08Tool \u540D\u7F3A\u7701\u53D6\u51FD\u6570\u540D\uFF0C--name \u53EF\u8986\u76D6\uFF09").requiredOption("--function <fn>", "\u8981\u53D1\u5E03\u7684\u51FD\u6570\u540D").option("--name <tool>", "\u6CE8\u518C\u7684 Tool \u540D\uFF08\u7F3A\u7701\u53D6\u51FD\u6570\u540D\uFF09").option(
|
|
6020
5901
|
"--description <text>",
|
|
6021
5902
|
"\u8986\u76D6\u9762\u5411 Agent \u7684\u5DE5\u5177\u63CF\u8FF0\uFF08\u7F3A\u7701\u7528\u6E90\u7801 @description / \u63A8\u5BFC\u63CF\u8FF0\uFF09"
|
|
6022
5903
|
).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(
|
|
6023
5904
|
async (flags) => {
|
|
6024
|
-
|
|
5905
|
+
const command = ctx.io("mcp publish");
|
|
5906
|
+
await command.run(async () => {
|
|
6025
5907
|
const { mcpPublish: mcpPublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6026
|
-
const result = await mcpPublish2(paths, {
|
|
6027
|
-
cwd,
|
|
5908
|
+
const result = await mcpPublish2(ctx.paths, {
|
|
5909
|
+
cwd: ctx.cwd,
|
|
6028
5910
|
fn: flags.function,
|
|
6029
5911
|
...flags.name === void 0 ? {} : { toolName: flags.name },
|
|
6030
5912
|
...flags.description === void 0 ? {} : { description: flags.description },
|
|
6031
5913
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6032
5914
|
});
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
} catch (error) {
|
|
6039
|
-
emitError(output, "mcp publish", jsonMode(), error);
|
|
6040
|
-
}
|
|
5915
|
+
command.ok(result, (data) => {
|
|
5916
|
+
const r = data;
|
|
5917
|
+
return `\u2713 MCP tool published \xB7 ${r.tool.name}`;
|
|
5918
|
+
});
|
|
5919
|
+
});
|
|
6041
5920
|
}
|
|
6042
5921
|
);
|
|
6043
5922
|
mcp.command("unpublish").description("\u53D6\u6D88\u53D1\u5E03\u4E91\u51FD\u6570\u5BF9\u5E94\u7684 MCP Tool\uFF08\u7ACB\u5373\u4ECE\u9879\u76EE tools/list \u79FB\u9664\uFF09").requiredOption("--function <fn>", "\u51FD\u6570\u540D").option("--name <tool>", "\u5DF2\u6CE8\u518C\u7684 Tool \u540D\uFF08\u7F3A\u7701\u53D6\u51FD\u6570\u540D\uFF1B\u53D1\u5E03\u65F6\u7528\u4E86\u522B\u540D\u624D\u9700\u7ED9\u51FA\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6044
|
-
|
|
5923
|
+
const command = ctx.io("mcp unpublish");
|
|
5924
|
+
await command.run(async () => {
|
|
6045
5925
|
const { mcpUnpublish: mcpUnpublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6046
|
-
const result = await mcpUnpublish2(paths, {
|
|
6047
|
-
cwd,
|
|
5926
|
+
const result = await mcpUnpublish2(ctx.paths, {
|
|
5927
|
+
cwd: ctx.cwd,
|
|
6048
5928
|
fn: flags.function,
|
|
6049
5929
|
...flags.name === void 0 ? {} : { toolName: flags.name },
|
|
6050
5930
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6051
5931
|
});
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
output(`\uFF08\u9879\u76EE\u672A\u53D1\u5E03\u540D\u4E3A ${result.toolName} \u7684 MCP tool\uFF0C\u65E0\u9700\u53D6\u6D88\uFF09`);
|
|
6058
|
-
}
|
|
6059
|
-
} catch (error) {
|
|
6060
|
-
emitError(output, "mcp unpublish", jsonMode(), error);
|
|
6061
|
-
}
|
|
5932
|
+
command.ok(result, (data) => {
|
|
5933
|
+
const r = data;
|
|
5934
|
+
return r.removed ? `\u2713 MCP tool unpublished \xB7 ${r.toolName}` : `\uFF08\u9879\u76EE\u672A\u53D1\u5E03\u540D\u4E3A ${r.toolName} \u7684 MCP tool\uFF0C\u65E0\u9700\u53D6\u6D88\uFF09`;
|
|
5935
|
+
});
|
|
5936
|
+
});
|
|
6062
5937
|
});
|
|
6063
5938
|
mcp.command("list").description("\u5217\u51FA\u9879\u76EE\u5DF2\u53D1\u5E03\u7684 MCP Tool \u4E0E\u7AEF\u70B9\u5730\u5740\uFF08\u8BFB\u9879\u76EE /mcp \u7684 tools/list\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6064
|
-
|
|
5939
|
+
const command = ctx.io("mcp list");
|
|
5940
|
+
await command.run(async () => {
|
|
6065
5941
|
const { mcpList: mcpList2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6066
|
-
const result = await mcpList2(paths, {
|
|
6067
|
-
cwd,
|
|
5942
|
+
const result = await mcpList2(ctx.paths, {
|
|
5943
|
+
cwd: ctx.cwd,
|
|
6068
5944
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6069
5945
|
});
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
for (const tool of result.tools) {
|
|
6078
|
-
output(`${tool.name} ${tool.description ?? ""}`);
|
|
5946
|
+
command.ok(result, (data) => {
|
|
5947
|
+
const r = data;
|
|
5948
|
+
const lines = [`\u7AEF\u70B9\uFF1A${r.endpoint}`];
|
|
5949
|
+
if (r.tools.length === 0) {
|
|
5950
|
+
lines.push("\uFF08\u8FD8\u6CA1\u6709\u5DF2\u53D1\u5E03\u7684 MCP tool\uFF1Aadep mcp publish --function <fn>\uFF09");
|
|
5951
|
+
} else {
|
|
5952
|
+
for (const tool of r.tools) lines.push(`${tool.name} ${tool.description ?? ""}`);
|
|
6079
5953
|
}
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
}
|
|
5954
|
+
return lines;
|
|
5955
|
+
});
|
|
5956
|
+
});
|
|
6084
5957
|
});
|
|
5958
|
+
}
|
|
5959
|
+
|
|
5960
|
+
// packages/cli/src/commands/doctor.ts
|
|
5961
|
+
function registerDoctor(program2, ctx) {
|
|
6085
5962
|
program2.command("doctor").description("\u73AF\u5883\u81EA\u68C0\uFF1A\u51ED\u636E\u72B6\u6001 / \u5E73\u53F0\u53EF\u8FBE\u6027 / \u79BB\u7EBF\u53EF\u7528\u8303\u56F4\uFF08\u8865\u9F50\u65AD\u7F51\u6587\u6848\u5F15\u7528\u7684\u60AC\u7A7A\u547D\u4EE4\uFF09").action(async () => {
|
|
6086
|
-
|
|
5963
|
+
const command = ctx.io("doctor");
|
|
5964
|
+
await command.run(async () => {
|
|
6087
5965
|
const { runDoctor: runDoctor2, formatDoctorReport: formatDoctorReport2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
|
|
6088
|
-
const report = await runDoctor2(paths);
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
} else {
|
|
6092
|
-
for (const line of formatDoctorReport2(report)) output(line);
|
|
6093
|
-
}
|
|
6094
|
-
} catch (error) {
|
|
6095
|
-
emitError(output, "doctor", jsonMode(), error);
|
|
6096
|
-
}
|
|
5966
|
+
const report = await runDoctor2(ctx.paths);
|
|
5967
|
+
command.ok(report, () => formatDoctorReport2(report));
|
|
5968
|
+
});
|
|
6097
5969
|
});
|
|
5970
|
+
}
|
|
5971
|
+
|
|
5972
|
+
// packages/cli/src/commands/db.ts
|
|
5973
|
+
function registerDb(program2, ctx) {
|
|
6098
5974
|
const db = program2.command("db").description("\u9879\u76EE\u6570\u636E\u5E93\u7EF4\u62A4\uFF1A\u542F\u52A8 / \u72B6\u6001 / \u505C\u6B62 / SQL / \u5FEB\u7167 / \u56DE\u6EDA").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09");
|
|
6099
5975
|
db.command("start").description("\u542F\u52A8\u9879\u76EE\u6570\u636E\u5E93\uFF08\u5DF2\u5B58\u5728\u5219\u91CD\u65B0\u6FC0\u6D3B\uFF0C\u4E0D\u91CD\u5EFA\u6570\u636E\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6100
|
-
|
|
5976
|
+
const command = ctx.io("db start");
|
|
5977
|
+
await command.run(async () => {
|
|
6101
5978
|
const { dbStart: dbStart2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
6102
|
-
const result = await dbStart2(paths, {
|
|
6103
|
-
cwd,
|
|
5979
|
+
const result = await dbStart2(ctx.paths, {
|
|
5980
|
+
cwd: ctx.cwd,
|
|
6104
5981
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6105
5982
|
});
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
);
|
|
6112
|
-
}
|
|
6113
|
-
} catch (error) {
|
|
6114
|
-
emitError(output, "db start", jsonMode(), error);
|
|
6115
|
-
}
|
|
5983
|
+
command.ok(result, (data) => {
|
|
5984
|
+
const r = data;
|
|
5985
|
+
return `\u6570\u636E\u5E93\u5DF2\u5C31\u7EEA\uFF1A${r.projectId}\uFF08${r.journalMode}\uFF0C${r.usage.tableCount} \u8868 / ${r.usage.rowCount} \u884C / ${formatBytes(r.usage.sizeBytes)}\uFF09`;
|
|
5986
|
+
});
|
|
5987
|
+
});
|
|
6116
5988
|
});
|
|
6117
5989
|
db.command("status").description("\u67E5\u8BE2\u9879\u76EE\u6570\u636E\u5E93\u72B6\u6001\u4E0E\u7528\u91CF\uFF08\u4F53\u79EF / \u8868\u6570 / \u884C\u6570\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6118
|
-
|
|
5990
|
+
const command = ctx.io("db status");
|
|
5991
|
+
await command.run(async () => {
|
|
6119
5992
|
const { dbStatus: dbStatus2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
6120
|
-
const result = await dbStatus2(paths, {
|
|
6121
|
-
cwd,
|
|
5993
|
+
const result = await dbStatus2(ctx.paths, {
|
|
5994
|
+
cwd: ctx.cwd,
|
|
6122
5995
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6123
5996
|
});
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
);
|
|
6130
|
-
}
|
|
6131
|
-
} catch (error) {
|
|
6132
|
-
emitError(output, "db status", jsonMode(), error);
|
|
6133
|
-
}
|
|
5997
|
+
command.ok(result, (data) => {
|
|
5998
|
+
const r = data;
|
|
5999
|
+
return `\u72B6\u6001\uFF1A${r.status}\uFF08${r.projectId}\uFF0C${r.usage.tableCount} \u8868 / ${r.usage.rowCount} \u884C / ${formatBytes(r.usage.sizeBytes)}\uFF09`;
|
|
6000
|
+
});
|
|
6001
|
+
});
|
|
6134
6002
|
});
|
|
6135
6003
|
db.command("stop").description("\u505C\u6B62\u9879\u76EE\u6570\u636E\u5E93\uFF08\u8FDE\u63A5\u5173\u95ED\u5E76\u6807\u8BB0\uFF1B\u6587\u4EF6\u4FDD\u7559\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6136
|
-
|
|
6004
|
+
const command = ctx.io("db stop");
|
|
6005
|
+
await command.run(async () => {
|
|
6137
6006
|
const { dbStop: dbStop2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
6138
|
-
const result = await dbStop2(paths, {
|
|
6139
|
-
cwd,
|
|
6007
|
+
const result = await dbStop2(ctx.paths, {
|
|
6008
|
+
cwd: ctx.cwd,
|
|
6140
6009
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6141
6010
|
});
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
} else {
|
|
6145
|
-
output(`\u6570\u636E\u5E93\u5DF2\u505C\u6B62\uFF1A${result.status}`);
|
|
6146
|
-
}
|
|
6147
|
-
} catch (error) {
|
|
6148
|
-
emitError(output, "db stop", jsonMode(), error);
|
|
6149
|
-
}
|
|
6011
|
+
command.ok(result, (data) => `\u6570\u636E\u5E93\u5DF2\u505C\u6B62\uFF1A${data.status}`);
|
|
6012
|
+
});
|
|
6150
6013
|
});
|
|
6151
6014
|
db.command("exec").description("\u6267\u884C\u5355\u6761 SQL\uFF08\u5199 / \u7834\u574F\u6027\u8BED\u53E5\u9700 --confirm-table \u4E8C\u6B21\u786E\u8BA4\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").requiredOption("--sql <sql>", "\u5F85\u6267\u884C SQL").option("--confirm-table <table>", "\u7834\u574F\u6027\u64CD\u4F5C\u7684\u76EE\u6807\u8868\u540D\uFF08\u4E8C\u6B21\u786E\u8BA4\uFF09").action(async (flags) => {
|
|
6152
|
-
|
|
6015
|
+
const command = ctx.io("db exec");
|
|
6016
|
+
await command.run(async () => {
|
|
6153
6017
|
const { dbExec: dbExec2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
6154
|
-
const result = await dbExec2(paths, {
|
|
6155
|
-
cwd,
|
|
6018
|
+
const result = await dbExec2(ctx.paths, {
|
|
6019
|
+
cwd: ctx.cwd,
|
|
6156
6020
|
sql: flags.sql,
|
|
6157
6021
|
...flags.project === void 0 ? {} : { slug: flags.project },
|
|
6158
6022
|
...flags.confirmTable === void 0 ? {} : { confirmTable: flags.confirmTable }
|
|
6159
6023
|
});
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
if (
|
|
6164
|
-
|
|
6165
|
-
if (
|
|
6166
|
-
} else if (
|
|
6167
|
-
|
|
6024
|
+
command.ok(result, (data) => {
|
|
6025
|
+
const r = data;
|
|
6026
|
+
const lines = [];
|
|
6027
|
+
if (r.columns.length > 0) {
|
|
6028
|
+
lines.push(formatTable(r.columns, r.rows));
|
|
6029
|
+
if (r.truncated) lines.push(`\uFF08\u7ED3\u679C\u5DF2\u622A\u65AD\u5230 ${r.rows.length} \u884C\uFF09`);
|
|
6030
|
+
} else if (r.changes > 0) {
|
|
6031
|
+
lines.push(`${r.changes} \u884C\u53D7\u5F71\u54CD`);
|
|
6168
6032
|
} else {
|
|
6169
|
-
|
|
6033
|
+
lines.push("\u8BED\u53E5\u6267\u884C\u6210\u529F\uFF08\u65E0\u8FD4\u56DE\u884C\uFF09");
|
|
6170
6034
|
}
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
}
|
|
6035
|
+
lines.push(`\u8017\u65F6 ${r.elapsedMs}ms`);
|
|
6036
|
+
return lines;
|
|
6037
|
+
});
|
|
6038
|
+
});
|
|
6176
6039
|
});
|
|
6177
6040
|
const snapshot = db.command("snapshot").description("\u6570\u636E\u5E93\u5FEB\u7167\uFF08\u4ED8\u8D39\u6863\u4F4D\uFF09\uFF1A\u5217\u51FA\uFF08\u7F3A\u7701\uFF09/ \u521B\u5EFA / \u8FD8\u539F");
|
|
6178
6041
|
snapshot.command("list").description("\u5217\u51FA\u9879\u76EE\u6570\u636E\u5E93\u5FEB\u7167\uFF08\u6309\u521B\u5EFA\u65F6\u95F4\u5012\u5E8F\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6179
|
-
|
|
6042
|
+
const command = ctx.io("db snapshot list");
|
|
6043
|
+
await command.run(async () => {
|
|
6180
6044
|
const { dbSnapshotList: dbSnapshotList2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
6181
|
-
const result = await dbSnapshotList2(paths, {
|
|
6182
|
-
cwd,
|
|
6045
|
+
const result = await dbSnapshotList2(ctx.paths, {
|
|
6046
|
+
cwd: ctx.cwd,
|
|
6183
6047
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6184
6048
|
});
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
`${snap.id} ${snap.type} ${snap.plan} ${formatBytes(snap.sizeBytes)} ${snap.createdAt}`
|
|
6194
|
-
);
|
|
6195
|
-
}
|
|
6196
|
-
}
|
|
6197
|
-
} catch (error) {
|
|
6198
|
-
emitError(output, "db snapshot list", jsonMode(), error);
|
|
6199
|
-
}
|
|
6049
|
+
command.ok(result, (data) => {
|
|
6050
|
+
const r = data;
|
|
6051
|
+
if (r.snapshots.length === 0) return "\u6682\u65E0\u5FEB\u7167";
|
|
6052
|
+
return r.snapshots.map(
|
|
6053
|
+
(snap) => `${snap.id} ${snap.type} ${snap.plan} ${formatBytes(snap.sizeBytes)} ${snap.createdAt}`
|
|
6054
|
+
);
|
|
6055
|
+
});
|
|
6056
|
+
});
|
|
6200
6057
|
});
|
|
6201
6058
|
snapshot.command("create").description("\u521B\u5EFA\u624B\u52A8\u6570\u636E\u5E93\u5FEB\u7167\uFF08\u514D\u8D39\u7248\u5E73\u53F0\u8FD4\u56DE 403 \u6743\u76CA\u672A\u5F00\u653E\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6202
|
-
|
|
6059
|
+
const command = ctx.io("db snapshot create");
|
|
6060
|
+
await command.run(async () => {
|
|
6203
6061
|
const { dbSnapshotCreate: dbSnapshotCreate2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
6204
|
-
const result = await dbSnapshotCreate2(paths, {
|
|
6205
|
-
cwd,
|
|
6062
|
+
const result = await dbSnapshotCreate2(ctx.paths, {
|
|
6063
|
+
cwd: ctx.cwd,
|
|
6206
6064
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6207
6065
|
});
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
} catch (error) {
|
|
6214
|
-
emitError(output, "db snapshot create", jsonMode(), error);
|
|
6215
|
-
}
|
|
6066
|
+
command.ok(result, (data) => {
|
|
6067
|
+
const r = data;
|
|
6068
|
+
return `\u5FEB\u7167\u5DF2\u521B\u5EFA\uFF1A${r.id}\uFF08${r.plan}\uFF0C${formatBytes(r.sizeBytes)}\uFF09`;
|
|
6069
|
+
});
|
|
6070
|
+
});
|
|
6216
6071
|
});
|
|
6217
6072
|
snapshot.command("restore").description("\u6574\u4F53\u8FD8\u539F\u6570\u636E\u5E93\u5230\u5FEB\u7167\u65F6\u523B\uFF08\u4ED8\u8D39\u6863\u4F4D\uFF09").argument("<snapshotId>", "\u5FEB\u7167 id").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (snapshotId, flags) => {
|
|
6218
|
-
|
|
6073
|
+
const command = ctx.io("db snapshot restore");
|
|
6074
|
+
await command.run(async () => {
|
|
6219
6075
|
const { dbSnapshotRestore: dbSnapshotRestore2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
6220
|
-
const result = await dbSnapshotRestore2(paths, {
|
|
6221
|
-
cwd,
|
|
6076
|
+
const result = await dbSnapshotRestore2(ctx.paths, {
|
|
6077
|
+
cwd: ctx.cwd,
|
|
6222
6078
|
snapshotId,
|
|
6223
6079
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6224
6080
|
});
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
} else {
|
|
6228
|
-
output(`\u5DF2\u8FD8\u539F\u5230\u5FEB\u7167 ${result.snapshotId}`);
|
|
6229
|
-
}
|
|
6230
|
-
} catch (error) {
|
|
6231
|
-
emitError(output, "db snapshot restore", jsonMode(), error);
|
|
6232
|
-
}
|
|
6081
|
+
command.ok(result, (data) => `\u5DF2\u8FD8\u539F\u5230\u5FEB\u7167 ${data.snapshotId}`);
|
|
6082
|
+
});
|
|
6233
6083
|
});
|
|
6234
6084
|
db.command("rollback").description("\u65F6\u95F4\u70B9\u56DE\u6EDA\u5230\u6307\u5B9A\u65F6\u523B\uFF08\u56E2\u961F\u7248\uFF1B\u57FA\u4E8E\u53D8\u66F4\u6D41\u91CD\u653E\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").requiredOption("--to <iso-time>", "\u56DE\u6EDA\u76EE\u6807\u65F6\u523B\uFF08ISO 8601\uFF09").action(async (flags) => {
|
|
6235
|
-
|
|
6085
|
+
const command = ctx.io("db rollback");
|
|
6086
|
+
await command.run(async () => {
|
|
6236
6087
|
const { dbRollback: dbRollback2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
6237
|
-
const result = await dbRollback2(paths, {
|
|
6238
|
-
cwd,
|
|
6088
|
+
const result = await dbRollback2(ctx.paths, {
|
|
6089
|
+
cwd: ctx.cwd,
|
|
6239
6090
|
to: flags.to,
|
|
6240
6091
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6241
6092
|
});
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
} catch (error) {
|
|
6248
|
-
emitError(output, "db rollback", jsonMode(), error);
|
|
6249
|
-
}
|
|
6093
|
+
command.ok(result, (data) => {
|
|
6094
|
+
const r = data;
|
|
6095
|
+
return `\u5DF2\u56DE\u6EDA\u5230 ${r.to}\uFF08\u91CD\u653E ${r.reverted} \u6761\u53D8\u66F4\uFF09`;
|
|
6096
|
+
});
|
|
6097
|
+
});
|
|
6250
6098
|
});
|
|
6099
|
+
}
|
|
6100
|
+
|
|
6101
|
+
// packages/cli/src/commands/storage.ts
|
|
6102
|
+
function registerStorage(program2, ctx) {
|
|
6251
6103
|
const storage = program2.command("storage").description("\u4E91\u5B58\u50A8 / \u6587\u4EF6\u5B58\u50A8\uFF1A\u4E0A\u4F20 / \u4E0B\u8F7D / \u5217\u8868 / \u5220\u9664").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09");
|
|
6252
6104
|
storage.command("upload").description("\u4E0A\u4F20\u5355\u4E2A\u6587\u4EF6\uFF08multipart\uFF1B\u5355\u6587\u4EF6 \u2264 50MB\uFF09").argument("<file>", "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84").requiredOption("--path <remote-path>", "\u6876\u5185\u76EE\u6807\u8DEF\u5F84\uFF08\u5982 avatars/a.png\uFF09").option(
|
|
6253
6105
|
"--visibility <public|private>",
|
|
6254
6106
|
"public \u76F4\u8FDE / private \u7B7E\u540D\uFF08\u7F3A\u7701 private\uFF09",
|
|
6255
6107
|
"private"
|
|
6256
6108
|
).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (file, flags) => {
|
|
6257
|
-
|
|
6109
|
+
const command = ctx.io("storage upload");
|
|
6110
|
+
await command.run(async () => {
|
|
6258
6111
|
const { storageUpload: storageUpload2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
|
|
6259
|
-
const result = await storageUpload2(paths, {
|
|
6260
|
-
cwd,
|
|
6112
|
+
const result = await storageUpload2(ctx.paths, {
|
|
6113
|
+
cwd: ctx.cwd,
|
|
6261
6114
|
file,
|
|
6262
6115
|
path: flags.path,
|
|
6263
6116
|
visibility: flags.visibility === "public" ? "public" : "private",
|
|
6264
6117
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6265
6118
|
});
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
}
|
|
6272
|
-
}
|
|
6273
|
-
emitError(output, "storage upload", jsonMode(), error);
|
|
6274
|
-
}
|
|
6119
|
+
command.ok(result, (data) => {
|
|
6120
|
+
const r = data;
|
|
6121
|
+
const lines = [`\u5DF2\u4E0A\u4F20 ${r.path}\uFF08${r.visibility}\uFF0C${formatBytes(r.size)}\uFF09`];
|
|
6122
|
+
if (r.signedUrl !== void 0) lines.push(`\u7B7E\u540D URL\uFF1A${r.signedUrl}`);
|
|
6123
|
+
return lines;
|
|
6124
|
+
});
|
|
6125
|
+
});
|
|
6275
6126
|
});
|
|
6276
6127
|
storage.command("download").description("\u4E0B\u8F7D\u6587\u4EF6\u5230\u672C\u5730\uFF08public \u76F4\u8FDE / private \u7B7E\u540D URL\uFF09").argument("<remote-path>", "\u6876\u5185\u6587\u4EF6\u8DEF\u5F84").option("-o, --output <file>", "\u672C\u5730\u8F93\u51FA\u8DEF\u5F84\uFF08\u7F3A\u7701\u5199\u5230 cwd\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (remotePath, flags) => {
|
|
6277
|
-
|
|
6128
|
+
const command = ctx.io("storage download");
|
|
6129
|
+
await command.run(async () => {
|
|
6278
6130
|
const { storageDownload: storageDownload2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
|
|
6279
|
-
const result = await storageDownload2(paths, {
|
|
6280
|
-
cwd,
|
|
6131
|
+
const result = await storageDownload2(ctx.paths, {
|
|
6132
|
+
cwd: ctx.cwd,
|
|
6281
6133
|
path: remotePath,
|
|
6282
6134
|
...flags.output === void 0 ? {} : { output: flags.output },
|
|
6283
6135
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6284
6136
|
});
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
} catch (error) {
|
|
6291
|
-
emitError(output, "storage download", jsonMode(), error);
|
|
6292
|
-
}
|
|
6137
|
+
command.ok(result, (data) => {
|
|
6138
|
+
const r = data;
|
|
6139
|
+
return `\u5DF2\u4E0B\u8F7D ${r.path} \u2192 ${r.output}\uFF08${formatBytes(r.size)}\uFF09`;
|
|
6140
|
+
});
|
|
6141
|
+
});
|
|
6293
6142
|
});
|
|
6294
6143
|
storage.command("ls").description("\u5217\u51FA\u9879\u76EE\u6587\u4EF6\uFF08\u6309\u524D\u7F00\u8FC7\u6EE4\uFF1Bpublic \u9644\u76F4\u8FDE url\u3001private \u9644\u7B7E\u540D url\uFF09").option("--prefix <prefix>", "\u6309\u524D\u7F00\u8FC7\u6EE4").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6295
|
-
|
|
6144
|
+
const command = ctx.io("storage ls");
|
|
6145
|
+
await command.run(async () => {
|
|
6296
6146
|
const { storageList: storageList2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
|
|
6297
|
-
const result = await storageList2(paths, {
|
|
6298
|
-
cwd,
|
|
6147
|
+
const result = await storageList2(ctx.paths, {
|
|
6148
|
+
cwd: ctx.cwd,
|
|
6299
6149
|
...flags.prefix === void 0 ? {} : { prefix: flags.prefix },
|
|
6300
6150
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6301
6151
|
});
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
`${file.path} ${file.visibility} ${formatBytes(file.size)} ${file.url ?? file.signedUrl ?? ""}`
|
|
6311
|
-
);
|
|
6312
|
-
}
|
|
6313
|
-
}
|
|
6314
|
-
} catch (error) {
|
|
6315
|
-
emitError(output, "storage ls", jsonMode(), error);
|
|
6316
|
-
}
|
|
6152
|
+
command.ok(result, (data) => {
|
|
6153
|
+
const r = data;
|
|
6154
|
+
if (r.files.length === 0) return "\uFF08\u65E0\u6587\u4EF6\uFF09";
|
|
6155
|
+
return r.files.map(
|
|
6156
|
+
(file) => `${file.path} ${file.visibility} ${formatBytes(file.size)} ${file.url ?? file.signedUrl ?? ""}`
|
|
6157
|
+
);
|
|
6158
|
+
});
|
|
6159
|
+
});
|
|
6317
6160
|
});
|
|
6318
6161
|
storage.command("rm").description("\u5220\u9664\u6587\u4EF6\uFF08\u4EC5\u9879\u76EE\u6240\u6709\u8005\uFF09").argument("<remote-path>", "\u6876\u5185\u6587\u4EF6\u8DEF\u5F84").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (remotePath, flags) => {
|
|
6319
|
-
|
|
6162
|
+
const command = ctx.io("storage rm");
|
|
6163
|
+
await command.run(async () => {
|
|
6320
6164
|
const { storageRemove: storageRemove2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
|
|
6321
|
-
const result = await storageRemove2(paths, {
|
|
6322
|
-
cwd,
|
|
6165
|
+
const result = await storageRemove2(ctx.paths, {
|
|
6166
|
+
cwd: ctx.cwd,
|
|
6323
6167
|
path: remotePath,
|
|
6324
6168
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6325
6169
|
});
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
} else {
|
|
6329
|
-
output(`\u5DF2\u5220\u9664 ${remotePath}`);
|
|
6330
|
-
}
|
|
6331
|
-
} catch (error) {
|
|
6332
|
-
emitError(output, "storage rm", jsonMode(), error);
|
|
6333
|
-
}
|
|
6170
|
+
command.ok(result, () => `\u5DF2\u5220\u9664 ${remotePath}`);
|
|
6171
|
+
});
|
|
6334
6172
|
});
|
|
6173
|
+
}
|
|
6174
|
+
|
|
6175
|
+
// packages/cli/src/commands/hosting.ts
|
|
6176
|
+
init_auth();
|
|
6177
|
+
function parseBool(raw) {
|
|
6178
|
+
if (raw === void 0) return void 0;
|
|
6179
|
+
if (raw === "true") return true;
|
|
6180
|
+
if (raw === "false") return false;
|
|
6181
|
+
throw new CliError("INVALID_BOOLEAN", `\u5E03\u5C14\u53C2\u6570\u987B\u4E3A true \u6216 false\uFF0C\u6536\u5230 "${raw}"`);
|
|
6182
|
+
}
|
|
6183
|
+
function registerHosting(program2, ctx) {
|
|
6335
6184
|
const hosting = program2.command("hosting").description("\u9759\u6001\u6258\u7BA1\uFF1A\u67E5\u770B / \u90E8\u7F72 / \u62C9\u53D6 / \u914D\u7F6E").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09");
|
|
6336
6185
|
hosting.command("info").description("\u67E5\u770B\u9759\u6001\u6258\u7BA1\u914D\u7F6E\u3001\u7AD9\u70B9\u5730\u5740\u4E0E\u6587\u4EF6\u6811").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6337
|
-
|
|
6186
|
+
const command = ctx.io("hosting info");
|
|
6187
|
+
await command.run(async () => {
|
|
6338
6188
|
const { hostingInfo: hostingInfo2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
|
|
6339
|
-
const result = await hostingInfo2(paths, {
|
|
6340
|
-
cwd,
|
|
6189
|
+
const result = await hostingInfo2(ctx.paths, {
|
|
6190
|
+
cwd: ctx.cwd,
|
|
6341
6191
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6342
6192
|
});
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
);
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
}
|
|
6353
|
-
} catch (error) {
|
|
6354
|
-
emitError(output, "hosting info", jsonMode(), error);
|
|
6355
|
-
}
|
|
6193
|
+
command.ok(result, (data) => {
|
|
6194
|
+
const r = data;
|
|
6195
|
+
const lines = [
|
|
6196
|
+
`\u7AD9\u70B9\uFF1A${r.siteUrl}\uFF08\u6258\u7BA1 ${r.config.enabled ? "\u5F00" : "\u5173"}\uFF0CSPA \u56DE\u9000 ${r.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`
|
|
6197
|
+
];
|
|
6198
|
+
for (const file of r.files) lines.push(`${file.path} ${formatBytes(file.size)}`);
|
|
6199
|
+
return lines;
|
|
6200
|
+
});
|
|
6201
|
+
});
|
|
6356
6202
|
});
|
|
6357
6203
|
hosting.command("deploy").description("\u90E8\u7F72\u672C\u5730\u76EE\u5F55\u4E3A\u9759\u6001\u7AD9\u70B9\uFF1A\u9012\u5F52\u4E0A\u4F20\u5230 site/ \u5E76\u6253\u5F00\u6258\u7BA1").argument("<dir>", "\u672C\u5730\u7AD9\u70B9\u76EE\u5F55").option("--spa", "\u6253\u5F00\u6258\u7BA1\u5E76\u542F\u7528 SPA \u56DE\u9000\uFF08\u7F3A\u7701\u4EC5\u6253\u5F00\u6258\u7BA1\uFF09", false).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (dir, flags) => {
|
|
6358
|
-
|
|
6204
|
+
const command = ctx.io("hosting deploy");
|
|
6205
|
+
await command.run(async () => {
|
|
6359
6206
|
const { hostingDeploy: hostingDeploy2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
|
|
6360
|
-
const result = await hostingDeploy2(paths, {
|
|
6361
|
-
cwd,
|
|
6207
|
+
const result = await hostingDeploy2(ctx.paths, {
|
|
6208
|
+
cwd: ctx.cwd,
|
|
6362
6209
|
dir,
|
|
6363
6210
|
...flags.spa === true ? { spa: true } : {},
|
|
6364
6211
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6365
6212
|
});
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
);
|
|
6372
|
-
}
|
|
6373
|
-
} catch (error) {
|
|
6374
|
-
emitError(output, "hosting deploy", jsonMode(), error);
|
|
6375
|
-
}
|
|
6213
|
+
command.ok(result, (data) => {
|
|
6214
|
+
const r = data;
|
|
6215
|
+
return `\u7AD9\u70B9\u5DF2\u4E0A\u7EBF\uFF1A${r.siteUrl}\uFF08${r.uploaded.length} \u4E2A\u6587\u4EF6\uFF0CSPA \u56DE\u9000 ${r.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`;
|
|
6216
|
+
});
|
|
6217
|
+
});
|
|
6376
6218
|
});
|
|
6377
6219
|
hosting.command("pull").description("\u62C9\u53D6\u7AD9\u70B9\u516C\u5F00\u6587\u4EF6\u5230\u672C\u5730\u76EE\u5F55\uFF08\u8DF3\u8FC7\u6258\u7BA1\u914D\u7F6E\uFF09").option("-o, --output <dir>", "\u672C\u5730\u8F93\u51FA\u76EE\u5F55\uFF08\u7F3A\u7701\u5199\u5230 cwd\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6378
|
-
|
|
6220
|
+
const command = ctx.io("hosting pull");
|
|
6221
|
+
await command.run(async () => {
|
|
6379
6222
|
const { hostingPull: hostingPull2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
|
|
6380
|
-
const result = await hostingPull2(paths, {
|
|
6381
|
-
cwd,
|
|
6223
|
+
const result = await hostingPull2(ctx.paths, {
|
|
6224
|
+
cwd: ctx.cwd,
|
|
6382
6225
|
...flags.output === void 0 ? {} : { output: flags.output },
|
|
6383
6226
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6384
6227
|
});
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
);
|
|
6391
|
-
}
|
|
6392
|
-
} catch (error) {
|
|
6393
|
-
emitError(output, "hosting pull", jsonMode(), error);
|
|
6394
|
-
}
|
|
6228
|
+
command.ok(result, (data) => {
|
|
6229
|
+
const r = data;
|
|
6230
|
+
return `\u5DF2\u62C9\u53D6 ${r.files.length} \u4E2A\u6587\u4EF6 \u2192 ${r.outputDir}\uFF08\u7AD9\u70B9\uFF1A${r.siteUrl}\uFF09`;
|
|
6231
|
+
});
|
|
6232
|
+
});
|
|
6395
6233
|
});
|
|
6396
6234
|
hosting.command("config").description("\u66F4\u65B0\u9759\u6001\u6258\u7BA1\u914D\u7F6E\uFF08\u6258\u7BA1\u5F00\u5173 / SPA \u56DE\u9000\u6A21\u5F0F\uFF0C\u5E42\u7B49\uFF09").option("--enabled <true|false>", "\u6258\u7BA1\u5F00\u5173").option("--spa <true|false>", "SPA \u56DE\u9000\u6A21\u5F0F").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6397
|
-
|
|
6235
|
+
const command = ctx.io("hosting config");
|
|
6236
|
+
await command.run(async () => {
|
|
6398
6237
|
const { hostingConfig: hostingConfig2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
|
|
6399
6238
|
const enabled = parseBool(flags.enabled);
|
|
6400
6239
|
const spa = parseBool(flags.spa);
|
|
6401
|
-
const config = await hostingConfig2(paths, {
|
|
6402
|
-
cwd,
|
|
6240
|
+
const config = await hostingConfig2(ctx.paths, {
|
|
6241
|
+
cwd: ctx.cwd,
|
|
6403
6242
|
...enabled === void 0 ? {} : { enabled },
|
|
6404
6243
|
...spa === void 0 ? {} : { spa },
|
|
6405
6244
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6406
6245
|
});
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
} catch (error) {
|
|
6413
|
-
emitError(output, "hosting config", jsonMode(), error);
|
|
6414
|
-
}
|
|
6246
|
+
command.ok({ config }, (data) => {
|
|
6247
|
+
const c = data.config;
|
|
6248
|
+
return `\u6258\u7BA1 ${c.enabled ? "\u5F00" : "\u5173"}\uFF0CSPA \u56DE\u9000 ${c.spaMode ? "\u5F00" : "\u5173"}`;
|
|
6249
|
+
});
|
|
6250
|
+
});
|
|
6415
6251
|
});
|
|
6252
|
+
}
|
|
6253
|
+
|
|
6254
|
+
// packages/cli/src/commands/export.ts
|
|
6255
|
+
function registerExport(program2, ctx) {
|
|
6416
6256
|
program2.command("export").description("\u5BFC\u51FA\u81EA\u6258\u7BA1\u90E8\u7F72\u5305\uFF1A\u89E6\u53D1\u957F\u4EFB\u52A1 \u2192 \u8F6E\u8BE2\u8FDB\u5EA6 \u2192 \u4E0B\u8F7D zip \u2192 manifest \u9010\u9879\u81EA\u68C0").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").option("--with-data", "\u5305\u542B\u6570\u636E\u5E93\u884C\u6570\u636E\uFF08\u7F3A\u7701\u4EC5 schema\uFF09").option("--with-source", "\u5305\u542B\u51FD\u6570\u6E90\u7801\uFF08\u7F3A\u7701\u5E73\u53F0\u5DF2\u542B\uFF0C\u663E\u5F0F\u7F6E\u6B64\u4E0D\u6539\u53D8\u9ED8\u8BA4\uFF09").option("--out <dir>", "\u8F93\u51FA\u76EE\u5F55\uFF08\u7F3A\u7701 ./exports\uFF09").action(
|
|
6417
6257
|
async (flags) => {
|
|
6418
|
-
|
|
6258
|
+
const command = ctx.io("export");
|
|
6259
|
+
await command.run(async () => {
|
|
6419
6260
|
const { createExportApiClient: createExportApiClient2 } = await Promise.resolve().then(() => (init_client2(), client_exports2));
|
|
6420
6261
|
const { createExportFileSystem: createExportFileSystem2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
6421
6262
|
const { ExportCommand: ExportCommand2 } = await Promise.resolve().then(() => (init_command(), command_exports));
|
|
6422
6263
|
const { resolveSlug: resolveSlug2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
6423
|
-
const project2 = await resolveSlug2(cwd, flags.project);
|
|
6424
|
-
const apiClient = await createExportApiClient2(paths);
|
|
6425
|
-
const
|
|
6426
|
-
const result = await
|
|
6264
|
+
const project2 = await resolveSlug2(ctx.cwd, flags.project);
|
|
6265
|
+
const apiClient = await createExportApiClient2(ctx.paths);
|
|
6266
|
+
const exportCommand = new ExportCommand2(apiClient, createExportFileSystem2());
|
|
6267
|
+
const result = await exportCommand.execute({
|
|
6427
6268
|
project: project2,
|
|
6428
6269
|
...flags.withData === true ? { withData: true } : {},
|
|
6429
6270
|
...flags.withSource === true ? { withSource: true } : {},
|
|
6430
6271
|
...flags.out === void 0 ? {} : { out: flags.out },
|
|
6431
|
-
json:
|
|
6272
|
+
json: command.json
|
|
6432
6273
|
});
|
|
6433
|
-
if (
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
} else {
|
|
6437
|
-
output(
|
|
6438
|
-
JSON.stringify({
|
|
6439
|
-
ok: false,
|
|
6440
|
-
command: "export",
|
|
6441
|
-
error: { code: "EXPORT_FAILED", message: result.error ?? "\u5BFC\u51FA\u5931\u8D25" }
|
|
6442
|
-
})
|
|
6443
|
-
);
|
|
6444
|
-
process.exitCode = 1;
|
|
6445
|
-
}
|
|
6446
|
-
} else if (!result.success) {
|
|
6447
|
-
output(`\u9519\u8BEF\uFF1A${result.error ?? "\u5BFC\u51FA\u5931\u8D25"}`);
|
|
6448
|
-
process.exitCode = 1;
|
|
6274
|
+
if (!result.success) {
|
|
6275
|
+
command.fail("EXPORT_FAILED", result.error ?? "\u5BFC\u51FA\u5931\u8D25");
|
|
6276
|
+
return;
|
|
6449
6277
|
}
|
|
6450
|
-
|
|
6451
|
-
emitError(output, "export", jsonMode(), error);
|
|
6452
|
-
}
|
|
6453
|
-
}
|
|
6454
|
-
);
|
|
6455
|
-
const widget = program2.command("widget").description("\u5FAE\u524D\u7AEF\u7EC4\u4EF6\uFF08widget\uFF09\uFF1A\u811A\u624B\u67B6 / \u672C\u5730\u6C99\u7BB1 / \u53D1\u5E03");
|
|
6456
|
-
widget.command("init").description("\u521D\u59CB\u5316 widget \u5DE5\u7A0B\uFF08\u6A21\u677F\uFF1Avue3-ts / react-ts\uFF09").argument("<name>", "widget \u540D\u79F0\uFF08\u5C0F\u5199\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u8FDE\u5B57\u7B26\uFF09").option("-t, --template <template>", "\u6A21\u677F\uFF1Avue3-ts | react-ts", "vue3-ts").action(async (name, flags) => {
|
|
6457
|
-
try {
|
|
6458
|
-
const { initWidget: initWidget2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
6459
|
-
const result = await initWidget2(cwd, name, flags.template);
|
|
6460
|
-
if (jsonMode()) {
|
|
6461
|
-
output(JSON.stringify({ ok: true, command: "widget init", data: result }));
|
|
6462
|
-
} else {
|
|
6463
|
-
output(`\u5DF2\u521B\u5EFA widget ${result.projectPath}`);
|
|
6464
|
-
}
|
|
6465
|
-
} catch (error) {
|
|
6466
|
-
emitError(output, "widget init", jsonMode(), error);
|
|
6467
|
-
}
|
|
6468
|
-
});
|
|
6469
|
-
widget.command("dev").description("\u672C\u5730\u5BBF\u4E3B\u6C99\u7BB1\uFF1A\u4E3B\u9898\u53D8\u91CF + mock props + token \u6CE8\u5165 + \u70ED\u66F4\u65B0").option("-p, --port <port>", "\u76D1\u542C\u7AEF\u53E3\uFF08\u7F3A\u7701 8788\uFF09", "8788").action(async (flags) => {
|
|
6470
|
-
try {
|
|
6471
|
-
const { startWidgetDev: startWidgetDev2 } = await Promise.resolve().then(() => (init_dev2(), dev_exports2));
|
|
6472
|
-
const started = await startWidgetDev2({ cwd, port: Number(flags.port ?? "8788") });
|
|
6473
|
-
output(
|
|
6474
|
-
`[adep] widget dev sandbox on ${started.baseUrl}\uFF08?token=<...> \u6CE8\u5165\u9274\u6743 token\uFF1BCtrl-C \u9000\u51FA\uFF09`
|
|
6475
|
-
);
|
|
6476
|
-
await new Promise(() => void 0);
|
|
6477
|
-
} catch (error) {
|
|
6478
|
-
emitError(output, "widget dev", jsonMode(), error);
|
|
6479
|
-
}
|
|
6480
|
-
});
|
|
6481
|
-
widget.command("publish").description("\u6309\u6846\u67B6\u6784\u5EFA \u2192 \u4E0A\u4F20\u5E73\u53F0\u9759\u6001\u8D44\u6E90 \u2192 \u7248\u672C\u5316\u8F93\u51FA URL").requiredOption("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug").action(async (flags) => {
|
|
6482
|
-
try {
|
|
6483
|
-
const { publishWidget: publishWidget2 } = await Promise.resolve().then(() => (init_publish(), publish_exports));
|
|
6484
|
-
const result = await publishWidget2(paths, {
|
|
6485
|
-
cwd,
|
|
6486
|
-
project: flags.project
|
|
6278
|
+
command.ok(result);
|
|
6487
6279
|
});
|
|
6488
|
-
if (jsonMode()) {
|
|
6489
|
-
output(JSON.stringify({ ok: true, command: "widget publish", data: result }));
|
|
6490
|
-
} else {
|
|
6491
|
-
output(`${result.name} v${result.version} ${result.url}`);
|
|
6492
|
-
}
|
|
6493
|
-
} catch (error) {
|
|
6494
|
-
emitError(output, "widget publish", jsonMode(), error);
|
|
6495
6280
|
}
|
|
6496
|
-
|
|
6281
|
+
);
|
|
6282
|
+
}
|
|
6283
|
+
|
|
6284
|
+
// packages/cli/src/cli.ts
|
|
6285
|
+
var requireJson = createRequire(import.meta.url);
|
|
6286
|
+
var APP_VERSION = requireJson("../package.json").version;
|
|
6287
|
+
function buildProgram(options = {}) {
|
|
6288
|
+
const output = options.output ?? ((line) => process.stdout.write(`${line}
|
|
6289
|
+
`));
|
|
6290
|
+
const paths = options.paths ?? resolvePaths();
|
|
6291
|
+
const cwd = options.cwd ?? process.cwd();
|
|
6292
|
+
const program2 = new Command();
|
|
6293
|
+
program2.name("adep").description("AgentDeploy CLI").version(APP_VERSION);
|
|
6294
|
+
program2.option("--json", "\u4EE5\u673A\u5668\u53EF\u8BFB JSON \u8F93\u51FA\uFF08Agent / \u811A\u672C\u8C03\u7528\uFF09", false);
|
|
6295
|
+
const jsonMode = () => program2.opts()["json"] === true;
|
|
6296
|
+
const ctx = createCliContext({ output, paths, cwd, json: jsonMode });
|
|
6297
|
+
registerAuth(program2, ctx);
|
|
6298
|
+
registerInit(program2, ctx);
|
|
6299
|
+
registerDevServers(program2, ctx);
|
|
6300
|
+
registerDeploy(program2, ctx);
|
|
6301
|
+
registerProjects(program2, ctx);
|
|
6302
|
+
registerFunctions(program2, ctx);
|
|
6303
|
+
registerMcp(program2, ctx);
|
|
6304
|
+
registerDoctor(program2, ctx);
|
|
6305
|
+
registerDb(program2, ctx);
|
|
6306
|
+
registerStorage(program2, ctx);
|
|
6307
|
+
registerHosting(program2, ctx);
|
|
6308
|
+
registerExport(program2, ctx);
|
|
6497
6309
|
return program2;
|
|
6498
6310
|
}
|
|
6499
6311
|
|