@adep/cli 0.0.9 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -38
- package/dist/index.js +2064 -1576
- package/dist/vite.js +2719 -0
- package/package.json +15 -5
package/dist/index.js
CHANGED
|
@@ -232,6 +232,139 @@ var init_auth = __esm({
|
|
|
232
232
|
}
|
|
233
233
|
});
|
|
234
234
|
|
|
235
|
+
// shared/sdk/adep-config.ts
|
|
236
|
+
function typeNameOf(value) {
|
|
237
|
+
if (value === null) return "null";
|
|
238
|
+
if (Array.isArray(value)) return "array";
|
|
239
|
+
return typeof value;
|
|
240
|
+
}
|
|
241
|
+
function asRecord(value) {
|
|
242
|
+
if (value === null || Array.isArray(value) || typeof value !== "object") return null;
|
|
243
|
+
return value;
|
|
244
|
+
}
|
|
245
|
+
function asStringRecord(value) {
|
|
246
|
+
const rec = asRecord(value);
|
|
247
|
+
if (rec === null) return null;
|
|
248
|
+
for (const v of Object.values(rec)) {
|
|
249
|
+
if (typeof v !== "string") return null;
|
|
250
|
+
}
|
|
251
|
+
return rec;
|
|
252
|
+
}
|
|
253
|
+
function parseAdepConfig(raw) {
|
|
254
|
+
if (raw === null || raw === void 0) {
|
|
255
|
+
return { ok: true, data: { ...DEFAULT_ADEP_CONFIG } };
|
|
256
|
+
}
|
|
257
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
258
|
+
return {
|
|
259
|
+
ok: false,
|
|
260
|
+
errors: [`adep.config.ts \u7684 default export \u5FC5\u987B\u662F\u5BF9\u8C61\uFF0C\u6536\u5230 ${typeNameOf(raw)}`]
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
const errors = [];
|
|
264
|
+
const input = raw;
|
|
265
|
+
const data = { ...DEFAULT_ADEP_CONFIG };
|
|
266
|
+
if (input.name !== void 0) {
|
|
267
|
+
if (typeof input.name !== "string") {
|
|
268
|
+
errors.push(`name \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\uFF0C\u6536\u5230 ${typeNameOf(input.name)}`);
|
|
269
|
+
} else {
|
|
270
|
+
data.name = input.name;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (input.functionsDir !== void 0) {
|
|
274
|
+
if (typeof input.functionsDir !== "string") {
|
|
275
|
+
errors.push(`functionsDir \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\uFF0C\u6536\u5230 ${typeNameOf(input.functionsDir)}`);
|
|
276
|
+
} else {
|
|
277
|
+
data.functionsDir = input.functionsDir;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (input.functions_prefix !== void 0) {
|
|
281
|
+
if (typeof input.functions_prefix !== "string") {
|
|
282
|
+
errors.push(`functions_prefix \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\uFF0C\u6536\u5230 ${typeNameOf(input.functions_prefix)}`);
|
|
283
|
+
} else {
|
|
284
|
+
data.functions_prefix = input.functions_prefix;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (input.frontend !== void 0) {
|
|
288
|
+
const rec = asRecord(input.frontend);
|
|
289
|
+
if (rec === null) {
|
|
290
|
+
errors.push(`frontend \u5FC5\u987B\u662F\u5BF9\u8C61\uFF0C\u6536\u5230 ${typeNameOf(input.frontend)}`);
|
|
291
|
+
} else {
|
|
292
|
+
data.frontend = rec;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (input.environment !== void 0) {
|
|
296
|
+
const rec = asStringRecord(input.environment);
|
|
297
|
+
if (rec === null) {
|
|
298
|
+
errors.push(
|
|
299
|
+
`environment \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u5230\u5B57\u7B26\u4E32\u7684\u6620\u5C04\uFF08Record<string, string>\uFF09\uFF0C\u6536\u5230 ${typeNameOf(input.environment)}`
|
|
300
|
+
);
|
|
301
|
+
} else {
|
|
302
|
+
data.environment = rec;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (input.runtime !== void 0) {
|
|
306
|
+
const rec = asRecord(input.runtime);
|
|
307
|
+
if (rec === null) {
|
|
308
|
+
errors.push(`runtime \u5FC5\u987B\u662F\u5BF9\u8C61\uFF0C\u6536\u5230 ${typeNameOf(input.runtime)}`);
|
|
309
|
+
} else {
|
|
310
|
+
data.runtime = rec;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (errors.length > 0) return { ok: false, errors };
|
|
314
|
+
return { ok: true, data };
|
|
315
|
+
}
|
|
316
|
+
function renderTsValue(value) {
|
|
317
|
+
if (value === null) return "null";
|
|
318
|
+
if (typeof value === "string") return `'${value}'`;
|
|
319
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
320
|
+
if (typeof value === "number") return String(value);
|
|
321
|
+
if (Array.isArray(value)) return `[${value.map(renderTsValue).join(", ")}]`;
|
|
322
|
+
if (typeof value === "object") {
|
|
323
|
+
const entries = Object.entries(value).map(([k, v]) => `${k}: ${renderTsValue(v)}`).join(", ");
|
|
324
|
+
return `{ ${entries} }`;
|
|
325
|
+
}
|
|
326
|
+
return String(value);
|
|
327
|
+
}
|
|
328
|
+
function renderAdepConfig(config, options = {}) {
|
|
329
|
+
const functionsDir = config.functionsDir ?? DEFAULT_ADEP_CONFIG.functionsDir;
|
|
330
|
+
const functionsPrefix = config.functions_prefix ?? DEFAULT_ADEP_CONFIG.functions_prefix;
|
|
331
|
+
const lines = [];
|
|
332
|
+
if (options.header !== void 0 && options.header.length > 0) {
|
|
333
|
+
lines.push(options.header);
|
|
334
|
+
}
|
|
335
|
+
lines.push("export default {");
|
|
336
|
+
if (config.name !== void 0) lines.push(` name: '${config.name}',`);
|
|
337
|
+
lines.push(` functionsDir: '${functionsDir}',`);
|
|
338
|
+
lines.push(` functions_prefix: '${functionsPrefix}',`);
|
|
339
|
+
if (config.frontend !== void 0) {
|
|
340
|
+
lines.push(` frontend: ${renderTsValue(config.frontend)},`);
|
|
341
|
+
}
|
|
342
|
+
if (config.environment !== void 0) {
|
|
343
|
+
lines.push(` environment: ${renderTsValue(config.environment)},`);
|
|
344
|
+
}
|
|
345
|
+
if (config.runtime !== void 0) {
|
|
346
|
+
lines.push(` runtime: ${renderTsValue(config.runtime)},`);
|
|
347
|
+
}
|
|
348
|
+
if (options.extraFields !== void 0) {
|
|
349
|
+
for (const [key, value] of Object.entries(options.extraFields)) {
|
|
350
|
+
lines.push(` ${key}: ${renderTsValue(value)},`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
lines.push("}");
|
|
354
|
+
return `${lines.join("\n")}
|
|
355
|
+
`;
|
|
356
|
+
}
|
|
357
|
+
var DEFAULT_ADEP_CONFIG;
|
|
358
|
+
var init_adep_config = __esm({
|
|
359
|
+
"shared/sdk/adep-config.ts"() {
|
|
360
|
+
"use strict";
|
|
361
|
+
DEFAULT_ADEP_CONFIG = {
|
|
362
|
+
functionsDir: "functions",
|
|
363
|
+
functions_prefix: "/api"
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
|
|
235
368
|
// packages/cli/src/prompt.ts
|
|
236
369
|
var prompt_exports = {};
|
|
237
370
|
__export(prompt_exports, {
|
|
@@ -535,7 +668,7 @@ var init_worker_executor = __esm({
|
|
|
535
668
|
const entry = input.entry ?? "index.ts";
|
|
536
669
|
const deps = this.depsConfig === void 0 ? void 0 : resolveExecutionDeps(this.depsConfig, input.project.id, input.files["package.json"]);
|
|
537
670
|
const logs = [];
|
|
538
|
-
return new Promise((
|
|
671
|
+
return new Promise((resolve12, reject) => {
|
|
539
672
|
let worker;
|
|
540
673
|
try {
|
|
541
674
|
worker = new Worker(resolveWorkerEntry(), {
|
|
@@ -597,7 +730,7 @@ var init_worker_executor = __esm({
|
|
|
597
730
|
if (message.type === "result") {
|
|
598
731
|
clearTimeout(timer);
|
|
599
732
|
void worker.terminate();
|
|
600
|
-
|
|
733
|
+
resolve12({ body: message.body, logs });
|
|
601
734
|
return;
|
|
602
735
|
}
|
|
603
736
|
if (message.type === "error") {
|
|
@@ -2739,6 +2872,58 @@ var init_boundary = __esm({
|
|
|
2739
2872
|
}
|
|
2740
2873
|
});
|
|
2741
2874
|
|
|
2875
|
+
// packages/cli/src/ts-config.ts
|
|
2876
|
+
import { stat as stat4, readFile as readFile5 } from "node:fs/promises";
|
|
2877
|
+
import { join as join7 } from "node:path";
|
|
2878
|
+
async function loadAdepConfigModule(cwd) {
|
|
2879
|
+
const configPath = join7(cwd, "adep.config.ts");
|
|
2880
|
+
try {
|
|
2881
|
+
await stat4(configPath);
|
|
2882
|
+
} catch {
|
|
2883
|
+
return null;
|
|
2884
|
+
}
|
|
2885
|
+
let rawDefault;
|
|
2886
|
+
try {
|
|
2887
|
+
const bun = globalThis.Bun;
|
|
2888
|
+
if (bun !== void 0) {
|
|
2889
|
+
const mod = await import(configPath);
|
|
2890
|
+
rawDefault = mod.default;
|
|
2891
|
+
} else {
|
|
2892
|
+
const { transform } = await import("esbuild");
|
|
2893
|
+
const source = await readFile5(configPath, "utf8");
|
|
2894
|
+
const { code } = await transform(source, {
|
|
2895
|
+
loader: "ts",
|
|
2896
|
+
format: "esm",
|
|
2897
|
+
target: "node22"
|
|
2898
|
+
});
|
|
2899
|
+
const url = `data:text/javascript;base64,${Buffer.from(code).toString("base64")}`;
|
|
2900
|
+
const mod = await import(url);
|
|
2901
|
+
rawDefault = mod.default;
|
|
2902
|
+
}
|
|
2903
|
+
} catch (error) {
|
|
2904
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
2905
|
+
const message = `adep.config.ts \u52A0\u8F7D\u5931\u8D25\uFF1A${reason}`;
|
|
2906
|
+
process.stderr.write(`\u9519\u8BEF\uFF1A${message}
|
|
2907
|
+
`);
|
|
2908
|
+
throw new Error(message, { cause: error });
|
|
2909
|
+
}
|
|
2910
|
+
const result = parseAdepConfig(rawDefault);
|
|
2911
|
+
if (!result.ok) {
|
|
2912
|
+
const message = `adep.config.ts \u6821\u9A8C\u5931\u8D25\uFF1A
|
|
2913
|
+
${result.errors.map((e) => ` - ${e}`).join("\n")}`;
|
|
2914
|
+
process.stderr.write(`${message}
|
|
2915
|
+
`);
|
|
2916
|
+
throw new Error(message);
|
|
2917
|
+
}
|
|
2918
|
+
return result.data;
|
|
2919
|
+
}
|
|
2920
|
+
var init_ts_config = __esm({
|
|
2921
|
+
"packages/cli/src/ts-config.ts"() {
|
|
2922
|
+
"use strict";
|
|
2923
|
+
init_adep_config();
|
|
2924
|
+
}
|
|
2925
|
+
});
|
|
2926
|
+
|
|
2742
2927
|
// packages/cli/src/dev.ts
|
|
2743
2928
|
var dev_exports = {};
|
|
2744
2929
|
__export(dev_exports, {
|
|
@@ -2749,28 +2934,16 @@ __export(dev_exports, {
|
|
|
2749
2934
|
});
|
|
2750
2935
|
import { createServer } from "node:http";
|
|
2751
2936
|
import { watch } from "node:fs";
|
|
2752
|
-
import { mkdir as mkdir5, readdir as readdir2, readFile as
|
|
2753
|
-
import { basename, join as
|
|
2937
|
+
import { mkdir as mkdir5, readdir as readdir2, readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
|
|
2938
|
+
import { basename, join as join8, resolve as resolve3 } from "node:path";
|
|
2754
2939
|
async function loadConfig(cwd) {
|
|
2755
2940
|
const name = basename(resolve3(cwd));
|
|
2756
|
-
const
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
}
|
|
2762
|
-
const bun = globalThis.Bun;
|
|
2763
|
-
if (bun === void 0) return { name, functionsDir: "functions", functionsPrefix: "" };
|
|
2764
|
-
try {
|
|
2765
|
-
const mod = await import(configPath);
|
|
2766
|
-
return {
|
|
2767
|
-
name: mod.default?.name ?? name,
|
|
2768
|
-
functionsDir: mod.default?.functionsDir ?? "functions",
|
|
2769
|
-
functionsPrefix: mod.default?.functions_prefix ?? ""
|
|
2770
|
-
};
|
|
2771
|
-
} catch {
|
|
2772
|
-
return { name, functionsDir: "functions", functionsPrefix: "" };
|
|
2773
|
-
}
|
|
2941
|
+
const config = await loadAdepConfigModule(cwd);
|
|
2942
|
+
return {
|
|
2943
|
+
name: config?.name ?? name,
|
|
2944
|
+
functionsDir: config?.functionsDir ?? "functions",
|
|
2945
|
+
functionsPrefix: config?.functions_prefix ?? ""
|
|
2946
|
+
};
|
|
2774
2947
|
}
|
|
2775
2948
|
function parseEnvFile(content) {
|
|
2776
2949
|
const env = {};
|
|
@@ -2796,11 +2969,11 @@ async function collectFunctions(dir) {
|
|
|
2796
2969
|
}
|
|
2797
2970
|
for (const entry of entries) {
|
|
2798
2971
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
2799
|
-
const full =
|
|
2972
|
+
const full = join8(sub, entry.name);
|
|
2800
2973
|
if (entry.isDirectory()) {
|
|
2801
2974
|
await walk(full, rel);
|
|
2802
2975
|
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
2803
|
-
files[rel] = await
|
|
2976
|
+
files[rel] = await readFile6(full, "utf8");
|
|
2804
2977
|
}
|
|
2805
2978
|
}
|
|
2806
2979
|
};
|
|
@@ -2863,8 +3036,8 @@ function printBoundaries(log) {
|
|
|
2863
3036
|
}
|
|
2864
3037
|
}
|
|
2865
3038
|
async function ensureGitignore(cwd) {
|
|
2866
|
-
const gitignorePath =
|
|
2867
|
-
const existing = await
|
|
3039
|
+
const gitignorePath = join8(cwd, ".gitignore");
|
|
3040
|
+
const existing = await readFile6(gitignorePath, "utf8").catch(() => "");
|
|
2868
3041
|
if (existing.split(/\r?\n/).includes(".adep/")) return;
|
|
2869
3042
|
await writeFile4(gitignorePath, `${existing.replace(/\n+$/, "")}
|
|
2870
3043
|
.adep/
|
|
@@ -2875,7 +3048,10 @@ async function startDevServer(options) {
|
|
|
2875
3048
|
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
2876
3049
|
`));
|
|
2877
3050
|
const config = await loadConfig(cwd);
|
|
2878
|
-
|
|
3051
|
+
if (options.prefix !== void 0) {
|
|
3052
|
+
config.functionsPrefix = options.prefix.replace(/^\/+|\/+$/g, "");
|
|
3053
|
+
}
|
|
3054
|
+
const functionsDir = join8(cwd, config.functionsDir);
|
|
2879
3055
|
const coldStartAt = Date.now();
|
|
2880
3056
|
const executor = new WorkerFunctionExecutor();
|
|
2881
3057
|
await mkdir5(functionsDir, { recursive: true });
|
|
@@ -2893,12 +3069,12 @@ async function startDevServer(options) {
|
|
|
2893
3069
|
const reload = async () => {
|
|
2894
3070
|
const [nextFiles, envText2] = await Promise.all([
|
|
2895
3071
|
collectFunctions(functionsDir),
|
|
2896
|
-
|
|
3072
|
+
readFile6(join8(cwd, ".env.local"), "utf8").catch(() => "")
|
|
2897
3073
|
]);
|
|
2898
3074
|
files = nextFiles;
|
|
2899
3075
|
env = parseEnvFile(envText2);
|
|
2900
3076
|
};
|
|
2901
|
-
const envText = await
|
|
3077
|
+
const envText = await readFile6(join8(cwd, ".env.local"), "utf8").catch(() => "");
|
|
2902
3078
|
env = parseEnvFile(envText);
|
|
2903
3079
|
let debounceTimer;
|
|
2904
3080
|
let watcher;
|
|
@@ -2995,10 +3171,28 @@ async function startDevServer(options) {
|
|
|
2995
3171
|
void handle(req, res);
|
|
2996
3172
|
});
|
|
2997
3173
|
const port = options.port ?? 8787;
|
|
3174
|
+
const disposeAfterListenError = async () => {
|
|
3175
|
+
if (debounceTimer !== void 0) clearTimeout(debounceTimer);
|
|
3176
|
+
try {
|
|
3177
|
+
watcher?.close();
|
|
3178
|
+
} catch {
|
|
3179
|
+
}
|
|
3180
|
+
try {
|
|
3181
|
+
await executor.dispose();
|
|
3182
|
+
} catch {
|
|
3183
|
+
}
|
|
3184
|
+
try {
|
|
3185
|
+
await runtime.dispose();
|
|
3186
|
+
} catch {
|
|
3187
|
+
}
|
|
3188
|
+
};
|
|
2998
3189
|
await new Promise((resolveListen, rejectListen) => {
|
|
2999
|
-
|
|
3190
|
+
const onListenError = (error) => {
|
|
3191
|
+
void disposeAfterListenError().finally(() => rejectListen(error));
|
|
3192
|
+
};
|
|
3193
|
+
server.once("error", onListenError);
|
|
3000
3194
|
server.listen(port, "127.0.0.1", () => {
|
|
3001
|
-
server.off("error",
|
|
3195
|
+
server.off("error", onListenError);
|
|
3002
3196
|
resolveListen();
|
|
3003
3197
|
});
|
|
3004
3198
|
});
|
|
@@ -3006,8 +3200,9 @@ async function startDevServer(options) {
|
|
|
3006
3200
|
const actualPort = typeof address === "object" && address !== null ? address.port : port;
|
|
3007
3201
|
const baseUrl = `http://127.0.0.1:${actualPort}`;
|
|
3008
3202
|
const coldStartMs = Date.now() - coldStartAt;
|
|
3203
|
+
const curlPath = config.functionsPrefix.length === 0 ? "/hello" : `/${config.functionsPrefix}/hello`;
|
|
3009
3204
|
log(`[adep] dev server listening on ${baseUrl}\uFF08\u6A21\u62DF\u8FD0\u884C\u65F6\uFF0C\u51B7\u542F\u52A8 ${coldStartMs}ms\uFF09`);
|
|
3010
|
-
log(`[adep] curl \u793A\u4F8B\uFF1Acurl ${baseUrl}
|
|
3205
|
+
log(`[adep] curl \u793A\u4F8B\uFF1Acurl ${baseUrl}${curlPath}`);
|
|
3011
3206
|
printBoundaries(log);
|
|
3012
3207
|
log(`[adep] \u6A21\u62DF\u6570\u636E\u76EE\u5F55\uFF1A${simDir(cwd)}`);
|
|
3013
3208
|
return {
|
|
@@ -3031,6 +3226,7 @@ var init_dev = __esm({
|
|
|
3031
3226
|
init_env();
|
|
3032
3227
|
init_invoke();
|
|
3033
3228
|
init_boundary();
|
|
3229
|
+
init_ts_config();
|
|
3034
3230
|
}
|
|
3035
3231
|
});
|
|
3036
3232
|
|
|
@@ -3106,8 +3302,8 @@ __export(server_exports, {
|
|
|
3106
3302
|
});
|
|
3107
3303
|
import { createServer as createServer2 } from "node:http";
|
|
3108
3304
|
import { watch as watch2 } from "node:fs";
|
|
3109
|
-
import { mkdir as mkdir6, readdir as readdir3, readFile as
|
|
3110
|
-
import { join as
|
|
3305
|
+
import { mkdir as mkdir6, readdir as readdir3, readFile as readFile7, stat as stat5 } from "node:fs/promises";
|
|
3306
|
+
import { join as join9, relative, resolve as resolve4 } from "node:path";
|
|
3111
3307
|
function envNumber(name) {
|
|
3112
3308
|
const raw = process.env[name];
|
|
3113
3309
|
if (raw === void 0 || raw.trim() === "") return void 0;
|
|
@@ -3129,11 +3325,11 @@ async function collectFunctions2(dir) {
|
|
|
3129
3325
|
}
|
|
3130
3326
|
for (const entry of entries) {
|
|
3131
3327
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
3132
|
-
const full =
|
|
3328
|
+
const full = join9(sub, entry.name);
|
|
3133
3329
|
if (entry.isDirectory()) {
|
|
3134
3330
|
await walk(full, rel);
|
|
3135
3331
|
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
3136
|
-
files[rel] = await
|
|
3332
|
+
files[rel] = await readFile7(full, "utf8");
|
|
3137
3333
|
}
|
|
3138
3334
|
}
|
|
3139
3335
|
};
|
|
@@ -3178,7 +3374,7 @@ async function startServeServer(options) {
|
|
|
3178
3374
|
options.staticDir ?? envString("ADEP_SERVE_STATIC_DIR") ?? "public"
|
|
3179
3375
|
);
|
|
3180
3376
|
const config = await loadConfig(cwd);
|
|
3181
|
-
const functionsDir =
|
|
3377
|
+
const functionsDir = join9(cwd, config.functionsDir);
|
|
3182
3378
|
let hasStatic = false;
|
|
3183
3379
|
try {
|
|
3184
3380
|
const publicStat = await stat5(staticDir);
|
|
@@ -3188,7 +3384,7 @@ async function startServeServer(options) {
|
|
|
3188
3384
|
}
|
|
3189
3385
|
let files = await collectFunctions2(functionsDir);
|
|
3190
3386
|
let functionNames = listFunctionNames(files);
|
|
3191
|
-
const envText = await
|
|
3387
|
+
const envText = await readFile7(join9(cwd, ".env.local"), "utf8").catch(() => "");
|
|
3192
3388
|
let env = parseEnvFile(envText);
|
|
3193
3389
|
let simEnv = await loadSimEnv(cwd).catch(() => ({}));
|
|
3194
3390
|
const runtime = await createSimRuntime({
|
|
@@ -3205,7 +3401,7 @@ async function startServeServer(options) {
|
|
|
3205
3401
|
const reload = async () => {
|
|
3206
3402
|
const [nextFiles, envLocalText] = await Promise.all([
|
|
3207
3403
|
collectFunctions2(functionsDir),
|
|
3208
|
-
|
|
3404
|
+
readFile7(join9(cwd, ".env.local"), "utf8").catch(() => "")
|
|
3209
3405
|
]);
|
|
3210
3406
|
files = nextFiles;
|
|
3211
3407
|
env = parseEnvFile(envLocalText);
|
|
@@ -3274,16 +3470,16 @@ async function startServeServer(options) {
|
|
|
3274
3470
|
const serveStatic = async (pathname, res) => {
|
|
3275
3471
|
if (!hasStatic) return false;
|
|
3276
3472
|
const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
|
|
3277
|
-
const filePath =
|
|
3278
|
-
const resolvedPath = safePath === "" || safePath === "/" ?
|
|
3473
|
+
const filePath = join9(staticDir, safePath);
|
|
3474
|
+
const resolvedPath = safePath === "" || safePath === "/" ? join9(filePath, "index.html") : filePath;
|
|
3279
3475
|
try {
|
|
3280
3476
|
const fileStat = await stat5(resolvedPath);
|
|
3281
3477
|
if (fileStat.isDirectory()) {
|
|
3282
|
-
const indexPath =
|
|
3478
|
+
const indexPath = join9(resolvedPath, "index.html");
|
|
3283
3479
|
try {
|
|
3284
3480
|
const indexStat = await stat5(indexPath);
|
|
3285
3481
|
if (indexStat.isFile()) {
|
|
3286
|
-
const content2 = await
|
|
3482
|
+
const content2 = await readFile7(indexPath);
|
|
3287
3483
|
res.writeHead(200, { "content-type": contentTypeFor(indexPath) });
|
|
3288
3484
|
res.end(content2);
|
|
3289
3485
|
return true;
|
|
@@ -3292,7 +3488,7 @@ async function startServeServer(options) {
|
|
|
3292
3488
|
}
|
|
3293
3489
|
return false;
|
|
3294
3490
|
}
|
|
3295
|
-
const content = await
|
|
3491
|
+
const content = await readFile7(resolvedPath);
|
|
3296
3492
|
res.writeHead(200, { "content-type": contentTypeFor(resolvedPath) });
|
|
3297
3493
|
res.end(content);
|
|
3298
3494
|
return true;
|
|
@@ -3567,8 +3763,8 @@ __export(deploy_exports, {
|
|
|
3567
3763
|
deploy: () => deploy
|
|
3568
3764
|
});
|
|
3569
3765
|
import { createHash as createHash2 } from "node:crypto";
|
|
3570
|
-
import { readdir as readdir4, readFile as
|
|
3571
|
-
import { join as
|
|
3766
|
+
import { readdir as readdir4, readFile as readFile8 } from "node:fs/promises";
|
|
3767
|
+
import { join as join10, resolve as resolve5, basename as basename2 } from "node:path";
|
|
3572
3768
|
function functionUrlBase(prefix) {
|
|
3573
3769
|
const raw = (prefix ?? "/api").trim();
|
|
3574
3770
|
const normalized = raw === "/" ? "/" : raw.replace(/\/+$/, "");
|
|
@@ -3584,7 +3780,7 @@ async function collectEntries(functionsDir) {
|
|
|
3584
3780
|
return entries;
|
|
3585
3781
|
}
|
|
3586
3782
|
for (const name of names) {
|
|
3587
|
-
entries[name] = await
|
|
3783
|
+
entries[name] = await readFile8(join10(functionsDir, `${name}.ts`), "utf8");
|
|
3588
3784
|
}
|
|
3589
3785
|
return entries;
|
|
3590
3786
|
}
|
|
@@ -3599,7 +3795,7 @@ async function deploy(paths, options) {
|
|
|
3599
3795
|
const cwd = resolve5(options.cwd);
|
|
3600
3796
|
const config = await loadConfig(cwd);
|
|
3601
3797
|
const slug = options.slug ?? config.name;
|
|
3602
|
-
const functionsDir = options.functionsDir === void 0 ?
|
|
3798
|
+
const functionsDir = options.functionsDir === void 0 ? join10(cwd, config.functionsDir) : resolve5(cwd, options.functionsDir);
|
|
3603
3799
|
const local = await collectEntries(functionsDir);
|
|
3604
3800
|
if (Object.keys(local).length === 0) {
|
|
3605
3801
|
throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
|
|
@@ -3677,1371 +3873,1379 @@ var init_deploy = __esm({
|
|
|
3677
3873
|
}
|
|
3678
3874
|
});
|
|
3679
3875
|
|
|
3680
|
-
// packages/cli/src/
|
|
3681
|
-
var
|
|
3682
|
-
__export(
|
|
3683
|
-
|
|
3684
|
-
projectsInfo: () => projectsInfo,
|
|
3685
|
-
projectsList: () => projectsList
|
|
3876
|
+
// packages/cli/src/export/client.ts
|
|
3877
|
+
var client_exports2 = {};
|
|
3878
|
+
__export(client_exports2, {
|
|
3879
|
+
createExportApiClient: () => createExportApiClient
|
|
3686
3880
|
});
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
const created = await client.request(
|
|
3701
|
-
"/api/v1/projects",
|
|
3702
|
-
{ body },
|
|
3703
|
-
"PROJECT_CREATE_FAILED"
|
|
3704
|
-
);
|
|
3705
|
-
if (created.url === void 0 || created.url.length === 0) {
|
|
3706
|
-
throw new CliError("PROJECT_CREATE_FAILED", "\u5E73\u53F0\u672A\u8FD4\u56DE\u9879\u76EE\u5730\u5740\uFF0C\u65E0\u6CD5\u8F93\u51FA\u5B50\u57DF URL");
|
|
3707
|
-
}
|
|
3708
|
-
return created;
|
|
3881
|
+
import { writeFile as writeFile5 } from "node:fs/promises";
|
|
3882
|
+
function toExportJob(view) {
|
|
3883
|
+
return {
|
|
3884
|
+
id: view.id,
|
|
3885
|
+
status: view.status,
|
|
3886
|
+
progress: view.progress,
|
|
3887
|
+
createdAt: view.createdAt,
|
|
3888
|
+
...view.stage === void 0 ? {} : { stage: view.stage },
|
|
3889
|
+
...view.error === void 0 ? {} : { error: view.error },
|
|
3890
|
+
...view.downloadUrl === void 0 ? {} : { downloadUrl: view.downloadUrl },
|
|
3891
|
+
...view.bundleSize === void 0 ? {} : { bundleSize: view.bundleSize },
|
|
3892
|
+
...view.completedAt === void 0 ? {} : { completedAt: view.completedAt }
|
|
3893
|
+
};
|
|
3709
3894
|
}
|
|
3710
|
-
async function
|
|
3711
|
-
await requireNetworkGuard();
|
|
3895
|
+
async function createExportApiClient(paths) {
|
|
3712
3896
|
const client = await createClient(paths);
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3897
|
+
return {
|
|
3898
|
+
async triggerExport(projectId, options) {
|
|
3899
|
+
const view = await client.request(
|
|
3900
|
+
`/api/v1/projects/${encodeURIComponent(projectId)}/export`,
|
|
3901
|
+
{
|
|
3902
|
+
method: "POST",
|
|
3903
|
+
body: {
|
|
3904
|
+
withData: options.withData,
|
|
3905
|
+
withSource: options.withSource,
|
|
3906
|
+
...options.withoutSource === true ? { withoutSource: true } : {}
|
|
3907
|
+
}
|
|
3908
|
+
},
|
|
3909
|
+
"EXPORT_TRIGGER_FAILED"
|
|
3910
|
+
);
|
|
3911
|
+
return toExportJob(view);
|
|
3912
|
+
},
|
|
3913
|
+
async getJobStatus(jobId) {
|
|
3914
|
+
const view = await client.request(
|
|
3915
|
+
`/api/v1/exports/${encodeURIComponent(jobId)}`,
|
|
3916
|
+
{},
|
|
3917
|
+
"EXPORT_STATUS_FAILED"
|
|
3918
|
+
);
|
|
3919
|
+
return toExportJob(view);
|
|
3920
|
+
},
|
|
3921
|
+
async downloadBundle(jobId, outputPath) {
|
|
3922
|
+
const download = await client.request(
|
|
3923
|
+
`/api/v1/exports/${encodeURIComponent(jobId)}/download`,
|
|
3924
|
+
{},
|
|
3925
|
+
"EXPORT_DOWNLOAD_FAILED"
|
|
3926
|
+
);
|
|
3927
|
+
if (download.downloadUrl.length === 0) {
|
|
3928
|
+
throw new CliError("EXPORT_BUNDLE_UNAVAILABLE", "\u5BFC\u51FA\u4EA7\u7269\u4E0B\u8F7D URL \u4E3A\u7A7A\uFF0C\u4EA7\u7269\u53EF\u80FD\u5C1A\u4E0D\u53EF\u7528");
|
|
3929
|
+
}
|
|
3930
|
+
const response = await client.download(download.downloadUrl, "EXPORT_DOWNLOAD_FAILED");
|
|
3931
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
3932
|
+
await writeFile5(outputPath, bytes);
|
|
3933
|
+
return { path: outputPath, size: bytes.length };
|
|
3934
|
+
}
|
|
3935
|
+
};
|
|
3733
3936
|
}
|
|
3734
|
-
var
|
|
3735
|
-
"packages/cli/src/
|
|
3937
|
+
var init_client2 = __esm({
|
|
3938
|
+
"packages/cli/src/export/client.ts"() {
|
|
3736
3939
|
"use strict";
|
|
3737
3940
|
init_auth();
|
|
3738
3941
|
init_client();
|
|
3739
3942
|
}
|
|
3740
3943
|
});
|
|
3741
3944
|
|
|
3742
|
-
//
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3945
|
+
// shared/deploy-bundle/zip.ts
|
|
3946
|
+
function zipRead(buf) {
|
|
3947
|
+
const r = new Reader(buf);
|
|
3948
|
+
const eocd = findEocd(buf);
|
|
3949
|
+
if (eocd < 0) throw new ZipFormatError("\u627E\u4E0D\u5230 EOCD \u7B7E\u540D");
|
|
3950
|
+
const total = r.u16(eocd + 10);
|
|
3951
|
+
const centralOffset = r.u32(eocd + 16);
|
|
3952
|
+
const decoder = new TextDecoder();
|
|
3953
|
+
const out = /* @__PURE__ */ new Map();
|
|
3954
|
+
let cursor = centralOffset;
|
|
3955
|
+
for (let i = 0; i < total; i++) {
|
|
3956
|
+
if (cursor + 46 > buf.length) throw new ZipFormatError("\u4E2D\u592E\u76EE\u5F55\u8BB0\u5F55\u8D8A\u754C");
|
|
3957
|
+
if (r.u32(cursor) !== SIG_CENTRAL) throw new ZipFormatError("\u4E2D\u592E\u76EE\u5F55\u7B7E\u540D\u4E0D\u5339\u914D");
|
|
3958
|
+
const method = r.u16(cursor + 10);
|
|
3959
|
+
if (method !== 0) throw new ZipFormatError("\u4EC5\u652F\u6301 store \u578B\u6761\u76EE\u8BFB\u53D6");
|
|
3960
|
+
const compSize = r.u32(cursor + 20);
|
|
3961
|
+
const nameLen = r.u16(cursor + 28);
|
|
3962
|
+
const extraLen = r.u16(cursor + 30);
|
|
3963
|
+
const commentLen = r.u16(cursor + 32);
|
|
3964
|
+
const localHeaderOffset = r.u32(cursor + 42);
|
|
3965
|
+
if (localHeaderOffset + 30 > buf.length) throw new ZipFormatError("\u672C\u5730\u5934\u504F\u79FB\u8D8A\u754C");
|
|
3966
|
+
const name = decoder.decode(r.slice(cursor + 46, nameLen));
|
|
3967
|
+
const localNameLen = r.u16(localHeaderOffset + 26);
|
|
3968
|
+
const localExtraLen = r.u16(localHeaderOffset + 28);
|
|
3969
|
+
const dataStart = localHeaderOffset + 30 + localNameLen + localExtraLen;
|
|
3970
|
+
if (dataStart + compSize > buf.length) throw new ZipFormatError("\u6761\u76EE\u6570\u636E\u8D8A\u754C");
|
|
3971
|
+
if (!out.has(name)) out.set(name, r.slice(dataStart, compSize));
|
|
3972
|
+
cursor += 46 + nameLen + extraLen + commentLen;
|
|
3973
|
+
}
|
|
3974
|
+
return out;
|
|
3759
3975
|
}
|
|
3760
|
-
|
|
3761
|
-
const
|
|
3762
|
-
const
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
{},
|
|
3766
|
-
"FUNCTION_LIST_FAILED"
|
|
3767
|
-
);
|
|
3768
|
-
const prefix = project2.functionsPrefix ?? "/api";
|
|
3769
|
-
const prefixBase = prefix.trim() === "/" ? "" : prefix.trim().replace(/\/+$/, "");
|
|
3770
|
-
return {
|
|
3771
|
-
projectId: project2.id,
|
|
3772
|
-
slug: project2.slug,
|
|
3773
|
-
baseUrl: `${project2.url.replace(/\/+$/, "")}${prefixBase}`,
|
|
3774
|
-
functions: result.functions
|
|
3775
|
-
};
|
|
3776
|
-
}
|
|
3777
|
-
async function functionsLogs(paths, options) {
|
|
3778
|
-
if (options.name === void 0 || options.name.trim().length === 0) {
|
|
3779
|
-
throw new CliError("INVALID_ARGUMENT", "\u7F3A\u5C11\u51FD\u6570\u540D\uFF1Aadep functions logs <name>");
|
|
3780
|
-
}
|
|
3781
|
-
const client = await createClient(paths);
|
|
3782
|
-
const project2 = await resolveProject(client, options);
|
|
3783
|
-
const listed = await client.request(
|
|
3784
|
-
`/api/v1/projects/${project2.id}/functions`,
|
|
3785
|
-
{},
|
|
3786
|
-
"FUNCTION_LIST_FAILED"
|
|
3787
|
-
);
|
|
3788
|
-
const target = listed.functions.find((fn) => fn.name === options.name);
|
|
3789
|
-
if (target === void 0) {
|
|
3790
|
-
throw new CliError("FN_NOT_FOUND", `\u51FD\u6570 "${options.name}" \u4E0D\u5B58\u5728\u4E8E\u9879\u76EE "${project2.slug}"`);
|
|
3791
|
-
}
|
|
3792
|
-
const tail = options.tail === void 0 ? "" : `?tail=${encodeURIComponent(String(options.tail))}`;
|
|
3793
|
-
const result = await client.request(
|
|
3794
|
-
`/api/v1/functions/${target.id}/logs${tail}`,
|
|
3795
|
-
{},
|
|
3796
|
-
"FUNCTION_LOGS_FAILED"
|
|
3797
|
-
);
|
|
3798
|
-
return { functionId: target.id, name: target.name, logs: result.logs };
|
|
3799
|
-
}
|
|
3800
|
-
async function resolveProject(client, options) {
|
|
3801
|
-
const slug = await resolveSlug(resolve6(options.cwd), options.slug);
|
|
3802
|
-
const projects = await projectsListFrom(client);
|
|
3803
|
-
const match = projects.find((project2) => project2.slug === slug);
|
|
3804
|
-
if (match === void 0) {
|
|
3805
|
-
throw new CliError(
|
|
3806
|
-
"PROJECT_NOT_FOUND",
|
|
3807
|
-
`\u5E73\u53F0\u9879\u76EE "${slug}" \u4E0D\u5B58\u5728\u6216\u4F60\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\uFF1A\u5148\u6267\u884C adep projects create ${slug}`
|
|
3808
|
-
);
|
|
3976
|
+
function findEocd(buf) {
|
|
3977
|
+
const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
3978
|
+
const min = Math.max(0, buf.length - 65557);
|
|
3979
|
+
for (let i = buf.length - 22; i >= min; i--) {
|
|
3980
|
+
if (view.getUint32(i, true) === SIG_EOCD) return i;
|
|
3809
3981
|
}
|
|
3810
|
-
return
|
|
3811
|
-
}
|
|
3812
|
-
async function projectsListFrom(client) {
|
|
3813
|
-
const result = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
3814
|
-
return result.projects;
|
|
3982
|
+
return -1;
|
|
3815
3983
|
}
|
|
3816
|
-
var
|
|
3817
|
-
|
|
3984
|
+
var SIG_CENTRAL, SIG_EOCD, CRC_TABLE, Reader, ZipFormatError;
|
|
3985
|
+
var init_zip = __esm({
|
|
3986
|
+
"shared/deploy-bundle/zip.ts"() {
|
|
3818
3987
|
"use strict";
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3988
|
+
SIG_CENTRAL = 33639248;
|
|
3989
|
+
SIG_EOCD = 101010256;
|
|
3990
|
+
CRC_TABLE = (() => {
|
|
3991
|
+
const table = new Uint32Array(256);
|
|
3992
|
+
for (let i = 0; i < 256; i++) {
|
|
3993
|
+
let c = i;
|
|
3994
|
+
for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
3995
|
+
table[i] = c >>> 0;
|
|
3996
|
+
}
|
|
3997
|
+
return table;
|
|
3998
|
+
})();
|
|
3999
|
+
Reader = class {
|
|
4000
|
+
constructor(buf) {
|
|
4001
|
+
this.buf = buf;
|
|
4002
|
+
this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
4003
|
+
}
|
|
4004
|
+
view;
|
|
4005
|
+
u16(offset) {
|
|
4006
|
+
return this.view.getUint16(offset, true);
|
|
4007
|
+
}
|
|
4008
|
+
u32(offset) {
|
|
4009
|
+
return this.view.getUint32(offset, true);
|
|
4010
|
+
}
|
|
4011
|
+
slice(start, length) {
|
|
4012
|
+
return this.buf.subarray(start, start + length);
|
|
4013
|
+
}
|
|
4014
|
+
};
|
|
4015
|
+
ZipFormatError = class extends Error {
|
|
4016
|
+
constructor(message) {
|
|
4017
|
+
super(`[appexport] \u975E\u6CD5 zip\uFF1A${message}`);
|
|
4018
|
+
this.name = "ZipFormatError";
|
|
4019
|
+
}
|
|
4020
|
+
};
|
|
3822
4021
|
}
|
|
3823
4022
|
});
|
|
3824
4023
|
|
|
3825
|
-
// packages/cli/src/
|
|
3826
|
-
var
|
|
3827
|
-
__export(
|
|
3828
|
-
|
|
3829
|
-
mcpPublish: () => mcpPublish,
|
|
3830
|
-
mcpUnpublish: () => mcpUnpublish
|
|
4024
|
+
// packages/cli/src/export/fs.ts
|
|
4025
|
+
var fs_exports = {};
|
|
4026
|
+
__export(fs_exports, {
|
|
4027
|
+
createExportFileSystem: () => createExportFileSystem
|
|
3831
4028
|
});
|
|
3832
|
-
import {
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
const client = await createClient(paths);
|
|
3836
|
-
const project2 = await resolveProject2(client, options);
|
|
3837
|
-
const target = await resolveFunction(client, project2, fn);
|
|
3838
|
-
const body = {};
|
|
3839
|
-
if (options.toolName !== void 0 && options.toolName.trim().length > 0) {
|
|
3840
|
-
body.toolName = options.toolName.trim();
|
|
3841
|
-
}
|
|
3842
|
-
if (options.description !== void 0 && options.description.length > 0) {
|
|
3843
|
-
body.description = options.description;
|
|
3844
|
-
}
|
|
3845
|
-
const tool = await client.request(
|
|
3846
|
-
`/api/v1/functions/${target.id}/mcp-publish`,
|
|
3847
|
-
{ method: "POST", ...Object.keys(body).length === 0 ? {} : { body } },
|
|
3848
|
-
"MCP_PUBLISH_FAILED"
|
|
3849
|
-
);
|
|
3850
|
-
return { projectId: project2.id, tool };
|
|
3851
|
-
}
|
|
3852
|
-
async function mcpUnpublish(paths, options) {
|
|
3853
|
-
const fn = requireFunctionName(options.fn);
|
|
3854
|
-
const client = await createClient(paths);
|
|
3855
|
-
const project2 = await resolveProject2(client, options);
|
|
3856
|
-
const target = await resolveFunction(client, project2, fn);
|
|
3857
|
-
const toolName = options.toolName?.trim() || fn;
|
|
3858
|
-
const result = await client.request(
|
|
3859
|
-
`/api/v1/functions/${target.id}/mcp-publish?tool=${encodeURIComponent(toolName)}`,
|
|
3860
|
-
{ method: "DELETE" },
|
|
3861
|
-
"MCP_UNPUBLISH_FAILED"
|
|
3862
|
-
);
|
|
3863
|
-
return { projectId: project2.id, toolName, removed: result.unpublished === true };
|
|
3864
|
-
}
|
|
3865
|
-
async function mcpList(paths, options) {
|
|
3866
|
-
const client = await createClient(paths);
|
|
3867
|
-
const project2 = await resolveProject2(client, options);
|
|
3868
|
-
const prefix = project2.functionsPrefix ?? "/api";
|
|
3869
|
-
const prefixBase = prefix.trim() === "/" ? "" : prefix.trim().replace(/\/+$/, "");
|
|
3870
|
-
const endpoint = `${project2.url.replace(/\/+$/, "")}${prefixBase}/mcp`;
|
|
3871
|
-
let response;
|
|
3872
|
-
try {
|
|
3873
|
-
response = await fetch(endpoint, {
|
|
3874
|
-
method: "POST",
|
|
3875
|
-
headers: { "content-type": "application/json", cookie: client.cookie },
|
|
3876
|
-
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "tools/list" })
|
|
3877
|
-
});
|
|
3878
|
-
} catch (error) {
|
|
3879
|
-
throw new CliError(
|
|
3880
|
-
"SERVER_UNREACHABLE",
|
|
3881
|
-
`\u65E0\u6CD5\u8FDE\u63A5 MCP \u7AEF\u70B9 ${endpoint}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
3882
|
-
);
|
|
3883
|
-
}
|
|
3884
|
-
const parsed = await response.json().catch(() => null);
|
|
3885
|
-
if (!response.ok) {
|
|
3886
|
-
const envelope = parsed ?? null;
|
|
3887
|
-
throw new CliError(
|
|
3888
|
-
envelope?.error?.code ?? "MCP_LIST_FAILED",
|
|
3889
|
-
envelope?.error?.message ?? `MCP \u7AEF\u70B9\u8FD4\u56DE HTTP ${response.status}`
|
|
3890
|
-
);
|
|
3891
|
-
}
|
|
3892
|
-
const rpcError = parsed?.error;
|
|
3893
|
-
if (rpcError !== void 0) {
|
|
3894
|
-
throw new CliError(
|
|
3895
|
-
rpcError.code ?? "MCP_LIST_FAILED",
|
|
3896
|
-
rpcError.message ?? "MCP tools/list \u5931\u8D25"
|
|
3897
|
-
);
|
|
3898
|
-
}
|
|
3899
|
-
return {
|
|
3900
|
-
projectId: project2.id,
|
|
3901
|
-
slug: project2.slug,
|
|
3902
|
-
endpoint,
|
|
3903
|
-
tools: parsed?.result?.tools ?? []
|
|
3904
|
-
};
|
|
3905
|
-
}
|
|
3906
|
-
function requireFunctionName(fn) {
|
|
3907
|
-
if (fn === void 0 || fn.trim().length === 0) {
|
|
3908
|
-
throw new CliError("INVALID_ARGUMENT", "\u7F3A\u5C11\u51FD\u6570\u540D\uFF1Aadep mcp publish --function <fn>");
|
|
3909
|
-
}
|
|
3910
|
-
return fn.trim();
|
|
3911
|
-
}
|
|
3912
|
-
async function resolveProject2(client, options) {
|
|
3913
|
-
const slug = await resolveSlug(resolve7(options.cwd), options.slug);
|
|
3914
|
-
const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
3915
|
-
const match = listed.projects.find((project2) => project2.slug === slug);
|
|
3916
|
-
if (match === void 0) {
|
|
3917
|
-
throw new CliError(
|
|
3918
|
-
"PROJECT_NOT_FOUND",
|
|
3919
|
-
`\u5E73\u53F0\u9879\u76EE "${slug}" \u4E0D\u5B58\u5728\u6216\u4F60\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\uFF1A\u5148\u6267\u884C adep projects create ${slug}`
|
|
3920
|
-
);
|
|
3921
|
-
}
|
|
4029
|
+
import { mkdir as mkdir7, readFile as readFile9, rm as rm3, stat as stat6, writeFile as writeFile6 } from "node:fs/promises";
|
|
4030
|
+
import { dirname as dirname6, join as join11 } from "node:path";
|
|
4031
|
+
function createExportFileSystem() {
|
|
3922
4032
|
return {
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
4033
|
+
readFile: (path) => readFile9(path),
|
|
4034
|
+
writeFile: (path, content) => writeFile6(path, content),
|
|
4035
|
+
// 同时用于清理解压临时目录(${zip}.tmp 是个目录)——递归强制删除,缺失不报错。
|
|
4036
|
+
deleteFile: async (path) => {
|
|
4037
|
+
await rm3(path, { recursive: true, force: true });
|
|
4038
|
+
},
|
|
4039
|
+
fileExists: async (path) => {
|
|
4040
|
+
try {
|
|
4041
|
+
await stat6(path);
|
|
4042
|
+
return true;
|
|
4043
|
+
} catch {
|
|
4044
|
+
return false;
|
|
4045
|
+
}
|
|
4046
|
+
},
|
|
4047
|
+
mkdir: async (path) => {
|
|
4048
|
+
await mkdir7(path, { recursive: true });
|
|
4049
|
+
},
|
|
4050
|
+
unzip: async (zipPath, targetDir) => {
|
|
4051
|
+
const entries = zipRead(await readFile9(zipPath));
|
|
4052
|
+
for (const [name, data] of entries) {
|
|
4053
|
+
const dest = join11(targetDir, name);
|
|
4054
|
+
await mkdir7(dirname6(dest), { recursive: true });
|
|
4055
|
+
await writeFile6(dest, data);
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
3927
4058
|
};
|
|
3928
4059
|
}
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
const target = listed.functions.find((fn) => fn.name === name);
|
|
3932
|
-
if (target === void 0) {
|
|
3933
|
-
throw new CliError("FN_NOT_FOUND", `\u51FD\u6570 "${name}" \u4E0D\u5B58\u5728\u4E8E\u9879\u76EE "${project2.slug}"`);
|
|
3934
|
-
}
|
|
3935
|
-
return { id: target.id, name: target.name };
|
|
3936
|
-
}
|
|
3937
|
-
var init_mcp = __esm({
|
|
3938
|
-
"packages/cli/src/mcp.ts"() {
|
|
4060
|
+
var init_fs = __esm({
|
|
4061
|
+
"packages/cli/src/export/fs.ts"() {
|
|
3939
4062
|
"use strict";
|
|
3940
|
-
|
|
3941
|
-
init_client();
|
|
4063
|
+
init_zip();
|
|
3942
4064
|
}
|
|
3943
4065
|
});
|
|
3944
4066
|
|
|
3945
|
-
//
|
|
3946
|
-
var
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
4067
|
+
// shared/deploy-bundle/manifest.ts
|
|
4068
|
+
var CURRENT_SCHEMA_VERSION, BundleContentKind, ALLOWED_CONTENT_KINDS;
|
|
4069
|
+
var init_manifest2 = __esm({
|
|
4070
|
+
"shared/deploy-bundle/manifest.ts"() {
|
|
4071
|
+
"use strict";
|
|
4072
|
+
CURRENT_SCHEMA_VERSION = 2;
|
|
4073
|
+
BundleContentKind = {
|
|
4074
|
+
/** 云函数代码与配置。 */
|
|
4075
|
+
Functions: "functions",
|
|
4076
|
+
/** 数据库 schema 与种子数据。 */
|
|
4077
|
+
Database: "database",
|
|
4078
|
+
/** 前端静态资源。 */
|
|
4079
|
+
Web: "web",
|
|
4080
|
+
/** 运行时配置(Dockerfile / docker-compose.yml)。 */
|
|
4081
|
+
Runtime: "runtime",
|
|
4082
|
+
/** 启动 / 备份 / 恢复脚本。 */
|
|
4083
|
+
Scripts: "scripts",
|
|
4084
|
+
/** 文档(README / 部署手册)。 */
|
|
4085
|
+
Docs: "docs"
|
|
4086
|
+
};
|
|
4087
|
+
ALLOWED_CONTENT_KINDS = Object.values(BundleContentKind);
|
|
4088
|
+
}
|
|
3950
4089
|
});
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
const
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
return { reachable: true, status: response.status };
|
|
3958
|
-
} catch (error) {
|
|
4090
|
+
|
|
4091
|
+
// shared/deploy-bundle/validate.ts
|
|
4092
|
+
function validateBundleManifest(manifest) {
|
|
4093
|
+
const errors = [];
|
|
4094
|
+
const warnings = [];
|
|
4095
|
+
if (typeof manifest !== "object" || manifest === null) {
|
|
3959
4096
|
return {
|
|
3960
|
-
|
|
3961
|
-
|
|
4097
|
+
valid: false,
|
|
4098
|
+
errors: [{ code: "INVALID_TYPE", message: "Manifest \u5FC5\u987B\u662F\u5BF9\u8C61" }],
|
|
4099
|
+
warnings: []
|
|
3962
4100
|
};
|
|
3963
|
-
} finally {
|
|
3964
|
-
clearTimeout(timer);
|
|
3965
4101
|
}
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
4102
|
+
const m = manifest;
|
|
4103
|
+
const schemaVersion = m.schemaVersion;
|
|
4104
|
+
if (typeof schemaVersion !== "number" || !Number.isInteger(schemaVersion)) {
|
|
4105
|
+
errors.push({
|
|
4106
|
+
code: "INVALID_SCHEMA_VERSION",
|
|
4107
|
+
message: "schemaVersion \u5FC5\u987B\u662F\u6574\u6570",
|
|
4108
|
+
field: "schemaVersion"
|
|
4109
|
+
});
|
|
4110
|
+
} else if (schemaVersion > CURRENT_SCHEMA_VERSION) {
|
|
4111
|
+
errors.push({
|
|
4112
|
+
code: "SCHEMA_VERSION_TOO_HIGH",
|
|
4113
|
+
message: `schemaVersion ${schemaVersion} \u9AD8\u4E8E\u5F53\u524D\u652F\u6301\u7248\u672C ${CURRENT_SCHEMA_VERSION}\uFF0C\u9700\u5347\u7EA7\u5BFC\u51FA\u7AEF`,
|
|
4114
|
+
field: "schemaVersion"
|
|
4115
|
+
});
|
|
4116
|
+
} else if (schemaVersion < CURRENT_SCHEMA_VERSION) {
|
|
4117
|
+
warnings.push({
|
|
4118
|
+
code: "SCHEMA_VERSION_LOW",
|
|
4119
|
+
message: `schemaVersion ${schemaVersion} \u4F4E\u4E8E\u5F53\u524D\u7248\u672C ${CURRENT_SCHEMA_VERSION}\uFF0C\u5EFA\u8BAE\u91CD\u65B0\u5BFC\u51FA`,
|
|
4120
|
+
field: "schemaVersion"
|
|
4121
|
+
});
|
|
3973
4122
|
}
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
const health = await probeServer(server);
|
|
3981
|
-
const report = {
|
|
3982
|
-
server,
|
|
3983
|
-
credentials: {
|
|
3984
|
-
file: paths.credentialsFile,
|
|
3985
|
-
present: credentials !== null,
|
|
3986
|
-
...mode === void 0 ? {} : { mode }
|
|
3987
|
-
},
|
|
3988
|
-
network: { offline },
|
|
3989
|
-
serverHealth: health,
|
|
3990
|
-
offlineCommands: [...OFFLINE_COMMANDS],
|
|
3991
|
-
boundaries: SIM_BOUNDARIES.map((b) => ({ kind: b.kind, title: b.title, detail: b.detail }))
|
|
3992
|
-
};
|
|
3993
|
-
if (credentials !== null) report.credentials.email = credentials.email;
|
|
3994
|
-
if (mode !== void 0 && mode !== "600") {
|
|
3995
|
-
report.credentials.warning = `\u6743\u9650 ${mode} \u5BBD\u4E8E 0600\uFF0C\u5EFA\u8BAE chmod 600 ${paths.credentialsFile}`;
|
|
4123
|
+
if (typeof m.platformVersion !== "string" || m.platformVersion.trim() === "") {
|
|
4124
|
+
errors.push({
|
|
4125
|
+
code: "MISSING_PLATFORM_VERSION",
|
|
4126
|
+
message: "platformVersion \u5FC5\u987B\u975E\u7A7A",
|
|
4127
|
+
field: "platformVersion"
|
|
4128
|
+
});
|
|
3996
4129
|
}
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
lines.push(` \u2713 \u5DF2\u767B\u5F55 ${report.credentials.email ?? "(\u672A\u77E5\u90AE\u7BB1)"} @ ${report.server}`);
|
|
4004
|
-
lines.push(
|
|
4005
|
-
` \xB7 \u51ED\u636E\u6587\u4EF6 ${report.credentials.file}\uFF08${report.credentials.mode ?? "\u6743\u9650\u672A\u77E5"}\uFF09`
|
|
4006
|
-
);
|
|
4007
|
-
if (report.credentials.warning !== void 0) lines.push(` ! ${report.credentials.warning}`);
|
|
4130
|
+
if (typeof m.project !== "object" || m.project === null) {
|
|
4131
|
+
errors.push({
|
|
4132
|
+
code: "MISSING_PROJECT",
|
|
4133
|
+
message: "project \u5FC5\u987B\u662F\u5BF9\u8C61",
|
|
4134
|
+
field: "project"
|
|
4135
|
+
});
|
|
4008
4136
|
} else {
|
|
4009
|
-
|
|
4010
|
-
|
|
4137
|
+
const project2 = m.project;
|
|
4138
|
+
if (typeof project2.id !== "string" || project2.id.trim() === "") {
|
|
4139
|
+
errors.push({
|
|
4140
|
+
code: "MISSING_PROJECT_ID",
|
|
4141
|
+
message: "project.id \u5FC5\u987B\u975E\u7A7A",
|
|
4142
|
+
field: "project.id"
|
|
4143
|
+
});
|
|
4144
|
+
}
|
|
4145
|
+
if (typeof project2.name !== "string" || project2.name.trim() === "") {
|
|
4146
|
+
errors.push({
|
|
4147
|
+
code: "MISSING_PROJECT_NAME",
|
|
4148
|
+
message: "project.name \u5FC5\u987B\u975E\u7A7A",
|
|
4149
|
+
field: "project.name"
|
|
4150
|
+
});
|
|
4151
|
+
}
|
|
4152
|
+
if (typeof project2.slug !== "string" || project2.slug.trim() === "") {
|
|
4153
|
+
errors.push({
|
|
4154
|
+
code: "MISSING_PROJECT_SLUG",
|
|
4155
|
+
message: "project.slug \u5FC5\u987B\u975E\u7A7A",
|
|
4156
|
+
field: "project.slug"
|
|
4157
|
+
});
|
|
4158
|
+
}
|
|
4159
|
+
if (typeof project2.version !== "number" || !Number.isInteger(project2.version) || project2.version < 1) {
|
|
4160
|
+
errors.push({
|
|
4161
|
+
code: "INVALID_PROJECT_VERSION",
|
|
4162
|
+
message: "project.version \u5FC5\u987B\u662F\u6B63\u6574\u6570",
|
|
4163
|
+
field: "project.version"
|
|
4164
|
+
});
|
|
4165
|
+
}
|
|
4011
4166
|
}
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4167
|
+
if (!Array.isArray(m.contents)) {
|
|
4168
|
+
errors.push({
|
|
4169
|
+
code: "MISSING_CONTENTS",
|
|
4170
|
+
message: "contents \u5FC5\u987B\u662F\u6570\u7EC4",
|
|
4171
|
+
field: "contents"
|
|
4172
|
+
});
|
|
4173
|
+
} else if (m.contents.length === 0) {
|
|
4174
|
+
errors.push({
|
|
4175
|
+
code: "EMPTY_CONTENTS",
|
|
4176
|
+
message: "contents \u4E0D\u80FD\u4E3A\u7A7A",
|
|
4177
|
+
field: "contents"
|
|
4178
|
+
});
|
|
4018
4179
|
} else {
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
);
|
|
4180
|
+
m.contents.forEach((content, index) => {
|
|
4181
|
+
validateContent(content, index, errors, warnings);
|
|
4182
|
+
});
|
|
4023
4183
|
}
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4184
|
+
if (typeof m.runtime !== "object" || m.runtime === null) {
|
|
4185
|
+
errors.push({
|
|
4186
|
+
code: "MISSING_RUNTIME",
|
|
4187
|
+
message: "runtime \u5FC5\u987B\u662F\u5BF9\u8C61",
|
|
4188
|
+
field: "runtime"
|
|
4189
|
+
});
|
|
4190
|
+
} else {
|
|
4191
|
+
const runtime = m.runtime;
|
|
4192
|
+
if (typeof runtime.engine !== "string" || runtime.engine.trim() === "") {
|
|
4193
|
+
errors.push({
|
|
4194
|
+
code: "MISSING_ENGINE",
|
|
4195
|
+
message: "runtime.engine \u5FC5\u987B\u975E\u7A7A",
|
|
4196
|
+
field: "runtime.engine"
|
|
4197
|
+
});
|
|
4198
|
+
}
|
|
4199
|
+
if (typeof runtime.engineVersion !== "string" || runtime.engineVersion.trim() === "") {
|
|
4200
|
+
errors.push({
|
|
4201
|
+
code: "MISSING_ENGINE_VERSION",
|
|
4202
|
+
message: "runtime.engineVersion \u5FC5\u987B\u975E\u7A7A",
|
|
4203
|
+
field: "runtime.engineVersion"
|
|
4204
|
+
});
|
|
4205
|
+
}
|
|
4206
|
+
if (typeof runtime.port !== "number" || !Number.isInteger(runtime.port) || runtime.port < 1 || runtime.port > 65535) {
|
|
4207
|
+
errors.push({
|
|
4208
|
+
code: "INVALID_PORT",
|
|
4209
|
+
message: "runtime.port \u5FC5\u987B\u662F 1-65535 \u7684\u6574\u6570",
|
|
4210
|
+
field: "runtime.port"
|
|
4211
|
+
});
|
|
4212
|
+
}
|
|
4213
|
+
if (typeof runtime.startCommand !== "string" || runtime.startCommand.trim() === "") {
|
|
4214
|
+
errors.push({
|
|
4215
|
+
code: "MISSING_START_COMMAND",
|
|
4216
|
+
message: "runtime.startCommand \u5FC5\u987B\u975E\u7A7A",
|
|
4217
|
+
field: "runtime.startCommand"
|
|
4218
|
+
});
|
|
4219
|
+
}
|
|
4029
4220
|
}
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
"adep db\uFF08\u672C\u5730\u6A21\u62DF\uFF09",
|
|
4046
|
-
"adep doctor"
|
|
4047
|
-
];
|
|
4221
|
+
if (typeof m.exportedAt !== "string" || m.exportedAt.trim() === "") {
|
|
4222
|
+
errors.push({
|
|
4223
|
+
code: "MISSING_EXPORTED_AT",
|
|
4224
|
+
message: "exportedAt \u5FC5\u987B\u975E\u7A7A",
|
|
4225
|
+
field: "exportedAt"
|
|
4226
|
+
});
|
|
4227
|
+
} else {
|
|
4228
|
+
const date = new Date(m.exportedAt);
|
|
4229
|
+
if (Number.isNaN(date.getTime())) {
|
|
4230
|
+
errors.push({
|
|
4231
|
+
code: "INVALID_EXPORTED_AT",
|
|
4232
|
+
message: "exportedAt \u5FC5\u987B\u662F\u6709\u6548\u7684 ISO 8601 \u65F6\u95F4",
|
|
4233
|
+
field: "exportedAt"
|
|
4234
|
+
});
|
|
4235
|
+
}
|
|
4048
4236
|
}
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
dbExec: () => dbExec,
|
|
4055
|
-
dbRollback: () => dbRollback,
|
|
4056
|
-
dbSnapshotCreate: () => dbSnapshotCreate,
|
|
4057
|
-
dbSnapshotList: () => dbSnapshotList,
|
|
4058
|
-
dbSnapshotRestore: () => dbSnapshotRestore,
|
|
4059
|
-
dbStart: () => dbStart,
|
|
4060
|
-
dbStatus: () => dbStatus,
|
|
4061
|
-
dbStop: () => dbStop
|
|
4062
|
-
});
|
|
4063
|
-
import { resolve as resolve8 } from "node:path";
|
|
4064
|
-
async function open2(paths, options) {
|
|
4065
|
-
const client = await createClient(paths);
|
|
4066
|
-
const project2 = await resolveSlug(resolve8(options.cwd), options.slug);
|
|
4067
|
-
return { client, project: project2 };
|
|
4068
|
-
}
|
|
4069
|
-
async function dbStart(paths, options) {
|
|
4070
|
-
const { client, project: project2 } = await open2(paths, options);
|
|
4071
|
-
return client.request(`/api/v1/projects/${project2}/database`, { method: "POST" });
|
|
4072
|
-
}
|
|
4073
|
-
async function dbStatus(paths, options) {
|
|
4074
|
-
const { client, project: project2 } = await open2(paths, options);
|
|
4075
|
-
return client.request(`/api/v1/projects/${project2}/database`);
|
|
4076
|
-
}
|
|
4077
|
-
async function dbStop(paths, options) {
|
|
4078
|
-
const { client, project: project2 } = await open2(paths, options);
|
|
4079
|
-
return client.request(`/api/v1/projects/${project2}/database`, {
|
|
4080
|
-
method: "DELETE"
|
|
4081
|
-
});
|
|
4237
|
+
return {
|
|
4238
|
+
valid: errors.length === 0,
|
|
4239
|
+
errors,
|
|
4240
|
+
warnings
|
|
4241
|
+
};
|
|
4082
4242
|
}
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
...options.params === void 0 ? {} : { params: options.params },
|
|
4092
|
-
...options.confirmTable === void 0 ? {} : { confirmTable: options.confirmTable }
|
|
4093
|
-
}
|
|
4094
|
-
},
|
|
4095
|
-
"SQL_EXEC_FAILED"
|
|
4096
|
-
);
|
|
4097
|
-
}
|
|
4098
|
-
async function dbSnapshotList(paths, options) {
|
|
4099
|
-
const { client, project: project2 } = await open2(paths, options);
|
|
4100
|
-
return client.request(
|
|
4101
|
-
`/api/v1/projects/${project2}/database/snapshots`
|
|
4102
|
-
);
|
|
4103
|
-
}
|
|
4104
|
-
async function dbSnapshotCreate(paths, options) {
|
|
4105
|
-
const { client, project: project2 } = await open2(paths, options);
|
|
4106
|
-
return client.request(`/api/v1/projects/${project2}/database/snapshots`, {
|
|
4107
|
-
method: "POST"
|
|
4108
|
-
});
|
|
4109
|
-
}
|
|
4110
|
-
async function dbSnapshotRestore(paths, options) {
|
|
4111
|
-
const { client, project: project2 } = await open2(paths, options);
|
|
4112
|
-
return client.request(
|
|
4113
|
-
`/api/v1/projects/${project2}/database/snapshots/${options.snapshotId}/restore`,
|
|
4114
|
-
{ method: "POST" }
|
|
4115
|
-
);
|
|
4116
|
-
}
|
|
4117
|
-
async function dbRollback(paths, options) {
|
|
4118
|
-
const { client, project: project2 } = await open2(paths, options);
|
|
4119
|
-
return client.request(
|
|
4120
|
-
`/api/v1/projects/${project2}/database/rollback`,
|
|
4121
|
-
{ method: "POST", body: { to: options.to } }
|
|
4122
|
-
);
|
|
4123
|
-
}
|
|
4124
|
-
var init_db2 = __esm({
|
|
4125
|
-
"packages/cli/src/db.ts"() {
|
|
4126
|
-
"use strict";
|
|
4127
|
-
init_client();
|
|
4243
|
+
function validateContent(content, index, errors, _warnings) {
|
|
4244
|
+
if (typeof content !== "object" || content === null) {
|
|
4245
|
+
errors.push({
|
|
4246
|
+
code: "INVALID_CONTENT",
|
|
4247
|
+
message: `contents[${index}] \u5FC5\u987B\u662F\u5BF9\u8C61`,
|
|
4248
|
+
field: `contents[${index}]`
|
|
4249
|
+
});
|
|
4250
|
+
return;
|
|
4128
4251
|
}
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
storageList: () => storageList,
|
|
4137
|
-
storageRemove: () => storageRemove,
|
|
4138
|
-
storageUpload: () => storageUpload
|
|
4139
|
-
});
|
|
4140
|
-
import { mkdir as mkdir7, readFile as readFile8, stat as stat7, writeFile as writeFile5 } from "node:fs/promises";
|
|
4141
|
-
import { basename as basename3, dirname as dirname6, extname, join as join10, resolve as resolve9 } from "node:path";
|
|
4142
|
-
async function open3(paths, options) {
|
|
4143
|
-
const client = await createClient(paths);
|
|
4144
|
-
const project2 = await resolveSlug(resolve9(options.cwd), options.slug);
|
|
4145
|
-
return { client, project: project2 };
|
|
4146
|
-
}
|
|
4147
|
-
function contentTypeOf(path) {
|
|
4148
|
-
const map = {
|
|
4149
|
-
".html": "text/html; charset=utf-8",
|
|
4150
|
-
".htm": "text/html; charset=utf-8",
|
|
4151
|
-
".css": "text/css; charset=utf-8",
|
|
4152
|
-
".js": "text/javascript; charset=utf-8",
|
|
4153
|
-
".mjs": "text/javascript; charset=utf-8",
|
|
4154
|
-
".json": "application/json; charset=utf-8",
|
|
4155
|
-
".png": "image/png",
|
|
4156
|
-
".jpg": "image/jpeg",
|
|
4157
|
-
".jpeg": "image/jpeg",
|
|
4158
|
-
".gif": "image/gif",
|
|
4159
|
-
".svg": "image/svg+xml",
|
|
4160
|
-
".webp": "image/webp",
|
|
4161
|
-
".ico": "image/x-icon",
|
|
4162
|
-
".txt": "text/plain; charset=utf-8",
|
|
4163
|
-
".md": "text/markdown; charset=utf-8",
|
|
4164
|
-
".xml": "application/xml",
|
|
4165
|
-
".wasm": "application/wasm",
|
|
4166
|
-
".pdf": "application/pdf",
|
|
4167
|
-
".zip": "application/zip",
|
|
4168
|
-
".woff": "font/woff",
|
|
4169
|
-
".woff2": "font/woff2",
|
|
4170
|
-
".ttf": "font/ttf",
|
|
4171
|
-
".otf": "font/otf"
|
|
4172
|
-
};
|
|
4173
|
-
return map[extname(path).toLowerCase()] ?? "application/octet-stream";
|
|
4174
|
-
}
|
|
4175
|
-
async function storageUpload(paths, options) {
|
|
4176
|
-
const { client, project: project2 } = await open3(paths, options);
|
|
4177
|
-
const local = resolve9(options.file);
|
|
4178
|
-
const info = await stat7(local).catch(() => null);
|
|
4179
|
-
if (info === null || !info.isFile()) {
|
|
4180
|
-
throw new CliError("FILE_NOT_FOUND", `\u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${local}`);
|
|
4252
|
+
const c = content;
|
|
4253
|
+
if (typeof c.path !== "string" || c.path.trim() === "") {
|
|
4254
|
+
errors.push({
|
|
4255
|
+
code: "MISSING_CONTENT_PATH",
|
|
4256
|
+
message: `contents[${index}].path \u5FC5\u987B\u975E\u7A7A`,
|
|
4257
|
+
field: `contents[${index}].path`
|
|
4258
|
+
});
|
|
4181
4259
|
}
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
}
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
}
|
|
4208
|
-
async function resolveDownloadUrl(client, project2, path) {
|
|
4209
|
-
const body = await client.request(
|
|
4210
|
-
`/api/v1/projects/${project2}/files?prefix=${encodeURIComponent(path)}`
|
|
4211
|
-
);
|
|
4212
|
-
const entry = body.files.find((file) => file.path === path);
|
|
4213
|
-
const url = entry?.url ?? entry?.signedUrl;
|
|
4214
|
-
if (entry === void 0 || url === void 0 || url.length === 0) {
|
|
4215
|
-
throw new CliError("STORAGE_NOT_FOUND", `\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${path}`);
|
|
4260
|
+
if (typeof c.sha256 !== "string" || c.sha256.trim() === "") {
|
|
4261
|
+
errors.push({
|
|
4262
|
+
code: "MISSING_CONTENT_SHA256",
|
|
4263
|
+
message: `contents[${index}].sha256 \u5FC5\u987B\u975E\u7A7A`,
|
|
4264
|
+
field: `contents[${index}].sha256`
|
|
4265
|
+
});
|
|
4266
|
+
} else if (!/^[a-fA-F0-9]{64}$/.test(c.sha256)) {
|
|
4267
|
+
errors.push({
|
|
4268
|
+
code: "INVALID_SHA256_FORMAT",
|
|
4269
|
+
message: `contents[${index}].sha256 \u5FC5\u987B\u662F 64 \u5B57\u7B26\u5341\u516D\u8FDB\u5236`,
|
|
4270
|
+
field: `contents[${index}].sha256`
|
|
4271
|
+
});
|
|
4272
|
+
}
|
|
4273
|
+
if (typeof c.kind !== "string" || c.kind.trim() === "") {
|
|
4274
|
+
errors.push({
|
|
4275
|
+
code: "MISSING_CONTENT_KIND",
|
|
4276
|
+
message: `contents[${index}].kind \u5FC5\u987B\u975E\u7A7A`,
|
|
4277
|
+
field: `contents[${index}].kind`
|
|
4278
|
+
});
|
|
4279
|
+
} else if (!ALLOWED_CONTENT_KINDS.includes(c.kind)) {
|
|
4280
|
+
errors.push({
|
|
4281
|
+
code: "INVALID_CONTENT_KIND",
|
|
4282
|
+
message: `contents[${index}].kind "${c.kind}" \u4E0D\u5728\u5141\u8BB8\u5217\u8868\u5185\uFF0C\u5141\u8BB8\u503C\uFF1A${ALLOWED_CONTENT_KINDS.join(", ")}`,
|
|
4283
|
+
field: `contents[${index}].kind`
|
|
4284
|
+
});
|
|
4216
4285
|
}
|
|
4217
|
-
return url;
|
|
4218
|
-
}
|
|
4219
|
-
async function storageDownload(paths, options) {
|
|
4220
|
-
const { client, project: project2 } = await open3(paths, options);
|
|
4221
|
-
const url = await resolveDownloadUrl(client, project2, options.path);
|
|
4222
|
-
const response = await client.download(url, "STORAGE_DOWNLOAD_FAILED");
|
|
4223
|
-
const bytes = Buffer.from(await response.arrayBuffer());
|
|
4224
|
-
const output = resolve9(options.output ?? join10(resolve9(options.cwd), basename3(options.path)));
|
|
4225
|
-
await mkdir7(dirname6(output), { recursive: true });
|
|
4226
|
-
await writeFile5(output, bytes);
|
|
4227
|
-
return { path: options.path, output, size: bytes.length };
|
|
4228
4286
|
}
|
|
4229
|
-
|
|
4230
|
-
const
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4287
|
+
function verifyContents(contents, actualContents, hashFunction) {
|
|
4288
|
+
const errors = [];
|
|
4289
|
+
const warnings = [];
|
|
4290
|
+
for (const content of contents) {
|
|
4291
|
+
const actual = actualContents.get(content.path);
|
|
4292
|
+
if (actual === void 0) {
|
|
4293
|
+
errors.push({
|
|
4294
|
+
code: "CONTENT_NOT_FOUND",
|
|
4295
|
+
message: `\u5185\u5BB9\u7269 ${content.path} \u5728\u5B9E\u9645\u5305\u4E2D\u4E0D\u5B58\u5728`,
|
|
4296
|
+
field: `contents[${content.path}]`
|
|
4297
|
+
});
|
|
4298
|
+
continue;
|
|
4299
|
+
}
|
|
4300
|
+
const actualHash = hashFunction(actual);
|
|
4301
|
+
if (actualHash.toLowerCase() !== content.sha256.toLowerCase()) {
|
|
4302
|
+
errors.push({
|
|
4303
|
+
code: "CHECKSUM_MISMATCH",
|
|
4304
|
+
message: `\u5185\u5BB9\u7269 ${content.path} \u7684\u6821\u9A8C\u548C\u4E0D\u5339\u914D\uFF1A\u671F\u671B ${content.sha256}\uFF0C\u5B9E\u9645 ${actualHash}`,
|
|
4305
|
+
field: `contents[${content.path}].sha256`
|
|
4306
|
+
});
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
for (const path of actualContents.keys()) {
|
|
4310
|
+
if (!contents.some((c) => c.path === path)) {
|
|
4311
|
+
warnings.push({
|
|
4312
|
+
code: "UNDECLARED_CONTENT",
|
|
4313
|
+
message: `\u5B9E\u9645\u5305\u4E2D\u5B58\u5728 Manifest \u672A\u58F0\u660E\u7684\u5185\u5BB9\uFF1A${path}`,
|
|
4314
|
+
field: `contents[${path}]`
|
|
4315
|
+
});
|
|
4316
|
+
}
|
|
4317
|
+
}
|
|
4318
|
+
return {
|
|
4319
|
+
valid: errors.length === 0,
|
|
4320
|
+
errors,
|
|
4321
|
+
warnings
|
|
4322
|
+
};
|
|
4235
4323
|
}
|
|
4236
|
-
var
|
|
4237
|
-
"
|
|
4324
|
+
var init_validate = __esm({
|
|
4325
|
+
"shared/deploy-bundle/validate.ts"() {
|
|
4238
4326
|
"use strict";
|
|
4239
|
-
|
|
4240
|
-
init_auth();
|
|
4327
|
+
init_manifest2();
|
|
4241
4328
|
}
|
|
4242
4329
|
});
|
|
4243
4330
|
|
|
4244
|
-
// packages/cli/src/
|
|
4245
|
-
var
|
|
4246
|
-
__export(
|
|
4247
|
-
|
|
4248
|
-
hostingDeploy: () => hostingDeploy,
|
|
4249
|
-
hostingInfo: () => hostingInfo,
|
|
4250
|
-
hostingPull: () => hostingPull
|
|
4331
|
+
// packages/cli/src/export/command.ts
|
|
4332
|
+
var command_exports = {};
|
|
4333
|
+
__export(command_exports, {
|
|
4334
|
+
ExportCommand: () => ExportCommand
|
|
4251
4335
|
});
|
|
4252
|
-
import {
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
siteUrl: body.siteUrl,
|
|
4265
|
-
files: body.files ?? []
|
|
4266
|
-
};
|
|
4267
|
-
}
|
|
4268
|
-
async function collectSiteFiles(dir) {
|
|
4269
|
-
const root = resolve10(dir);
|
|
4270
|
-
const files = /* @__PURE__ */ new Map();
|
|
4271
|
-
const walk = async (sub) => {
|
|
4272
|
-
let entries;
|
|
4273
|
-
try {
|
|
4274
|
-
entries = await readdir5(sub, { withFileTypes: true });
|
|
4275
|
-
} catch {
|
|
4276
|
-
return;
|
|
4277
|
-
}
|
|
4278
|
-
for (const entry of entries) {
|
|
4279
|
-
const full = join11(sub, entry.name);
|
|
4280
|
-
if (entry.isDirectory()) {
|
|
4281
|
-
await walk(full);
|
|
4282
|
-
} else if (entry.isFile()) {
|
|
4283
|
-
const rel = relative2(root, full).split(sep).join("/");
|
|
4284
|
-
files.set(rel, full);
|
|
4336
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
4337
|
+
var ExportCommand;
|
|
4338
|
+
var init_command = __esm({
|
|
4339
|
+
"packages/cli/src/export/command.ts"() {
|
|
4340
|
+
"use strict";
|
|
4341
|
+
init_validate();
|
|
4342
|
+
ExportCommand = class {
|
|
4343
|
+
constructor(apiClient, fs, pollInterval = 2e3, maxPollAttempts = 300) {
|
|
4344
|
+
this.apiClient = apiClient;
|
|
4345
|
+
this.fs = fs;
|
|
4346
|
+
this.pollInterval = pollInterval;
|
|
4347
|
+
this.maxPollAttempts = maxPollAttempts;
|
|
4285
4348
|
}
|
|
4286
|
-
|
|
4349
|
+
/**
|
|
4350
|
+
* 执行导出命令。
|
|
4351
|
+
*
|
|
4352
|
+
* @param options 命令选项
|
|
4353
|
+
* @returns 导出结果
|
|
4354
|
+
*/
|
|
4355
|
+
async execute(options) {
|
|
4356
|
+
const projectId = options.project ?? "default";
|
|
4357
|
+
const outputDir = options.out ?? "./exports";
|
|
4358
|
+
const jsonOutput = options.json ?? false;
|
|
4359
|
+
try {
|
|
4360
|
+
if (!jsonOutput) {
|
|
4361
|
+
console.log(`\u89E6\u53D1\u5BFC\u51FA\uFF1A\u9879\u76EE ${projectId}`);
|
|
4362
|
+
}
|
|
4363
|
+
const job = await this.apiClient.triggerExport(projectId, {
|
|
4364
|
+
withData: options.withData,
|
|
4365
|
+
withSource: options.withSource,
|
|
4366
|
+
withoutSource: options.withoutSource
|
|
4367
|
+
});
|
|
4368
|
+
if (!jsonOutput) {
|
|
4369
|
+
console.log(`\u5BFC\u51FA\u4EFB\u52A1\u5DF2\u521B\u5EFA\uFF1A${job.id}`);
|
|
4370
|
+
}
|
|
4371
|
+
const completedJob = await this.pollJobStatus(job.id, jsonOutput);
|
|
4372
|
+
if (completedJob.status === "failed") {
|
|
4373
|
+
return {
|
|
4374
|
+
success: false,
|
|
4375
|
+
jobId: job.id,
|
|
4376
|
+
status: "failed",
|
|
4377
|
+
error: completedJob.error ?? "\u5BFC\u51FA\u5931\u8D25"
|
|
4378
|
+
};
|
|
4379
|
+
}
|
|
4380
|
+
if (!jsonOutput) {
|
|
4381
|
+
console.log("\u4E0B\u8F7D\u5BFC\u51FA\u4EA7\u7269...");
|
|
4382
|
+
}
|
|
4383
|
+
const outputPath = `${outputDir}/${projectId}-export-${Date.now()}.zip`;
|
|
4384
|
+
await this.fs.mkdir(outputDir);
|
|
4385
|
+
const downloadResult = await this.apiClient.downloadBundle(job.id, outputPath);
|
|
4386
|
+
if (!jsonOutput) {
|
|
4387
|
+
console.log(`\u4EA7\u7269\u5DF2\u4E0B\u8F7D\uFF1A${downloadResult.path}\uFF08${this.formatSize(downloadResult.size)}\uFF09`);
|
|
4388
|
+
}
|
|
4389
|
+
if (!jsonOutput) {
|
|
4390
|
+
console.log("\u6267\u884C manifest \u81EA\u68C0...");
|
|
4391
|
+
}
|
|
4392
|
+
const manifest = await this.verifyManifest(downloadResult.path);
|
|
4393
|
+
if (!jsonOutput) {
|
|
4394
|
+
this.printContentList(manifest);
|
|
4395
|
+
}
|
|
4396
|
+
return {
|
|
4397
|
+
success: true,
|
|
4398
|
+
jobId: job.id,
|
|
4399
|
+
status: "completed",
|
|
4400
|
+
downloadPath: downloadResult.path,
|
|
4401
|
+
manifest: {
|
|
4402
|
+
projectName: manifest.project.name,
|
|
4403
|
+
platformVersion: manifest.platformVersion,
|
|
4404
|
+
exportedAt: manifest.exportedAt,
|
|
4405
|
+
contents: this.countContents(manifest.contents)
|
|
4406
|
+
}
|
|
4407
|
+
};
|
|
4408
|
+
} catch (error) {
|
|
4409
|
+
const message = error instanceof Error ? error.message : "unknown_error";
|
|
4410
|
+
if (message.includes("ECONNREFUSED") || message.includes("ENOTFOUND") || message.includes("network")) {
|
|
4411
|
+
return {
|
|
4412
|
+
success: false,
|
|
4413
|
+
error: `\u5E73\u53F0\u7AEF\u70B9\u4E0D\u53EF\u8FBE\uFF1A${message}\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C\u5E73\u53F0\u5730\u5740\u914D\u7F6E\uFF0C\u7136\u540E\u91CD\u8BD5\u3002`
|
|
4414
|
+
};
|
|
4415
|
+
}
|
|
4416
|
+
return {
|
|
4417
|
+
success: false,
|
|
4418
|
+
error: message
|
|
4419
|
+
};
|
|
4420
|
+
}
|
|
4421
|
+
}
|
|
4422
|
+
/**
|
|
4423
|
+
* 轮询任务状态。
|
|
4424
|
+
*
|
|
4425
|
+
* @param jobId 任务 ID
|
|
4426
|
+
* @param jsonOutput 是否 JSON 输出
|
|
4427
|
+
* @returns 完成的任务
|
|
4428
|
+
*/
|
|
4429
|
+
async pollJobStatus(jobId, jsonOutput) {
|
|
4430
|
+
let attempts = 0;
|
|
4431
|
+
let lastProgress = -1;
|
|
4432
|
+
while (attempts < this.maxPollAttempts) {
|
|
4433
|
+
const job = await this.apiClient.getJobStatus(jobId);
|
|
4434
|
+
if (!jsonOutput && job.progress !== lastProgress) {
|
|
4435
|
+
const stage = job.stage ? `\uFF08${job.stage}\uFF09` : "";
|
|
4436
|
+
console.log(`\u8FDB\u5EA6\uFF1A${job.progress}%${stage}`);
|
|
4437
|
+
lastProgress = job.progress;
|
|
4438
|
+
}
|
|
4439
|
+
if (job.status === "completed" || job.status === "failed") {
|
|
4440
|
+
return job;
|
|
4441
|
+
}
|
|
4442
|
+
attempts++;
|
|
4443
|
+
await this.sleep(this.pollInterval);
|
|
4444
|
+
}
|
|
4445
|
+
throw new Error(`\u5BFC\u51FA\u4EFB\u52A1\u8D85\u65F6\uFF1A\u8F6E\u8BE2 ${this.maxPollAttempts} \u6B21\u540E\u4ECD\u672A\u5B8C\u6210`);
|
|
4446
|
+
}
|
|
4447
|
+
/**
|
|
4448
|
+
* 验证 Manifest:解压 → 契约校验 → 逐项 sha256 校验 → 清理临时目录。
|
|
4449
|
+
*
|
|
4450
|
+
* 逐项校验与导出端同法:内容物以 latin1 承载(逐字节双射,二进制条目不被解码改写),
|
|
4451
|
+
* 比对时对原字节做真实 sha256;任一不匹配即判定包损坏并抛错,不静默放行。
|
|
4452
|
+
* 无论成功失败,`${zip}.tmp` 临时目录都在 finally 里删除,不留残余。
|
|
4453
|
+
*
|
|
4454
|
+
* @param zipPath ZIP 文件路径
|
|
4455
|
+
* @returns Manifest
|
|
4456
|
+
*/
|
|
4457
|
+
async verifyManifest(zipPath) {
|
|
4458
|
+
const tempDir = `${zipPath}.tmp`;
|
|
4459
|
+
try {
|
|
4460
|
+
await this.fs.mkdir(tempDir);
|
|
4461
|
+
await this.fs.unzip(zipPath, tempDir);
|
|
4462
|
+
const manifestPath = `${tempDir}/manifest.json`;
|
|
4463
|
+
if (!await this.fs.fileExists(manifestPath)) {
|
|
4464
|
+
throw new Error("manifest.json \u4E0D\u5B58\u5728\uFF0C\u5305\u53EF\u80FD\u5DF2\u635F\u574F");
|
|
4465
|
+
}
|
|
4466
|
+
const manifestContent = await this.fs.readFile(manifestPath);
|
|
4467
|
+
const manifest = JSON.parse(manifestContent.toString("utf-8"));
|
|
4468
|
+
const validationResult = validateBundleManifest(manifest);
|
|
4469
|
+
if (!validationResult.valid) {
|
|
4470
|
+
const errors = validationResult.errors.map((e) => `${e.field ?? ""}: ${e.message}`).join("\n");
|
|
4471
|
+
throw new Error(`manifest \u6821\u9A8C\u5931\u8D25\uFF1A
|
|
4472
|
+
${errors}`);
|
|
4473
|
+
}
|
|
4474
|
+
const actual = /* @__PURE__ */ new Map();
|
|
4475
|
+
for (const content of manifest.contents) {
|
|
4476
|
+
const filePath = `${tempDir}/${content.path}`;
|
|
4477
|
+
if (await this.fs.fileExists(filePath)) {
|
|
4478
|
+
const bytes = await this.fs.readFile(filePath);
|
|
4479
|
+
actual.set(content.path, bytes.toString("latin1"));
|
|
4480
|
+
}
|
|
4481
|
+
}
|
|
4482
|
+
const contentResult = verifyContents(
|
|
4483
|
+
manifest.contents,
|
|
4484
|
+
actual,
|
|
4485
|
+
(text) => createHash3("sha256").update(Buffer.from(text, "latin1")).digest("hex")
|
|
4486
|
+
);
|
|
4487
|
+
if (!contentResult.valid) {
|
|
4488
|
+
const detail = contentResult.errors.map((e) => e.message).join("\n");
|
|
4489
|
+
throw new Error(`\u5185\u5BB9\u7269\u6821\u9A8C\u548C\u4E0D\u5339\u914D\uFF1A
|
|
4490
|
+
${detail}`);
|
|
4491
|
+
}
|
|
4492
|
+
return manifest;
|
|
4493
|
+
} finally {
|
|
4494
|
+
await this.fs.deleteFile(tempDir);
|
|
4495
|
+
}
|
|
4496
|
+
}
|
|
4497
|
+
/**
|
|
4498
|
+
* 统计内容物数量。
|
|
4499
|
+
*
|
|
4500
|
+
* @param contents 内容物列表
|
|
4501
|
+
* @returns 统计结果
|
|
4502
|
+
*/
|
|
4503
|
+
countContents(contents) {
|
|
4504
|
+
return {
|
|
4505
|
+
functions: contents.filter((c) => c.kind === "functions").length,
|
|
4506
|
+
database: contents.filter((c) => c.kind === "database").length,
|
|
4507
|
+
web: contents.filter((c) => c.kind === "web").length,
|
|
4508
|
+
runtime: contents.filter((c) => c.kind === "runtime").length,
|
|
4509
|
+
scripts: contents.filter((c) => c.kind === "scripts").length,
|
|
4510
|
+
docs: contents.filter((c) => c.kind === "docs").length,
|
|
4511
|
+
total: contents.length
|
|
4512
|
+
};
|
|
4513
|
+
}
|
|
4514
|
+
/**
|
|
4515
|
+
* 打印内容清单。
|
|
4516
|
+
*
|
|
4517
|
+
* @param manifest Manifest
|
|
4518
|
+
*/
|
|
4519
|
+
printContentList(manifest) {
|
|
4520
|
+
const counts = this.countContents(manifest.contents);
|
|
4521
|
+
console.log("");
|
|
4522
|
+
console.log("==========================================");
|
|
4523
|
+
console.log("\u5BFC\u51FA\u5185\u5BB9\u6E05\u5355");
|
|
4524
|
+
console.log("==========================================");
|
|
4525
|
+
console.log(`\u9879\u76EE\uFF1A${manifest.project.name}`);
|
|
4526
|
+
console.log(`\u5E73\u53F0\u7248\u672C\uFF1A${manifest.platformVersion}`);
|
|
4527
|
+
console.log(`\u5BFC\u51FA\u65F6\u95F4\uFF1A${manifest.exportedAt}`);
|
|
4528
|
+
console.log("");
|
|
4529
|
+
console.log(`\u51FD\u6570\u6587\u4EF6\uFF1A${counts.functions}`);
|
|
4530
|
+
console.log(`\u6570\u636E\u5E93\u6587\u4EF6\uFF1A${counts.database}`);
|
|
4531
|
+
console.log(`\u524D\u7AEF\u6587\u4EF6\uFF1A${counts.web}`);
|
|
4532
|
+
console.log(`\u8FD0\u884C\u65F6\u6587\u4EF6\uFF1A${counts.runtime}`);
|
|
4533
|
+
console.log(`\u811A\u672C\u6587\u4EF6\uFF1A${counts.scripts}`);
|
|
4534
|
+
console.log(`\u6587\u6863\u6587\u4EF6\uFF1A${counts.docs}`);
|
|
4535
|
+
console.log(`\u603B\u6587\u4EF6\u6570\uFF1A${counts.total}`);
|
|
4536
|
+
console.log("==========================================");
|
|
4537
|
+
}
|
|
4538
|
+
/**
|
|
4539
|
+
* 格式化文件大小。
|
|
4540
|
+
*
|
|
4541
|
+
* @param bytes 字节数
|
|
4542
|
+
* @returns 格式化后的大小
|
|
4543
|
+
*/
|
|
4544
|
+
formatSize(bytes) {
|
|
4545
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
4546
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
4547
|
+
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
4548
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
4549
|
+
}
|
|
4550
|
+
/**
|
|
4551
|
+
* 睡眠指定毫秒数。
|
|
4552
|
+
*
|
|
4553
|
+
* @param ms 毫秒数
|
|
4554
|
+
*/
|
|
4555
|
+
sleep(ms) {
|
|
4556
|
+
return new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
4557
|
+
}
|
|
4558
|
+
};
|
|
4559
|
+
}
|
|
4560
|
+
});
|
|
4561
|
+
|
|
4562
|
+
// packages/cli/src/db.ts
|
|
4563
|
+
var db_exports = {};
|
|
4564
|
+
__export(db_exports, {
|
|
4565
|
+
dbExec: () => dbExec,
|
|
4566
|
+
dbRollback: () => dbRollback,
|
|
4567
|
+
dbSnapshotCreate: () => dbSnapshotCreate,
|
|
4568
|
+
dbSnapshotList: () => dbSnapshotList,
|
|
4569
|
+
dbSnapshotRestore: () => dbSnapshotRestore,
|
|
4570
|
+
dbStart: () => dbStart,
|
|
4571
|
+
dbStatus: () => dbStatus,
|
|
4572
|
+
dbStop: () => dbStop
|
|
4573
|
+
});
|
|
4574
|
+
import { resolve as resolve7 } from "node:path";
|
|
4575
|
+
async function open2(paths, options) {
|
|
4576
|
+
const client = await createClient(paths);
|
|
4577
|
+
const project2 = await resolveSlug(resolve7(options.cwd), options.slug);
|
|
4578
|
+
return { client, project: project2 };
|
|
4579
|
+
}
|
|
4580
|
+
async function dbStart(paths, options) {
|
|
4581
|
+
const { client, project: project2 } = await open2(paths, options);
|
|
4582
|
+
return client.request(`/api/v1/projects/${project2}/database`, { method: "POST" });
|
|
4583
|
+
}
|
|
4584
|
+
async function dbStatus(paths, options) {
|
|
4585
|
+
const { client, project: project2 } = await open2(paths, options);
|
|
4586
|
+
return client.request(`/api/v1/projects/${project2}/database`);
|
|
4587
|
+
}
|
|
4588
|
+
async function dbStop(paths, options) {
|
|
4589
|
+
const { client, project: project2 } = await open2(paths, options);
|
|
4590
|
+
return client.request(`/api/v1/projects/${project2}/database`, {
|
|
4591
|
+
method: "DELETE"
|
|
4592
|
+
});
|
|
4593
|
+
}
|
|
4594
|
+
async function dbExec(paths, options) {
|
|
4595
|
+
const { client, project: project2 } = await open2(paths, options);
|
|
4596
|
+
return client.request(
|
|
4597
|
+
`/api/v1/projects/${project2}/database/console/sql`,
|
|
4598
|
+
{
|
|
4599
|
+
method: "POST",
|
|
4600
|
+
body: {
|
|
4601
|
+
sql: options.sql,
|
|
4602
|
+
...options.params === void 0 ? {} : { params: options.params },
|
|
4603
|
+
...options.confirmTable === void 0 ? {} : { confirmTable: options.confirmTable }
|
|
4604
|
+
}
|
|
4605
|
+
},
|
|
4606
|
+
"SQL_EXEC_FAILED"
|
|
4607
|
+
);
|
|
4608
|
+
}
|
|
4609
|
+
async function dbSnapshotList(paths, options) {
|
|
4610
|
+
const { client, project: project2 } = await open2(paths, options);
|
|
4611
|
+
return client.request(
|
|
4612
|
+
`/api/v1/projects/${project2}/database/snapshots`
|
|
4613
|
+
);
|
|
4614
|
+
}
|
|
4615
|
+
async function dbSnapshotCreate(paths, options) {
|
|
4616
|
+
const { client, project: project2 } = await open2(paths, options);
|
|
4617
|
+
return client.request(`/api/v1/projects/${project2}/database/snapshots`, {
|
|
4618
|
+
method: "POST"
|
|
4619
|
+
});
|
|
4620
|
+
}
|
|
4621
|
+
async function dbSnapshotRestore(paths, options) {
|
|
4622
|
+
const { client, project: project2 } = await open2(paths, options);
|
|
4623
|
+
return client.request(
|
|
4624
|
+
`/api/v1/projects/${project2}/database/snapshots/${options.snapshotId}/restore`,
|
|
4625
|
+
{ method: "POST" }
|
|
4626
|
+
);
|
|
4627
|
+
}
|
|
4628
|
+
async function dbRollback(paths, options) {
|
|
4629
|
+
const { client, project: project2 } = await open2(paths, options);
|
|
4630
|
+
return client.request(
|
|
4631
|
+
`/api/v1/projects/${project2}/database/rollback`,
|
|
4632
|
+
{ method: "POST", body: { to: options.to } }
|
|
4633
|
+
);
|
|
4634
|
+
}
|
|
4635
|
+
var init_db2 = __esm({
|
|
4636
|
+
"packages/cli/src/db.ts"() {
|
|
4637
|
+
"use strict";
|
|
4638
|
+
init_client();
|
|
4639
|
+
}
|
|
4640
|
+
});
|
|
4641
|
+
|
|
4642
|
+
// packages/cli/src/storage.ts
|
|
4643
|
+
var storage_exports = {};
|
|
4644
|
+
__export(storage_exports, {
|
|
4645
|
+
contentTypeOf: () => contentTypeOf,
|
|
4646
|
+
storageDownload: () => storageDownload,
|
|
4647
|
+
storageList: () => storageList,
|
|
4648
|
+
storageRemove: () => storageRemove,
|
|
4649
|
+
storageUpload: () => storageUpload
|
|
4650
|
+
});
|
|
4651
|
+
import { mkdir as mkdir8, readFile as readFile10, stat as stat7, writeFile as writeFile7 } from "node:fs/promises";
|
|
4652
|
+
import { basename as basename3, dirname as dirname7, extname, join as join12, resolve as resolve8 } from "node:path";
|
|
4653
|
+
async function open3(paths, options) {
|
|
4654
|
+
const client = await createClient(paths);
|
|
4655
|
+
const project2 = await resolveSlug(resolve8(options.cwd), options.slug);
|
|
4656
|
+
return { client, project: project2 };
|
|
4657
|
+
}
|
|
4658
|
+
function contentTypeOf(path) {
|
|
4659
|
+
const map = {
|
|
4660
|
+
".html": "text/html; charset=utf-8",
|
|
4661
|
+
".htm": "text/html; charset=utf-8",
|
|
4662
|
+
".css": "text/css; charset=utf-8",
|
|
4663
|
+
".js": "text/javascript; charset=utf-8",
|
|
4664
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
4665
|
+
".json": "application/json; charset=utf-8",
|
|
4666
|
+
".png": "image/png",
|
|
4667
|
+
".jpg": "image/jpeg",
|
|
4668
|
+
".jpeg": "image/jpeg",
|
|
4669
|
+
".gif": "image/gif",
|
|
4670
|
+
".svg": "image/svg+xml",
|
|
4671
|
+
".webp": "image/webp",
|
|
4672
|
+
".ico": "image/x-icon",
|
|
4673
|
+
".txt": "text/plain; charset=utf-8",
|
|
4674
|
+
".md": "text/markdown; charset=utf-8",
|
|
4675
|
+
".xml": "application/xml",
|
|
4676
|
+
".wasm": "application/wasm",
|
|
4677
|
+
".pdf": "application/pdf",
|
|
4678
|
+
".zip": "application/zip",
|
|
4679
|
+
".woff": "font/woff",
|
|
4680
|
+
".woff2": "font/woff2",
|
|
4681
|
+
".ttf": "font/ttf",
|
|
4682
|
+
".otf": "font/otf"
|
|
4287
4683
|
};
|
|
4288
|
-
|
|
4289
|
-
return files;
|
|
4684
|
+
return map[extname(path).toLowerCase()] ?? "application/octet-stream";
|
|
4290
4685
|
}
|
|
4291
|
-
async function
|
|
4292
|
-
const { client, project: project2 } = await
|
|
4293
|
-
const
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${resolve10(options.dir)}`);
|
|
4686
|
+
async function storageUpload(paths, options) {
|
|
4687
|
+
const { client, project: project2 } = await open3(paths, options);
|
|
4688
|
+
const local = resolve8(options.file);
|
|
4689
|
+
const info = await stat7(local).catch(() => null);
|
|
4690
|
+
if (info === null || !info.isFile()) {
|
|
4691
|
+
throw new CliError("FILE_NOT_FOUND", `\u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${local}`);
|
|
4298
4692
|
}
|
|
4299
|
-
const
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4693
|
+
const visibility = options.visibility ?? "private";
|
|
4694
|
+
const bytes = await readFile10(local);
|
|
4695
|
+
const form = new FormData();
|
|
4696
|
+
form.set("path", options.path);
|
|
4697
|
+
form.set("visibility", visibility);
|
|
4698
|
+
form.set(
|
|
4699
|
+
"file",
|
|
4700
|
+
new Blob([bytes], { type: contentTypeOf(options.path) }),
|
|
4701
|
+
basename3(local)
|
|
4702
|
+
);
|
|
4703
|
+
const response = await client.upload(
|
|
4704
|
+
`/api/v1/projects/${project2}/files`,
|
|
4705
|
+
form,
|
|
4706
|
+
"STORAGE_UPLOAD_FAILED"
|
|
4707
|
+
);
|
|
4708
|
+
const body = await response.json();
|
|
4709
|
+
return { ...body.file, ...body.signedUrl === void 0 ? {} : { signedUrl: body.signedUrl } };
|
|
4710
|
+
}
|
|
4711
|
+
async function storageList(paths, options) {
|
|
4712
|
+
const { client, project: project2 } = await open3(paths, options);
|
|
4713
|
+
const query = options.prefix === void 0 ? "" : `?prefix=${encodeURIComponent(options.prefix)}`;
|
|
4714
|
+
const body = await client.request(
|
|
4715
|
+
`/api/v1/projects/${project2}/files${query}`
|
|
4716
|
+
);
|
|
4717
|
+
return { project: project2, files: body.files };
|
|
4718
|
+
}
|
|
4719
|
+
async function resolveDownloadUrl(client, project2, path) {
|
|
4720
|
+
const body = await client.request(
|
|
4721
|
+
`/api/v1/projects/${project2}/files?prefix=${encodeURIComponent(path)}`
|
|
4722
|
+
);
|
|
4723
|
+
const entry = body.files.find((file) => file.path === path);
|
|
4724
|
+
const url = entry?.url ?? entry?.signedUrl;
|
|
4725
|
+
if (entry === void 0 || url === void 0 || url.length === 0) {
|
|
4726
|
+
throw new CliError("STORAGE_NOT_FOUND", `\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${path}`);
|
|
4314
4727
|
}
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4728
|
+
return url;
|
|
4729
|
+
}
|
|
4730
|
+
async function storageDownload(paths, options) {
|
|
4731
|
+
const { client, project: project2 } = await open3(paths, options);
|
|
4732
|
+
const url = await resolveDownloadUrl(client, project2, options.path);
|
|
4733
|
+
const response = await client.download(url, "STORAGE_DOWNLOAD_FAILED");
|
|
4734
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
4735
|
+
const output = resolve8(options.output ?? join12(resolve8(options.cwd), basename3(options.path)));
|
|
4736
|
+
await mkdir8(dirname7(output), { recursive: true });
|
|
4737
|
+
await writeFile7(output, bytes);
|
|
4738
|
+
return { path: options.path, output, size: bytes.length };
|
|
4739
|
+
}
|
|
4740
|
+
async function storageRemove(paths, options) {
|
|
4741
|
+
const { client, project: project2 } = await open3(paths, options);
|
|
4742
|
+
return client.request(
|
|
4743
|
+
`/api/v1/projects/${project2}/files/${encodeURIComponent(options.path)}`,
|
|
4744
|
+
{ method: "DELETE" }
|
|
4321
4745
|
);
|
|
4322
|
-
const info = await hostingInfo(paths, options);
|
|
4323
|
-
return { config: config.config, siteUrl: info.siteUrl, uploaded };
|
|
4324
4746
|
}
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4747
|
+
var init_storage2 = __esm({
|
|
4748
|
+
"packages/cli/src/storage.ts"() {
|
|
4749
|
+
"use strict";
|
|
4750
|
+
init_client();
|
|
4751
|
+
init_auth();
|
|
4752
|
+
}
|
|
4753
|
+
});
|
|
4754
|
+
|
|
4755
|
+
// packages/cli/src/doctor.ts
|
|
4756
|
+
var doctor_exports = {};
|
|
4757
|
+
__export(doctor_exports, {
|
|
4758
|
+
formatDoctorReport: () => formatDoctorReport,
|
|
4759
|
+
runDoctor: () => runDoctor
|
|
4760
|
+
});
|
|
4761
|
+
import { stat as stat8 } from "node:fs/promises";
|
|
4762
|
+
async function probeServer(server) {
|
|
4763
|
+
const controller = new AbortController();
|
|
4764
|
+
const timer = setTimeout(() => controller.abort(), SERVER_PROBE_TIMEOUT_MS);
|
|
4765
|
+
try {
|
|
4766
|
+
const response = await fetch(`${server}/api/v1/health`, { signal: controller.signal });
|
|
4767
|
+
return { reachable: true, status: response.status };
|
|
4768
|
+
} catch (error) {
|
|
4769
|
+
return {
|
|
4770
|
+
reachable: false,
|
|
4771
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4772
|
+
};
|
|
4773
|
+
} finally {
|
|
4774
|
+
clearTimeout(timer);
|
|
4775
|
+
}
|
|
4776
|
+
}
|
|
4777
|
+
async function credentialMode(file) {
|
|
4778
|
+
try {
|
|
4779
|
+
const info = await stat8(file);
|
|
4780
|
+
return (info.mode & 511).toString(8).padStart(3, "0");
|
|
4781
|
+
} catch {
|
|
4782
|
+
return void 0;
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
async function runDoctor(paths) {
|
|
4786
|
+
const credentials = await loadCredentials(paths);
|
|
4787
|
+
const server = credentials?.server ?? resolveServer();
|
|
4788
|
+
const mode = await credentialMode(paths.credentialsFile);
|
|
4789
|
+
const offline = await isOffline();
|
|
4790
|
+
const health = await probeServer(server);
|
|
4791
|
+
const report = {
|
|
4792
|
+
server,
|
|
4793
|
+
credentials: {
|
|
4794
|
+
file: paths.credentialsFile,
|
|
4795
|
+
present: credentials !== null,
|
|
4796
|
+
...mode === void 0 ? {} : { mode }
|
|
4797
|
+
},
|
|
4798
|
+
network: { offline },
|
|
4799
|
+
serverHealth: health,
|
|
4800
|
+
offlineCommands: [...OFFLINE_COMMANDS],
|
|
4801
|
+
boundaries: SIM_BOUNDARIES.map((b) => ({ kind: b.kind, title: b.title, detail: b.detail }))
|
|
4802
|
+
};
|
|
4803
|
+
if (credentials !== null) report.credentials.email = credentials.email;
|
|
4804
|
+
if (mode !== void 0 && mode !== "600") {
|
|
4805
|
+
report.credentials.warning = `\u6743\u9650 ${mode} \u5BBD\u4E8E 0600\uFF0C\u5EFA\u8BAE chmod 600 ${paths.credentialsFile}`;
|
|
4345
4806
|
}
|
|
4346
|
-
return
|
|
4807
|
+
return report;
|
|
4347
4808
|
}
|
|
4348
|
-
|
|
4349
|
-
const
|
|
4350
|
-
|
|
4351
|
-
if (
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4809
|
+
function formatDoctorReport(report) {
|
|
4810
|
+
const lines = ["adep doctor \xB7 \u73AF\u5883\u81EA\u68C0", ""];
|
|
4811
|
+
lines.push("\u51ED\u636E\u4E0E\u8EAB\u4EFD");
|
|
4812
|
+
if (report.credentials.present) {
|
|
4813
|
+
lines.push(` \u2713 \u5DF2\u767B\u5F55 ${report.credentials.email ?? "(\u672A\u77E5\u90AE\u7BB1)"} @ ${report.server}`);
|
|
4814
|
+
lines.push(
|
|
4815
|
+
` \xB7 \u51ED\u636E\u6587\u4EF6 ${report.credentials.file}\uFF08${report.credentials.mode ?? "\u6743\u9650\u672A\u77E5"}\uFF09`
|
|
4816
|
+
);
|
|
4817
|
+
if (report.credentials.warning !== void 0) lines.push(` ! ${report.credentials.warning}`);
|
|
4818
|
+
} else {
|
|
4819
|
+
lines.push(` \u2717 \u672A\u767B\u5F55\uFF08\u65E0 ${report.credentials.file}\uFF09`);
|
|
4820
|
+
lines.push(" \u63D0\u793A\uFF1A\u5148\u6267\u884C adep login");
|
|
4821
|
+
}
|
|
4822
|
+
lines.push("", "\u7F51\u7EDC\u4E0E\u670D\u52A1\u7AEF");
|
|
4823
|
+
lines.push(
|
|
4824
|
+
report.network.offline ? " \u2717 \u5916\u7F51\u4E0D\u53EF\u8FBE\uFF08\u4F9D\u8D56\u5B89\u88C5 / \u90E8\u7F72\u7B49\u547D\u4EE4\u5C06\u660E\u786E\u5931\u8D25\uFF09" : " \u2713 \u5916\u7F51\u53EF\u8FBE"
|
|
4356
4825
|
);
|
|
4357
|
-
|
|
4826
|
+
if (report.serverHealth.reachable) {
|
|
4827
|
+
lines.push(` \u2713 \u5E73\u53F0\u53EF\u8FBE ${report.server}\uFF08/api/v1/health \u2192 ${report.serverHealth.status}\uFF09`);
|
|
4828
|
+
} else {
|
|
4829
|
+
lines.push(
|
|
4830
|
+
` \u2717 \u5E73\u53F0\u4E0D\u53EF\u8FBE ${report.server}\uFF1A${report.serverHealth.error ?? "\u65E0\u5E94\u7B54"}`,
|
|
4831
|
+
" \u63D0\u793A\uFF1A\u68C0\u67E5 ADEP_SERVER / \u767B\u5F55\u65F6\u7684 --server\uFF0C\u6216\u5148\u8D77\u672C\u5730 pnpm run dev"
|
|
4832
|
+
);
|
|
4833
|
+
}
|
|
4834
|
+
lines.push("", "\u79BB\u7EBF\u53EF\u7528\u8303\u56F4\uFF08\u65AD\u7F51\u65F6\u4ECD\u53EF\u6267\u884C\uFF09");
|
|
4835
|
+
for (const command of report.offlineCommands) lines.push(` \xB7 ${command}`);
|
|
4836
|
+
lines.push("", "\u672C\u5730\u6A21\u62DF\u8FD0\u884C\u65F6\u7684\u80FD\u529B\u8FB9\u754C\uFF08\u4E0E adep dev \u542F\u52A8\u6A2A\u5E45\u540C\u6E90\uFF09");
|
|
4837
|
+
for (const boundary of report.boundaries) {
|
|
4838
|
+
lines.push(` \xB7 [${boundary.kind}] ${boundary.title}\uFF1A${boundary.detail}`);
|
|
4839
|
+
}
|
|
4840
|
+
return lines;
|
|
4358
4841
|
}
|
|
4359
|
-
var
|
|
4360
|
-
var
|
|
4361
|
-
"packages/cli/src/
|
|
4842
|
+
var SERVER_PROBE_TIMEOUT_MS, OFFLINE_COMMANDS;
|
|
4843
|
+
var init_doctor = __esm({
|
|
4844
|
+
"packages/cli/src/doctor.ts"() {
|
|
4362
4845
|
"use strict";
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4846
|
+
init_credentials();
|
|
4847
|
+
init_config();
|
|
4848
|
+
init_boundary();
|
|
4849
|
+
init_net();
|
|
4850
|
+
SERVER_PROBE_TIMEOUT_MS = 5e3;
|
|
4851
|
+
OFFLINE_COMMANDS = [
|
|
4852
|
+
"adep init",
|
|
4853
|
+
"adep dev",
|
|
4854
|
+
"adep serve",
|
|
4855
|
+
"adep db\uFF08\u672C\u5730\u6A21\u62DF\uFF09",
|
|
4856
|
+
"adep doctor"
|
|
4857
|
+
];
|
|
4367
4858
|
}
|
|
4368
4859
|
});
|
|
4369
4860
|
|
|
4370
|
-
// packages/cli/src/
|
|
4371
|
-
var
|
|
4372
|
-
__export(
|
|
4373
|
-
|
|
4861
|
+
// packages/cli/src/mcp.ts
|
|
4862
|
+
var mcp_exports = {};
|
|
4863
|
+
__export(mcp_exports, {
|
|
4864
|
+
mcpList: () => mcpList,
|
|
4865
|
+
mcpPublish: () => mcpPublish,
|
|
4866
|
+
mcpUnpublish: () => mcpUnpublish
|
|
4374
4867
|
});
|
|
4375
|
-
import {
|
|
4376
|
-
function
|
|
4377
|
-
|
|
4378
|
-
id: view.id,
|
|
4379
|
-
status: view.status,
|
|
4380
|
-
progress: view.progress,
|
|
4381
|
-
createdAt: view.createdAt,
|
|
4382
|
-
...view.stage === void 0 ? {} : { stage: view.stage },
|
|
4383
|
-
...view.error === void 0 ? {} : { error: view.error },
|
|
4384
|
-
...view.downloadUrl === void 0 ? {} : { downloadUrl: view.downloadUrl },
|
|
4385
|
-
...view.bundleSize === void 0 ? {} : { bundleSize: view.bundleSize },
|
|
4386
|
-
...view.completedAt === void 0 ? {} : { completedAt: view.completedAt }
|
|
4387
|
-
};
|
|
4388
|
-
}
|
|
4389
|
-
async function createExportApiClient(paths) {
|
|
4868
|
+
import { resolve as resolve9 } from "node:path";
|
|
4869
|
+
async function mcpPublish(paths, options) {
|
|
4870
|
+
const fn = requireFunctionName(options.fn);
|
|
4390
4871
|
const client = await createClient(paths);
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
"EXPORT_TRIGGER_FAILED"
|
|
4397
|
-
);
|
|
4398
|
-
return toExportJob(view);
|
|
4399
|
-
},
|
|
4400
|
-
async getJobStatus(jobId) {
|
|
4401
|
-
const view = await client.request(
|
|
4402
|
-
`/api/v1/exports/${encodeURIComponent(jobId)}`,
|
|
4403
|
-
{},
|
|
4404
|
-
"EXPORT_STATUS_FAILED"
|
|
4405
|
-
);
|
|
4406
|
-
return toExportJob(view);
|
|
4407
|
-
},
|
|
4408
|
-
async downloadBundle(jobId, outputPath) {
|
|
4409
|
-
const download = await client.request(
|
|
4410
|
-
`/api/v1/exports/${encodeURIComponent(jobId)}/download`,
|
|
4411
|
-
{},
|
|
4412
|
-
"EXPORT_DOWNLOAD_FAILED"
|
|
4413
|
-
);
|
|
4414
|
-
if (download.downloadUrl.length === 0) {
|
|
4415
|
-
throw new CliError("EXPORT_BUNDLE_UNAVAILABLE", "\u5BFC\u51FA\u4EA7\u7269\u4E0B\u8F7D URL \u4E3A\u7A7A\uFF0C\u4EA7\u7269\u53EF\u80FD\u5C1A\u4E0D\u53EF\u7528");
|
|
4416
|
-
}
|
|
4417
|
-
const response = await client.download(download.downloadUrl, "EXPORT_DOWNLOAD_FAILED");
|
|
4418
|
-
const bytes = Buffer.from(await response.arrayBuffer());
|
|
4419
|
-
await writeFile6(outputPath, bytes);
|
|
4420
|
-
return { path: outputPath, size: bytes.length };
|
|
4421
|
-
}
|
|
4422
|
-
};
|
|
4423
|
-
}
|
|
4424
|
-
var init_client2 = __esm({
|
|
4425
|
-
"packages/cli/src/export/client.ts"() {
|
|
4426
|
-
"use strict";
|
|
4427
|
-
init_auth();
|
|
4428
|
-
init_client();
|
|
4872
|
+
const project2 = await resolveProject(client, options);
|
|
4873
|
+
const target = await resolveFunction(client, project2, fn);
|
|
4874
|
+
const body = {};
|
|
4875
|
+
if (options.toolName !== void 0 && options.toolName.trim().length > 0) {
|
|
4876
|
+
body.toolName = options.toolName.trim();
|
|
4429
4877
|
}
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
// shared/deploy-bundle/zip.ts
|
|
4433
|
-
function zipRead(buf) {
|
|
4434
|
-
const r = new Reader(buf);
|
|
4435
|
-
const eocd = findEocd(buf);
|
|
4436
|
-
if (eocd < 0) throw new ZipFormatError("\u627E\u4E0D\u5230 EOCD \u7B7E\u540D");
|
|
4437
|
-
const total = r.u16(eocd + 10);
|
|
4438
|
-
const centralOffset = r.u32(eocd + 16);
|
|
4439
|
-
const decoder = new TextDecoder();
|
|
4440
|
-
const out = /* @__PURE__ */ new Map();
|
|
4441
|
-
let cursor = centralOffset;
|
|
4442
|
-
for (let i = 0; i < total; i++) {
|
|
4443
|
-
if (cursor + 46 > buf.length) throw new ZipFormatError("\u4E2D\u592E\u76EE\u5F55\u8BB0\u5F55\u8D8A\u754C");
|
|
4444
|
-
if (r.u32(cursor) !== SIG_CENTRAL) throw new ZipFormatError("\u4E2D\u592E\u76EE\u5F55\u7B7E\u540D\u4E0D\u5339\u914D");
|
|
4445
|
-
const method = r.u16(cursor + 10);
|
|
4446
|
-
if (method !== 0) throw new ZipFormatError("\u4EC5\u652F\u6301 store \u578B\u6761\u76EE\u8BFB\u53D6");
|
|
4447
|
-
const compSize = r.u32(cursor + 20);
|
|
4448
|
-
const nameLen = r.u16(cursor + 28);
|
|
4449
|
-
const extraLen = r.u16(cursor + 30);
|
|
4450
|
-
const commentLen = r.u16(cursor + 32);
|
|
4451
|
-
const localHeaderOffset = r.u32(cursor + 42);
|
|
4452
|
-
if (localHeaderOffset + 30 > buf.length) throw new ZipFormatError("\u672C\u5730\u5934\u504F\u79FB\u8D8A\u754C");
|
|
4453
|
-
const name = decoder.decode(r.slice(cursor + 46, nameLen));
|
|
4454
|
-
const localNameLen = r.u16(localHeaderOffset + 26);
|
|
4455
|
-
const localExtraLen = r.u16(localHeaderOffset + 28);
|
|
4456
|
-
const dataStart = localHeaderOffset + 30 + localNameLen + localExtraLen;
|
|
4457
|
-
if (dataStart + compSize > buf.length) throw new ZipFormatError("\u6761\u76EE\u6570\u636E\u8D8A\u754C");
|
|
4458
|
-
if (!out.has(name)) out.set(name, r.slice(dataStart, compSize));
|
|
4459
|
-
cursor += 46 + nameLen + extraLen + commentLen;
|
|
4878
|
+
if (options.description !== void 0 && options.description.length > 0) {
|
|
4879
|
+
body.description = options.description;
|
|
4460
4880
|
}
|
|
4461
|
-
|
|
4881
|
+
const tool = await client.request(
|
|
4882
|
+
`/api/v1/functions/${target.id}/mcp-publish`,
|
|
4883
|
+
{ method: "POST", ...Object.keys(body).length === 0 ? {} : { body } },
|
|
4884
|
+
"MCP_PUBLISH_FAILED"
|
|
4885
|
+
);
|
|
4886
|
+
return { projectId: project2.id, tool };
|
|
4462
4887
|
}
|
|
4463
|
-
function
|
|
4464
|
-
const
|
|
4465
|
-
const
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4888
|
+
async function mcpUnpublish(paths, options) {
|
|
4889
|
+
const fn = requireFunctionName(options.fn);
|
|
4890
|
+
const client = await createClient(paths);
|
|
4891
|
+
const project2 = await resolveProject(client, options);
|
|
4892
|
+
const target = await resolveFunction(client, project2, fn);
|
|
4893
|
+
const toolName = options.toolName?.trim() || fn;
|
|
4894
|
+
const result = await client.request(
|
|
4895
|
+
`/api/v1/functions/${target.id}/mcp-publish?tool=${encodeURIComponent(toolName)}`,
|
|
4896
|
+
{ method: "DELETE" },
|
|
4897
|
+
"MCP_UNPUBLISH_FAILED"
|
|
4898
|
+
);
|
|
4899
|
+
return { projectId: project2.id, toolName, removed: result.unpublished === true };
|
|
4470
4900
|
}
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
super(`[appexport] \u975E\u6CD5 zip\uFF1A${message}`);
|
|
4505
|
-
this.name = "ZipFormatError";
|
|
4506
|
-
}
|
|
4507
|
-
};
|
|
4901
|
+
async function mcpList(paths, options) {
|
|
4902
|
+
const client = await createClient(paths);
|
|
4903
|
+
const project2 = await resolveProject(client, options);
|
|
4904
|
+
const prefix = project2.functionsPrefix ?? "/api";
|
|
4905
|
+
const prefixBase = prefix.trim() === "/" ? "" : prefix.trim().replace(/\/+$/, "");
|
|
4906
|
+
const endpoint = `${project2.url.replace(/\/+$/, "")}${prefixBase}/mcp`;
|
|
4907
|
+
let response;
|
|
4908
|
+
try {
|
|
4909
|
+
response = await fetch(endpoint, {
|
|
4910
|
+
method: "POST",
|
|
4911
|
+
headers: { "content-type": "application/json", cookie: client.cookie },
|
|
4912
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "tools/list" })
|
|
4913
|
+
});
|
|
4914
|
+
} catch (error) {
|
|
4915
|
+
throw new CliError(
|
|
4916
|
+
"SERVER_UNREACHABLE",
|
|
4917
|
+
`\u65E0\u6CD5\u8FDE\u63A5 MCP \u7AEF\u70B9 ${endpoint}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
4918
|
+
);
|
|
4919
|
+
}
|
|
4920
|
+
const parsed = await response.json().catch(() => null);
|
|
4921
|
+
if (!response.ok) {
|
|
4922
|
+
const envelope = parsed ?? null;
|
|
4923
|
+
throw new CliError(
|
|
4924
|
+
envelope?.error?.code ?? "MCP_LIST_FAILED",
|
|
4925
|
+
envelope?.error?.message ?? `MCP \u7AEF\u70B9\u8FD4\u56DE HTTP ${response.status}`
|
|
4926
|
+
);
|
|
4927
|
+
}
|
|
4928
|
+
const rpcError = parsed?.error;
|
|
4929
|
+
if (rpcError !== void 0) {
|
|
4930
|
+
throw new CliError(
|
|
4931
|
+
rpcError.code ?? "MCP_LIST_FAILED",
|
|
4932
|
+
rpcError.message ?? "MCP tools/list \u5931\u8D25"
|
|
4933
|
+
);
|
|
4508
4934
|
}
|
|
4509
|
-
});
|
|
4510
|
-
|
|
4511
|
-
// packages/cli/src/export/fs.ts
|
|
4512
|
-
var fs_exports = {};
|
|
4513
|
-
__export(fs_exports, {
|
|
4514
|
-
createExportFileSystem: () => createExportFileSystem
|
|
4515
|
-
});
|
|
4516
|
-
import { mkdir as mkdir8, readFile as readFile10, rm as rm3, stat as stat9, writeFile as writeFile7 } from "node:fs/promises";
|
|
4517
|
-
import { dirname as dirname8, join as join12 } from "node:path";
|
|
4518
|
-
function createExportFileSystem() {
|
|
4519
4935
|
return {
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
await rm3(path, { recursive: true, force: true });
|
|
4525
|
-
},
|
|
4526
|
-
fileExists: async (path) => {
|
|
4527
|
-
try {
|
|
4528
|
-
await stat9(path);
|
|
4529
|
-
return true;
|
|
4530
|
-
} catch {
|
|
4531
|
-
return false;
|
|
4532
|
-
}
|
|
4533
|
-
},
|
|
4534
|
-
mkdir: async (path) => {
|
|
4535
|
-
await mkdir8(path, { recursive: true });
|
|
4536
|
-
},
|
|
4537
|
-
unzip: async (zipPath, targetDir) => {
|
|
4538
|
-
const entries = zipRead(await readFile10(zipPath));
|
|
4539
|
-
for (const [name, data] of entries) {
|
|
4540
|
-
const dest = join12(targetDir, name);
|
|
4541
|
-
await mkdir8(dirname8(dest), { recursive: true });
|
|
4542
|
-
await writeFile7(dest, data);
|
|
4543
|
-
}
|
|
4544
|
-
}
|
|
4936
|
+
projectId: project2.id,
|
|
4937
|
+
slug: project2.slug,
|
|
4938
|
+
endpoint,
|
|
4939
|
+
tools: parsed?.result?.tools ?? []
|
|
4545
4940
|
};
|
|
4546
4941
|
}
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
"
|
|
4550
|
-
init_zip();
|
|
4942
|
+
function requireFunctionName(fn) {
|
|
4943
|
+
if (fn === void 0 || fn.trim().length === 0) {
|
|
4944
|
+
throw new CliError("INVALID_ARGUMENT", "\u7F3A\u5C11\u51FD\u6570\u540D\uFF1Aadep mcp publish --function <fn>");
|
|
4551
4945
|
}
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4946
|
+
return fn.trim();
|
|
4947
|
+
}
|
|
4948
|
+
async function resolveProject(client, options) {
|
|
4949
|
+
const slug = await resolveSlug(resolve9(options.cwd), options.slug);
|
|
4950
|
+
const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
4951
|
+
const match = listed.projects.find((project2) => project2.slug === slug);
|
|
4952
|
+
if (match === void 0) {
|
|
4953
|
+
throw new CliError(
|
|
4954
|
+
"PROJECT_NOT_FOUND",
|
|
4955
|
+
`\u5E73\u53F0\u9879\u76EE "${slug}" \u4E0D\u5B58\u5728\u6216\u4F60\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\uFF1A\u5148\u6267\u884C adep projects create ${slug}`
|
|
4956
|
+
);
|
|
4957
|
+
}
|
|
4958
|
+
return {
|
|
4959
|
+
id: match.id,
|
|
4960
|
+
slug: match.slug,
|
|
4961
|
+
url: match.url,
|
|
4962
|
+
...match.functionsPrefix === void 0 ? {} : { functionsPrefix: match.functionsPrefix }
|
|
4963
|
+
};
|
|
4964
|
+
}
|
|
4965
|
+
async function resolveFunction(client, project2, name) {
|
|
4966
|
+
const listed = await client.request(`/api/v1/projects/${project2.id}/functions`, {}, "FUNCTION_LIST_FAILED");
|
|
4967
|
+
const target = listed.functions.find((fn) => fn.name === name);
|
|
4968
|
+
if (target === void 0) {
|
|
4969
|
+
throw new CliError("FN_NOT_FOUND", `\u51FD\u6570 "${name}" \u4E0D\u5B58\u5728\u4E8E\u9879\u76EE "${project2.slug}"`);
|
|
4970
|
+
}
|
|
4971
|
+
return { id: target.id, name: target.name };
|
|
4972
|
+
}
|
|
4973
|
+
var init_mcp = __esm({
|
|
4974
|
+
"packages/cli/src/mcp.ts"() {
|
|
4558
4975
|
"use strict";
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
/** 云函数代码与配置。 */
|
|
4562
|
-
Functions: "functions",
|
|
4563
|
-
/** 数据库 schema 与种子数据。 */
|
|
4564
|
-
Database: "database",
|
|
4565
|
-
/** 前端静态资源。 */
|
|
4566
|
-
Web: "web",
|
|
4567
|
-
/** 运行时配置(Dockerfile / docker-compose.yml)。 */
|
|
4568
|
-
Runtime: "runtime",
|
|
4569
|
-
/** 启动 / 备份 / 恢复脚本。 */
|
|
4570
|
-
Scripts: "scripts",
|
|
4571
|
-
/** 文档(README / 部署手册)。 */
|
|
4572
|
-
Docs: "docs"
|
|
4573
|
-
};
|
|
4574
|
-
ALLOWED_CONTENT_KINDS = Object.values(BundleContentKind);
|
|
4976
|
+
init_auth();
|
|
4977
|
+
init_client();
|
|
4575
4978
|
}
|
|
4576
4979
|
});
|
|
4577
4980
|
|
|
4578
|
-
//
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
};
|
|
4588
|
-
}
|
|
4589
|
-
const m = manifest;
|
|
4590
|
-
const schemaVersion = m.schemaVersion;
|
|
4591
|
-
if (typeof schemaVersion !== "number" || !Number.isInteger(schemaVersion)) {
|
|
4592
|
-
errors.push({
|
|
4593
|
-
code: "INVALID_SCHEMA_VERSION",
|
|
4594
|
-
message: "schemaVersion \u5FC5\u987B\u662F\u6574\u6570",
|
|
4595
|
-
field: "schemaVersion"
|
|
4596
|
-
});
|
|
4597
|
-
} else if (schemaVersion > CURRENT_SCHEMA_VERSION) {
|
|
4598
|
-
errors.push({
|
|
4599
|
-
code: "SCHEMA_VERSION_TOO_HIGH",
|
|
4600
|
-
message: `schemaVersion ${schemaVersion} \u9AD8\u4E8E\u5F53\u524D\u652F\u6301\u7248\u672C ${CURRENT_SCHEMA_VERSION}\uFF0C\u9700\u5347\u7EA7\u5BFC\u51FA\u7AEF`,
|
|
4601
|
-
field: "schemaVersion"
|
|
4602
|
-
});
|
|
4603
|
-
} else if (schemaVersion < CURRENT_SCHEMA_VERSION) {
|
|
4604
|
-
warnings.push({
|
|
4605
|
-
code: "SCHEMA_VERSION_LOW",
|
|
4606
|
-
message: `schemaVersion ${schemaVersion} \u4F4E\u4E8E\u5F53\u524D\u7248\u672C ${CURRENT_SCHEMA_VERSION}\uFF0C\u5EFA\u8BAE\u91CD\u65B0\u5BFC\u51FA`,
|
|
4607
|
-
field: "schemaVersion"
|
|
4608
|
-
});
|
|
4609
|
-
}
|
|
4610
|
-
if (typeof m.platformVersion !== "string" || m.platformVersion.trim() === "") {
|
|
4611
|
-
errors.push({
|
|
4612
|
-
code: "MISSING_PLATFORM_VERSION",
|
|
4613
|
-
message: "platformVersion \u5FC5\u987B\u975E\u7A7A",
|
|
4614
|
-
field: "platformVersion"
|
|
4615
|
-
});
|
|
4616
|
-
}
|
|
4617
|
-
if (typeof m.project !== "object" || m.project === null) {
|
|
4618
|
-
errors.push({
|
|
4619
|
-
code: "MISSING_PROJECT",
|
|
4620
|
-
message: "project \u5FC5\u987B\u662F\u5BF9\u8C61",
|
|
4621
|
-
field: "project"
|
|
4622
|
-
});
|
|
4623
|
-
} else {
|
|
4624
|
-
const project2 = m.project;
|
|
4625
|
-
if (typeof project2.id !== "string" || project2.id.trim() === "") {
|
|
4626
|
-
errors.push({
|
|
4627
|
-
code: "MISSING_PROJECT_ID",
|
|
4628
|
-
message: "project.id \u5FC5\u987B\u975E\u7A7A",
|
|
4629
|
-
field: "project.id"
|
|
4630
|
-
});
|
|
4631
|
-
}
|
|
4632
|
-
if (typeof project2.name !== "string" || project2.name.trim() === "") {
|
|
4633
|
-
errors.push({
|
|
4634
|
-
code: "MISSING_PROJECT_NAME",
|
|
4635
|
-
message: "project.name \u5FC5\u987B\u975E\u7A7A",
|
|
4636
|
-
field: "project.name"
|
|
4637
|
-
});
|
|
4638
|
-
}
|
|
4639
|
-
if (typeof project2.slug !== "string" || project2.slug.trim() === "") {
|
|
4640
|
-
errors.push({
|
|
4641
|
-
code: "MISSING_PROJECT_SLUG",
|
|
4642
|
-
message: "project.slug \u5FC5\u987B\u975E\u7A7A",
|
|
4643
|
-
field: "project.slug"
|
|
4644
|
-
});
|
|
4645
|
-
}
|
|
4646
|
-
if (typeof project2.version !== "number" || !Number.isInteger(project2.version) || project2.version < 1) {
|
|
4647
|
-
errors.push({
|
|
4648
|
-
code: "INVALID_PROJECT_VERSION",
|
|
4649
|
-
message: "project.version \u5FC5\u987B\u662F\u6B63\u6574\u6570",
|
|
4650
|
-
field: "project.version"
|
|
4651
|
-
});
|
|
4652
|
-
}
|
|
4981
|
+
// packages/cli/src/projects.ts
|
|
4982
|
+
var projects_exports = {};
|
|
4983
|
+
__export(projects_exports, {
|
|
4984
|
+
projectsCreate: () => projectsCreate,
|
|
4985
|
+
projectsInfo: () => projectsInfo,
|
|
4986
|
+
projectsList: () => projectsList
|
|
4987
|
+
});
|
|
4988
|
+
function requireSlug(slug, hint) {
|
|
4989
|
+
if (slug === void 0 || slug.trim().length === 0) {
|
|
4990
|
+
throw new CliError("INVALID_SLUG", `\u7F3A\u5C11\u9879\u76EE slug\uFF1A${hint}`);
|
|
4653
4991
|
}
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
}
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4992
|
+
return slug.trim();
|
|
4993
|
+
}
|
|
4994
|
+
async function projectsCreate(paths, options) {
|
|
4995
|
+
await requireNetworkGuard();
|
|
4996
|
+
const client = await createClient(paths);
|
|
4997
|
+
const slug = requireSlug(options.slug, "adep projects create <slug>");
|
|
4998
|
+
const name = options.name ?? slug;
|
|
4999
|
+
const body = { slug, name };
|
|
5000
|
+
if (options.spaceId !== void 0) body.spaceId = options.spaceId;
|
|
5001
|
+
const created = await client.request(
|
|
5002
|
+
"/api/v1/projects",
|
|
5003
|
+
{ body },
|
|
5004
|
+
"PROJECT_CREATE_FAILED"
|
|
5005
|
+
);
|
|
5006
|
+
if (created.url === void 0 || created.url.length === 0) {
|
|
5007
|
+
throw new CliError("PROJECT_CREATE_FAILED", "\u5E73\u53F0\u672A\u8FD4\u56DE\u9879\u76EE\u5730\u5740\uFF0C\u65E0\u6CD5\u8F93\u51FA\u5B50\u57DF URL");
|
|
4670
5008
|
}
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
field: "runtime.engineVersion"
|
|
4691
|
-
});
|
|
4692
|
-
}
|
|
4693
|
-
if (typeof runtime.port !== "number" || !Number.isInteger(runtime.port) || runtime.port < 1 || runtime.port > 65535) {
|
|
4694
|
-
errors.push({
|
|
4695
|
-
code: "INVALID_PORT",
|
|
4696
|
-
message: "runtime.port \u5FC5\u987B\u662F 1-65535 \u7684\u6574\u6570",
|
|
4697
|
-
field: "runtime.port"
|
|
4698
|
-
});
|
|
4699
|
-
}
|
|
4700
|
-
if (typeof runtime.startCommand !== "string" || runtime.startCommand.trim() === "") {
|
|
4701
|
-
errors.push({
|
|
4702
|
-
code: "MISSING_START_COMMAND",
|
|
4703
|
-
message: "runtime.startCommand \u5FC5\u987B\u975E\u7A7A",
|
|
4704
|
-
field: "runtime.startCommand"
|
|
4705
|
-
});
|
|
4706
|
-
}
|
|
5009
|
+
return created;
|
|
5010
|
+
}
|
|
5011
|
+
async function projectsList(paths) {
|
|
5012
|
+
await requireNetworkGuard();
|
|
5013
|
+
const client = await createClient(paths);
|
|
5014
|
+
const result = await client.request(
|
|
5015
|
+
"/api/v1/projects",
|
|
5016
|
+
{},
|
|
5017
|
+
"PROJECT_LIST_FAILED"
|
|
5018
|
+
);
|
|
5019
|
+
return result.projects;
|
|
5020
|
+
}
|
|
5021
|
+
async function projectsInfo(paths, options) {
|
|
5022
|
+
await requireNetworkGuard();
|
|
5023
|
+
const slug = requireSlug(options.slug, "adep projects info <slug>");
|
|
5024
|
+
const projects = await projectsList(paths);
|
|
5025
|
+
const match = projects.find((project2) => project2.slug === slug);
|
|
5026
|
+
if (match === void 0) {
|
|
5027
|
+
throw new CliError("PROJECT_NOT_FOUND", `\u9879\u76EE "${slug}" \u4E0D\u5B58\u5728\u6216\u4F60\u6CA1\u6709\u8BBF\u95EE\u6743\u9650`);
|
|
4707
5028
|
}
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
message: "exportedAt \u5FC5\u987B\u662F\u6709\u6548\u7684 ISO 8601 \u65F6\u95F4",
|
|
4720
|
-
field: "exportedAt"
|
|
4721
|
-
});
|
|
4722
|
-
}
|
|
5029
|
+
return match;
|
|
5030
|
+
}
|
|
5031
|
+
async function requireNetworkGuard() {
|
|
5032
|
+
const { requireNetwork: requireNetwork2 } = await Promise.resolve().then(() => (init_net(), net_exports));
|
|
5033
|
+
await requireNetwork2("adep projects");
|
|
5034
|
+
}
|
|
5035
|
+
var init_projects = __esm({
|
|
5036
|
+
"packages/cli/src/projects.ts"() {
|
|
5037
|
+
"use strict";
|
|
5038
|
+
init_auth();
|
|
5039
|
+
init_client();
|
|
4723
5040
|
}
|
|
5041
|
+
});
|
|
5042
|
+
|
|
5043
|
+
// packages/cli/src/functions.ts
|
|
5044
|
+
var functions_exports = {};
|
|
5045
|
+
__export(functions_exports, {
|
|
5046
|
+
functionsDeploy: () => functionsDeploy,
|
|
5047
|
+
functionsList: () => functionsList,
|
|
5048
|
+
functionsLogs: () => functionsLogs
|
|
5049
|
+
});
|
|
5050
|
+
import { resolve as resolve10 } from "node:path";
|
|
5051
|
+
async function functionsDeploy(paths, options) {
|
|
5052
|
+
const startedAt = Date.now();
|
|
5053
|
+
const result = await deploy(paths, {
|
|
5054
|
+
cwd: options.cwd,
|
|
5055
|
+
...options.slug === void 0 ? {} : { slug: options.slug },
|
|
5056
|
+
...options.dir === void 0 ? {} : { functionsDir: resolve10(options.cwd, options.dir) },
|
|
5057
|
+
silent: true
|
|
5058
|
+
});
|
|
5059
|
+
return { ...result, elapsedSeconds: (Date.now() - startedAt) / 1e3 };
|
|
5060
|
+
}
|
|
5061
|
+
async function functionsList(paths, options) {
|
|
5062
|
+
const client = await createClient(paths);
|
|
5063
|
+
const project2 = await resolveProject2(client, options);
|
|
5064
|
+
const result = await client.request(
|
|
5065
|
+
`/api/v1/projects/${project2.id}/functions`,
|
|
5066
|
+
{},
|
|
5067
|
+
"FUNCTION_LIST_FAILED"
|
|
5068
|
+
);
|
|
5069
|
+
const prefix = project2.functionsPrefix ?? "/api";
|
|
5070
|
+
const prefixBase = prefix.trim() === "/" ? "" : prefix.trim().replace(/\/+$/, "");
|
|
4724
5071
|
return {
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
5072
|
+
projectId: project2.id,
|
|
5073
|
+
slug: project2.slug,
|
|
5074
|
+
baseUrl: `${project2.url.replace(/\/+$/, "")}${prefixBase}`,
|
|
5075
|
+
functions: result.functions
|
|
4728
5076
|
};
|
|
4729
5077
|
}
|
|
4730
|
-
function
|
|
4731
|
-
if (
|
|
4732
|
-
|
|
4733
|
-
code: "INVALID_CONTENT",
|
|
4734
|
-
message: `contents[${index}] \u5FC5\u987B\u662F\u5BF9\u8C61`,
|
|
4735
|
-
field: `contents[${index}]`
|
|
4736
|
-
});
|
|
4737
|
-
return;
|
|
5078
|
+
async function functionsLogs(paths, options) {
|
|
5079
|
+
if (options.name === void 0 || options.name.trim().length === 0) {
|
|
5080
|
+
throw new CliError("INVALID_ARGUMENT", "\u7F3A\u5C11\u51FD\u6570\u540D\uFF1Aadep functions logs <name>");
|
|
4738
5081
|
}
|
|
4739
|
-
const
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
5082
|
+
const client = await createClient(paths);
|
|
5083
|
+
const project2 = await resolveProject2(client, options);
|
|
5084
|
+
const listed = await client.request(
|
|
5085
|
+
`/api/v1/projects/${project2.id}/functions`,
|
|
5086
|
+
{},
|
|
5087
|
+
"FUNCTION_LIST_FAILED"
|
|
5088
|
+
);
|
|
5089
|
+
const target = listed.functions.find((fn) => fn.name === options.name);
|
|
5090
|
+
if (target === void 0) {
|
|
5091
|
+
throw new CliError("FN_NOT_FOUND", `\u51FD\u6570 "${options.name}" \u4E0D\u5B58\u5728\u4E8E\u9879\u76EE "${project2.slug}"`);
|
|
4746
5092
|
}
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
5093
|
+
const tail = options.tail === void 0 ? "" : `?tail=${encodeURIComponent(String(options.tail))}`;
|
|
5094
|
+
const result = await client.request(
|
|
5095
|
+
`/api/v1/functions/${target.id}/logs${tail}`,
|
|
5096
|
+
{},
|
|
5097
|
+
"FUNCTION_LOGS_FAILED"
|
|
5098
|
+
);
|
|
5099
|
+
return { functionId: target.id, name: target.name, logs: result.logs };
|
|
5100
|
+
}
|
|
5101
|
+
async function resolveProject2(client, options) {
|
|
5102
|
+
const slug = await resolveSlug(resolve10(options.cwd), options.slug);
|
|
5103
|
+
const projects = await projectsListFrom(client);
|
|
5104
|
+
const match = projects.find((project2) => project2.slug === slug);
|
|
5105
|
+
if (match === void 0) {
|
|
5106
|
+
throw new CliError(
|
|
5107
|
+
"PROJECT_NOT_FOUND",
|
|
5108
|
+
`\u5E73\u53F0\u9879\u76EE "${slug}" \u4E0D\u5B58\u5728\u6216\u4F60\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\uFF1A\u5148\u6267\u884C adep projects create ${slug}`
|
|
5109
|
+
);
|
|
4759
5110
|
}
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
5111
|
+
return match;
|
|
5112
|
+
}
|
|
5113
|
+
async function projectsListFrom(client) {
|
|
5114
|
+
const result = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
5115
|
+
return result.projects;
|
|
5116
|
+
}
|
|
5117
|
+
var init_functions = __esm({
|
|
5118
|
+
"packages/cli/src/functions.ts"() {
|
|
5119
|
+
"use strict";
|
|
5120
|
+
init_auth();
|
|
5121
|
+
init_client();
|
|
5122
|
+
init_deploy();
|
|
4772
5123
|
}
|
|
5124
|
+
});
|
|
5125
|
+
|
|
5126
|
+
// packages/cli/src/hosting.ts
|
|
5127
|
+
var hosting_exports = {};
|
|
5128
|
+
__export(hosting_exports, {
|
|
5129
|
+
hostingConfig: () => hostingConfig,
|
|
5130
|
+
hostingDeploy: () => hostingDeploy,
|
|
5131
|
+
hostingInfo: () => hostingInfo,
|
|
5132
|
+
hostingPull: () => hostingPull
|
|
5133
|
+
});
|
|
5134
|
+
import { readdir as readdir5, readFile as readFile11, stat as stat9 } from "node:fs/promises";
|
|
5135
|
+
import { dirname as dirname8, join as join13, relative as relative2, resolve as resolve11, sep } from "node:path";
|
|
5136
|
+
async function open4(paths, options) {
|
|
5137
|
+
const client = await createClient(paths);
|
|
5138
|
+
const project2 = await resolveSlug(resolve11(options.cwd), options.slug);
|
|
5139
|
+
return { client, project: project2 };
|
|
4773
5140
|
}
|
|
4774
|
-
function
|
|
4775
|
-
const
|
|
4776
|
-
const
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
5141
|
+
async function hostingInfo(paths, options) {
|
|
5142
|
+
const { client, project: project2 } = await open4(paths, options);
|
|
5143
|
+
const body = await client.request(`/api/v1/projects/${project2}/hosting`);
|
|
5144
|
+
return {
|
|
5145
|
+
config: body.config,
|
|
5146
|
+
siteUrl: body.siteUrl,
|
|
5147
|
+
files: body.files ?? []
|
|
5148
|
+
};
|
|
5149
|
+
}
|
|
5150
|
+
async function collectSiteFiles(dir) {
|
|
5151
|
+
const root = resolve11(dir);
|
|
5152
|
+
const files = /* @__PURE__ */ new Map();
|
|
5153
|
+
const walk = async (sub) => {
|
|
5154
|
+
let entries;
|
|
5155
|
+
try {
|
|
5156
|
+
entries = await readdir5(sub, { withFileTypes: true });
|
|
5157
|
+
} catch {
|
|
5158
|
+
return;
|
|
4786
5159
|
}
|
|
4787
|
-
const
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
5160
|
+
for (const entry of entries) {
|
|
5161
|
+
const full = join13(sub, entry.name);
|
|
5162
|
+
if (entry.isDirectory()) {
|
|
5163
|
+
await walk(full);
|
|
5164
|
+
} else if (entry.isFile()) {
|
|
5165
|
+
const rel = relative2(root, full).split(sep).join("/");
|
|
5166
|
+
files.set(rel, full);
|
|
5167
|
+
}
|
|
4794
5168
|
}
|
|
5169
|
+
};
|
|
5170
|
+
await walk(root);
|
|
5171
|
+
return files;
|
|
5172
|
+
}
|
|
5173
|
+
async function hostingDeploy(paths, options) {
|
|
5174
|
+
const { client, project: project2 } = await open4(paths, options);
|
|
5175
|
+
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
5176
|
+
`));
|
|
5177
|
+
const files = await collectSiteFiles(options.dir);
|
|
5178
|
+
if (files.size === 0) {
|
|
5179
|
+
throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${resolve11(options.dir)}`);
|
|
4795
5180
|
}
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
5181
|
+
const uploaded = [];
|
|
5182
|
+
for (const [rel, full] of files) {
|
|
5183
|
+
log(`[adep] \u4E0A\u4F20 site/${rel}`);
|
|
5184
|
+
const info2 = await stat9(full);
|
|
5185
|
+
const bytes = await readFile11(full);
|
|
5186
|
+
const form = new FormData();
|
|
5187
|
+
form.set("path", `site/${rel}`);
|
|
5188
|
+
form.set("visibility", "public");
|
|
5189
|
+
form.set(
|
|
5190
|
+
"file",
|
|
5191
|
+
new Blob([bytes], { type: contentTypeOf(rel) }),
|
|
5192
|
+
rel.split("/").pop()
|
|
5193
|
+
);
|
|
5194
|
+
await client.upload(`/api/v1/projects/${project2}/files`, form, "HOSTING_UPLOAD_FAILED");
|
|
5195
|
+
uploaded.push({ path: `site/${rel}`, size: info2.size });
|
|
4804
5196
|
}
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
5197
|
+
const config = await client.request(
|
|
5198
|
+
`/api/v1/projects/${project2}/hosting`,
|
|
5199
|
+
{
|
|
5200
|
+
method: "PUT",
|
|
5201
|
+
body: options.spa === void 0 ? { enabled: true } : { enabled: true, spaMode: options.spa }
|
|
5202
|
+
}
|
|
5203
|
+
);
|
|
5204
|
+
const info = await hostingInfo(paths, options);
|
|
5205
|
+
return { config: config.config, siteUrl: info.siteUrl, uploaded };
|
|
4810
5206
|
}
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
5207
|
+
async function hostingPull(paths, options) {
|
|
5208
|
+
const { client } = await open4(paths, options);
|
|
5209
|
+
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
5210
|
+
`));
|
|
5211
|
+
const info = await hostingInfo(paths, options);
|
|
5212
|
+
const outputDir = resolve11(options.output ?? resolve11(options.cwd));
|
|
5213
|
+
const { mkdir: mkdir9, writeFile: writeFile8 } = await import("node:fs/promises");
|
|
5214
|
+
const files = [];
|
|
5215
|
+
for (const entry of info.files) {
|
|
5216
|
+
if (entry.visibility !== "public" || entry.path === HOSTING_CONFIG_PATH) continue;
|
|
5217
|
+
const url = entry.url;
|
|
5218
|
+
if (url === void 0 || url.length === 0) continue;
|
|
5219
|
+
log(`[adep] \u4E0B\u8F7D ${entry.path}`);
|
|
5220
|
+
const response = await client.download(url, "HOSTING_DOWNLOAD_FAILED");
|
|
5221
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
5222
|
+
const rel = entry.path.replace(/^site\//, "");
|
|
5223
|
+
const target = join13(outputDir, ...rel.split("/"));
|
|
5224
|
+
await mkdir9(dirname8(target), { recursive: true });
|
|
5225
|
+
await writeFile8(target, bytes);
|
|
5226
|
+
files.push({ path: entry.path, size: bytes.length });
|
|
4815
5227
|
}
|
|
4816
|
-
}
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
* 执行导出命令。
|
|
4838
|
-
*
|
|
4839
|
-
* @param options 命令选项
|
|
4840
|
-
* @returns 导出结果
|
|
4841
|
-
*/
|
|
4842
|
-
async execute(options) {
|
|
4843
|
-
const projectId = options.project ?? "default";
|
|
4844
|
-
const outputDir = options.out ?? "./exports";
|
|
4845
|
-
const jsonOutput = options.json ?? false;
|
|
4846
|
-
try {
|
|
4847
|
-
if (!jsonOutput) {
|
|
4848
|
-
console.log(`\u89E6\u53D1\u5BFC\u51FA\uFF1A\u9879\u76EE ${projectId}`);
|
|
4849
|
-
}
|
|
4850
|
-
const job = await this.apiClient.triggerExport(projectId, {
|
|
4851
|
-
withData: options.withData,
|
|
4852
|
-
withSource: options.withSource
|
|
4853
|
-
});
|
|
4854
|
-
if (!jsonOutput) {
|
|
4855
|
-
console.log(`\u5BFC\u51FA\u4EFB\u52A1\u5DF2\u521B\u5EFA\uFF1A${job.id}`);
|
|
4856
|
-
}
|
|
4857
|
-
const completedJob = await this.pollJobStatus(job.id, jsonOutput);
|
|
4858
|
-
if (completedJob.status === "failed") {
|
|
4859
|
-
return {
|
|
4860
|
-
success: false,
|
|
4861
|
-
jobId: job.id,
|
|
4862
|
-
status: "failed",
|
|
4863
|
-
error: completedJob.error ?? "\u5BFC\u51FA\u5931\u8D25"
|
|
4864
|
-
};
|
|
4865
|
-
}
|
|
4866
|
-
if (!jsonOutput) {
|
|
4867
|
-
console.log("\u4E0B\u8F7D\u5BFC\u51FA\u4EA7\u7269...");
|
|
4868
|
-
}
|
|
4869
|
-
const outputPath = `${outputDir}/${projectId}-export-${Date.now()}.zip`;
|
|
4870
|
-
await this.fs.mkdir(outputDir);
|
|
4871
|
-
const downloadResult = await this.apiClient.downloadBundle(job.id, outputPath);
|
|
4872
|
-
if (!jsonOutput) {
|
|
4873
|
-
console.log(`\u4EA7\u7269\u5DF2\u4E0B\u8F7D\uFF1A${downloadResult.path}\uFF08${this.formatSize(downloadResult.size)}\uFF09`);
|
|
4874
|
-
}
|
|
4875
|
-
if (!jsonOutput) {
|
|
4876
|
-
console.log("\u6267\u884C manifest \u81EA\u68C0...");
|
|
4877
|
-
}
|
|
4878
|
-
const manifest = await this.verifyManifest(downloadResult.path);
|
|
4879
|
-
if (!jsonOutput) {
|
|
4880
|
-
this.printContentList(manifest);
|
|
4881
|
-
}
|
|
4882
|
-
return {
|
|
4883
|
-
success: true,
|
|
4884
|
-
jobId: job.id,
|
|
4885
|
-
status: "completed",
|
|
4886
|
-
downloadPath: downloadResult.path,
|
|
4887
|
-
manifest: {
|
|
4888
|
-
projectName: manifest.project.name,
|
|
4889
|
-
platformVersion: manifest.platformVersion,
|
|
4890
|
-
exportedAt: manifest.exportedAt,
|
|
4891
|
-
contents: this.countContents(manifest.contents)
|
|
4892
|
-
}
|
|
4893
|
-
};
|
|
4894
|
-
} catch (error) {
|
|
4895
|
-
const message = error instanceof Error ? error.message : "unknown_error";
|
|
4896
|
-
if (message.includes("ECONNREFUSED") || message.includes("ENOTFOUND") || message.includes("network")) {
|
|
4897
|
-
return {
|
|
4898
|
-
success: false,
|
|
4899
|
-
error: `\u5E73\u53F0\u7AEF\u70B9\u4E0D\u53EF\u8FBE\uFF1A${message}\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C\u5E73\u53F0\u5730\u5740\u914D\u7F6E\uFF0C\u7136\u540E\u91CD\u8BD5\u3002`
|
|
4900
|
-
};
|
|
4901
|
-
}
|
|
4902
|
-
return {
|
|
4903
|
-
success: false,
|
|
4904
|
-
error: message
|
|
4905
|
-
};
|
|
4906
|
-
}
|
|
4907
|
-
}
|
|
4908
|
-
/**
|
|
4909
|
-
* 轮询任务状态。
|
|
4910
|
-
*
|
|
4911
|
-
* @param jobId 任务 ID
|
|
4912
|
-
* @param jsonOutput 是否 JSON 输出
|
|
4913
|
-
* @returns 完成的任务
|
|
4914
|
-
*/
|
|
4915
|
-
async pollJobStatus(jobId, jsonOutput) {
|
|
4916
|
-
let attempts = 0;
|
|
4917
|
-
let lastProgress = -1;
|
|
4918
|
-
while (attempts < this.maxPollAttempts) {
|
|
4919
|
-
const job = await this.apiClient.getJobStatus(jobId);
|
|
4920
|
-
if (!jsonOutput && job.progress !== lastProgress) {
|
|
4921
|
-
const stage = job.stage ? `\uFF08${job.stage}\uFF09` : "";
|
|
4922
|
-
console.log(`\u8FDB\u5EA6\uFF1A${job.progress}%${stage}`);
|
|
4923
|
-
lastProgress = job.progress;
|
|
4924
|
-
}
|
|
4925
|
-
if (job.status === "completed" || job.status === "failed") {
|
|
4926
|
-
return job;
|
|
4927
|
-
}
|
|
4928
|
-
attempts++;
|
|
4929
|
-
await this.sleep(this.pollInterval);
|
|
4930
|
-
}
|
|
4931
|
-
throw new Error(`\u5BFC\u51FA\u4EFB\u52A1\u8D85\u65F6\uFF1A\u8F6E\u8BE2 ${this.maxPollAttempts} \u6B21\u540E\u4ECD\u672A\u5B8C\u6210`);
|
|
4932
|
-
}
|
|
4933
|
-
/**
|
|
4934
|
-
* 验证 Manifest:解压 → 契约校验 → 逐项 sha256 校验 → 清理临时目录。
|
|
4935
|
-
*
|
|
4936
|
-
* 逐项校验与导出端同法:内容物以 latin1 承载(逐字节双射,二进制条目不被解码改写),
|
|
4937
|
-
* 比对时对原字节做真实 sha256;任一不匹配即判定包损坏并抛错,不静默放行。
|
|
4938
|
-
* 无论成功失败,`${zip}.tmp` 临时目录都在 finally 里删除,不留残余。
|
|
4939
|
-
*
|
|
4940
|
-
* @param zipPath ZIP 文件路径
|
|
4941
|
-
* @returns Manifest
|
|
4942
|
-
*/
|
|
4943
|
-
async verifyManifest(zipPath) {
|
|
4944
|
-
const tempDir = `${zipPath}.tmp`;
|
|
4945
|
-
try {
|
|
4946
|
-
await this.fs.mkdir(tempDir);
|
|
4947
|
-
await this.fs.unzip(zipPath, tempDir);
|
|
4948
|
-
const manifestPath = `${tempDir}/manifest.json`;
|
|
4949
|
-
if (!await this.fs.fileExists(manifestPath)) {
|
|
4950
|
-
throw new Error("manifest.json \u4E0D\u5B58\u5728\uFF0C\u5305\u53EF\u80FD\u5DF2\u635F\u574F");
|
|
4951
|
-
}
|
|
4952
|
-
const manifestContent = await this.fs.readFile(manifestPath);
|
|
4953
|
-
const manifest = JSON.parse(manifestContent.toString("utf-8"));
|
|
4954
|
-
const validationResult = validateBundleManifest(manifest);
|
|
4955
|
-
if (!validationResult.valid) {
|
|
4956
|
-
const errors = validationResult.errors.map((e) => `${e.field ?? ""}: ${e.message}`).join("\n");
|
|
4957
|
-
throw new Error(`manifest \u6821\u9A8C\u5931\u8D25\uFF1A
|
|
4958
|
-
${errors}`);
|
|
4959
|
-
}
|
|
4960
|
-
const actual = /* @__PURE__ */ new Map();
|
|
4961
|
-
for (const content of manifest.contents) {
|
|
4962
|
-
const filePath = `${tempDir}/${content.path}`;
|
|
4963
|
-
if (await this.fs.fileExists(filePath)) {
|
|
4964
|
-
const bytes = await this.fs.readFile(filePath);
|
|
4965
|
-
actual.set(content.path, bytes.toString("latin1"));
|
|
4966
|
-
}
|
|
4967
|
-
}
|
|
4968
|
-
const contentResult = verifyContents(
|
|
4969
|
-
manifest.contents,
|
|
4970
|
-
actual,
|
|
4971
|
-
(text) => createHash3("sha256").update(Buffer.from(text, "latin1")).digest("hex")
|
|
4972
|
-
);
|
|
4973
|
-
if (!contentResult.valid) {
|
|
4974
|
-
const detail = contentResult.errors.map((e) => e.message).join("\n");
|
|
4975
|
-
throw new Error(`\u5185\u5BB9\u7269\u6821\u9A8C\u548C\u4E0D\u5339\u914D\uFF1A
|
|
4976
|
-
${detail}`);
|
|
4977
|
-
}
|
|
4978
|
-
return manifest;
|
|
4979
|
-
} finally {
|
|
4980
|
-
await this.fs.deleteFile(tempDir);
|
|
4981
|
-
}
|
|
4982
|
-
}
|
|
4983
|
-
/**
|
|
4984
|
-
* 统计内容物数量。
|
|
4985
|
-
*
|
|
4986
|
-
* @param contents 内容物列表
|
|
4987
|
-
* @returns 统计结果
|
|
4988
|
-
*/
|
|
4989
|
-
countContents(contents) {
|
|
4990
|
-
return {
|
|
4991
|
-
functions: contents.filter((c) => c.kind === "functions").length,
|
|
4992
|
-
database: contents.filter((c) => c.kind === "database").length,
|
|
4993
|
-
web: contents.filter((c) => c.kind === "web").length,
|
|
4994
|
-
runtime: contents.filter((c) => c.kind === "runtime").length,
|
|
4995
|
-
scripts: contents.filter((c) => c.kind === "scripts").length,
|
|
4996
|
-
docs: contents.filter((c) => c.kind === "docs").length,
|
|
4997
|
-
total: contents.length
|
|
4998
|
-
};
|
|
4999
|
-
}
|
|
5000
|
-
/**
|
|
5001
|
-
* 打印内容清单。
|
|
5002
|
-
*
|
|
5003
|
-
* @param manifest Manifest
|
|
5004
|
-
*/
|
|
5005
|
-
printContentList(manifest) {
|
|
5006
|
-
const counts = this.countContents(manifest.contents);
|
|
5007
|
-
console.log("");
|
|
5008
|
-
console.log("==========================================");
|
|
5009
|
-
console.log("\u5BFC\u51FA\u5185\u5BB9\u6E05\u5355");
|
|
5010
|
-
console.log("==========================================");
|
|
5011
|
-
console.log(`\u9879\u76EE\uFF1A${manifest.project.name}`);
|
|
5012
|
-
console.log(`\u5E73\u53F0\u7248\u672C\uFF1A${manifest.platformVersion}`);
|
|
5013
|
-
console.log(`\u5BFC\u51FA\u65F6\u95F4\uFF1A${manifest.exportedAt}`);
|
|
5014
|
-
console.log("");
|
|
5015
|
-
console.log(`\u51FD\u6570\u6587\u4EF6\uFF1A${counts.functions}`);
|
|
5016
|
-
console.log(`\u6570\u636E\u5E93\u6587\u4EF6\uFF1A${counts.database}`);
|
|
5017
|
-
console.log(`\u524D\u7AEF\u6587\u4EF6\uFF1A${counts.web}`);
|
|
5018
|
-
console.log(`\u8FD0\u884C\u65F6\u6587\u4EF6\uFF1A${counts.runtime}`);
|
|
5019
|
-
console.log(`\u811A\u672C\u6587\u4EF6\uFF1A${counts.scripts}`);
|
|
5020
|
-
console.log(`\u6587\u6863\u6587\u4EF6\uFF1A${counts.docs}`);
|
|
5021
|
-
console.log(`\u603B\u6587\u4EF6\u6570\uFF1A${counts.total}`);
|
|
5022
|
-
console.log("==========================================");
|
|
5023
|
-
}
|
|
5024
|
-
/**
|
|
5025
|
-
* 格式化文件大小。
|
|
5026
|
-
*
|
|
5027
|
-
* @param bytes 字节数
|
|
5028
|
-
* @returns 格式化后的大小
|
|
5029
|
-
*/
|
|
5030
|
-
formatSize(bytes) {
|
|
5031
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
5032
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
5033
|
-
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
5034
|
-
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
5035
|
-
}
|
|
5036
|
-
/**
|
|
5037
|
-
* 睡眠指定毫秒数。
|
|
5038
|
-
*
|
|
5039
|
-
* @param ms 毫秒数
|
|
5040
|
-
*/
|
|
5041
|
-
sleep(ms) {
|
|
5042
|
-
return new Promise((resolve11) => setTimeout(resolve11, ms));
|
|
5043
|
-
}
|
|
5044
|
-
};
|
|
5228
|
+
return { siteUrl: info.siteUrl, outputDir, files };
|
|
5229
|
+
}
|
|
5230
|
+
async function hostingConfig(paths, options) {
|
|
5231
|
+
const { client, project: project2 } = await open4(paths, options);
|
|
5232
|
+
const body = {};
|
|
5233
|
+
if (options.enabled !== void 0) body["enabled"] = options.enabled;
|
|
5234
|
+
if (options.spa !== void 0) body["spaMode"] = options.spa;
|
|
5235
|
+
const result = await client.request(
|
|
5236
|
+
`/api/v1/projects/${project2}/hosting`,
|
|
5237
|
+
{ method: "PUT", body }
|
|
5238
|
+
);
|
|
5239
|
+
return result.config;
|
|
5240
|
+
}
|
|
5241
|
+
var HOSTING_CONFIG_PATH;
|
|
5242
|
+
var init_hosting = __esm({
|
|
5243
|
+
"packages/cli/src/hosting.ts"() {
|
|
5244
|
+
"use strict";
|
|
5245
|
+
init_client();
|
|
5246
|
+
init_auth();
|
|
5247
|
+
init_storage2();
|
|
5248
|
+
HOSTING_CONFIG_PATH = "site/.hosting.json";
|
|
5045
5249
|
}
|
|
5046
5250
|
});
|
|
5047
5251
|
|
|
@@ -5334,7 +5538,30 @@ var ADEP_TSCONFIG_JSON = `{
|
|
|
5334
5538
|
}
|
|
5335
5539
|
`;
|
|
5336
5540
|
|
|
5541
|
+
// packages/cli/src/init.ts
|
|
5542
|
+
init_adep_config();
|
|
5543
|
+
|
|
5337
5544
|
// shared/sdk/web-project-template.ts
|
|
5545
|
+
var ADEP_CLIENT_VERSION = "^0.2.0";
|
|
5546
|
+
var ADEP_VITE_PLUGIN_VERSION = "^0.1.0";
|
|
5547
|
+
var WEB_DEPENDENCIES = {
|
|
5548
|
+
vue: "^3.3.4",
|
|
5549
|
+
// @adep/client:浏览器端云函数调用 SDK(IDE-031)。模板默认在 web/src/lib/adep.ts
|
|
5550
|
+
// 封装并由 App.vue 示例调用;运行时 fetch('/api/{name}') 在 dev 态被 @adep/vite-plugin
|
|
5551
|
+
// 拦截(CLI 代理到本地 adep dev / Web IDE 经 postMessage 转发到 IDE 主线程),
|
|
5552
|
+
// 生产态由平台网关路由到已发布云函数。
|
|
5553
|
+
"@adep/client": ADEP_CLIENT_VERSION
|
|
5554
|
+
};
|
|
5555
|
+
var WEB_DEV_DEPENDENCIES = {
|
|
5556
|
+
vite: "^4.4.0",
|
|
5557
|
+
"@vitejs/plugin-vue": "^4.3.0",
|
|
5558
|
+
// vite 内部动态 import('esbuild-wasm'),必须在 package.json 显式声明才能被 Nodebox 解析
|
|
5559
|
+
"esbuild-wasm": "0.18.20",
|
|
5560
|
+
// @adep/vite-plugin:云函数 Vite 插件(IDE-030)。dev 时自动注入 /api/* fetch 拦截器
|
|
5561
|
+
// (Web IDE 预览经 postMessage 转发到 IDE 主线程执行云函数草稿),若注入 createDevServer
|
|
5562
|
+
// (CLI 场景)则启动本地 adep dev server 并按 functions_prefix 代理 /{prefix}/* 到云函数。
|
|
5563
|
+
"@adep/vite-plugin": ADEP_VITE_PLUGIN_VERSION
|
|
5564
|
+
};
|
|
5338
5565
|
function webProjectFiles() {
|
|
5339
5566
|
return [
|
|
5340
5567
|
{
|
|
@@ -5345,13 +5572,8 @@ function webProjectFiles() {
|
|
|
5345
5572
|
version: "0.0.0",
|
|
5346
5573
|
type: "module",
|
|
5347
5574
|
scripts: { dev: "vite" },
|
|
5348
|
-
dependencies:
|
|
5349
|
-
devDependencies:
|
|
5350
|
-
vite: "^4.4.0",
|
|
5351
|
-
"@vitejs/plugin-vue": "^4.3.0",
|
|
5352
|
-
// vite 内部动态 import('esbuild-wasm'),必须在 package.json 显式声明才能被 Nodebox 解析
|
|
5353
|
-
"esbuild-wasm": "0.18.20"
|
|
5354
|
-
}
|
|
5575
|
+
dependencies: WEB_DEPENDENCIES,
|
|
5576
|
+
devDependencies: WEB_DEV_DEPENDENCIES
|
|
5355
5577
|
},
|
|
5356
5578
|
null,
|
|
5357
5579
|
2
|
|
@@ -5378,12 +5600,17 @@ function webProjectFiles() {
|
|
|
5378
5600
|
{
|
|
5379
5601
|
path: "vite.config.ts",
|
|
5380
5602
|
content: [
|
|
5381
|
-
`// web/vite.config.ts \u2014\u2014 \u6807\u51C6 Vite \u914D\u7F6E\uFF08Vue 3 \
|
|
5603
|
+
`// web/vite.config.ts \u2014\u2014 \u6807\u51C6 Vite \u914D\u7F6E\uFF08Vue 3 + @adep/vite-plugin \u4E91\u51FD\u6570\u4EE3\u7406\uFF09\u3002`,
|
|
5604
|
+
`// @adep/vite-plugin \u5728 dev \u65F6\uFF1A`,
|
|
5605
|
+
`// 1. \u6CE8\u5165 /api/* fetch \u62E6\u622A\u5668\uFF08Web IDE \u9884\u89C8\u7ECF postMessage \u8F6C\u53D1\u5230 IDE \u4E3B\u7EBF\u7A0B\u6267\u884C\u4E91\u51FD\u6570\u8349\u7A3F\uFF09\uFF1B`,
|
|
5606
|
+
`// 2. \u82E5\u6CE8\u5165 createDevServer\uFF08CLI \u573A\u666F\uFF09\uFF0C\u542F\u52A8\u672C\u5730 adep dev \u5E76\u4EE3\u7406 /api/* \u5230\u4E91\u51FD\u6570\u3002`,
|
|
5607
|
+
`// \u6D4F\u89C8\u5668\u5185 vite-dev \u9884\u89C8\uFF08@adep/web-container buildDocument\uFF09\u6CE8\u5165\u540C\u4E00\u4EFD\u811A\u672C\uFF0C\u65E0\u9700\u5728\u6B64\u5185\u8054\u3002`,
|
|
5382
5608
|
`import { defineConfig } from 'vite'`,
|
|
5383
5609
|
`import vue from '@vitejs/plugin-vue'`,
|
|
5610
|
+
`import { adepPlugin } from '@adep/vite-plugin'`,
|
|
5384
5611
|
``,
|
|
5385
5612
|
`export default defineConfig({`,
|
|
5386
|
-
` plugins: [vue()],`,
|
|
5613
|
+
` plugins: [vue(), adepPlugin()],`,
|
|
5387
5614
|
`})`,
|
|
5388
5615
|
``
|
|
5389
5616
|
].join("\n")
|
|
@@ -5400,14 +5627,45 @@ function webProjectFiles() {
|
|
|
5400
5627
|
``
|
|
5401
5628
|
].join("\n")
|
|
5402
5629
|
},
|
|
5630
|
+
{
|
|
5631
|
+
path: "src/lib/adep.ts",
|
|
5632
|
+
content: [
|
|
5633
|
+
`// web/src/lib/adep.ts \u2014\u2014 @adep/client \u6D4F\u89C8\u5668\u7AEF\u5C01\u88C5\uFF08IDE-032\uFF09\u3002`,
|
|
5634
|
+
`// \u5F00\u53D1\u6001\uFF08vite dev + @adep/vite-plugin\uFF09\uFF1AinvokeFunction \u8D70 fetch('/api/*')\uFF0C`,
|
|
5635
|
+
`// \u7531 vite \u63D2\u4EF6\u62E6\u622A\u5230\u672C\u5730\u4E91\u51FD\u6570\u6267\u884C\uFF08CLI\uFF09\u6216\u7ECF postMessage \u8F6C\u53D1\u5230 IDE \u4E3B\u7EBF\u7A0B\uFF08Web IDE\uFF09\u3002`,
|
|
5636
|
+
`// \u751F\u4EA7\u6001\uFF08\u5DF2\u90E8\u7F72\u7AD9\u70B9\uFF09\uFF1Afetch('/api/*') \u7531\u5E73\u53F0\u7F51\u5173\u8DEF\u7531\u5230\u5DF2\u53D1\u5E03\u4E91\u51FD\u6570\u3002`,
|
|
5637
|
+
`import { createAdepClient } from '@adep/client'`,
|
|
5638
|
+
``,
|
|
5639
|
+
`export const adep = createAdepClient()`,
|
|
5640
|
+
``,
|
|
5641
|
+
`export const { invokeFunction } = adep`,
|
|
5642
|
+
``
|
|
5643
|
+
].join("\n")
|
|
5644
|
+
},
|
|
5403
5645
|
{
|
|
5404
5646
|
path: "src/App.vue",
|
|
5405
5647
|
content: [
|
|
5406
5648
|
`<script setup lang="ts">`,
|
|
5407
5649
|
`import { ref } from 'vue'`,
|
|
5650
|
+
`import { invokeFunction } from './lib/adep'`,
|
|
5408
5651
|
``,
|
|
5409
5652
|
`const title = ref('adep web')`,
|
|
5410
5653
|
`const clicks = ref(0)`,
|
|
5654
|
+
`const fnResult = ref<string>('')`,
|
|
5655
|
+
`const fnLoading = ref(false)`,
|
|
5656
|
+
``,
|
|
5657
|
+
`async function callHello() {`,
|
|
5658
|
+
` fnLoading.value = true`,
|
|
5659
|
+
` fnResult.value = ''`,
|
|
5660
|
+
` try {`,
|
|
5661
|
+
` const result = await invokeFunction<{ message: string }>('hello')`,
|
|
5662
|
+
` fnResult.value = result.message`,
|
|
5663
|
+
` } catch (err) {`,
|
|
5664
|
+
` fnResult.value = \`\u8C03\u7528\u5931\u8D25\uFF1A\${err instanceof Error ? err.message : String(err)}\``,
|
|
5665
|
+
` } finally {`,
|
|
5666
|
+
` fnLoading.value = false`,
|
|
5667
|
+
` }`,
|
|
5668
|
+
`}`,
|
|
5411
5669
|
`</script>`,
|
|
5412
5670
|
``,
|
|
5413
5671
|
`<template>`,
|
|
@@ -5415,6 +5673,12 @@ function webProjectFiles() {
|
|
|
5415
5673
|
` <h1>{{ title }}</h1>`,
|
|
5416
5674
|
` <p>\u5728 web/src/App.vue \u91CC\u7F16\u8F91\uFF0C\u4FDD\u5B58\u540E\u9884\u89C8\u81EA\u52A8\u5237\u65B0\uFF08HMR\uFF09\u3002</p>`,
|
|
5417
5675
|
` <button @click="clicks++">clicks: {{ clicks }}</button>`,
|
|
5676
|
+
` <div style="margin-top: 16px;">`,
|
|
5677
|
+
` <button @click="callHello" :disabled="fnLoading">`,
|
|
5678
|
+
` {{ fnLoading ? '\u8C03\u7528\u4E2D\u2026' : '\u8C03\u7528 hello \u51FD\u6570' }}`,
|
|
5679
|
+
` </button>`,
|
|
5680
|
+
` <p v-if="fnResult" style="margin-top: 8px; color: #059669;">\u7ED3\u679C\uFF1A{{ fnResult }}</p>`,
|
|
5681
|
+
` </div>`,
|
|
5418
5682
|
` </main>`,
|
|
5419
5683
|
`</template>`,
|
|
5420
5684
|
``,
|
|
@@ -5430,12 +5694,19 @@ function webProjectFiles() {
|
|
|
5430
5694
|
` background: #eef2ff;`,
|
|
5431
5695
|
` cursor: pointer;`,
|
|
5432
5696
|
`}`,
|
|
5697
|
+
`button:disabled {`,
|
|
5698
|
+
` opacity: 0.6;`,
|
|
5699
|
+
` cursor: not-allowed;`,
|
|
5700
|
+
`}`,
|
|
5433
5701
|
`</style>`,
|
|
5434
5702
|
``
|
|
5435
5703
|
].join("\n")
|
|
5436
5704
|
}
|
|
5437
5705
|
];
|
|
5438
5706
|
}
|
|
5707
|
+
function webSrcFiles() {
|
|
5708
|
+
return webProjectFiles().filter((file) => file.path.startsWith("src/"));
|
|
5709
|
+
}
|
|
5439
5710
|
|
|
5440
5711
|
// packages/cli/src/init.ts
|
|
5441
5712
|
var TEMPLATE_NAMES = ["empty", "function", "fullstack"];
|
|
@@ -5448,38 +5719,34 @@ var InitError = class extends Error {
|
|
|
5448
5719
|
};
|
|
5449
5720
|
var requireJson = createRequire(import.meta.url);
|
|
5450
5721
|
var CLI_VERSION = requireJson("../package.json").version;
|
|
5451
|
-
var
|
|
5722
|
+
var ADEP_CONFIG_HEADER = `// adep \u9879\u76EE\u914D\u7F6E\uFF1ACLI\uFF08dev / serve / deploy\uFF09\u4E0E\u4E91\u51FD\u6570 vite \u63D2\u4EF6\u6309 default export \u8BFB\u53D6\u3002
|
|
5452
5723
|
// - name\uFF1A\u9879\u76EE\u6807\u8BC6\uFF08deploy / db \u7B49\u547D\u4EE4\u7684\u7F3A\u7701 project slug\uFF09
|
|
5453
5724
|
// - template\uFF1A\u811A\u624B\u67B6\u6A21\u677F\uFF08empty / function / fullstack\uFF0Cinit \u65F6\u786E\u5B9A\uFF09
|
|
5454
5725
|
// - functionsDir\uFF1A\u4E91\u51FD\u6570\u76EE\u5F55\uFF08dev / serve / deploy \u8BFB\u53D6\uFF0C\u7F3A\u7701 functions/\uFF09
|
|
5455
|
-
// - functions_prefix\uFF1A\
|
|
5456
|
-
//
|
|
5457
|
-
// \
|
|
5458
|
-
|
|
5459
|
-
name: '${name}',
|
|
5460
|
-
template: '${template}',
|
|
5461
|
-
functionsDir: 'functions',
|
|
5462
|
-
functions_prefix: '',
|
|
5463
|
-
}
|
|
5464
|
-
`;
|
|
5726
|
+
// - functions_prefix\uFF1A\u4E91\u51FD\u6570\u8DEF\u7531\u524D\u7F00\uFF0C**\u9ED8\u8BA4 /api**\uFF08\u4E0E\u7EBF\u4E0A\u51FD\u6570\u8DEF\u7531 /api/{fn} \u5BF9\u9F50\uFF09\u3002
|
|
5727
|
+
// dev \u8BBF\u95EE\u8DEF\u5F84\u4E3A /{prefix}/{fnName}\uFF08\u5982 /api/hello\uFF09\uFF1Bserve \u4E3A /api/{prefix}/{fnName}\u3002
|
|
5728
|
+
// vite \u63D2\u4EF6\uFF08vite.config.ts \u7684 adepPlugin()\uFF09\u6309\u6B64\u524D\u7F00\u628A\u524D\u7AEF /{prefix}/* \u8BF7\u6C42\u4EE3\u7406\u5230\u4E91\u51FD\u6570\u3002
|
|
5729
|
+
// \u8FB9\u754C\uFF1A\u53EA\u5F71\u54CD\u672C\u5730 HTTP \u5165\u53E3\u8DEF\u7531\uFF1B\u51FD\u6570\u4E92\u8C03\uFF08ctx.cloud.invoke\uFF09\u4E0E\u7EBF\u4E0A\u90E8\u7F72\u8DEF\u5F84\u6309\u51FD\u6570\u540D\uFF0C\u4E0D\u53D7\u5F71\u54CD\u3002`;
|
|
5465
5730
|
var PACKAGE_JSON = (name, template) => {
|
|
5466
5731
|
const pkg = {
|
|
5467
5732
|
name,
|
|
5468
5733
|
version: "0.1.0",
|
|
5469
5734
|
private: true,
|
|
5470
5735
|
type: "module",
|
|
5471
|
-
description: `AgentDeploy \u5168\u6808\u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u2014\u2014functions/ \u4E91\u51FD\u6570 + web/ \u524D\u7AEF\
|
|
5736
|
+
description: `AgentDeploy \u5168\u6808\u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u2014\u2014functions/ \u4E91\u51FD\u6570 + web/src/ \u524D\u7AEF\u6E90\u7801 + site/ \u524D\u7AEF\u6784\u5EFA\u4EA7\u7269`,
|
|
5472
5737
|
scripts: {
|
|
5473
|
-
dev: "
|
|
5738
|
+
dev: "vite",
|
|
5739
|
+
build: "vite build",
|
|
5740
|
+
"site:deploy": "adep hosting deploy site --spa",
|
|
5474
5741
|
serve: "adep serve",
|
|
5475
5742
|
deploy: "adep deploy",
|
|
5476
|
-
"web:dev": "cd web && npm install && npm run dev",
|
|
5477
|
-
"web:build": "cd web && npm install && npm run build",
|
|
5478
5743
|
doctor: "adep doctor"
|
|
5479
5744
|
},
|
|
5480
5745
|
dependencies: {
|
|
5481
|
-
"@adep/cli": CLI_VERSION
|
|
5746
|
+
"@adep/cli": CLI_VERSION,
|
|
5747
|
+
...WEB_DEPENDENCIES
|
|
5482
5748
|
},
|
|
5749
|
+
devDependencies: WEB_DEV_DEPENDENCIES,
|
|
5483
5750
|
engines: {
|
|
5484
5751
|
node: ">=18",
|
|
5485
5752
|
bun: ">=1.0"
|
|
@@ -5494,32 +5761,71 @@ AgentDeploy \u5168\u6808\u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u3
|
|
|
5494
5761
|
|
|
5495
5762
|
## \u5E38\u7528\u547D\u4EE4
|
|
5496
5763
|
|
|
5497
|
-
- \`pnpm dev\`\uFF08= \`
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
- \`pnpm
|
|
5501
|
-
- \`pnpm
|
|
5764
|
+
- \`pnpm dev\`\uFF08= \`vite\`\uFF09\uFF1A**\u5168\u6808\u5F00\u53D1**\u2014\u2014vite \u542F\u52A8\u524D\u7AEF\uFF08HMR\uFF09\uFF0C\u4E91\u51FD\u6570 vite \u63D2\u4EF6\u5185\u7F6E
|
|
5765
|
+
\`adep dev\` \u5E76\u628A \`/api/*\` \u8BF7\u6C42\u4EE3\u7406\u5230\u4E91\u51FD\u6570\uFF0C\u4E00\u4E2A\u547D\u4EE4\u8C03\u8BD5\u524D\u7AEF + \u51FD\u6570
|
|
5766
|
+
\uFF08\`curl http://localhost:5173/api/hello\`\uFF09\u3002
|
|
5767
|
+
- \`pnpm build\`\uFF08= \`vite build\`\uFF09\uFF1A\u6784\u5EFA\u524D\u7AEF \u2192 \`site/\`\uFF08\u4E91\u51FD\u6570\u5DE5\u7A0B\u7AD9\u70B9\u6258\u7BA1\u76EE\u5F55\uFF09\u3002
|
|
5768
|
+
- \`pnpm site:deploy\`\uFF08= \`adep hosting deploy site --spa\`\uFF09\uFF1A\u628A \`site/\` \u4E0A\u4F20\u5230\u5E73\u53F0
|
|
5769
|
+
\u9759\u6001\u6258\u7BA1\u5E76\u5F00\u542F SPA \u56DE\u9000\uFF0C\u8F93\u51FA\u7AD9\u70B9\u5730\u5740\u3002
|
|
5770
|
+
- \`pnpm serve\`\uFF08= \`adep serve\`\uFF09\uFF1A\u5F00\u53D1\u6001\u670D\u52A1\u5668\uFF08\u51FD\u6570 /api/{prefix}/{fn} + /healthz + \u9759\u6001\u6258\u7BA1\uFF09
|
|
5771
|
+
- \`pnpm deploy\`\uFF08= \`adep deploy\`\uFF09\uFF1A\u589E\u91CF\u90E8\u7F72\u4E91\u51FD\u6570\uFF08\u5BF9\u6BD4\u8FDC\u7AEF\u54C8\u5E0C \u2192 \u4EC5\u4E0A\u4F20\u53D8\u66F4 \u2192 \u53D1\u5E03 \u2192 \u8F93\u51FA\u8BBF\u95EE\u57DF\u540D\uFF09
|
|
5502
5772
|
- \`pnpm doctor\`\uFF08= \`adep doctor\`\uFF09\uFF1A\u672C\u5730\u73AF\u5883\u79BB\u7EBF\u8BCA\u65AD
|
|
5503
5773
|
|
|
5504
5774
|
## \u76EE\u5F55\u7ED3\u6784
|
|
5505
5775
|
|
|
5506
|
-
- \`package.json\`\uFF1A\u5E94\u7528\u5B9A\u4E49\uFF08
|
|
5507
|
-
- \`
|
|
5776
|
+
- \`package.json\`\uFF1A\u5E94\u7528\u5B9A\u4E49\uFF08@adep/cli + \u524D\u7AEF\u4F9D\u8D56\u540C\u6839\u58F0\u660E\uFF1Bvite \u5DE5\u7A0B\u6839\u5728\u9879\u76EE\u6839\u76EE\u5F55\uFF09
|
|
5777
|
+
- \`vite.config.ts\`\uFF1Avite \u914D\u7F6E\uFF08vue \u63D2\u4EF6 + \`adepPlugin()\` \u4E91\u51FD\u6570\u63D2\u4EF6\uFF0C\u6765\u81EA @adep/vite-plugin\uFF1Bbuild.outDir = site/\uFF09
|
|
5778
|
+
- \`index.html\`\uFF1Avite \u5165\u53E3\uFF08\u5F15\u7528 \`/web/src/main.ts\`\uFF09
|
|
5779
|
+
- \`adep.config.ts\`\uFF1A\u9879\u76EE\u914D\u7F6E\uFF08name / template / functionsDir / functions_prefix\uFF0C\u9ED8\u8BA4 /api\uFF09
|
|
5508
5780
|
- \`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
|
|
5509
|
-
- \`web/\`\uFF1A\u524D\u7AEF\
|
|
5781
|
+
- \`web/src/\`\uFF1A\u524D\u7AEF\u6E90\u7801\uFF08Vue 3\uFF1B\u4E0E Web IDE \u7684 \`web/\` \u5DE5\u7A0B\u5171\u7528\u540C\u4E00\u4EFD \`src/\`\uFF09
|
|
5782
|
+
- \`web/src/lib/adep.ts\`\uFF1A@adep/client \u6D4F\u89C8\u5668\u7AEF\u5C01\u88C5\uFF08\`invokeFunction('hello', args)\` \u8C03\u7528\u4E91\u51FD\u6570\uFF09
|
|
5783
|
+
- \`site/\`\uFF1A\`vite build\` \u7684\u524D\u7AEF\u6784\u5EFA\u4EA7\u7269\uFF08\u7AD9\u70B9\u6258\u7BA1\u76EE\u5F55\uFF0C\`adep hosting deploy site\` \u4E0A\u4F20\uFF1B\u5DF2 gitignore\uFF09
|
|
5510
5784
|
- \`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
|
|
5511
|
-
- \`tsconfig.json\`\
|
|
5785
|
+
- \`tsconfig.json\`\uFF1ATypeScript \u7F16\u8F91\u5668\u914D\u7F6E\uFF08strict + noEmit\uFF09
|
|
5512
5786
|
- \`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
|
|
5513
5787
|
|
|
5514
|
-
## \
|
|
5788
|
+
## \u5168\u6808\u5F00\u53D1\uFF08vite + \u4E91\u51FD\u6570\u4EE3\u7406\uFF09
|
|
5515
5789
|
|
|
5516
|
-
\`
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5790
|
+
\`pnpm dev\` \u542F\u52A8 vite \u540E\uFF0C\u4E91\u51FD\u6570\u63D2\u4EF6\u81EA\u52A8\u505A\u4E24\u4EF6\u4E8B\uFF1A
|
|
5791
|
+
1. \u5728 vite \u8FDB\u7A0B\u5185\u542F\u52A8 \`adep dev\`\uFF08\u6A21\u62DF\u8FD0\u884C\u65F6\uFF0C\u51FD\u6570\u70ED\u91CD\u8F7D\u3001\`.env.local\`\u3001cloud.db/storage/realtime \u5168\u53EF\u7528\uFF09\uFF1B
|
|
5792
|
+
2. \u628A \`/{functions_prefix}/*\` \u8BF7\u6C42\u4EE3\u7406\u5230\u4E91\u51FD\u6570\u2014\u2014\`adep.config.ts\` \u9ED8\u8BA4
|
|
5793
|
+
\`functions_prefix: '/api'\`\uFF0C\u56E0\u6B64\u524D\u7AEF \`fetch('/api/hello')\` \u5373\u8C03\u7528 \`functions/hello.ts\`\uFF0C
|
|
5794
|
+
\u4E0E\u7EBF\u4E0A\u90E8\u7F72\u540E\u7684\u51FD\u6570\u8DEF\u7531 \`/api/{fn}\` \u4E00\u81F4\u3002
|
|
5795
|
+
|
|
5796
|
+
## \u4ECE\u524D\u7AEF\u8C03\u7528\u4E91\u51FD\u6570\uFF08@adep/client\uFF09
|
|
5797
|
+
|
|
5798
|
+
\u6A21\u677F\u9884\u7F6E \`@adep/client\` SDK\uFF0C\`web/src/lib/adep.ts\` \u5DF2\u5C01\u88C5\u597D \`invokeFunction\`\uFF1A
|
|
5799
|
+
|
|
5800
|
+
\`\`\`ts
|
|
5801
|
+
import { invokeFunction } from './lib/adep'
|
|
5802
|
+
|
|
5803
|
+
// POST /api/hello\uFF0Cargs \u4F5C\u4E3A JSON body \u4F20\u7ED9\u51FD\u6570
|
|
5804
|
+
const result = await invokeFunction<{ message: string }>('hello', { name: 'world' })
|
|
5805
|
+
console.log(result.message)
|
|
5806
|
+
\`\`\`
|
|
5807
|
+
|
|
5808
|
+
- **\u5F00\u53D1\u6001**\uFF1A\`invokeFunction\` \u8D70 \`fetch('/api/*')\`\uFF0C\u7531 \`@adep/vite-plugin\` \u4EE3\u7406\u5230\u672C\u5730
|
|
5809
|
+
\`adep dev\`\uFF08CLI\uFF09\u6216\u7ECF postMessage \u8F6C\u53D1\u5230 IDE \u4E3B\u7EBF\u7A0B\u6267\u884C\u4E91\u51FD\u6570\u8349\u7A3F\uFF08Web IDE\uFF09\u3002
|
|
5810
|
+
- **\u751F\u4EA7\u6001**\uFF1A\`fetch('/api/*')\` \u7531\u5E73\u53F0\u7F51\u5173\u8DEF\u7531\u5230\u5DF2\u53D1\u5E03\u4E91\u51FD\u6570\uFF08\`adep deploy\` \u540E\u751F\u6548\uFF09\u3002
|
|
5811
|
+
- \u9519\u8BEF\u5904\u7406\uFF1A\u975E 2xx \u629B \`FunctionInvokeError\`\uFF08\u542B status / code / body\uFF09\uFF0C\u8D85\u65F6\u629B
|
|
5812
|
+
\`FunctionTimeoutError\`\u3002\u8BE6\u89C1\u6587\u6863\u7AD9\u300CSDK \u2192 \u6D4F\u89C8\u5668\u7AEF SDK\u300D\u3002
|
|
5813
|
+
|
|
5814
|
+
## \u4E91\u51FD\u6570\u8DEF\u7531\u524D\u7F00\uFF08functions_prefix\uFF09
|
|
5815
|
+
|
|
5816
|
+
\`adep.config.ts\` \u7684 \`functions_prefix\`\uFF08\u9ED8\u8BA4 \`/api\`\uFF09\uFF1A
|
|
5817
|
+
- \`adep dev\`\uFF1A\`/{prefix}/{fn}\`\uFF0C\u5982 \`/api/hello\`\uFF1Bvite \u63D2\u4EF6\u6309\u540C\u4E00\u524D\u7F00\u4EE3\u7406\u3002
|
|
5818
|
+
- \`adep serve\`\uFF1A\`/api/{prefix}/{fn}\`\uFF08\u524D\u7F00\u62FC\u63A5\uFF09\u3002
|
|
5520
5819
|
- **\u8FB9\u754C**\uFF1A\u53EA\u5F71\u54CD\u672C\u5730 HTTP \u5165\u53E3\uFF1B\u51FD\u6570\u4E92\u8C03 \`ctx.cloud.invoke('name')\` \u4E0E\u7EBF\u4E0A\u90E8\u7F72\u8DEF\u5F84\u6309\u51FD\u6570\u540D\uFF0C
|
|
5521
5820
|
\u4E0D\u968F\u524D\u7F00\u53D8\u5316\uFF08\u4E0E\u7EBF\u4E0A\u540C\u6784\uFF09\u3002
|
|
5522
5821
|
|
|
5822
|
+
## \u7AD9\u70B9\u6258\u7BA1\uFF08\u6784\u5EFA \u2192 \u4E0A\u4F20 \u2192 \u4E0A\u7EBF\uFF09
|
|
5823
|
+
|
|
5824
|
+
1. \`pnpm build\`\uFF1Avite \u6784\u5EFA\u524D\u7AEF\u5230 \`site/\`\uFF08\u7AD9\u70B9\u6258\u7BA1\u76EE\u5F55\uFF09\u3002
|
|
5825
|
+
2. \`pnpm site:deploy\`\uFF1A\`adep hosting deploy site --spa\` \u9012\u5F52\u4E0A\u4F20 \`site/\` \u5230\u5E73\u53F0\u9759\u6001\u6258\u7BA1
|
|
5826
|
+
\uFF08site/ \u524D\u7F00\uFF09\uFF0C\u6253\u5F00\u6258\u7BA1\u5F00\u5173\u5E76\u542F\u7528 SPA \u56DE\u9000\uFF0C\u8FD4\u56DE\u7AD9\u70B9\u5730\u5740\u3002
|
|
5827
|
+
\uFF08\u7B49\u4EF7\u547D\u4EE4\uFF1A\`npx adep hosting deploy site --spa\`\uFF1B\u67E5\u770B\uFF1A\`npx adep hosting info\`\uFF09
|
|
5828
|
+
|
|
5523
5829
|
## \u4E91\u51FD\u6570\u7C7B\u578B\u63D0\u793A
|
|
5524
5830
|
|
|
5525
5831
|
\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
|
|
@@ -5528,19 +5834,18 @@ AgentDeploy \u5168\u6808\u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u3
|
|
|
5528
5834
|
|
|
5529
5835
|
## \u6A21\u677F\u8BF4\u660E\uFF08adep init\uFF09
|
|
5530
5836
|
|
|
5531
|
-
- \`adep init <name>\`\uFF1A\u9ED8\u8BA4 \`fullstack\` \u6A21\u677F\uFF08functions/ + web/ \u524D\u7AEF\
|
|
5837
|
+
- \`adep init <name>\`\uFF1A\u9ED8\u8BA4 \`fullstack\` \u6A21\u677F\uFF08functions/ + web/src/ \u524D\u7AEF\u6E90\u7801 + database/\uFF09
|
|
5532
5838
|
- \`adep init <name> -t function\`\uFF1A\u4EC5\u4E91\u51FD\u6570\uFF08\u5355\u4E2A\u793A\u4F8B\u51FD\u6570\uFF09
|
|
5533
5839
|
- \`adep init <name> -t empty\`\uFF1A\u7A7A\u6A21\u677F\uFF08\u4EC5\u9879\u76EE\u9AA8\u67B6\uFF09
|
|
5534
5840
|
- \`adep init --list\`\uFF1A\u4ECE\u5E73\u53F0 /api/v1/templates \u5217\u51FA\u53EF\u7528\u6A21\u677F
|
|
5535
5841
|
- \`adep init --list -s <server>\`\uFF1A\u6307\u5B9A\u5E73\u53F0\u5730\u5740
|
|
5536
5842
|
|
|
5537
|
-
## \u524D\u7AEF\
|
|
5843
|
+
## \u524D\u7AEF\u6E90\u7801\uFF08web/src/\uFF09
|
|
5538
5844
|
|
|
5539
|
-
\`web/\` \
|
|
5540
|
-
|
|
5541
|
-
\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
|
|
5845
|
+
\`web/src/\` \u5B58\u653E\u524D\u7AEF\u6E90\u7801\uFF08\`main.ts\` / \`App.vue\`\uFF09\uFF0C\u4E0E Web IDE \u5185 \`web/\` \u5DE5\u7A0B\u7684 \`src/\`
|
|
5846
|
+
\u5B8C\u5168\u540C\u6784\uFF1Bvite \u5DE5\u7A0B\u6839\u5728\u9879\u76EE\u6839\u76EE\u5F55\uFF08\`vite.config.ts\` / \`index.html\` / \`package.json\`\uFF09\u3002
|
|
5542
5847
|
`;
|
|
5543
|
-
var HELLO_FUNCTION = `// \u793A\u4F8B\u51FD\u6570\uFF1Aadep deploy \u540E\u7ECF https://<project-slug>.<platform-domain>/hello \u89E6\u53D1\u3002
|
|
5848
|
+
var HELLO_FUNCTION = `// \u793A\u4F8B\u51FD\u6570\uFF1Aadep deploy \u540E\u7ECF https://<project-slug>.<platform-domain>/api/hello \u89E6\u53D1\u3002
|
|
5544
5849
|
// \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
|
|
5545
5850
|
//\uFF08ctx \u5951\u7EA6\u89C1 adep.d.ts\uFF1Amethod / path / query / headers / body / files / user / cloud.*\uFF09\u3002
|
|
5546
5851
|
export default async (ctx: AdepContext) => {
|
|
@@ -5551,11 +5856,40 @@ export default async (ctx: AdepContext) => {
|
|
|
5551
5856
|
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
|
|
5552
5857
|
// \u9ED8\u8BA4\u5BFC\u51FA (ctx: AdepContext) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668\uFF08\u5951\u7EA6\u89C1 adep.d.ts\uFF09\u3002
|
|
5553
5858
|
`;
|
|
5554
|
-
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
|
|
5859
|
+
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/src/\uFF0C\u914D\u7F6E\u89C1 adep.config.ts\u3002
|
|
5555
5860
|
`;
|
|
5556
5861
|
var SCHEMA_SQL = `-- AgentDeploy \u9879\u76EE\u6570\u636E\u5E93\u7ED3\u6784\uFF08\u5360\u4F4D\uFF09\u3002
|
|
5557
5862
|
-- \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
|
|
5558
5863
|
`;
|
|
5864
|
+
var INDEX_HTML = `<!doctype html>
|
|
5865
|
+
<html lang="zh-CN">
|
|
5866
|
+
<head>
|
|
5867
|
+
<meta charset="utf-8" />
|
|
5868
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
5869
|
+
<title>adep web</title>
|
|
5870
|
+
</head>
|
|
5871
|
+
<body>
|
|
5872
|
+
<div id="app"></div>
|
|
5873
|
+
<script type="module" src="/web/src/main.ts"></script>
|
|
5874
|
+
</body>
|
|
5875
|
+
</html>
|
|
5876
|
+
`;
|
|
5877
|
+
var VITE_CONFIG = `// vite.config.ts \u2014\u2014 \u9879\u76EE\u6839 vite \u914D\u7F6E\uFF08CLI-014 \u5168\u6808\u5F00\u53D1\u4F53\u9A8C\uFF09\u3002
|
|
5878
|
+
// adep() \u662F @adep/cli/vite \u7684\u4E91\u51FD\u6570 vite \u63D2\u4EF6\uFF1A\u5185\u7F6E adep dev server \u5E76\u6309
|
|
5879
|
+
// adep.config.ts \u7684 functions_prefix\uFF08\u9ED8\u8BA4 /api\uFF09\u628A /api/* \u8BF7\u6C42\u4EE3\u7406\u5230\u4E91\u51FD\u6570\u2014\u2014
|
|
5880
|
+
// vite dev \u5373\u53EF\u8C03\u8BD5\u524D\u7AEF + \u51FD\u6570\uFF08curl http://localhost:5173/api/hello\uFF09\u3002
|
|
5881
|
+
import { defineConfig } from 'vite'
|
|
5882
|
+
import vue from '@vitejs/plugin-vue'
|
|
5883
|
+
import adep from '@adep/cli/vite'
|
|
5884
|
+
|
|
5885
|
+
export default defineConfig({
|
|
5886
|
+
plugins: [vue(), adep()],
|
|
5887
|
+
build: {
|
|
5888
|
+
// \u524D\u7AEF\u6784\u5EFA\u4EA7\u7269 \u2192 site/\uFF08\u4E91\u51FD\u6570\u5DE5\u7A0B\u7AD9\u70B9\u6258\u7BA1\u76EE\u5F55\uFF1Bpnpm site:deploy \u4E0A\u4F20\u90E8\u7F72\uFF09
|
|
5889
|
+
outDir: 'site',
|
|
5890
|
+
},
|
|
5891
|
+
})
|
|
5892
|
+
`;
|
|
5559
5893
|
async function initProject(cwd, name, template) {
|
|
5560
5894
|
if (!/^[a-z][a-z0-9-]{0,62}$/.test(name)) {
|
|
5561
5895
|
throw new InitError(
|
|
@@ -5580,14 +5914,22 @@ async function initProject(cwd, name, template) {
|
|
|
5580
5914
|
throw new InitError("DIR_EXISTS", `\u76EE\u5F55 ${projectPath} \u5DF2\u5B58\u5728\uFF1A\u8BF7\u6362\u4E00\u4E2A\u540D\u5B57\u6216\u5148\u5220\u9664`);
|
|
5581
5915
|
}
|
|
5582
5916
|
const files = [
|
|
5583
|
-
// 根 package.json
|
|
5917
|
+
// 根 package.json:应用定义(@adep/cli + 前端依赖同根声明;与导出的离线部署包同构键集)。
|
|
5584
5918
|
{ path: "package.json", content: PACKAGE_JSON(name, template) },
|
|
5585
|
-
|
|
5919
|
+
// adep.config.ts:经 shared/sdk/adep-config 的 renderAdepConfig 渲染(schema 唯一真相源)。
|
|
5920
|
+
// template 是 init 元数据(不在 AdepConfig 中),经 extraFields 传入。
|
|
5921
|
+
{
|
|
5922
|
+
path: "adep.config.ts",
|
|
5923
|
+
content: renderAdepConfig(
|
|
5924
|
+
{ name, functionsDir: "functions", functions_prefix: "/api" },
|
|
5925
|
+
{ header: ADEP_CONFIG_HEADER, extraFields: { template } }
|
|
5926
|
+
)
|
|
5927
|
+
},
|
|
5586
5928
|
// 云函数 TypeScript 类型提示:tsconfig 把 adep.d.ts 纳入 include,写 ctx: AdepContext 即有补全。
|
|
5587
5929
|
{ path: "tsconfig.json", content: ADEP_TSCONFIG_JSON },
|
|
5588
5930
|
{ path: "adep.d.ts", content: ADEP_ENV_DTS },
|
|
5589
5931
|
{ path: "README.md", content: README(name, template) },
|
|
5590
|
-
{ path: ".gitignore", content: "node_modules/\ndata/\n.adep/\
|
|
5932
|
+
{ path: ".gitignore", content: "node_modules/\ndata/\n.adep/\nsite/\n" }
|
|
5591
5933
|
];
|
|
5592
5934
|
if (template === "function") {
|
|
5593
5935
|
files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION });
|
|
@@ -5596,7 +5938,9 @@ async function initProject(cwd, name, template) {
|
|
|
5596
5938
|
files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION });
|
|
5597
5939
|
files.push({ path: "functions/README.md", content: FUNCTION_INDEX });
|
|
5598
5940
|
files.push({ path: "database/schema.sql", content: SCHEMA_SQL });
|
|
5599
|
-
|
|
5941
|
+
files.push({ path: "index.html", content: INDEX_HTML });
|
|
5942
|
+
files.push({ path: "vite.config.ts", content: VITE_CONFIG });
|
|
5943
|
+
for (const file of webSrcFiles()) {
|
|
5600
5944
|
files.push({ path: `web/${file.path}`, content: file.content });
|
|
5601
5945
|
}
|
|
5602
5946
|
} else {
|
|
@@ -5857,6 +6201,122 @@ function registerDevServers(program2, ctx) {
|
|
|
5857
6201
|
});
|
|
5858
6202
|
}
|
|
5859
6203
|
|
|
6204
|
+
// packages/cli/src/commands/publish.ts
|
|
6205
|
+
init_auth();
|
|
6206
|
+
init_client();
|
|
6207
|
+
init_deploy();
|
|
6208
|
+
import { resolve as resolve6 } from "node:path";
|
|
6209
|
+
async function resolveProjectId(client, cwd, slug) {
|
|
6210
|
+
const resolvedSlug = await resolveSlug(resolve6(cwd), slug);
|
|
6211
|
+
const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
6212
|
+
const match = listed.projects.find((project2) => project2.slug === resolvedSlug);
|
|
6213
|
+
if (match === void 0) {
|
|
6214
|
+
throw new CliError(
|
|
6215
|
+
"PROJECT_NOT_FOUND",
|
|
6216
|
+
`\u5E73\u53F0\u9879\u76EE "${resolvedSlug}" \u4E0D\u5B58\u5728\u6216\u4F60\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\uFF1A\u5148\u6267\u884C adep projects create ${resolvedSlug}`
|
|
6217
|
+
);
|
|
6218
|
+
}
|
|
6219
|
+
return { id: match.id, slug: match.slug };
|
|
6220
|
+
}
|
|
6221
|
+
async function publishFrontend(paths, options) {
|
|
6222
|
+
const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
|
|
6223
|
+
`));
|
|
6224
|
+
const client = await createClient(paths);
|
|
6225
|
+
const project2 = await resolveProjectId(client, options.cwd, options.slug);
|
|
6226
|
+
log(`[adep] \u89E6\u53D1\u5E73\u53F0\u4FA7\u524D\u7AEF\u6784\u5EFA\uFF08\u9879\u76EE ${project2.slug}\uFF09\u2026`);
|
|
6227
|
+
const published = await client.request(
|
|
6228
|
+
`/api/v1/projects/${project2.id}/frontend/publish`,
|
|
6229
|
+
{ method: "POST" },
|
|
6230
|
+
"FRONTEND_PUBLISH_FAILED"
|
|
6231
|
+
);
|
|
6232
|
+
const versions = await client.request(
|
|
6233
|
+
`/api/v1/projects/${project2.id}/frontend/versions`,
|
|
6234
|
+
{},
|
|
6235
|
+
"FRONTEND_VERSIONS_FAILED"
|
|
6236
|
+
);
|
|
6237
|
+
return {
|
|
6238
|
+
version: published.version,
|
|
6239
|
+
hash: published.hash,
|
|
6240
|
+
createdAt: published.createdAt,
|
|
6241
|
+
reused: published.reused,
|
|
6242
|
+
siteUrl: versions.siteUrl
|
|
6243
|
+
};
|
|
6244
|
+
}
|
|
6245
|
+
async function publishFunctions(paths, options) {
|
|
6246
|
+
const startedAt = Date.now();
|
|
6247
|
+
const result = await deploy(paths, {
|
|
6248
|
+
cwd: options.cwd,
|
|
6249
|
+
...options.slug === void 0 ? {} : { slug: options.slug },
|
|
6250
|
+
silent: options.silent ?? false,
|
|
6251
|
+
...options.log === void 0 ? {} : { log: options.log }
|
|
6252
|
+
});
|
|
6253
|
+
const elapsedSeconds = (Date.now() - startedAt) / 1e3;
|
|
6254
|
+
const deployedCount = result.functions.filter((fn) => fn.action !== "none").length;
|
|
6255
|
+
return { ...result, elapsedSeconds, deployedCount };
|
|
6256
|
+
}
|
|
6257
|
+
async function runPublish(paths, io, cwd, flags) {
|
|
6258
|
+
const scope = flags.only === void 0 ? "fullstack" : flags.only;
|
|
6259
|
+
if (flags.only !== void 0 && flags.only !== "functions" && flags.only !== "frontend") {
|
|
6260
|
+
throw new CliError("INVALID_SCOPE", `--only \u987B\u4E3A functions \u6216 frontend\uFF0C\u6536\u5230 "${flags.only}"`);
|
|
6261
|
+
}
|
|
6262
|
+
const wantFunctions = scope === "fullstack" || scope === "functions";
|
|
6263
|
+
const wantFrontend = scope === "fullstack" || scope === "frontend";
|
|
6264
|
+
const result = { scope };
|
|
6265
|
+
if (wantFunctions) {
|
|
6266
|
+
result.functions = await publishFunctions(paths, {
|
|
6267
|
+
cwd,
|
|
6268
|
+
...flags.project === void 0 ? {} : { slug: flags.project },
|
|
6269
|
+
silent: io.json,
|
|
6270
|
+
log: (line) => io.line(line)
|
|
6271
|
+
});
|
|
6272
|
+
}
|
|
6273
|
+
if (wantFrontend) {
|
|
6274
|
+
result.frontend = await publishFrontend(paths, {
|
|
6275
|
+
cwd,
|
|
6276
|
+
...flags.project === void 0 ? {} : { slug: flags.project },
|
|
6277
|
+
silent: io.json,
|
|
6278
|
+
log: (line) => io.line(line)
|
|
6279
|
+
});
|
|
6280
|
+
}
|
|
6281
|
+
return result;
|
|
6282
|
+
}
|
|
6283
|
+
function renderPublish(data) {
|
|
6284
|
+
const result = data;
|
|
6285
|
+
const lines = [];
|
|
6286
|
+
if (result.functions !== void 0) {
|
|
6287
|
+
for (const fn of result.functions.functions) {
|
|
6288
|
+
lines.push(`${fn.name} v${fn.version} ${fn.url}`);
|
|
6289
|
+
}
|
|
6290
|
+
if (result.functions.noChanges) {
|
|
6291
|
+
lines.push(
|
|
6292
|
+
`\u2713 no changes \xB7 ${result.functions.functions.length} functions up to date in ${formatSeconds(result.functions.elapsedSeconds)}`
|
|
6293
|
+
);
|
|
6294
|
+
} else {
|
|
6295
|
+
lines.push(
|
|
6296
|
+
`\u2713 ${result.functions.deployedCount} functions deployed in ${formatSeconds(result.functions.elapsedSeconds)}`
|
|
6297
|
+
);
|
|
6298
|
+
}
|
|
6299
|
+
}
|
|
6300
|
+
if (result.frontend !== void 0) {
|
|
6301
|
+
const fe = result.frontend;
|
|
6302
|
+
const status = fe.reused ? `\uFF08\u590D\u7528 v${fe.version}\uFF0C\u65E0\u53D8\u66F4\uFF09` : `v${fe.version}`;
|
|
6303
|
+
lines.push(`\u2713 frontend built ${status} \xB7 ${fe.siteUrl}`);
|
|
6304
|
+
}
|
|
6305
|
+
return lines;
|
|
6306
|
+
}
|
|
6307
|
+
function registerPublish(program2, ctx) {
|
|
6308
|
+
program2.command("publish").description("\u5168\u6808\u53D1\u5E03\uFF1A\u51FD\u6570\u90E8\u7F72 + \u524D\u7AEF\u6784\u5EFA\u6258\u7BA1\uFF08--only functions|frontend \u53EF\u5355\u72EC\u53D1\u5E03\u4E00\u4FA7\uFF09").option(
|
|
6309
|
+
"--only <scope>",
|
|
6310
|
+
"\u4EC5\u53D1\u5E03\u4E00\u4FA7\uFF1Afunctions\uFF08\u53EA\u90E8\u7F72\u4E91\u51FD\u6570\uFF09| frontend\uFF08\u53EA\u6784\u5EFA\u6258\u7BA1\u524D\u7AEF\uFF09\uFF1B\u7F3A\u7701\u5168\u6808\u53D1\u5E03"
|
|
6311
|
+
).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6312
|
+
const command = ctx.io("publish");
|
|
6313
|
+
await command.run(async () => {
|
|
6314
|
+
const result = await runPublish(ctx.paths, command, ctx.cwd, flags);
|
|
6315
|
+
command.ok(result, renderPublish);
|
|
6316
|
+
});
|
|
6317
|
+
});
|
|
6318
|
+
}
|
|
6319
|
+
|
|
5860
6320
|
// packages/cli/src/commands/deploy.ts
|
|
5861
6321
|
async function runDeploy(paths, io, cwd, slug, dir) {
|
|
5862
6322
|
const { deploy: deploy2 } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
|
|
@@ -5881,183 +6341,63 @@ async function runDeploy(paths, io, cwd, slug, dir) {
|
|
|
5881
6341
|
`\u2713 no changes \xB7 ${r.functions.length} functions up to date in ${formatSeconds(r.elapsedSeconds)}`
|
|
5882
6342
|
);
|
|
5883
6343
|
} else {
|
|
5884
|
-
lines.push(`\u2713 ${r.deployedCount} functions deployed in ${formatSeconds(r.elapsedSeconds)}`);
|
|
5885
|
-
}
|
|
5886
|
-
return lines;
|
|
5887
|
-
});
|
|
5888
|
-
}
|
|
5889
|
-
function registerDeploy(program2, ctx) {
|
|
5890
|
-
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) => {
|
|
5891
|
-
const command = ctx.io("deploy");
|
|
5892
|
-
await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project));
|
|
5893
|
-
});
|
|
5894
|
-
}
|
|
5895
|
-
|
|
5896
|
-
// packages/cli/src/commands/projects.ts
|
|
5897
|
-
function registerProjects(program2, ctx) {
|
|
5898
|
-
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");
|
|
5899
|
-
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) => {
|
|
5900
|
-
const command = ctx.io("projects create");
|
|
5901
|
-
await command.run(async () => {
|
|
5902
|
-
const { projectsCreate: projectsCreate2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
5903
|
-
const created = await projectsCreate2(ctx.paths, {
|
|
5904
|
-
slug,
|
|
5905
|
-
...flags.name === void 0 ? {} : { name: flags.name },
|
|
5906
|
-
...flags.space === void 0 ? {} : { spaceId: flags.space }
|
|
5907
|
-
});
|
|
5908
|
-
command.ok(created, (data) => `\u2713 Project created \xB7 ${data.url}`);
|
|
5909
|
-
});
|
|
5910
|
-
});
|
|
5911
|
-
projects.command("list").description("\u5217\u51FA\u5F53\u524D\u7528\u6237\u53EF\u8BBF\u95EE\u7684\u9879\u76EE").action(async () => {
|
|
5912
|
-
const command = ctx.io("projects list");
|
|
5913
|
-
await command.run(async () => {
|
|
5914
|
-
const { projectsList: projectsList2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
5915
|
-
const list = await projectsList2(ctx.paths);
|
|
5916
|
-
command.ok({ projects: list }, (data) => {
|
|
5917
|
-
const projectsData = data.projects;
|
|
5918
|
-
if (projectsData.length === 0) return "\uFF08\u8FD8\u6CA1\u6709\u9879\u76EE\uFF1Aadep projects create <slug>\uFF09";
|
|
5919
|
-
return projectsData.map((p) => `${p.slug} ${p.name} ${p.url}`);
|
|
5920
|
-
});
|
|
5921
|
-
});
|
|
5922
|
-
});
|
|
5923
|
-
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) => {
|
|
5924
|
-
const command = ctx.io("projects info");
|
|
5925
|
-
await command.run(async () => {
|
|
5926
|
-
const { projectsInfo: projectsInfo2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
5927
|
-
const project2 = await projectsInfo2(ctx.paths, { slug });
|
|
5928
|
-
command.ok(project2, (data) => {
|
|
5929
|
-
const p = data;
|
|
5930
|
-
return `${p.id} ${p.slug} ${p.name} ${p.url}`;
|
|
5931
|
-
});
|
|
5932
|
-
});
|
|
5933
|
-
});
|
|
5934
|
-
}
|
|
5935
|
-
|
|
5936
|
-
// packages/cli/src/commands/functions.ts
|
|
5937
|
-
init_auth();
|
|
5938
|
-
function registerFunctions(program2, ctx) {
|
|
5939
|
-
const functions = program2.command("functions").description("\u4E91\u51FD\u6570\uFF1A\u90E8\u7F72\uFF08\u53EF\u6307\u5B9A\u76EE\u5F55\uFF09/ \u5217\u51FA / \u67E5\u65E5\u5FD7");
|
|
5940
|
-
functions.command("deploy").description(
|
|
5941
|
-
"\u90E8\u7F72\u51FD\u6570\u76EE\u5F55\uFF08`adep deploy` \u7684\u547D\u4EE4\u65CF\u5165\u53E3\uFF1Bdir \u8986\u76D6 adep.config.ts \u7684 functionsDir\uFF09"
|
|
5942
|
-
).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) => {
|
|
5943
|
-
const command = ctx.io("functions deploy");
|
|
5944
|
-
await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project, dir));
|
|
5945
|
-
});
|
|
5946
|
-
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) => {
|
|
5947
|
-
const command = ctx.io("functions list");
|
|
5948
|
-
await command.run(async () => {
|
|
5949
|
-
const { functionsList: functionsList2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
5950
|
-
const result = await functionsList2(ctx.paths, {
|
|
5951
|
-
cwd: ctx.cwd,
|
|
5952
|
-
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
5953
|
-
});
|
|
5954
|
-
command.ok(result, (data) => {
|
|
5955
|
-
const r = data;
|
|
5956
|
-
if (r.functions.length === 0) return "\uFF08\u8BE5\u9879\u76EE\u4E0B\u8FD8\u6CA1\u6709\u51FD\u6570\uFF09";
|
|
5957
|
-
return r.functions.map((fn) => `${fn.name} ${r.baseUrl}/${fn.name}`);
|
|
5958
|
-
});
|
|
5959
|
-
});
|
|
5960
|
-
});
|
|
5961
|
-
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) => {
|
|
5962
|
-
const command = ctx.io("functions logs");
|
|
5963
|
-
await command.run(async () => {
|
|
5964
|
-
const { functionsLogs: functionsLogs2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
5965
|
-
const tail = flags.tail === void 0 ? void 0 : Number(flags.tail);
|
|
5966
|
-
if (tail !== void 0 && (!Number.isFinite(tail) || tail <= 0)) {
|
|
5967
|
-
throw new CliError("INVALID_TAIL", `--tail \u987B\u4E3A\u6B63\u6574\u6570\uFF0C\u6536\u5230 "${flags.tail}"`);
|
|
5968
|
-
}
|
|
5969
|
-
const result = await functionsLogs2(ctx.paths, {
|
|
5970
|
-
cwd: ctx.cwd,
|
|
5971
|
-
name,
|
|
5972
|
-
...tail === void 0 ? {} : { tail },
|
|
5973
|
-
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
5974
|
-
});
|
|
5975
|
-
command.ok(result, (data) => {
|
|
5976
|
-
const r = data;
|
|
5977
|
-
if (r.logs.length === 0) {
|
|
5978
|
-
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`;
|
|
5979
|
-
}
|
|
5980
|
-
return r.logs.map((log) => `${log.at} [${log.level}] ${log.message}`);
|
|
5981
|
-
});
|
|
5982
|
-
});
|
|
5983
|
-
});
|
|
5984
|
-
}
|
|
5985
|
-
|
|
5986
|
-
// packages/cli/src/commands/mcp.ts
|
|
5987
|
-
function registerMcp(program2, ctx) {
|
|
5988
|
-
const mcp = program2.command("mcp").description("MCP Tool\uFF1A\u628A\u4E91\u51FD\u6570\u53D1\u5E03\u4E3A\u5DE5\u5177 / \u53D6\u6D88\u53D1\u5E03 / \u5217\u51FA");
|
|
5989
|
-
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(
|
|
5990
|
-
"--description <text>",
|
|
5991
|
-
"\u8986\u76D6\u9762\u5411 Agent \u7684\u5DE5\u5177\u63CF\u8FF0\uFF08\u7F3A\u7701\u7528\u6E90\u7801 @description / \u63A8\u5BFC\u63CF\u8FF0\uFF09"
|
|
5992
|
-
).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(
|
|
5993
|
-
async (flags) => {
|
|
5994
|
-
const command = ctx.io("mcp publish");
|
|
5995
|
-
await command.run(async () => {
|
|
5996
|
-
const { mcpPublish: mcpPublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
5997
|
-
const result = await mcpPublish2(ctx.paths, {
|
|
5998
|
-
cwd: ctx.cwd,
|
|
5999
|
-
fn: flags.function,
|
|
6000
|
-
...flags.name === void 0 ? {} : { toolName: flags.name },
|
|
6001
|
-
...flags.description === void 0 ? {} : { description: flags.description },
|
|
6002
|
-
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6003
|
-
});
|
|
6004
|
-
command.ok(result, (data) => {
|
|
6005
|
-
const r = data;
|
|
6006
|
-
return `\u2713 MCP tool published \xB7 ${r.tool.name}`;
|
|
6007
|
-
});
|
|
6008
|
-
});
|
|
6009
|
-
}
|
|
6010
|
-
);
|
|
6011
|
-
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) => {
|
|
6012
|
-
const command = ctx.io("mcp unpublish");
|
|
6013
|
-
await command.run(async () => {
|
|
6014
|
-
const { mcpUnpublish: mcpUnpublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6015
|
-
const result = await mcpUnpublish2(ctx.paths, {
|
|
6016
|
-
cwd: ctx.cwd,
|
|
6017
|
-
fn: flags.function,
|
|
6018
|
-
...flags.name === void 0 ? {} : { toolName: flags.name },
|
|
6019
|
-
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6020
|
-
});
|
|
6021
|
-
command.ok(result, (data) => {
|
|
6022
|
-
const r = data;
|
|
6023
|
-
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`;
|
|
6024
|
-
});
|
|
6025
|
-
});
|
|
6026
|
-
});
|
|
6027
|
-
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) => {
|
|
6028
|
-
const command = ctx.io("mcp list");
|
|
6029
|
-
await command.run(async () => {
|
|
6030
|
-
const { mcpList: mcpList2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6031
|
-
const result = await mcpList2(ctx.paths, {
|
|
6032
|
-
cwd: ctx.cwd,
|
|
6033
|
-
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6034
|
-
});
|
|
6035
|
-
command.ok(result, (data) => {
|
|
6036
|
-
const r = data;
|
|
6037
|
-
const lines = [`\u7AEF\u70B9\uFF1A${r.endpoint}`];
|
|
6038
|
-
if (r.tools.length === 0) {
|
|
6039
|
-
lines.push("\uFF08\u8FD8\u6CA1\u6709\u5DF2\u53D1\u5E03\u7684 MCP tool\uFF1Aadep mcp publish --function <fn>\uFF09");
|
|
6040
|
-
} else {
|
|
6041
|
-
for (const tool of r.tools) lines.push(`${tool.name} ${tool.description ?? ""}`);
|
|
6042
|
-
}
|
|
6043
|
-
return lines;
|
|
6044
|
-
});
|
|
6045
|
-
});
|
|
6344
|
+
lines.push(`\u2713 ${r.deployedCount} functions deployed in ${formatSeconds(r.elapsedSeconds)}`);
|
|
6345
|
+
}
|
|
6346
|
+
return lines;
|
|
6046
6347
|
});
|
|
6047
6348
|
}
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
const command = ctx.io("
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
}
|
|
6349
|
+
function registerDeploy(program2, ctx) {
|
|
6350
|
+
program2.command("deploy").description(
|
|
6351
|
+
"[deprecated] \u63A8\u8350\u4F7F\u7528 adep publish\u3002\u589E\u91CF\u90E8\u7F72\u51FD\u6570\uFF1A\u5BF9\u6BD4\u8FDC\u7AEF\u54C8\u5E0C \u2192 \u4EC5\u4E0A\u4F20\u53D8\u66F4 \u2192 \u53D1\u5E03 \u2192 \u8F93\u51FA\u8BBF\u95EE\u57DF\u540D"
|
|
6352
|
+
).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
6353
|
+
const command = ctx.io("deploy");
|
|
6354
|
+
if (!command.json) {
|
|
6355
|
+
process.stderr.write(
|
|
6356
|
+
"\u63D0\u793A\uFF1Aadep deploy \u5DF2\u5E9F\u5F03\uFF0C\u63A8\u8350\u4F7F\u7528 adep publish\uFF08\u5168\u6808\u53D1\u5E03\uFF09\u6216 adep publish --only functions\uFF08\u4EC5\u51FD\u6570\uFF09\n"
|
|
6357
|
+
);
|
|
6358
|
+
}
|
|
6359
|
+
await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project));
|
|
6058
6360
|
});
|
|
6059
6361
|
}
|
|
6060
6362
|
|
|
6363
|
+
// packages/cli/src/commands/export.ts
|
|
6364
|
+
function registerExport(program2, ctx) {
|
|
6365
|
+
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", "[\u5DF2\u5E9F\u5F03] \u542B\u6E90\u7801\u5DF2\u4E3A\u9ED8\u8BA4\u884C\u4E3A\uFF1B\u4FDD\u7559\u4E0D\u62A5\u9519\uFF0C\u4EC5\u63D0\u793A\uFF0C\u5C06\u5728\u672A\u6765\u7248\u672C\u79FB\u9664").option(
|
|
6366
|
+
"--without-source",
|
|
6367
|
+
"\u51FA\u7EAF\u4EA7\u7269\u5305\uFF1A\u4E0D\u5305\u542B\u51FD\u6570\u6E90\u7801\u4E0E web/src/ \u524D\u7AEF\u6E90\u7801\uFF08\u4EC5 site/ \u9884\u6784\u5EFA\u4EA7\u7269\uFF09"
|
|
6368
|
+
).option("--out <dir>", "\u8F93\u51FA\u76EE\u5F55\uFF08\u7F3A\u7701 ./exports\uFF09").action(
|
|
6369
|
+
async (flags) => {
|
|
6370
|
+
const command = ctx.io("export");
|
|
6371
|
+
await command.run(async () => {
|
|
6372
|
+
const { createExportApiClient: createExportApiClient2 } = await Promise.resolve().then(() => (init_client2(), client_exports2));
|
|
6373
|
+
const { createExportFileSystem: createExportFileSystem2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
6374
|
+
const { ExportCommand: ExportCommand2 } = await Promise.resolve().then(() => (init_command(), command_exports));
|
|
6375
|
+
const { resolveSlug: resolveSlug2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
6376
|
+
if (flags.withSource === true) {
|
|
6377
|
+
process.stderr.write(
|
|
6378
|
+
"adep: --with-source \u5DF2\u4E3A\u9ED8\u8BA4\u884C\u4E3A\uFF08\u5BFC\u51FA\u5305\u9ED8\u8BA4\u542B\u51FD\u6570\u6E90\u7801\u4E0E web/src/ \u524D\u7AEF\u6E90\u7801\uFF09\uFF0C\u8BE5\u9009\u9879\u5C06\u5728\u672A\u6765\u7248\u672C\u79FB\u9664\n"
|
|
6379
|
+
);
|
|
6380
|
+
}
|
|
6381
|
+
const project2 = await resolveSlug2(ctx.cwd, flags.project);
|
|
6382
|
+
const apiClient = await createExportApiClient2(ctx.paths);
|
|
6383
|
+
const exportCommand = new ExportCommand2(apiClient, createExportFileSystem2());
|
|
6384
|
+
const result = await exportCommand.execute({
|
|
6385
|
+
project: project2,
|
|
6386
|
+
...flags.withData === true ? { withData: true } : {},
|
|
6387
|
+
...flags.withoutSource === true ? { withoutSource: true } : {},
|
|
6388
|
+
...flags.out === void 0 ? {} : { out: flags.out },
|
|
6389
|
+
json: command.json
|
|
6390
|
+
});
|
|
6391
|
+
if (!result.success) {
|
|
6392
|
+
command.fail("EXPORT_FAILED", result.error ?? "\u5BFC\u51FA\u5931\u8D25");
|
|
6393
|
+
return;
|
|
6394
|
+
}
|
|
6395
|
+
command.ok(result);
|
|
6396
|
+
});
|
|
6397
|
+
}
|
|
6398
|
+
);
|
|
6399
|
+
}
|
|
6400
|
+
|
|
6061
6401
|
// packages/cli/src/commands/db.ts
|
|
6062
6402
|
function registerDb(program2, ctx) {
|
|
6063
6403
|
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");
|
|
@@ -6261,6 +6601,176 @@ function registerStorage(program2, ctx) {
|
|
|
6261
6601
|
});
|
|
6262
6602
|
}
|
|
6263
6603
|
|
|
6604
|
+
// packages/cli/src/commands/doctor.ts
|
|
6605
|
+
function registerDoctor(program2, ctx) {
|
|
6606
|
+
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 () => {
|
|
6607
|
+
const command = ctx.io("doctor");
|
|
6608
|
+
await command.run(async () => {
|
|
6609
|
+
const { runDoctor: runDoctor2, formatDoctorReport: formatDoctorReport2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
|
|
6610
|
+
const report = await runDoctor2(ctx.paths);
|
|
6611
|
+
command.ok(report, () => formatDoctorReport2(report));
|
|
6612
|
+
});
|
|
6613
|
+
});
|
|
6614
|
+
}
|
|
6615
|
+
|
|
6616
|
+
// packages/cli/src/commands/mcp.ts
|
|
6617
|
+
function registerMcp(program2, ctx) {
|
|
6618
|
+
const mcp = program2.command("mcp").description("MCP Tool\uFF1A\u628A\u4E91\u51FD\u6570\u53D1\u5E03\u4E3A\u5DE5\u5177 / \u53D6\u6D88\u53D1\u5E03 / \u5217\u51FA");
|
|
6619
|
+
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(
|
|
6620
|
+
"--description <text>",
|
|
6621
|
+
"\u8986\u76D6\u9762\u5411 Agent \u7684\u5DE5\u5177\u63CF\u8FF0\uFF08\u7F3A\u7701\u7528\u6E90\u7801 @description / \u63A8\u5BFC\u63CF\u8FF0\uFF09"
|
|
6622
|
+
).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(
|
|
6623
|
+
async (flags) => {
|
|
6624
|
+
const command = ctx.io("mcp publish");
|
|
6625
|
+
await command.run(async () => {
|
|
6626
|
+
const { mcpPublish: mcpPublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6627
|
+
const result = await mcpPublish2(ctx.paths, {
|
|
6628
|
+
cwd: ctx.cwd,
|
|
6629
|
+
fn: flags.function,
|
|
6630
|
+
...flags.name === void 0 ? {} : { toolName: flags.name },
|
|
6631
|
+
...flags.description === void 0 ? {} : { description: flags.description },
|
|
6632
|
+
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6633
|
+
});
|
|
6634
|
+
command.ok(result, (data) => {
|
|
6635
|
+
const r = data;
|
|
6636
|
+
return `\u2713 MCP tool published \xB7 ${r.tool.name}`;
|
|
6637
|
+
});
|
|
6638
|
+
});
|
|
6639
|
+
}
|
|
6640
|
+
);
|
|
6641
|
+
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) => {
|
|
6642
|
+
const command = ctx.io("mcp unpublish");
|
|
6643
|
+
await command.run(async () => {
|
|
6644
|
+
const { mcpUnpublish: mcpUnpublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6645
|
+
const result = await mcpUnpublish2(ctx.paths, {
|
|
6646
|
+
cwd: ctx.cwd,
|
|
6647
|
+
fn: flags.function,
|
|
6648
|
+
...flags.name === void 0 ? {} : { toolName: flags.name },
|
|
6649
|
+
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6650
|
+
});
|
|
6651
|
+
command.ok(result, (data) => {
|
|
6652
|
+
const r = data;
|
|
6653
|
+
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`;
|
|
6654
|
+
});
|
|
6655
|
+
});
|
|
6656
|
+
});
|
|
6657
|
+
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) => {
|
|
6658
|
+
const command = ctx.io("mcp list");
|
|
6659
|
+
await command.run(async () => {
|
|
6660
|
+
const { mcpList: mcpList2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6661
|
+
const result = await mcpList2(ctx.paths, {
|
|
6662
|
+
cwd: ctx.cwd,
|
|
6663
|
+
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6664
|
+
});
|
|
6665
|
+
command.ok(result, (data) => {
|
|
6666
|
+
const r = data;
|
|
6667
|
+
const lines = [`\u7AEF\u70B9\uFF1A${r.endpoint}`];
|
|
6668
|
+
if (r.tools.length === 0) {
|
|
6669
|
+
lines.push("\uFF08\u8FD8\u6CA1\u6709\u5DF2\u53D1\u5E03\u7684 MCP tool\uFF1Aadep mcp publish --function <fn>\uFF09");
|
|
6670
|
+
} else {
|
|
6671
|
+
for (const tool of r.tools) lines.push(`${tool.name} ${tool.description ?? ""}`);
|
|
6672
|
+
}
|
|
6673
|
+
return lines;
|
|
6674
|
+
});
|
|
6675
|
+
});
|
|
6676
|
+
});
|
|
6677
|
+
}
|
|
6678
|
+
|
|
6679
|
+
// packages/cli/src/commands/projects.ts
|
|
6680
|
+
function registerProjects(program2, ctx) {
|
|
6681
|
+
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");
|
|
6682
|
+
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) => {
|
|
6683
|
+
const command = ctx.io("projects create");
|
|
6684
|
+
await command.run(async () => {
|
|
6685
|
+
const { projectsCreate: projectsCreate2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
6686
|
+
const created = await projectsCreate2(ctx.paths, {
|
|
6687
|
+
slug,
|
|
6688
|
+
...flags.name === void 0 ? {} : { name: flags.name },
|
|
6689
|
+
...flags.space === void 0 ? {} : { spaceId: flags.space }
|
|
6690
|
+
});
|
|
6691
|
+
command.ok(created, (data) => `\u2713 Project created \xB7 ${data.url}`);
|
|
6692
|
+
});
|
|
6693
|
+
});
|
|
6694
|
+
projects.command("list").description("\u5217\u51FA\u5F53\u524D\u7528\u6237\u53EF\u8BBF\u95EE\u7684\u9879\u76EE").action(async () => {
|
|
6695
|
+
const command = ctx.io("projects list");
|
|
6696
|
+
await command.run(async () => {
|
|
6697
|
+
const { projectsList: projectsList2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
6698
|
+
const list = await projectsList2(ctx.paths);
|
|
6699
|
+
command.ok({ projects: list }, (data) => {
|
|
6700
|
+
const projectsData = data.projects;
|
|
6701
|
+
if (projectsData.length === 0) return "\uFF08\u8FD8\u6CA1\u6709\u9879\u76EE\uFF1Aadep projects create <slug>\uFF09";
|
|
6702
|
+
return projectsData.map((p) => `${p.slug} ${p.name} ${p.url}`);
|
|
6703
|
+
});
|
|
6704
|
+
});
|
|
6705
|
+
});
|
|
6706
|
+
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) => {
|
|
6707
|
+
const command = ctx.io("projects info");
|
|
6708
|
+
await command.run(async () => {
|
|
6709
|
+
const { projectsInfo: projectsInfo2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
|
|
6710
|
+
const project2 = await projectsInfo2(ctx.paths, { slug });
|
|
6711
|
+
command.ok(project2, (data) => {
|
|
6712
|
+
const p = data;
|
|
6713
|
+
return `${p.id} ${p.slug} ${p.name} ${p.url}`;
|
|
6714
|
+
});
|
|
6715
|
+
});
|
|
6716
|
+
});
|
|
6717
|
+
}
|
|
6718
|
+
|
|
6719
|
+
// packages/cli/src/commands/functions.ts
|
|
6720
|
+
init_auth();
|
|
6721
|
+
function registerFunctions(program2, ctx) {
|
|
6722
|
+
const functions = program2.command("functions").description("\u4E91\u51FD\u6570\uFF1A\u90E8\u7F72\uFF08\u53EF\u6307\u5B9A\u76EE\u5F55\uFF09/ \u5217\u51FA / \u67E5\u65E5\u5FD7");
|
|
6723
|
+
functions.command("deploy").description(
|
|
6724
|
+
"[deprecated] \u63A8\u8350\u4F7F\u7528 adep publish --only functions\u3002\u90E8\u7F72\u51FD\u6570\u76EE\u5F55\uFF08dir \u8986\u76D6 adep.config.ts \u7684 functionsDir\uFF09"
|
|
6725
|
+
).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) => {
|
|
6726
|
+
const command = ctx.io("functions deploy");
|
|
6727
|
+
if (!command.json) {
|
|
6728
|
+
process.stderr.write(
|
|
6729
|
+
"\u63D0\u793A\uFF1Aadep functions deploy \u5DF2\u5E9F\u5F03\uFF0C\u63A8\u8350\u4F7F\u7528 adep publish --only functions\n"
|
|
6730
|
+
);
|
|
6731
|
+
}
|
|
6732
|
+
await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project, dir));
|
|
6733
|
+
});
|
|
6734
|
+
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) => {
|
|
6735
|
+
const command = ctx.io("functions list");
|
|
6736
|
+
await command.run(async () => {
|
|
6737
|
+
const { functionsList: functionsList2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
6738
|
+
const result = await functionsList2(ctx.paths, {
|
|
6739
|
+
cwd: ctx.cwd,
|
|
6740
|
+
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6741
|
+
});
|
|
6742
|
+
command.ok(result, (data) => {
|
|
6743
|
+
const r = data;
|
|
6744
|
+
if (r.functions.length === 0) return "\uFF08\u8BE5\u9879\u76EE\u4E0B\u8FD8\u6CA1\u6709\u51FD\u6570\uFF09";
|
|
6745
|
+
return r.functions.map((fn) => `${fn.name} ${r.baseUrl}/${fn.name}`);
|
|
6746
|
+
});
|
|
6747
|
+
});
|
|
6748
|
+
});
|
|
6749
|
+
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) => {
|
|
6750
|
+
const command = ctx.io("functions logs");
|
|
6751
|
+
await command.run(async () => {
|
|
6752
|
+
const { functionsLogs: functionsLogs2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
6753
|
+
const tail = flags.tail === void 0 ? void 0 : Number(flags.tail);
|
|
6754
|
+
if (tail !== void 0 && (!Number.isFinite(tail) || tail <= 0)) {
|
|
6755
|
+
throw new CliError("INVALID_TAIL", `--tail \u987B\u4E3A\u6B63\u6574\u6570\uFF0C\u6536\u5230 "${flags.tail}"`);
|
|
6756
|
+
}
|
|
6757
|
+
const result = await functionsLogs2(ctx.paths, {
|
|
6758
|
+
cwd: ctx.cwd,
|
|
6759
|
+
name,
|
|
6760
|
+
...tail === void 0 ? {} : { tail },
|
|
6761
|
+
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
6762
|
+
});
|
|
6763
|
+
command.ok(result, (data) => {
|
|
6764
|
+
const r = data;
|
|
6765
|
+
if (r.logs.length === 0) {
|
|
6766
|
+
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`;
|
|
6767
|
+
}
|
|
6768
|
+
return r.logs.map((log) => `${log.at} [${log.level}] ${log.message}`);
|
|
6769
|
+
});
|
|
6770
|
+
});
|
|
6771
|
+
});
|
|
6772
|
+
}
|
|
6773
|
+
|
|
6264
6774
|
// packages/cli/src/commands/hosting.ts
|
|
6265
6775
|
init_auth();
|
|
6266
6776
|
function parseBool(raw) {
|
|
@@ -6289,8 +6799,15 @@ function registerHosting(program2, ctx) {
|
|
|
6289
6799
|
});
|
|
6290
6800
|
});
|
|
6291
6801
|
});
|
|
6292
|
-
hosting.command("deploy").description(
|
|
6802
|
+
hosting.command("deploy").description(
|
|
6803
|
+
"[deprecated] \u63A8\u8350\u4F7F\u7528 adep publish --only frontend\u3002\u90E8\u7F72\u672C\u5730\u76EE\u5F55\u4E3A\u9759\u6001\u7AD9\u70B9\uFF1A\u9012\u5F52\u4E0A\u4F20\u5230 site/ \u5E76\u6253\u5F00\u6258\u7BA1"
|
|
6804
|
+
).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) => {
|
|
6293
6805
|
const command = ctx.io("hosting deploy");
|
|
6806
|
+
if (!command.json) {
|
|
6807
|
+
process.stderr.write(
|
|
6808
|
+
"\u63D0\u793A\uFF1Aadep hosting deploy \u5DF2\u5E9F\u5F03\uFF0C\u63A8\u8350\u4F7F\u7528 adep publish --only frontend\uFF08\u5E73\u53F0\u4FA7\u6784\u5EFA web/ \u8349\u7A3F\uFF09\uFF1B\u5982\u786E\u9700\u4E0A\u4F20\u9884\u6784\u5EFA\u76EE\u5F55\uFF0C\u4ECD\u53EF\u7EE7\u7EED\u4F7F\u7528\u672C\u547D\u4EE4\n"
|
|
6809
|
+
);
|
|
6810
|
+
}
|
|
6294
6811
|
await command.run(async () => {
|
|
6295
6812
|
const { hostingDeploy: hostingDeploy2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
|
|
6296
6813
|
const result = await hostingDeploy2(ctx.paths, {
|
|
@@ -6340,36 +6857,6 @@ function registerHosting(program2, ctx) {
|
|
|
6340
6857
|
});
|
|
6341
6858
|
}
|
|
6342
6859
|
|
|
6343
|
-
// packages/cli/src/commands/export.ts
|
|
6344
|
-
function registerExport(program2, ctx) {
|
|
6345
|
-
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(
|
|
6346
|
-
async (flags) => {
|
|
6347
|
-
const command = ctx.io("export");
|
|
6348
|
-
await command.run(async () => {
|
|
6349
|
-
const { createExportApiClient: createExportApiClient2 } = await Promise.resolve().then(() => (init_client2(), client_exports2));
|
|
6350
|
-
const { createExportFileSystem: createExportFileSystem2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
6351
|
-
const { ExportCommand: ExportCommand2 } = await Promise.resolve().then(() => (init_command(), command_exports));
|
|
6352
|
-
const { resolveSlug: resolveSlug2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
6353
|
-
const project2 = await resolveSlug2(ctx.cwd, flags.project);
|
|
6354
|
-
const apiClient = await createExportApiClient2(ctx.paths);
|
|
6355
|
-
const exportCommand = new ExportCommand2(apiClient, createExportFileSystem2());
|
|
6356
|
-
const result = await exportCommand.execute({
|
|
6357
|
-
project: project2,
|
|
6358
|
-
...flags.withData === true ? { withData: true } : {},
|
|
6359
|
-
...flags.withSource === true ? { withSource: true } : {},
|
|
6360
|
-
...flags.out === void 0 ? {} : { out: flags.out },
|
|
6361
|
-
json: command.json
|
|
6362
|
-
});
|
|
6363
|
-
if (!result.success) {
|
|
6364
|
-
command.fail("EXPORT_FAILED", result.error ?? "\u5BFC\u51FA\u5931\u8D25");
|
|
6365
|
-
return;
|
|
6366
|
-
}
|
|
6367
|
-
command.ok(result);
|
|
6368
|
-
});
|
|
6369
|
-
}
|
|
6370
|
-
);
|
|
6371
|
-
}
|
|
6372
|
-
|
|
6373
6860
|
// packages/cli/src/cli.ts
|
|
6374
6861
|
var requireJson2 = createRequire2(import.meta.url);
|
|
6375
6862
|
var APP_VERSION = requireJson2("../package.json").version;
|
|
@@ -6383,18 +6870,19 @@ function buildProgram(options = {}) {
|
|
|
6383
6870
|
program2.option("--json", "\u4EE5\u673A\u5668\u53EF\u8BFB JSON \u8F93\u51FA\uFF08Agent / \u811A\u672C\u8C03\u7528\uFF09", false);
|
|
6384
6871
|
const jsonMode = () => program2.opts()["json"] === true;
|
|
6385
6872
|
const ctx = createCliContext({ output, paths, cwd, json: jsonMode });
|
|
6386
|
-
registerAuth(program2, ctx);
|
|
6387
6873
|
registerInit(program2, ctx);
|
|
6388
6874
|
registerDevServers(program2, ctx);
|
|
6875
|
+
registerPublish(program2, ctx);
|
|
6876
|
+
registerExport(program2, ctx);
|
|
6877
|
+
registerDb(program2, ctx);
|
|
6878
|
+
registerStorage(program2, ctx);
|
|
6879
|
+
registerDoctor(program2, ctx);
|
|
6880
|
+
registerAuth(program2, ctx);
|
|
6881
|
+
registerMcp(program2, ctx);
|
|
6389
6882
|
registerDeploy(program2, ctx);
|
|
6390
6883
|
registerProjects(program2, ctx);
|
|
6391
6884
|
registerFunctions(program2, ctx);
|
|
6392
|
-
registerMcp(program2, ctx);
|
|
6393
|
-
registerDoctor(program2, ctx);
|
|
6394
|
-
registerDb(program2, ctx);
|
|
6395
|
-
registerStorage(program2, ctx);
|
|
6396
6885
|
registerHosting(program2, ctx);
|
|
6397
|
-
registerExport(program2, ctx);
|
|
6398
6886
|
return program2;
|
|
6399
6887
|
}
|
|
6400
6888
|
|