@adep/cli 0.1.11 → 0.1.12
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 +13 -1
- package/dist/index.js +617 -213
- package/dist/vite.js +3 -3
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -707,20 +707,20 @@ var init_resolve = __esm({
|
|
|
707
707
|
// packages/runtime/src/functions/runtime/worker-executor.ts
|
|
708
708
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
709
709
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
710
|
-
import { dirname as dirname5, join as
|
|
710
|
+
import { dirname as dirname5, join as join5 } from "node:path";
|
|
711
711
|
import { Worker } from "node:worker_threads";
|
|
712
712
|
function resolveWorkerEntry(baseDir = fileURLToPath2(new URL(".", import.meta.url))) {
|
|
713
713
|
const candidates = [
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
714
|
+
join5(baseDir, "worker-entry.js"),
|
|
715
|
+
join5(baseDir, "worker-entry.ts"),
|
|
716
|
+
join5(baseDir, "domains/functions/runtime/worker-entry.js"),
|
|
717
|
+
join5(baseDir, "domains/functions/runtime/worker-entry.ts")
|
|
718
718
|
];
|
|
719
719
|
let current = baseDir;
|
|
720
720
|
for (let depth = 0; depth < 8; depth += 1) {
|
|
721
721
|
candidates.push(
|
|
722
|
-
|
|
723
|
-
|
|
722
|
+
join5(current, "packages/runtime/src/functions/runtime/worker-entry.js"),
|
|
723
|
+
join5(current, "packages/runtime/src/functions/runtime/worker-entry.ts")
|
|
724
724
|
);
|
|
725
725
|
const parent = dirname5(current);
|
|
726
726
|
if (parent === current) break;
|
|
@@ -764,7 +764,7 @@ var init_worker_executor = __esm({
|
|
|
764
764
|
const entry = input.entry ?? "index.ts";
|
|
765
765
|
const deps = this.depsConfig === void 0 ? void 0 : resolveExecutionDeps(this.depsConfig, input.project.id, input.files["package.json"]);
|
|
766
766
|
const logs = [];
|
|
767
|
-
return new Promise((
|
|
767
|
+
return new Promise((resolve15, reject) => {
|
|
768
768
|
let worker;
|
|
769
769
|
try {
|
|
770
770
|
worker = new Worker(resolveWorkerEntry(), {
|
|
@@ -826,7 +826,7 @@ var init_worker_executor = __esm({
|
|
|
826
826
|
if (message.type === "result") {
|
|
827
827
|
clearTimeout(timer);
|
|
828
828
|
void worker.terminate();
|
|
829
|
-
|
|
829
|
+
resolve15({ body: message.body, logs });
|
|
830
830
|
return;
|
|
831
831
|
}
|
|
832
832
|
if (message.type === "error") {
|
|
@@ -2838,15 +2838,15 @@ var init_cloud2 = __esm({
|
|
|
2838
2838
|
});
|
|
2839
2839
|
|
|
2840
2840
|
// packages/runtime/src/storage/driver/local.ts
|
|
2841
|
-
import { mkdir as
|
|
2842
|
-
import { dirname as dirname6, join as
|
|
2841
|
+
import { mkdir as mkdir5, readFile as readFile4, readdir as readdir3, rm as rm2, stat as stat5, unlink, writeFile as writeFile4 } from "node:fs/promises";
|
|
2842
|
+
import { dirname as dirname6, join as join6 } from "node:path";
|
|
2843
2843
|
function createLocalStorageDriver(options) {
|
|
2844
2844
|
const quotaBytes = options.quotaBytes ?? PROJECT_QUOTA_BYTES;
|
|
2845
|
-
const bucketDir = (projectId) =>
|
|
2846
|
-
const objectPath = (projectId, path) =>
|
|
2847
|
-
const metaPath = (projectId, path) =>
|
|
2845
|
+
const bucketDir = (projectId) => join6(options.dir, projectId);
|
|
2846
|
+
const objectPath = (projectId, path) => join6(bucketDir(projectId), path);
|
|
2847
|
+
const metaPath = (projectId, path) => join6(dirname6(objectPath(projectId, path)), `${path.split("/").pop() ?? ""}${META_SUFFIX}`);
|
|
2848
2848
|
const readStoredMeta = async (projectId, path) => {
|
|
2849
|
-
const raw = await
|
|
2849
|
+
const raw = await readFile4(metaPath(projectId, path), "utf8");
|
|
2850
2850
|
return JSON.parse(raw);
|
|
2851
2851
|
};
|
|
2852
2852
|
const writeStoredMeta = async (projectId, path, meta) => {
|
|
@@ -2856,7 +2856,7 @@ function createLocalStorageDriver(options) {
|
|
|
2856
2856
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2857
2857
|
...meta.contentType === void 0 ? {} : { contentType: meta.contentType }
|
|
2858
2858
|
};
|
|
2859
|
-
await
|
|
2859
|
+
await writeFile4(metaPath(projectId, path), JSON.stringify(payload), "utf8");
|
|
2860
2860
|
};
|
|
2861
2861
|
const totalSize = async (projectId) => {
|
|
2862
2862
|
const root = bucketDir(projectId);
|
|
@@ -2864,20 +2864,20 @@ function createLocalStorageDriver(options) {
|
|
|
2864
2864
|
const walk = async (dir) => {
|
|
2865
2865
|
let entries;
|
|
2866
2866
|
try {
|
|
2867
|
-
entries = await
|
|
2867
|
+
entries = await readdir3(dir, { withFileTypes: true });
|
|
2868
2868
|
} catch {
|
|
2869
2869
|
return;
|
|
2870
2870
|
}
|
|
2871
2871
|
const tasks = [];
|
|
2872
2872
|
for (const entry of entries) {
|
|
2873
|
-
const full =
|
|
2873
|
+
const full = join6(dir, entry.name);
|
|
2874
2874
|
if (entry.isDirectory()) {
|
|
2875
2875
|
tasks.push(walk(full));
|
|
2876
2876
|
} else if (entry.isFile() && !entry.name.endsWith(META_SUFFIX)) {
|
|
2877
2877
|
tasks.push(
|
|
2878
2878
|
(async () => {
|
|
2879
2879
|
try {
|
|
2880
|
-
const info = await
|
|
2880
|
+
const info = await stat5(full);
|
|
2881
2881
|
total += info.size;
|
|
2882
2882
|
} catch {
|
|
2883
2883
|
}
|
|
@@ -2899,7 +2899,7 @@ function createLocalStorageDriver(options) {
|
|
|
2899
2899
|
const used = await totalSize(projectId);
|
|
2900
2900
|
let existingSize = 0;
|
|
2901
2901
|
try {
|
|
2902
|
-
existingSize = (await
|
|
2902
|
+
existingSize = (await stat5(objectPath(projectId, path))).size;
|
|
2903
2903
|
} catch {
|
|
2904
2904
|
existingSize = 0;
|
|
2905
2905
|
}
|
|
@@ -2914,8 +2914,8 @@ function createLocalStorageDriver(options) {
|
|
|
2914
2914
|
);
|
|
2915
2915
|
}
|
|
2916
2916
|
const dest = objectPath(projectId, path);
|
|
2917
|
-
await
|
|
2918
|
-
await
|
|
2917
|
+
await mkdir5(dirname6(dest), { recursive: true });
|
|
2918
|
+
await writeFile4(dest, data);
|
|
2919
2919
|
await writeStoredMeta(projectId, path, {
|
|
2920
2920
|
visibility: putOptions.visibility,
|
|
2921
2921
|
size: data.byteLength,
|
|
@@ -2938,7 +2938,7 @@ function createLocalStorageDriver(options) {
|
|
|
2938
2938
|
} catch {
|
|
2939
2939
|
throw new StorageError(404, STORAGE_CODES.notFound, `\u6587\u4EF6 "${path}" \u4E0D\u5B58\u5728`);
|
|
2940
2940
|
}
|
|
2941
|
-
const data = await
|
|
2941
|
+
const data = await readFile4(objectPath(projectId, path));
|
|
2942
2942
|
const result = {
|
|
2943
2943
|
path,
|
|
2944
2944
|
size: meta.size,
|
|
@@ -2969,7 +2969,7 @@ function createLocalStorageDriver(options) {
|
|
|
2969
2969
|
assertSafeStoragePath(path);
|
|
2970
2970
|
let exists = true;
|
|
2971
2971
|
try {
|
|
2972
|
-
await
|
|
2972
|
+
await stat5(objectPath(projectId, path));
|
|
2973
2973
|
} catch {
|
|
2974
2974
|
exists = false;
|
|
2975
2975
|
}
|
|
@@ -2986,14 +2986,14 @@ function createLocalStorageDriver(options) {
|
|
|
2986
2986
|
const walk = async (dir, relative6) => {
|
|
2987
2987
|
let entries;
|
|
2988
2988
|
try {
|
|
2989
|
-
entries = await
|
|
2989
|
+
entries = await readdir3(dir, { withFileTypes: true });
|
|
2990
2990
|
} catch {
|
|
2991
2991
|
return;
|
|
2992
2992
|
}
|
|
2993
2993
|
const tasks = [];
|
|
2994
2994
|
for (const entry of entries) {
|
|
2995
2995
|
if (entry.name.endsWith(META_SUFFIX)) continue;
|
|
2996
|
-
const full =
|
|
2996
|
+
const full = join6(dir, entry.name);
|
|
2997
2997
|
const rel = relative6 === "" ? entry.name : `${relative6}/${entry.name}`;
|
|
2998
2998
|
if (entry.isFile()) {
|
|
2999
2999
|
if (prefix !== void 0 && !rel.startsWith(prefix)) continue;
|
|
@@ -3001,7 +3001,7 @@ function createLocalStorageDriver(options) {
|
|
|
3001
3001
|
(async () => {
|
|
3002
3002
|
try {
|
|
3003
3003
|
const payload = JSON.parse(
|
|
3004
|
-
await
|
|
3004
|
+
await readFile4(full + META_SUFFIX, "utf8")
|
|
3005
3005
|
);
|
|
3006
3006
|
metas.push({
|
|
3007
3007
|
path: rel,
|
|
@@ -3043,9 +3043,9 @@ var init_local = __esm({
|
|
|
3043
3043
|
});
|
|
3044
3044
|
|
|
3045
3045
|
// packages/cli/src/sim/storage.ts
|
|
3046
|
-
import { join as
|
|
3046
|
+
import { join as join7 } from "node:path";
|
|
3047
3047
|
function createSimStorageCapability(options) {
|
|
3048
|
-
const dir =
|
|
3048
|
+
const dir = join7(options.cwd, ".adep", "sim", "storage");
|
|
3049
3049
|
const driver = createLocalStorageDriver({ dir });
|
|
3050
3050
|
const signer = {
|
|
3051
3051
|
secret: options.secret ?? "adep-sim-secret",
|
|
@@ -3218,33 +3218,33 @@ var init_merge = __esm({
|
|
|
3218
3218
|
});
|
|
3219
3219
|
|
|
3220
3220
|
// packages/cli/src/sim/runtime.ts
|
|
3221
|
-
import { mkdir as
|
|
3222
|
-
import { dirname as dirname7, join as
|
|
3221
|
+
import { mkdir as mkdir6, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
|
|
3222
|
+
import { dirname as dirname7, join as join8 } from "node:path";
|
|
3223
3223
|
function simDir(cwd) {
|
|
3224
|
-
return
|
|
3224
|
+
return join8(cwd, ".adep", "sim");
|
|
3225
3225
|
}
|
|
3226
3226
|
function jsonStorage(cwd) {
|
|
3227
|
-
const file =
|
|
3227
|
+
const file = join8(simDir(cwd), "db.json");
|
|
3228
3228
|
return {
|
|
3229
3229
|
async load() {
|
|
3230
3230
|
try {
|
|
3231
|
-
const raw = await
|
|
3231
|
+
const raw = await readFile5(file, "utf8");
|
|
3232
3232
|
return JSON.parse(raw);
|
|
3233
3233
|
} catch {
|
|
3234
3234
|
return null;
|
|
3235
3235
|
}
|
|
3236
3236
|
},
|
|
3237
3237
|
async save(tables) {
|
|
3238
|
-
await
|
|
3239
|
-
await
|
|
3238
|
+
await mkdir6(dirname7(file), { recursive: true });
|
|
3239
|
+
await writeFile5(file, JSON.stringify(tables), "utf8");
|
|
3240
3240
|
}
|
|
3241
3241
|
};
|
|
3242
3242
|
}
|
|
3243
3243
|
async function createSimRuntime(options) {
|
|
3244
|
-
const db = createSimDbCapability({
|
|
3244
|
+
const db = options.driver === void 0 ? createSimDbCapability({
|
|
3245
3245
|
storage: options.dbStorage ?? jsonStorage(options.cwd),
|
|
3246
3246
|
...options.log === void 0 ? {} : { log: options.log }
|
|
3247
|
-
});
|
|
3247
|
+
}) : { bundle: createDbCapability(options.driver), driver: options.driver, engine: null };
|
|
3248
3248
|
const storage = createSimStorageCapability({
|
|
3249
3249
|
cwd: options.cwd,
|
|
3250
3250
|
...options.baseUrl === void 0 ? {} : { baseUrl: options.baseUrl },
|
|
@@ -3253,7 +3253,7 @@ async function createSimRuntime(options) {
|
|
|
3253
3253
|
const simRealtime = createSimRealtimeCapability();
|
|
3254
3254
|
const kvBundle = createKvCapability(db.driver);
|
|
3255
3255
|
const bundle = mergeBundles([db.bundle, storage.bundle, kvBundle, simRealtime.bundle]);
|
|
3256
|
-
await db.engine.load();
|
|
3256
|
+
if (db.engine !== null) await db.engine.load();
|
|
3257
3257
|
return {
|
|
3258
3258
|
bundle,
|
|
3259
3259
|
realtime: simRealtime.realtime,
|
|
@@ -3266,6 +3266,7 @@ async function createSimRuntime(options) {
|
|
|
3266
3266
|
var init_runtime = __esm({
|
|
3267
3267
|
"packages/cli/src/sim/runtime.ts"() {
|
|
3268
3268
|
"use strict";
|
|
3269
|
+
init_cloud();
|
|
3269
3270
|
init_db();
|
|
3270
3271
|
init_kv();
|
|
3271
3272
|
init_storage();
|
|
@@ -3275,8 +3276,8 @@ var init_runtime = __esm({
|
|
|
3275
3276
|
});
|
|
3276
3277
|
|
|
3277
3278
|
// packages/cli/src/sim/env.ts
|
|
3278
|
-
import { readFile as
|
|
3279
|
-
import { join as
|
|
3279
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
3280
|
+
import { join as join9 } from "node:path";
|
|
3280
3281
|
function parseEnv(content) {
|
|
3281
3282
|
const env = {};
|
|
3282
3283
|
for (const raw of content.split(/\r?\n/)) {
|
|
@@ -3291,8 +3292,8 @@ function parseEnv(content) {
|
|
|
3291
3292
|
return env;
|
|
3292
3293
|
}
|
|
3293
3294
|
async function loadSimEnv(cwd, config = {}) {
|
|
3294
|
-
const envRoot = await
|
|
3295
|
-
const envLocal = await
|
|
3295
|
+
const envRoot = await readFile6(join9(cwd, ".env"), "utf8").catch(() => "");
|
|
3296
|
+
const envLocal = await readFile6(join9(cwd, ".env.local"), "utf8").catch(() => "");
|
|
3296
3297
|
const merged = { ...parseEnv(envRoot), ...parseEnv(envLocal) };
|
|
3297
3298
|
for (const secret of config.secrets ?? []) {
|
|
3298
3299
|
if (merged[secret] !== void 0) continue;
|
|
@@ -3435,12 +3436,12 @@ var init_boundary = __esm({
|
|
|
3435
3436
|
});
|
|
3436
3437
|
|
|
3437
3438
|
// packages/cli/src/ts-config.ts
|
|
3438
|
-
import { stat as
|
|
3439
|
-
import { join as
|
|
3439
|
+
import { stat as stat6, readFile as readFile7 } from "node:fs/promises";
|
|
3440
|
+
import { join as join10 } from "node:path";
|
|
3440
3441
|
async function loadAdepConfigModule(cwd) {
|
|
3441
|
-
const configPath =
|
|
3442
|
+
const configPath = join10(cwd, "adep.config.ts");
|
|
3442
3443
|
try {
|
|
3443
|
-
await
|
|
3444
|
+
await stat6(configPath);
|
|
3444
3445
|
} catch {
|
|
3445
3446
|
return null;
|
|
3446
3447
|
}
|
|
@@ -3452,7 +3453,7 @@ async function loadAdepConfigModule(cwd) {
|
|
|
3452
3453
|
rawDefault = mod.default;
|
|
3453
3454
|
} else {
|
|
3454
3455
|
const { transform } = await import("esbuild");
|
|
3455
|
-
const source = await
|
|
3456
|
+
const source = await readFile7(configPath, "utf8");
|
|
3456
3457
|
const { code } = await transform(source, {
|
|
3457
3458
|
loader: "ts",
|
|
3458
3459
|
format: "esm",
|
|
@@ -4326,9 +4327,9 @@ function isChainCapability(value) {
|
|
|
4326
4327
|
return typeof spec === "object" && spec !== null && Array.isArray(spec.stepMethods) && Array.isArray(spec.terminalMethods);
|
|
4327
4328
|
}
|
|
4328
4329
|
function createChainClient(capability, port, pending, nextId, spec) {
|
|
4329
|
-
const call = (method, args) => new Promise((
|
|
4330
|
+
const call = (method, args) => new Promise((resolve15, reject) => {
|
|
4330
4331
|
const id = nextId();
|
|
4331
|
-
pending.set(id, { resolve:
|
|
4332
|
+
pending.set(id, { resolve: resolve15, reject });
|
|
4332
4333
|
port.postMessage({ type: "rpc", id, capability, method, args });
|
|
4333
4334
|
});
|
|
4334
4335
|
const makeChainable = (rootArgs, steps, txId) => new Proxy(
|
|
@@ -4400,7 +4401,7 @@ var init_chain = __esm({
|
|
|
4400
4401
|
// packages/runtime/src/functions/runtime/worker-entry.ts
|
|
4401
4402
|
import { parentPort, workerData } from "node:worker_threads";
|
|
4402
4403
|
import { createRequire } from "node:module";
|
|
4403
|
-
import { join as
|
|
4404
|
+
import { join as join11 } from "node:path";
|
|
4404
4405
|
function isRpcCapability(value) {
|
|
4405
4406
|
return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
|
|
4406
4407
|
}
|
|
@@ -4412,8 +4413,8 @@ function createRpcClient(capability, port, pending, nextId) {
|
|
|
4412
4413
|
if (typeof method !== "string") return void 0;
|
|
4413
4414
|
return (...args) => {
|
|
4414
4415
|
const id = nextId();
|
|
4415
|
-
return new Promise((
|
|
4416
|
-
pending.set(id, { resolve:
|
|
4416
|
+
return new Promise((resolve15, reject) => {
|
|
4417
|
+
pending.set(id, { resolve: resolve15, reject });
|
|
4417
4418
|
port.postMessage({ type: "rpc", id, capability, method, args });
|
|
4418
4419
|
});
|
|
4419
4420
|
};
|
|
@@ -4449,7 +4450,7 @@ function errorMessageWithLocation(error, files) {
|
|
|
4449
4450
|
}
|
|
4450
4451
|
function createBareResolver(deps) {
|
|
4451
4452
|
const platformRequire = createRequire(import.meta.url);
|
|
4452
|
-
const depsRequire = deps.dir === null ? null : createRequire(
|
|
4453
|
+
const depsRequire = deps.dir === null ? null : createRequire(join11(deps.dir, "__deps__.js"));
|
|
4453
4454
|
return (request) => {
|
|
4454
4455
|
if (deps.builtin.includes(request)) return platformRequire(request);
|
|
4455
4456
|
const root = splitBareSpecifier(request);
|
|
@@ -4640,8 +4641,8 @@ var init_shared_source = __esm({
|
|
|
4640
4641
|
});
|
|
4641
4642
|
|
|
4642
4643
|
// packages/cli/src/dev-shared.ts
|
|
4643
|
-
import { readdir as
|
|
4644
|
-
import { join as
|
|
4644
|
+
import { readdir as readdir4, readFile as readFile8 } from "node:fs/promises";
|
|
4645
|
+
import { join as join12 } from "node:path";
|
|
4645
4646
|
function bearerUserResolverFromEnv() {
|
|
4646
4647
|
const raw = process.env.ADEP_AUTH_ISSUER;
|
|
4647
4648
|
if (raw === void 0 || raw.trim() === "") return void 0;
|
|
@@ -4676,17 +4677,17 @@ async function collectFunctions(dir) {
|
|
|
4676
4677
|
const walk = async (sub, prefix) => {
|
|
4677
4678
|
let entries;
|
|
4678
4679
|
try {
|
|
4679
|
-
entries = await
|
|
4680
|
+
entries = await readdir4(sub, { withFileTypes: true });
|
|
4680
4681
|
} catch {
|
|
4681
4682
|
return;
|
|
4682
4683
|
}
|
|
4683
4684
|
for (const entry of entries) {
|
|
4684
4685
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
4685
|
-
const full =
|
|
4686
|
+
const full = join12(sub, entry.name);
|
|
4686
4687
|
if (entry.isDirectory()) {
|
|
4687
4688
|
await walk(full, rel);
|
|
4688
4689
|
} else if (entry.isFile() && isRuntimeSource(entry.name)) {
|
|
4689
|
-
files[rel] = await
|
|
4690
|
+
files[rel] = await readFile8(full, "utf8");
|
|
4690
4691
|
}
|
|
4691
4692
|
}
|
|
4692
4693
|
};
|
|
@@ -4774,8 +4775,8 @@ __export(dev_exports, {
|
|
|
4774
4775
|
});
|
|
4775
4776
|
import { createServer } from "node:http";
|
|
4776
4777
|
import { watch } from "node:fs";
|
|
4777
|
-
import { mkdir as
|
|
4778
|
-
import { basename as basename2, join as
|
|
4778
|
+
import { mkdir as mkdir7, readFile as readFile9, writeFile as writeFile6 } from "node:fs/promises";
|
|
4779
|
+
import { basename as basename2, join as join13, resolve as resolve4 } from "node:path";
|
|
4779
4780
|
async function loadConfig(cwd) {
|
|
4780
4781
|
const name = basename2(resolve4(cwd));
|
|
4781
4782
|
const config = await loadAdepConfigModule(cwd);
|
|
@@ -4819,10 +4820,10 @@ function printBoundaries(log) {
|
|
|
4819
4820
|
}
|
|
4820
4821
|
}
|
|
4821
4822
|
async function ensureGitignore(cwd) {
|
|
4822
|
-
const gitignorePath =
|
|
4823
|
-
const existing = await
|
|
4823
|
+
const gitignorePath = join13(cwd, ".gitignore");
|
|
4824
|
+
const existing = await readFile9(gitignorePath, "utf8").catch(() => "");
|
|
4824
4825
|
if (existing.split(/\r?\n/).includes(".adep/")) return;
|
|
4825
|
-
await
|
|
4826
|
+
await writeFile6(gitignorePath, `${existing.replace(/\n+$/, "")}
|
|
4826
4827
|
.adep/
|
|
4827
4828
|
`, "utf8");
|
|
4828
4829
|
}
|
|
@@ -4834,13 +4835,13 @@ async function startDevServer(options) {
|
|
|
4834
4835
|
if (options.prefix !== void 0) {
|
|
4835
4836
|
config.functionsPrefix = options.prefix.replace(/^\/+|\/+$/g, "");
|
|
4836
4837
|
}
|
|
4837
|
-
const functionsDir =
|
|
4838
|
+
const functionsDir = join13(cwd, config.functionsDir);
|
|
4838
4839
|
const coldStartAt = Date.now();
|
|
4839
4840
|
const bearerUser = bearerUserResolverFromEnv();
|
|
4840
4841
|
const executor = new WorkerFunctionExecutor({
|
|
4841
4842
|
deps: { rootDir: cwd, builtin: LOCAL_BUILTIN_DEPS }
|
|
4842
4843
|
});
|
|
4843
|
-
await
|
|
4844
|
+
await mkdir7(functionsDir, { recursive: true });
|
|
4844
4845
|
const runtime = await createSimRuntime({
|
|
4845
4846
|
cwd,
|
|
4846
4847
|
projectId: "local",
|
|
@@ -4927,12 +4928,12 @@ async function startDevServer(options) {
|
|
|
4927
4928
|
const reload = async () => {
|
|
4928
4929
|
const [nextFiles, envText2] = await Promise.all([
|
|
4929
4930
|
collectFunctions(functionsDir).then(mergeSharedIntoFunctions),
|
|
4930
|
-
|
|
4931
|
+
readFile9(join13(cwd, ".env.local"), "utf8").catch(() => "")
|
|
4931
4932
|
]);
|
|
4932
4933
|
files = nextFiles;
|
|
4933
4934
|
env = { ...config.environment, ...parseEnvFile(envText2) };
|
|
4934
4935
|
};
|
|
4935
|
-
const envText = await
|
|
4936
|
+
const envText = await readFile9(join13(cwd, ".env.local"), "utf8").catch(() => "");
|
|
4936
4937
|
env = { ...config.environment, ...parseEnvFile(envText) };
|
|
4937
4938
|
let debounceTimer;
|
|
4938
4939
|
let watcher;
|
|
@@ -5245,7 +5246,7 @@ __export(db_exports, {
|
|
|
5245
5246
|
dbStop: () => dbStop,
|
|
5246
5247
|
splitSqlStatements: () => splitSqlStatements
|
|
5247
5248
|
});
|
|
5248
|
-
import { readFile as
|
|
5249
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
5249
5250
|
import { resolve as resolve5 } from "node:path";
|
|
5250
5251
|
async function open2(paths, options) {
|
|
5251
5252
|
const client = await createClient(paths);
|
|
@@ -5353,7 +5354,7 @@ function splitSqlStatements(source) {
|
|
|
5353
5354
|
return statements;
|
|
5354
5355
|
}
|
|
5355
5356
|
async function dbMigrate(paths, options) {
|
|
5356
|
-
const source = await
|
|
5357
|
+
const source = await readFile10(resolve5(options.file), "utf8");
|
|
5357
5358
|
const statements = splitSqlStatements(source);
|
|
5358
5359
|
if (statements.length === 0) {
|
|
5359
5360
|
throw new Error(`\u8FC1\u79FB\u6587\u4EF6\u6CA1\u6709\u53EF\u6267\u884C\u8BED\u53E5\uFF1A${options.file}`);
|
|
@@ -5423,6 +5424,10 @@ function renderBanner(options) {
|
|
|
5423
5424
|
lines.push(` - \u9759\u6001\u6258\u7BA1: \u65E0\uFF08${staticDir} \u76EE\u5F55\u4E0D\u5B58\u5728\uFF09`);
|
|
5424
5425
|
}
|
|
5425
5426
|
lines.push(" - \u7EC4\u4EF6\u9884\u89C8: Widget / Page \u4EA7\u7269\uFF08\u5982\u5DF2\u6784\u5EFA\uFF09");
|
|
5427
|
+
if (options.dbMode !== void 0) {
|
|
5428
|
+
const label = options.dbMode === "sqlite" ? `SQLite \u771F\u5B9E\u5E93${options.dbDriver === void 0 ? "" : `\uFF08${options.dbDriver}\uFF09`}` : "sim \u5F15\u64CE\uFF08\u5185\u7F6E\u6A21\u62DF\uFF09";
|
|
5429
|
+
lines.push(` - \u6570\u636E\u5E93: ${label} \u2192 ${options.dbTarget ?? "\uFF08\u672A\u6807\u6CE8\uFF09"}`);
|
|
5430
|
+
}
|
|
5426
5431
|
lines.push(` - \u5065\u5EB7\u68C0\u67E5: ${baseUrl}/healthz`);
|
|
5427
5432
|
lines.push("");
|
|
5428
5433
|
lines.push(" \u8FB9\u754C\uFF08\u5F00\u53D1\u6001\u9ED8\u8BA4\u503C\uFF0C\u4E0D\u53EF\u5728\u6B64\u6A21\u5F0F\u4E0B\u5F00\u542F\uFF09:");
|
|
@@ -5455,6 +5460,132 @@ var init_banner = __esm({
|
|
|
5455
5460
|
}
|
|
5456
5461
|
});
|
|
5457
5462
|
|
|
5463
|
+
// packages/cli/src/serve/db-mode.ts
|
|
5464
|
+
import { resolve as resolve6 } from "node:path";
|
|
5465
|
+
function isServeDbMode(value) {
|
|
5466
|
+
return SERVE_DB_MODES.includes(value.trim().toLowerCase());
|
|
5467
|
+
}
|
|
5468
|
+
function parseServeDbMode(raw, source) {
|
|
5469
|
+
const value = raw.trim().toLowerCase();
|
|
5470
|
+
if (!isServeDbMode(value)) {
|
|
5471
|
+
throw new Error(
|
|
5472
|
+
`${source} \u7684\u6570\u636E\u5E93\u6A21\u5F0F "${raw}" \u65E0\u6548\uFF1A\u53EA\u652F\u6301 ${SERVE_DB_MODES.join(" | ")}\uFF08sim = \u5185\u7F6E\u6A21\u62DF\u5F15\u64CE\u4E0E .adep/sim/db.json\uFF1Bsqlite = \u771F\u5B9E SQLite \u5E93\u6587\u4EF6\uFF09`
|
|
5473
|
+
);
|
|
5474
|
+
}
|
|
5475
|
+
return value;
|
|
5476
|
+
}
|
|
5477
|
+
function resolveServeDbMode(explicit) {
|
|
5478
|
+
if (explicit !== void 0) return parseServeDbMode(explicit, "--db");
|
|
5479
|
+
const fromEnv = process.env["ADEP_SERVE_DB"];
|
|
5480
|
+
if (fromEnv !== void 0 && fromEnv.trim() !== "") {
|
|
5481
|
+
return parseServeDbMode(fromEnv, "ADEP_SERVE_DB");
|
|
5482
|
+
}
|
|
5483
|
+
return DEFAULT_SERVE_DB_MODE;
|
|
5484
|
+
}
|
|
5485
|
+
function resolveServeDbFile(cwd, explicit) {
|
|
5486
|
+
const raw = explicit ?? envDbFile() ?? DEFAULT_SQLITE_DB_FILE;
|
|
5487
|
+
return raw === ":memory:" ? raw : resolve6(cwd, raw);
|
|
5488
|
+
}
|
|
5489
|
+
function envDbFile() {
|
|
5490
|
+
const raw = process.env["ADEP_SERVE_DB_FILE"];
|
|
5491
|
+
return raw === void 0 || raw.trim() === "" ? void 0 : raw.trim();
|
|
5492
|
+
}
|
|
5493
|
+
var SERVE_DB_MODES, DEFAULT_SERVE_DB_MODE, DEFAULT_SQLITE_DB_FILE;
|
|
5494
|
+
var init_db_mode = __esm({
|
|
5495
|
+
"packages/cli/src/serve/db-mode.ts"() {
|
|
5496
|
+
"use strict";
|
|
5497
|
+
SERVE_DB_MODES = ["sim", "sqlite"];
|
|
5498
|
+
DEFAULT_SERVE_DB_MODE = "sim";
|
|
5499
|
+
DEFAULT_SQLITE_DB_FILE = ".adep/data/project.sqlite";
|
|
5500
|
+
}
|
|
5501
|
+
});
|
|
5502
|
+
|
|
5503
|
+
// packages/cli/src/serve/sqlite-driver.ts
|
|
5504
|
+
import { mkdir as mkdir8 } from "node:fs/promises";
|
|
5505
|
+
import { dirname as dirname8, resolve as resolve7 } from "node:path";
|
|
5506
|
+
function isBun(versions) {
|
|
5507
|
+
return versions["bun"] !== void 0 && versions["bun"] !== "";
|
|
5508
|
+
}
|
|
5509
|
+
function detectSqliteRuntime(versions = process.versions) {
|
|
5510
|
+
if (isBun(versions)) return "bun";
|
|
5511
|
+
const raw = versions["node"];
|
|
5512
|
+
if (raw === void 0) return null;
|
|
5513
|
+
const [majorText, minorText] = raw.split(".");
|
|
5514
|
+
const major = Number(majorText);
|
|
5515
|
+
const minor = Number(minorText ?? "0");
|
|
5516
|
+
if (!Number.isInteger(major) || !Number.isInteger(minor)) return null;
|
|
5517
|
+
if (major > NODE_SQLITE_MIN.major) return "node";
|
|
5518
|
+
if (major === NODE_SQLITE_MIN.major && minor >= NODE_SQLITE_MIN.minor) return "node";
|
|
5519
|
+
return null;
|
|
5520
|
+
}
|
|
5521
|
+
function sqliteModuleName(runtime) {
|
|
5522
|
+
return runtime === "bun" ? "bun:sqlite" : "node:sqlite";
|
|
5523
|
+
}
|
|
5524
|
+
function sqliteRuntimeRequirementMessage(versions = process.versions) {
|
|
5525
|
+
const current = isBun(versions) ? `Bun ${versions["bun"] ?? ""}`.trim() : `Node ${versions["node"] ?? "\u672A\u77E5"}`;
|
|
5526
|
+
return `--db sqlite \u9700\u8981 Bun\uFF08\u5185\u7F6E bun:sqlite\uFF09\u6216 Node \u2265 ${NODE_SQLITE_MIN.major}.${NODE_SQLITE_MIN.minor}\uFF08\u5185\u7F6E node:sqlite\uFF09\uFF1B\u5F53\u524D\u8FD0\u884C\u65F6 ${current} \u4E0D\u63D0\u4F9B SQLite \u5185\u5EFA\u6A21\u5757\u3002\u8BF7\u6539\u7528 \`--db sim\`\uFF08\u5185\u7F6E\u6A21\u62DF\u5F15\u64CE\uFF0C\u65E0\u9700\u989D\u5916\u8FD0\u884C\u65F6\uFF09\uFF0C\u6216\u5347\u7EA7 Node / \u7528 Bun \u8FD0\u884C\u3002`;
|
|
5527
|
+
}
|
|
5528
|
+
async function openSqliteProjectDriver(file, options = {}) {
|
|
5529
|
+
const runtime = options.runtime ?? detectSqliteRuntime();
|
|
5530
|
+
if (runtime === null) throw new Error(sqliteRuntimeRequirementMessage());
|
|
5531
|
+
const moduleName = sqliteModuleName(runtime);
|
|
5532
|
+
const ctorName = runtime === "bun" ? "Database" : "DatabaseSync";
|
|
5533
|
+
let mod;
|
|
5534
|
+
try {
|
|
5535
|
+
const specifier = moduleName;
|
|
5536
|
+
mod = await import(
|
|
5537
|
+
/* @vite-ignore */
|
|
5538
|
+
specifier
|
|
5539
|
+
);
|
|
5540
|
+
} catch (error) {
|
|
5541
|
+
throw new Error(
|
|
5542
|
+
`${sqliteRuntimeRequirementMessage()}
|
|
5543
|
+
\uFF08\u8F7D\u5165 ${moduleName} \u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}\uFF09`,
|
|
5544
|
+
{ cause: error }
|
|
5545
|
+
);
|
|
5546
|
+
}
|
|
5547
|
+
const Ctor = mod[ctorName];
|
|
5548
|
+
if (Ctor === void 0) {
|
|
5549
|
+
throw new Error(`${moduleName} \u672A\u5BFC\u51FA ${ctorName}\uFF1A\u5F53\u524D\u8FD0\u884C\u65F6\u7684 SQLite \u5185\u5EFA\u6A21\u5757\u4E0D\u53EF\u7528`);
|
|
5550
|
+
}
|
|
5551
|
+
const target = file === ":memory:" ? file : resolve7(file);
|
|
5552
|
+
if (target !== ":memory:") await mkdir8(dirname8(target), { recursive: true });
|
|
5553
|
+
const database = new Ctor(target);
|
|
5554
|
+
database.exec("PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;");
|
|
5555
|
+
return {
|
|
5556
|
+
engine: "sqlite",
|
|
5557
|
+
async run(sql, params = []) {
|
|
5558
|
+
if (params.length === 0) {
|
|
5559
|
+
database.exec(sql);
|
|
5560
|
+
return { changes: 0 };
|
|
5561
|
+
}
|
|
5562
|
+
const result = database.prepare(sql).run(...params);
|
|
5563
|
+
return { changes: Number(result.changes) };
|
|
5564
|
+
},
|
|
5565
|
+
async all(sql, params = []) {
|
|
5566
|
+
const statement = database.prepare(sql);
|
|
5567
|
+
statement.setReturnArrays?.(false);
|
|
5568
|
+
return statement.all(...params);
|
|
5569
|
+
},
|
|
5570
|
+
async get(sql, params = []) {
|
|
5571
|
+
const statement = database.prepare(sql);
|
|
5572
|
+
statement.setReturnArrays?.(false);
|
|
5573
|
+
const row = statement.get(...params);
|
|
5574
|
+
return row ?? null;
|
|
5575
|
+
},
|
|
5576
|
+
async close() {
|
|
5577
|
+
database.close();
|
|
5578
|
+
}
|
|
5579
|
+
};
|
|
5580
|
+
}
|
|
5581
|
+
var NODE_SQLITE_MIN;
|
|
5582
|
+
var init_sqlite_driver = __esm({
|
|
5583
|
+
"packages/cli/src/serve/sqlite-driver.ts"() {
|
|
5584
|
+
"use strict";
|
|
5585
|
+
NODE_SQLITE_MIN = { major: 22, minor: 5 };
|
|
5586
|
+
}
|
|
5587
|
+
});
|
|
5588
|
+
|
|
5458
5589
|
// packages/cli/src/serve/server.ts
|
|
5459
5590
|
var server_exports = {};
|
|
5460
5591
|
__export(server_exports, {
|
|
@@ -5464,8 +5595,8 @@ __export(server_exports, {
|
|
|
5464
5595
|
});
|
|
5465
5596
|
import { createServer as createServer2 } from "node:http";
|
|
5466
5597
|
import { watch as watch2 } from "node:fs";
|
|
5467
|
-
import { mkdir as
|
|
5468
|
-
import { extname, join as
|
|
5598
|
+
import { mkdir as mkdir9, readFile as readFile11, stat as stat7 } from "node:fs/promises";
|
|
5599
|
+
import { extname, join as join14, relative as relative2, resolve as resolve8 } from "node:path";
|
|
5469
5600
|
function envNumber(name) {
|
|
5470
5601
|
const raw = process.env[name];
|
|
5471
5602
|
if (raw === void 0 || raw.trim() === "") return void 0;
|
|
@@ -5483,22 +5614,29 @@ function contentTypeFor(path) {
|
|
|
5483
5614
|
const ext = path.slice(path.lastIndexOf(".")).toLowerCase();
|
|
5484
5615
|
return MIME_TYPES[ext] ?? "application/octet-stream";
|
|
5485
5616
|
}
|
|
5617
|
+
function displayPath(cwd, target) {
|
|
5618
|
+
if (target === ":memory:") return target;
|
|
5619
|
+
const rel = relative2(cwd, target);
|
|
5620
|
+
return rel.startsWith("..") ? target : rel;
|
|
5621
|
+
}
|
|
5486
5622
|
async function startServeServer(options) {
|
|
5487
|
-
const cwd =
|
|
5623
|
+
const cwd = resolve8(options.cwd);
|
|
5488
5624
|
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
5489
5625
|
`));
|
|
5490
5626
|
const host = options.host ?? envString("HOST") ?? "127.0.0.1";
|
|
5491
5627
|
const port = resolveServePort(options.port);
|
|
5492
|
-
const staticDir =
|
|
5628
|
+
const staticDir = resolve8(
|
|
5493
5629
|
cwd,
|
|
5494
5630
|
options.staticDir ?? envString("ADEP_SERVE_STATIC_DIR") ?? "public"
|
|
5495
5631
|
);
|
|
5632
|
+
const dbMode = resolveServeDbMode(options.db);
|
|
5633
|
+
const sqliteFile = dbMode === "sqlite" ? resolveServeDbFile(cwd, options.dbFile) : null;
|
|
5496
5634
|
const config = await loadConfig(cwd);
|
|
5497
|
-
const functionsDir =
|
|
5635
|
+
const functionsDir = join14(cwd, config.functionsDir);
|
|
5498
5636
|
const bearerUser = bearerUserResolverFromEnv();
|
|
5499
5637
|
let hasStatic = false;
|
|
5500
5638
|
try {
|
|
5501
|
-
const publicStat = await
|
|
5639
|
+
const publicStat = await stat7(staticDir);
|
|
5502
5640
|
hasStatic = publicStat.isDirectory();
|
|
5503
5641
|
} catch {
|
|
5504
5642
|
hasStatic = false;
|
|
@@ -5506,18 +5644,27 @@ async function startServeServer(options) {
|
|
|
5506
5644
|
const loadFunctionFiles = async () => mergeSharedIntoFunctions(await collectFunctions(functionsDir));
|
|
5507
5645
|
let files = await loadFunctionFiles();
|
|
5508
5646
|
let functionNames = listFunctionNames(files);
|
|
5509
|
-
const envText = await
|
|
5647
|
+
const envText = await readFile11(join14(cwd, ".env.local"), "utf8").catch(() => "");
|
|
5510
5648
|
let env = parseEnvFile(envText);
|
|
5511
5649
|
let simEnv = await loadSimEnv(cwd).catch(() => ({}));
|
|
5650
|
+
let sqliteModule = null;
|
|
5651
|
+
let sqliteDriver = null;
|
|
5652
|
+
if (sqliteFile !== null) {
|
|
5653
|
+
const runtimeName = detectSqliteRuntime();
|
|
5654
|
+
if (runtimeName === null) throw new Error(sqliteRuntimeRequirementMessage());
|
|
5655
|
+
sqliteModule = sqliteModuleName(runtimeName);
|
|
5656
|
+
sqliteDriver = await openSqliteProjectDriver(sqliteFile, { runtime: runtimeName });
|
|
5657
|
+
}
|
|
5512
5658
|
const runtime = await createSimRuntime({
|
|
5513
5659
|
cwd,
|
|
5514
5660
|
projectId: "local",
|
|
5515
5661
|
baseUrl: `http://${host}:${port}`,
|
|
5516
|
-
log
|
|
5662
|
+
log,
|
|
5663
|
+
...sqliteDriver === null ? {} : { driver: sqliteDriver }
|
|
5517
5664
|
});
|
|
5518
5665
|
if (options.schemaFile !== void 0) {
|
|
5519
|
-
const schemaPath =
|
|
5520
|
-
const schemaSource = await
|
|
5666
|
+
const schemaPath = resolve8(cwd, options.schemaFile);
|
|
5667
|
+
const schemaSource = await readFile11(schemaPath, "utf8").catch(
|
|
5521
5668
|
(error) => {
|
|
5522
5669
|
if (error.code === "ENOENT") {
|
|
5523
5670
|
throw new Error(`schema \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${schemaPath}`);
|
|
@@ -5528,18 +5675,23 @@ async function startServeServer(options) {
|
|
|
5528
5675
|
const statements = splitSqlStatements(schemaSource);
|
|
5529
5676
|
let applied = 0;
|
|
5530
5677
|
let skipped = 0;
|
|
5531
|
-
for (const statement of statements) {
|
|
5678
|
+
for (const [index, statement] of statements.entries()) {
|
|
5532
5679
|
try {
|
|
5533
|
-
await runtime.db.
|
|
5680
|
+
await runtime.db.driver.run(statement);
|
|
5534
5681
|
applied += 1;
|
|
5535
5682
|
} catch (error) {
|
|
5536
5683
|
const isUnsupported = error instanceof Error && "code" in error && error.code === "DB_UNSAFE_OP";
|
|
5537
|
-
if (isUnsupported) {
|
|
5684
|
+
if (dbMode === "sim" && isUnsupported) {
|
|
5538
5685
|
skipped += 1;
|
|
5539
5686
|
log(`[serve] \u8DF3\u8FC7 schema \u8BED\u53E5\uFF08sim \u5F15\u64CE\u4E0D\u652F\u6301\uFF09\uFF1A${statement.slice(0, 60)}\u2026`);
|
|
5540
|
-
|
|
5541
|
-
throw error;
|
|
5687
|
+
continue;
|
|
5542
5688
|
}
|
|
5689
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
5690
|
+
throw new Error(
|
|
5691
|
+
`schema \u8BED\u53E5\u6267\u884C\u5931\u8D25\uFF08--schema ${options.schemaFile}\uFF0C\u7B2C ${index + 1} \u6761\uFF0Cdb \u6A21\u5F0F ${dbMode}\uFF09\uFF1A${detail}
|
|
5692
|
+
\u8BED\u53E5\uFF1A${statement.slice(0, 200)}` + (dbMode === "sqlite" ? "\n\uFF08sqlite \u6A21\u5F0F\u4E0D\u505A\u8BED\u53E5\u8DF3\u8FC7\uFF1B\u5982\u9700\u8DF3\u8FC7\u8BED\u4E49\u8BF7\u6539\u7528 --db sim\uFF09" : ""),
|
|
5693
|
+
{ cause: error }
|
|
5694
|
+
);
|
|
5543
5695
|
}
|
|
5544
5696
|
}
|
|
5545
5697
|
const skipNote = skipped > 0 ? `\uFF0C\u8DF3\u8FC7 ${skipped} \u6761` : "";
|
|
@@ -5555,7 +5707,7 @@ async function startServeServer(options) {
|
|
|
5555
5707
|
const reload = async () => {
|
|
5556
5708
|
const [nextFiles, envLocalText] = await Promise.all([
|
|
5557
5709
|
loadFunctionFiles(),
|
|
5558
|
-
|
|
5710
|
+
readFile11(join14(cwd, ".env.local"), "utf8").catch(() => "")
|
|
5559
5711
|
]);
|
|
5560
5712
|
files = nextFiles;
|
|
5561
5713
|
env = parseEnvFile(envLocalText);
|
|
@@ -5572,7 +5724,7 @@ async function startServeServer(options) {
|
|
|
5572
5724
|
void reload();
|
|
5573
5725
|
}, 120);
|
|
5574
5726
|
};
|
|
5575
|
-
await
|
|
5727
|
+
await mkdir9(functionsDir, { recursive: true }).catch(() => void 0);
|
|
5576
5728
|
try {
|
|
5577
5729
|
watchers.push(watch2(functionsDir, { recursive: true }, scheduleReload));
|
|
5578
5730
|
} catch {
|
|
@@ -5610,16 +5762,16 @@ async function startServeServer(options) {
|
|
|
5610
5762
|
const serveStatic = async (pathname, res) => {
|
|
5611
5763
|
if (!hasStatic) return false;
|
|
5612
5764
|
const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
|
|
5613
|
-
const filePath =
|
|
5614
|
-
const resolvedPath = safePath === "" || safePath === "/" ?
|
|
5765
|
+
const filePath = join14(staticDir, safePath);
|
|
5766
|
+
const resolvedPath = safePath === "" || safePath === "/" ? join14(filePath, "index.html") : filePath;
|
|
5615
5767
|
try {
|
|
5616
|
-
const fileStat = await
|
|
5768
|
+
const fileStat = await stat7(resolvedPath);
|
|
5617
5769
|
if (fileStat.isDirectory()) {
|
|
5618
|
-
const indexPath =
|
|
5770
|
+
const indexPath = join14(resolvedPath, "index.html");
|
|
5619
5771
|
try {
|
|
5620
|
-
const indexStat = await
|
|
5772
|
+
const indexStat = await stat7(indexPath);
|
|
5621
5773
|
if (indexStat.isFile()) {
|
|
5622
|
-
const content2 = await
|
|
5774
|
+
const content2 = await readFile11(indexPath);
|
|
5623
5775
|
res.writeHead(200, { "content-type": contentTypeFor(indexPath) });
|
|
5624
5776
|
res.end(content2);
|
|
5625
5777
|
return true;
|
|
@@ -5628,7 +5780,7 @@ async function startServeServer(options) {
|
|
|
5628
5780
|
}
|
|
5629
5781
|
return false;
|
|
5630
5782
|
}
|
|
5631
|
-
const content = await
|
|
5783
|
+
const content = await readFile11(resolvedPath);
|
|
5632
5784
|
res.writeHead(200, { "content-type": contentTypeFor(resolvedPath) });
|
|
5633
5785
|
res.end(content);
|
|
5634
5786
|
return true;
|
|
@@ -5637,7 +5789,7 @@ async function startServeServer(options) {
|
|
|
5637
5789
|
const ext = extname(pathname);
|
|
5638
5790
|
if (ext === "" || ext === ".html") {
|
|
5639
5791
|
try {
|
|
5640
|
-
const indexContent = await
|
|
5792
|
+
const indexContent = await readFile11(join14(staticDir, "index.html"));
|
|
5641
5793
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
5642
5794
|
res.end(indexContent);
|
|
5643
5795
|
return true;
|
|
@@ -5724,6 +5876,8 @@ async function startServeServer(options) {
|
|
|
5724
5876
|
project: config.name,
|
|
5725
5877
|
functions: functionNames,
|
|
5726
5878
|
static: hasStatic,
|
|
5879
|
+
// CLI-020:当前数据面(换模式即换库,这里让脚本/e2e 有可断言的读数)。
|
|
5880
|
+
db: sqliteFile === null ? { mode: "sim", file: displayPath(cwd, join14(simDir(cwd), "db.json")) } : { mode: "sqlite", file: displayPath(cwd, sqliteFile), driver: sqliteModule },
|
|
5727
5881
|
endpoints: {
|
|
5728
5882
|
functions: "/api/{fn}",
|
|
5729
5883
|
static: `/ \u2192 ${staticDir}`,
|
|
@@ -5762,14 +5916,19 @@ async function startServeServer(options) {
|
|
|
5762
5916
|
functions: functionNames,
|
|
5763
5917
|
functionsPrefix: config.functionsPrefix,
|
|
5764
5918
|
hasStatic,
|
|
5765
|
-
staticDir: relative2(cwd, staticDir).length > 0 ? relative2(cwd, staticDir) : staticDir
|
|
5919
|
+
staticDir: relative2(cwd, staticDir).length > 0 ? relative2(cwd, staticDir) : staticDir,
|
|
5920
|
+
dbMode,
|
|
5921
|
+
dbTarget: sqliteFile === null ? displayPath(cwd, join14(simDir(cwd), "db.json")) : displayPath(cwd, sqliteFile),
|
|
5922
|
+
...sqliteModule === null ? {} : { dbDriver: sqliteModule }
|
|
5766
5923
|
});
|
|
5767
5924
|
log(banner);
|
|
5768
5925
|
if (options.watch === true) {
|
|
5769
5926
|
log(`[serve] \u70ED\u91CD\u8F7D\u5DF2\u5F00\u542F\uFF1A\u6539 functions/ \u4E0E .env* \u5373\u751F\u6548\uFF0C\u51FD\u6570 console \u8F93\u51FA\u76F4\u8FBE\u7EC8\u7AEF\uFF08--watch\uFF09`);
|
|
5770
5927
|
}
|
|
5771
5928
|
if (bearerUser !== void 0) {
|
|
5772
|
-
log(
|
|
5929
|
+
log(
|
|
5930
|
+
`[serve] \u767B\u5F55\u5373\u670D\u52A1\uFF1AADEP_AUTH_ISSUER \u5DF2\u914D\u7F6E\uFF0CBearer token \u5C06\u89E3\u6790\u4E3A\u7528\u6237\u8EAB\u4EFD\uFF08userinfo \u7AEF\u70B9\uFF09`
|
|
5931
|
+
);
|
|
5773
5932
|
}
|
|
5774
5933
|
return {
|
|
5775
5934
|
port: actualPort,
|
|
@@ -5780,6 +5939,7 @@ async function startServeServer(options) {
|
|
|
5780
5939
|
await new Promise((resolveClose) => {
|
|
5781
5940
|
server.close(() => resolveClose());
|
|
5782
5941
|
});
|
|
5942
|
+
await runtime.dispose();
|
|
5783
5943
|
}
|
|
5784
5944
|
};
|
|
5785
5945
|
}
|
|
@@ -5797,6 +5957,8 @@ var init_server = __esm({
|
|
|
5797
5957
|
init_invoke();
|
|
5798
5958
|
init_dev();
|
|
5799
5959
|
init_banner();
|
|
5960
|
+
init_db_mode();
|
|
5961
|
+
init_sqlite_driver();
|
|
5800
5962
|
init_dev_shared();
|
|
5801
5963
|
MIME_TYPES = {
|
|
5802
5964
|
".html": "text/html; charset=utf-8",
|
|
@@ -5831,8 +5993,8 @@ __export(deploy_exports, {
|
|
|
5831
5993
|
deploy: () => deploy
|
|
5832
5994
|
});
|
|
5833
5995
|
import { createHash as createHash2 } from "node:crypto";
|
|
5834
|
-
import { readdir as
|
|
5835
|
-
import { join as
|
|
5996
|
+
import { readdir as readdir5, readFile as readFile12 } from "node:fs/promises";
|
|
5997
|
+
import { join as join15, resolve as resolve9, basename as basename3, relative as relative3, sep } from "node:path";
|
|
5836
5998
|
function functionUrlBase(prefix) {
|
|
5837
5999
|
const raw = (prefix ?? "/api").trim();
|
|
5838
6000
|
const normalized = raw === "/" ? "/" : raw.replace(/\/+$/, "");
|
|
@@ -5844,7 +6006,7 @@ function isRuntimeSource2(name) {
|
|
|
5844
6006
|
async function collectFunctionFiles(functionsDir) {
|
|
5845
6007
|
let dirents;
|
|
5846
6008
|
try {
|
|
5847
|
-
dirents = await
|
|
6009
|
+
dirents = await readdir5(functionsDir, { withFileTypes: true });
|
|
5848
6010
|
} catch {
|
|
5849
6011
|
return {};
|
|
5850
6012
|
}
|
|
@@ -5858,10 +6020,10 @@ async function collectFunctionFiles(functionsDir) {
|
|
|
5858
6020
|
if (conflicting.length > 0) throw new AmbiguousFunctionError(functionsDir, conflicting);
|
|
5859
6021
|
const out = {};
|
|
5860
6022
|
for (const name of flatNames) {
|
|
5861
|
-
out[name] = { "index.ts": await
|
|
6023
|
+
out[name] = { "index.ts": await readFile12(join15(functionsDir, `${name}.ts`), "utf8") };
|
|
5862
6024
|
}
|
|
5863
6025
|
for (const name of dirNames) {
|
|
5864
|
-
const files = await collectFunctionDir(
|
|
6026
|
+
const files = await collectFunctionDir(join15(functionsDir, name));
|
|
5865
6027
|
if (files["index.ts"] === void 0) continue;
|
|
5866
6028
|
out[name] = files;
|
|
5867
6029
|
}
|
|
@@ -5872,7 +6034,7 @@ async function collectFunctionDir(absDir) {
|
|
|
5872
6034
|
const walk = async (dir, prefix) => {
|
|
5873
6035
|
let entries;
|
|
5874
6036
|
try {
|
|
5875
|
-
entries = await
|
|
6037
|
+
entries = await readdir5(dir, { withFileTypes: true });
|
|
5876
6038
|
} catch {
|
|
5877
6039
|
return;
|
|
5878
6040
|
}
|
|
@@ -5880,11 +6042,11 @@ async function collectFunctionDir(absDir) {
|
|
|
5880
6042
|
const rel = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
5881
6043
|
if (entry.isDirectory()) {
|
|
5882
6044
|
if (entry.name === "__tests__" || IGNORED_DIRS.has(entry.name)) continue;
|
|
5883
|
-
await walk(
|
|
6045
|
+
await walk(join15(dir, entry.name), rel);
|
|
5884
6046
|
continue;
|
|
5885
6047
|
}
|
|
5886
6048
|
if (!isRuntimeSource2(entry.name)) continue;
|
|
5887
|
-
files[rel] = await
|
|
6049
|
+
files[rel] = await readFile12(join15(dir, entry.name), "utf8");
|
|
5888
6050
|
}
|
|
5889
6051
|
};
|
|
5890
6052
|
await walk(absDir, "");
|
|
@@ -5894,25 +6056,25 @@ function sha256Hex(content) {
|
|
|
5894
6056
|
return createHash2("sha256").update(content).digest("hex");
|
|
5895
6057
|
}
|
|
5896
6058
|
async function collectShared(functionsDir) {
|
|
5897
|
-
const sharedDir =
|
|
6059
|
+
const sharedDir = join15(functionsDir, "_shared");
|
|
5898
6060
|
const files = {};
|
|
5899
6061
|
const walk = async (dir) => {
|
|
5900
6062
|
let entries;
|
|
5901
6063
|
try {
|
|
5902
|
-
entries = await
|
|
6064
|
+
entries = await readdir5(dir, { withFileTypes: true });
|
|
5903
6065
|
} catch {
|
|
5904
6066
|
return;
|
|
5905
6067
|
}
|
|
5906
6068
|
for (const entry of entries) {
|
|
5907
6069
|
if (entry.isDirectory()) {
|
|
5908
6070
|
if (entry.name === "__tests__" || entry.name === "node_modules") continue;
|
|
5909
|
-
await walk(
|
|
6071
|
+
await walk(join15(dir, entry.name));
|
|
5910
6072
|
continue;
|
|
5911
6073
|
}
|
|
5912
6074
|
if (!isRuntimeSource2(entry.name)) continue;
|
|
5913
|
-
const full =
|
|
6075
|
+
const full = join15(dir, entry.name);
|
|
5914
6076
|
const rel = relative3(sharedDir, full).split(sep).join("/");
|
|
5915
|
-
files[`${SHARED_SOURCE_ROOT3}${rel}`] = await
|
|
6077
|
+
files[`${SHARED_SOURCE_ROOT3}${rel}`] = await readFile12(full, "utf8");
|
|
5916
6078
|
}
|
|
5917
6079
|
};
|
|
5918
6080
|
await walk(sharedDir);
|
|
@@ -5923,10 +6085,10 @@ async function deploy(paths, options) {
|
|
|
5923
6085
|
const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
|
|
5924
6086
|
`));
|
|
5925
6087
|
const client = await createClient(paths);
|
|
5926
|
-
const cwd =
|
|
6088
|
+
const cwd = resolve9(options.cwd);
|
|
5927
6089
|
const config = await loadConfig(cwd);
|
|
5928
6090
|
const slug = options.slug ?? config.name;
|
|
5929
|
-
const functionsDir = options.functionsDir === void 0 ?
|
|
6091
|
+
const functionsDir = options.functionsDir === void 0 ? join15(cwd, config.functionsDir) : resolve9(cwd, options.functionsDir);
|
|
5930
6092
|
const local = await collectFunctionFiles(functionsDir);
|
|
5931
6093
|
if (Object.keys(local).length === 0) {
|
|
5932
6094
|
throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
|
|
@@ -6057,8 +6219,8 @@ var frontend_exports = {};
|
|
|
6057
6219
|
__export(frontend_exports, {
|
|
6058
6220
|
frontendSync: () => frontendSync
|
|
6059
6221
|
});
|
|
6060
|
-
import { readdir as
|
|
6061
|
-
import { join as
|
|
6222
|
+
import { readdir as readdir6, readFile as readFile13, stat as stat8 } from "node:fs/promises";
|
|
6223
|
+
import { join as join16, relative as relative4, sep as sep2 } from "node:path";
|
|
6062
6224
|
async function resolveProjectId(client, cwd, slug) {
|
|
6063
6225
|
const resolvedSlug = await resolveSlug(cwd, slug);
|
|
6064
6226
|
const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
@@ -6074,24 +6236,24 @@ async function resolveProjectId(client, cwd, slug) {
|
|
|
6074
6236
|
async function collectFiles(root, dir) {
|
|
6075
6237
|
const files = /* @__PURE__ */ new Map();
|
|
6076
6238
|
const skipped = [];
|
|
6077
|
-
const entries = await
|
|
6239
|
+
const entries = await readdir6(dir, { withFileTypes: true });
|
|
6078
6240
|
for (const entry of entries) {
|
|
6079
6241
|
if (entry.isDirectory()) {
|
|
6080
6242
|
if (IGNORED_DIRS2.has(entry.name)) continue;
|
|
6081
|
-
const nested = await collectFiles(root,
|
|
6243
|
+
const nested = await collectFiles(root, join16(dir, entry.name));
|
|
6082
6244
|
for (const [path, content] of nested.files) files.set(path, content);
|
|
6083
6245
|
skipped.push(...nested.skipped);
|
|
6084
6246
|
continue;
|
|
6085
6247
|
}
|
|
6086
|
-
const full =
|
|
6248
|
+
const full = join16(dir, entry.name);
|
|
6087
6249
|
const rel = relative4(root, full).split(sep2).join("/");
|
|
6088
|
-
const info = await
|
|
6250
|
+
const info = await stat8(full);
|
|
6089
6251
|
if (info.size > 1024 * 1024) {
|
|
6090
6252
|
skipped.push(rel);
|
|
6091
6253
|
continue;
|
|
6092
6254
|
}
|
|
6093
6255
|
try {
|
|
6094
|
-
const content = await
|
|
6256
|
+
const content = await readFile13(full, "utf8");
|
|
6095
6257
|
if (content.includes("\0")) {
|
|
6096
6258
|
skipped.push(rel);
|
|
6097
6259
|
continue;
|
|
@@ -6106,8 +6268,8 @@ async function collectFiles(root, dir) {
|
|
|
6106
6268
|
async function frontendSync(paths, options) {
|
|
6107
6269
|
const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
|
|
6108
6270
|
`));
|
|
6109
|
-
const webDir = options.dir ??
|
|
6110
|
-
const rootStat = await
|
|
6271
|
+
const webDir = options.dir ?? join16(options.cwd, "web");
|
|
6272
|
+
const rootStat = await stat8(webDir).catch(() => null);
|
|
6111
6273
|
if (rootStat === null || !rootStat.isDirectory()) {
|
|
6112
6274
|
throw new CliError(
|
|
6113
6275
|
"FRONTEND_DIR_MISSING",
|
|
@@ -6172,7 +6334,7 @@ var client_exports2 = {};
|
|
|
6172
6334
|
__export(client_exports2, {
|
|
6173
6335
|
createExportApiClient: () => createExportApiClient
|
|
6174
6336
|
});
|
|
6175
|
-
import { writeFile as
|
|
6337
|
+
import { writeFile as writeFile7 } from "node:fs/promises";
|
|
6176
6338
|
function toExportJob(view) {
|
|
6177
6339
|
return {
|
|
6178
6340
|
id: view.id,
|
|
@@ -6223,7 +6385,7 @@ async function createExportApiClient(paths) {
|
|
|
6223
6385
|
}
|
|
6224
6386
|
const response = await client.download(download.downloadUrl, "EXPORT_DOWNLOAD_FAILED");
|
|
6225
6387
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
6226
|
-
await
|
|
6388
|
+
await writeFile7(outputPath, bytes);
|
|
6227
6389
|
return { path: outputPath, size: bytes.length };
|
|
6228
6390
|
}
|
|
6229
6391
|
};
|
|
@@ -6320,33 +6482,33 @@ var fs_exports = {};
|
|
|
6320
6482
|
__export(fs_exports, {
|
|
6321
6483
|
createExportFileSystem: () => createExportFileSystem
|
|
6322
6484
|
});
|
|
6323
|
-
import { mkdir as
|
|
6324
|
-
import { dirname as
|
|
6485
|
+
import { mkdir as mkdir10, readFile as readFile14, rm as rm3, stat as stat10, writeFile as writeFile8 } from "node:fs/promises";
|
|
6486
|
+
import { dirname as dirname9, join as join18 } from "node:path";
|
|
6325
6487
|
function createExportFileSystem() {
|
|
6326
6488
|
return {
|
|
6327
|
-
readFile: (path) =>
|
|
6328
|
-
writeFile: (path, content) =>
|
|
6489
|
+
readFile: (path) => readFile14(path),
|
|
6490
|
+
writeFile: (path, content) => writeFile8(path, content),
|
|
6329
6491
|
// 同时用于清理解压临时目录(${zip}.tmp 是个目录)——递归强制删除,缺失不报错。
|
|
6330
6492
|
deleteFile: async (path) => {
|
|
6331
6493
|
await rm3(path, { recursive: true, force: true });
|
|
6332
6494
|
},
|
|
6333
6495
|
fileExists: async (path) => {
|
|
6334
6496
|
try {
|
|
6335
|
-
await
|
|
6497
|
+
await stat10(path);
|
|
6336
6498
|
return true;
|
|
6337
6499
|
} catch {
|
|
6338
6500
|
return false;
|
|
6339
6501
|
}
|
|
6340
6502
|
},
|
|
6341
6503
|
mkdir: async (path) => {
|
|
6342
|
-
await
|
|
6504
|
+
await mkdir10(path, { recursive: true });
|
|
6343
6505
|
},
|
|
6344
6506
|
unzip: async (zipPath, targetDir) => {
|
|
6345
|
-
const entries = zipRead(await
|
|
6507
|
+
const entries = zipRead(await readFile14(zipPath));
|
|
6346
6508
|
for (const [name, data] of entries) {
|
|
6347
|
-
const dest =
|
|
6348
|
-
await
|
|
6349
|
-
await
|
|
6509
|
+
const dest = join18(targetDir, name);
|
|
6510
|
+
await mkdir10(dirname9(dest), { recursive: true });
|
|
6511
|
+
await writeFile8(dest, data);
|
|
6350
6512
|
}
|
|
6351
6513
|
}
|
|
6352
6514
|
};
|
|
@@ -6847,7 +7009,7 @@ ${detail}`);
|
|
|
6847
7009
|
* @param ms 毫秒数
|
|
6848
7010
|
*/
|
|
6849
7011
|
sleep(ms) {
|
|
6850
|
-
return new Promise((
|
|
7012
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
6851
7013
|
}
|
|
6852
7014
|
};
|
|
6853
7015
|
}
|
|
@@ -6862,11 +7024,11 @@ __export(storage_exports, {
|
|
|
6862
7024
|
storageRemove: () => storageRemove,
|
|
6863
7025
|
storageUpload: () => storageUpload
|
|
6864
7026
|
});
|
|
6865
|
-
import { mkdir as
|
|
6866
|
-
import { basename as basename4, dirname as
|
|
7027
|
+
import { mkdir as mkdir11, readFile as readFile15, stat as stat11, writeFile as writeFile9 } from "node:fs/promises";
|
|
7028
|
+
import { basename as basename4, dirname as dirname10, extname as extname2, join as join19, resolve as resolve11 } from "node:path";
|
|
6867
7029
|
async function open3(paths, options) {
|
|
6868
7030
|
const client = await createClient(paths);
|
|
6869
|
-
const project2 = await resolveSlug(
|
|
7031
|
+
const project2 = await resolveSlug(resolve11(options.cwd), options.slug);
|
|
6870
7032
|
return { client, project: project2 };
|
|
6871
7033
|
}
|
|
6872
7034
|
function contentTypeOf(path) {
|
|
@@ -6899,13 +7061,13 @@ function contentTypeOf(path) {
|
|
|
6899
7061
|
}
|
|
6900
7062
|
async function storageUpload(paths, options) {
|
|
6901
7063
|
const { client, project: project2 } = await open3(paths, options);
|
|
6902
|
-
const local =
|
|
6903
|
-
const info = await
|
|
7064
|
+
const local = resolve11(options.file);
|
|
7065
|
+
const info = await stat11(local).catch(() => null);
|
|
6904
7066
|
if (info === null || !info.isFile()) {
|
|
6905
7067
|
throw new CliError("FILE_NOT_FOUND", `\u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${local}`);
|
|
6906
7068
|
}
|
|
6907
7069
|
const visibility = options.visibility ?? "private";
|
|
6908
|
-
const bytes = await
|
|
7070
|
+
const bytes = await readFile15(local);
|
|
6909
7071
|
const form = new FormData();
|
|
6910
7072
|
form.set("path", options.path);
|
|
6911
7073
|
form.set("visibility", visibility);
|
|
@@ -6946,9 +7108,9 @@ async function storageDownload(paths, options) {
|
|
|
6946
7108
|
const url = await resolveDownloadUrl(client, project2, options.path);
|
|
6947
7109
|
const response = await client.download(url, "STORAGE_DOWNLOAD_FAILED");
|
|
6948
7110
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
6949
|
-
const output =
|
|
6950
|
-
await
|
|
6951
|
-
await
|
|
7111
|
+
const output = resolve11(options.output ?? join19(resolve11(options.cwd), basename4(options.path)));
|
|
7112
|
+
await mkdir11(dirname10(output), { recursive: true });
|
|
7113
|
+
await writeFile9(output, bytes);
|
|
6952
7114
|
return { path: options.path, output, size: bytes.length };
|
|
6953
7115
|
}
|
|
6954
7116
|
async function storageRemove(paths, options) {
|
|
@@ -6972,7 +7134,7 @@ __export(doctor_exports, {
|
|
|
6972
7134
|
formatDoctorReport: () => formatDoctorReport,
|
|
6973
7135
|
runDoctor: () => runDoctor
|
|
6974
7136
|
});
|
|
6975
|
-
import { stat as
|
|
7137
|
+
import { stat as stat12 } from "node:fs/promises";
|
|
6976
7138
|
async function probeServer(server) {
|
|
6977
7139
|
const controller = new AbortController();
|
|
6978
7140
|
const timer = setTimeout(() => controller.abort(), SERVER_PROBE_TIMEOUT_MS);
|
|
@@ -6990,7 +7152,7 @@ async function probeServer(server) {
|
|
|
6990
7152
|
}
|
|
6991
7153
|
async function credentialMode(file) {
|
|
6992
7154
|
try {
|
|
6993
|
-
const info = await
|
|
7155
|
+
const info = await stat12(file);
|
|
6994
7156
|
return (info.mode & 511).toString(8).padStart(3, "0");
|
|
6995
7157
|
} catch {
|
|
6996
7158
|
return void 0;
|
|
@@ -7079,7 +7241,7 @@ __export(mcp_exports, {
|
|
|
7079
7241
|
mcpPublish: () => mcpPublish,
|
|
7080
7242
|
mcpUnpublish: () => mcpUnpublish
|
|
7081
7243
|
});
|
|
7082
|
-
import { resolve as
|
|
7244
|
+
import { resolve as resolve12 } from "node:path";
|
|
7083
7245
|
async function mcpPublish(paths, options) {
|
|
7084
7246
|
const fn = requireFunctionName(options.fn);
|
|
7085
7247
|
const client = await createClient(paths);
|
|
@@ -7160,7 +7322,7 @@ function requireFunctionName(fn) {
|
|
|
7160
7322
|
return fn.trim();
|
|
7161
7323
|
}
|
|
7162
7324
|
async function resolveProject(client, options) {
|
|
7163
|
-
const slug = await resolveSlug(
|
|
7325
|
+
const slug = await resolveSlug(resolve12(options.cwd), options.slug);
|
|
7164
7326
|
const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
7165
7327
|
const match = listed.projects.find((project2) => project2.slug === slug);
|
|
7166
7328
|
if (match === void 0) {
|
|
@@ -7360,7 +7522,7 @@ __export(functions_exports, {
|
|
|
7360
7522
|
functionsList: () => functionsList,
|
|
7361
7523
|
functionsLogs: () => functionsLogs
|
|
7362
7524
|
});
|
|
7363
|
-
import { resolve as
|
|
7525
|
+
import { resolve as resolve13 } from "node:path";
|
|
7364
7526
|
async function functionsList(paths, options) {
|
|
7365
7527
|
const client = await createClient(paths);
|
|
7366
7528
|
const project2 = await resolveProject2(client, options);
|
|
@@ -7402,7 +7564,7 @@ async function functionsLogs(paths, options) {
|
|
|
7402
7564
|
return { functionId: target.id, name: target.name, logs: result.logs };
|
|
7403
7565
|
}
|
|
7404
7566
|
async function resolveProject2(client, options) {
|
|
7405
|
-
const slug = await resolveSlug(
|
|
7567
|
+
const slug = await resolveSlug(resolve13(options.cwd), options.slug);
|
|
7406
7568
|
const projects = await projectsListFrom(client);
|
|
7407
7569
|
const match = projects.find((project2) => project2.slug === slug);
|
|
7408
7570
|
if (match === void 0) {
|
|
@@ -7433,11 +7595,11 @@ __export(hosting_exports, {
|
|
|
7433
7595
|
hostingInfo: () => hostingInfo,
|
|
7434
7596
|
hostingPull: () => hostingPull
|
|
7435
7597
|
});
|
|
7436
|
-
import { readdir as
|
|
7437
|
-
import { dirname as
|
|
7598
|
+
import { readdir as readdir7, readFile as readFile16, stat as stat13 } from "node:fs/promises";
|
|
7599
|
+
import { dirname as dirname11, join as join20, relative as relative5, resolve as resolve14, sep as sep3 } from "node:path";
|
|
7438
7600
|
async function open4(paths, options) {
|
|
7439
7601
|
const client = await createClient(paths);
|
|
7440
|
-
const project2 = await resolveSlug(
|
|
7602
|
+
const project2 = await resolveSlug(resolve14(options.cwd), options.slug);
|
|
7441
7603
|
return { client, project: project2 };
|
|
7442
7604
|
}
|
|
7443
7605
|
async function hostingInfo(paths, options) {
|
|
@@ -7450,17 +7612,17 @@ async function hostingInfo(paths, options) {
|
|
|
7450
7612
|
};
|
|
7451
7613
|
}
|
|
7452
7614
|
async function collectSiteFiles(dir) {
|
|
7453
|
-
const root =
|
|
7615
|
+
const root = resolve14(dir);
|
|
7454
7616
|
const files = /* @__PURE__ */ new Map();
|
|
7455
7617
|
const walk = async (sub) => {
|
|
7456
7618
|
let entries;
|
|
7457
7619
|
try {
|
|
7458
|
-
entries = await
|
|
7620
|
+
entries = await readdir7(sub, { withFileTypes: true });
|
|
7459
7621
|
} catch {
|
|
7460
7622
|
return;
|
|
7461
7623
|
}
|
|
7462
7624
|
for (const entry of entries) {
|
|
7463
|
-
const full =
|
|
7625
|
+
const full = join20(sub, entry.name);
|
|
7464
7626
|
if (entry.isDirectory()) {
|
|
7465
7627
|
await walk(full);
|
|
7466
7628
|
} else if (entry.isFile()) {
|
|
@@ -7478,13 +7640,13 @@ async function hostingDeploy(paths, options) {
|
|
|
7478
7640
|
`));
|
|
7479
7641
|
const files = await collectSiteFiles(options.dir);
|
|
7480
7642
|
if (files.size === 0) {
|
|
7481
|
-
throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${
|
|
7643
|
+
throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${resolve14(options.dir)}`);
|
|
7482
7644
|
}
|
|
7483
7645
|
const uploaded = [];
|
|
7484
7646
|
for (const [rel, full] of files) {
|
|
7485
7647
|
log(`[adep] \u4E0A\u4F20 site/${rel}`);
|
|
7486
|
-
const info2 = await
|
|
7487
|
-
const bytes = await
|
|
7648
|
+
const info2 = await stat13(full);
|
|
7649
|
+
const bytes = await readFile16(full);
|
|
7488
7650
|
const form = new FormData();
|
|
7489
7651
|
form.set("path", `site/${rel}`);
|
|
7490
7652
|
form.set("visibility", "public");
|
|
@@ -7511,8 +7673,8 @@ async function hostingPull(paths, options) {
|
|
|
7511
7673
|
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
7512
7674
|
`));
|
|
7513
7675
|
const info = await hostingInfo(paths, options);
|
|
7514
|
-
const outputDir =
|
|
7515
|
-
const { mkdir:
|
|
7676
|
+
const outputDir = resolve14(options.output ?? resolve14(options.cwd));
|
|
7677
|
+
const { mkdir: mkdir12, writeFile: writeFile10 } = await import("node:fs/promises");
|
|
7516
7678
|
const files = [];
|
|
7517
7679
|
for (const entry of info.files) {
|
|
7518
7680
|
if (entry.visibility !== "public" || entry.path === HOSTING_CONFIG_PATH) continue;
|
|
@@ -7522,9 +7684,9 @@ async function hostingPull(paths, options) {
|
|
|
7522
7684
|
const response = await client.download(url, "HOSTING_DOWNLOAD_FAILED");
|
|
7523
7685
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
7524
7686
|
const rel = entry.path.replace(/^site\//, "");
|
|
7525
|
-
const target =
|
|
7526
|
-
await
|
|
7527
|
-
await
|
|
7687
|
+
const target = join20(outputDir, ...rel.split("/"));
|
|
7688
|
+
await mkdir12(dirname11(target), { recursive: true });
|
|
7689
|
+
await writeFile10(target, bytes);
|
|
7528
7690
|
files.push({ path: entry.path, size: bytes.length });
|
|
7529
7691
|
}
|
|
7530
7692
|
return { siteUrl: info.siteUrl, outputDir, files };
|
|
@@ -10808,19 +10970,30 @@ function cliVersionOf() {
|
|
|
10808
10970
|
const pkg = JSON.parse(readFileSync(findCliPackageJson(), "utf8"));
|
|
10809
10971
|
return pkg.version;
|
|
10810
10972
|
}
|
|
10973
|
+
function cliPackageRoot() {
|
|
10974
|
+
return dirname2(findCliPackageJson());
|
|
10975
|
+
}
|
|
10976
|
+
function localTemplateDir(code) {
|
|
10977
|
+
return join(cliPackageRoot(), "src", "templates", code);
|
|
10978
|
+
}
|
|
10811
10979
|
function templateFiles(code, name) {
|
|
10812
10980
|
const generated = GENERATED_TEMPLATES[code];
|
|
10813
10981
|
if (generated === void 0) {
|
|
10814
10982
|
throw new Error(`\u672A\u77E5\u6A21\u677F "${code}"\uFF1A\u53EF\u9009 ${TEMPLATE_NAMES.join(" | ")}`);
|
|
10815
10983
|
}
|
|
10816
10984
|
const { manifest, files } = generated;
|
|
10817
|
-
|
|
10818
|
-
|
|
10985
|
+
return renderTemplatePackage({ code, version: manifest.version, manifest, files }, name);
|
|
10986
|
+
}
|
|
10987
|
+
function renderTemplatePackage(pkg, name) {
|
|
10988
|
+
const manifest = pkg.manifest;
|
|
10989
|
+
const vars = { name, template: pkg.code };
|
|
10990
|
+
const dirFiles = renderTemplateFiles(pkg.files, vars, manifest);
|
|
10991
|
+
const code = pkg.code;
|
|
10819
10992
|
const ctx = { name, template: code, cliVersion: cliVersionOf() };
|
|
10820
10993
|
const sharedFiles = (manifest.sharedAssets ?? []).flatMap((assetName) => {
|
|
10821
10994
|
const asset = SHARED_ASSETS[assetName];
|
|
10822
10995
|
if (asset === void 0) {
|
|
10823
|
-
throw new Error(`\u6A21\u677F ${code} \u58F0\u660E\u4E86\u672A\u77E5\u5171\u4EAB\u8D44\u4EA7 "${assetName}"\uFF08shared-assets.ts \u672A\u6CE8\u518C\uFF09`);
|
|
10996
|
+
throw new Error(`\u6A21\u677F ${pkg.code} \u58F0\u660E\u4E86\u672A\u77E5\u5171\u4EAB\u8D44\u4EA7 "${assetName}"\uFF08shared-assets.ts \u672A\u6CE8\u518C\uFF09`);
|
|
10824
10997
|
}
|
|
10825
10998
|
return asset(ctx);
|
|
10826
10999
|
});
|
|
@@ -10835,7 +11008,7 @@ var InitError = class extends Error {
|
|
|
10835
11008
|
this.name = "InitError";
|
|
10836
11009
|
}
|
|
10837
11010
|
};
|
|
10838
|
-
async function initProject(cwd, name, template) {
|
|
11011
|
+
async function initProject(cwd, name, template, filesOverride) {
|
|
10839
11012
|
if (!/^[a-z][a-z0-9-]{0,62}$/.test(name)) {
|
|
10840
11013
|
throw new InitError(
|
|
10841
11014
|
"INVALID_NAME",
|
|
@@ -10858,7 +11031,7 @@ async function initProject(cwd, name, template) {
|
|
|
10858
11031
|
if (existing !== null) {
|
|
10859
11032
|
throw new InitError("DIR_EXISTS", `\u76EE\u5F55 ${projectPath} \u5DF2\u5B58\u5728\uFF1A\u8BF7\u6362\u4E00\u4E2A\u540D\u5B57\u6216\u5148\u5220\u9664`);
|
|
10860
11033
|
}
|
|
10861
|
-
const files = templateFiles(template, name);
|
|
11034
|
+
const files = filesOverride ?? templateFiles(template, name);
|
|
10862
11035
|
await mkdir2(projectPath, { recursive: true });
|
|
10863
11036
|
await Promise.all(
|
|
10864
11037
|
files.map(async (file) => {
|
|
@@ -11039,19 +11212,178 @@ async function fetchTemplates(server) {
|
|
|
11039
11212
|
return templates ?? [];
|
|
11040
11213
|
}
|
|
11041
11214
|
|
|
11215
|
+
// packages/cli/src/template-package.ts
|
|
11216
|
+
init_auth();
|
|
11217
|
+
init_credentials();
|
|
11218
|
+
import { mkdir as mkdir3, readFile as readFile2, readdir, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
|
|
11219
|
+
import { join as join3 } from "node:path";
|
|
11220
|
+
function cachedPackagePath(paths, code, version) {
|
|
11221
|
+
return join3(paths.home, "templates", `${code}-${version}.json`);
|
|
11222
|
+
}
|
|
11223
|
+
async function collectTemplateDir(dir) {
|
|
11224
|
+
const files = [];
|
|
11225
|
+
async function walk(current, prefix) {
|
|
11226
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
11227
|
+
for (const entry of entries) {
|
|
11228
|
+
const full = join3(current, entry.name);
|
|
11229
|
+
const rel = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
11230
|
+
if (entry.isDirectory()) {
|
|
11231
|
+
await walk(full, rel);
|
|
11232
|
+
} else {
|
|
11233
|
+
files.push({ path: rel, content: await readFile2(full, "utf8") });
|
|
11234
|
+
}
|
|
11235
|
+
}
|
|
11236
|
+
}
|
|
11237
|
+
await walk(dir, "");
|
|
11238
|
+
files.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
11239
|
+
return files;
|
|
11240
|
+
}
|
|
11241
|
+
async function loadCachedPackage(paths, code, version) {
|
|
11242
|
+
let text;
|
|
11243
|
+
try {
|
|
11244
|
+
text = await readFile2(cachedPackagePath(paths, code, version), "utf8");
|
|
11245
|
+
} catch {
|
|
11246
|
+
return null;
|
|
11247
|
+
}
|
|
11248
|
+
let raw;
|
|
11249
|
+
try {
|
|
11250
|
+
raw = JSON.parse(text);
|
|
11251
|
+
} catch {
|
|
11252
|
+
return null;
|
|
11253
|
+
}
|
|
11254
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
11255
|
+
const pkg = raw;
|
|
11256
|
+
if (pkg.code !== code || pkg.version !== version || !Array.isArray(pkg.files)) return null;
|
|
11257
|
+
return pkg;
|
|
11258
|
+
}
|
|
11259
|
+
async function saveCachedPackage(paths, pkg) {
|
|
11260
|
+
await mkdir3(join3(paths.home, "templates"), { recursive: true });
|
|
11261
|
+
await writeFile2(cachedPackagePath(paths, pkg.code, pkg.version), JSON.stringify(pkg), "utf8");
|
|
11262
|
+
}
|
|
11263
|
+
async function downloadTemplatePackage(server, code) {
|
|
11264
|
+
let response;
|
|
11265
|
+
try {
|
|
11266
|
+
response = await fetch(`${server}/api/v1/templates/${code}/package`);
|
|
11267
|
+
} catch (error) {
|
|
11268
|
+
throw new CliError(
|
|
11269
|
+
"SERVER_UNREACHABLE",
|
|
11270
|
+
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
11271
|
+
);
|
|
11272
|
+
}
|
|
11273
|
+
const text = await response.text();
|
|
11274
|
+
let parsed = null;
|
|
11275
|
+
try {
|
|
11276
|
+
parsed = text.length === 0 ? null : JSON.parse(text);
|
|
11277
|
+
} catch {
|
|
11278
|
+
parsed = null;
|
|
11279
|
+
}
|
|
11280
|
+
if (response.status !== 200) {
|
|
11281
|
+
const msg = parsed?.error;
|
|
11282
|
+
throw new CliError(
|
|
11283
|
+
"TEMPLATE_PACKAGE_FAILED",
|
|
11284
|
+
msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}\uFF08\u6A21\u677F ${code} \u53EF\u80FD\u6682\u65E0\u6258\u7BA1\u5305\uFF09`
|
|
11285
|
+
);
|
|
11286
|
+
}
|
|
11287
|
+
const pkg = parsed;
|
|
11288
|
+
if (typeof pkg.code !== "string" || typeof pkg.version !== "string" || !Array.isArray(pkg.files)) {
|
|
11289
|
+
throw new CliError("TEMPLATE_PACKAGE_FAILED", `\u5E73\u53F0\u8FD4\u56DE\u7684\u6A21\u677F\u5305 ${code} \u5F62\u72B6\u975E\u6CD5`);
|
|
11290
|
+
}
|
|
11291
|
+
return pkg;
|
|
11292
|
+
}
|
|
11293
|
+
async function uploadTemplatePackage(paths, pkg) {
|
|
11294
|
+
const credentials = await loadCredentials(paths);
|
|
11295
|
+
if (credentials === null) {
|
|
11296
|
+
throw new CliError("NOT_LOGGED_IN", "\u672A\u767B\u5F55\uFF1A\u8BF7\u5148\u6267\u884C adep login\uFF08\u4E0A\u4F20\u6A21\u677F\u5305\u5230\u767B\u5F55\u7684\u5E73\u53F0\uFF09");
|
|
11297
|
+
}
|
|
11298
|
+
const server = credentials.server;
|
|
11299
|
+
let response;
|
|
11300
|
+
try {
|
|
11301
|
+
response = await fetch(`${server}/api/v1/templates/${pkg.code}/package`, {
|
|
11302
|
+
method: "PUT",
|
|
11303
|
+
headers: {
|
|
11304
|
+
"content-type": "application/json",
|
|
11305
|
+
cookie: `better-auth.session_token=${decodeToken(credentials.encodedToken)}`
|
|
11306
|
+
},
|
|
11307
|
+
body: JSON.stringify(pkg)
|
|
11308
|
+
});
|
|
11309
|
+
} catch (error) {
|
|
11310
|
+
throw new CliError(
|
|
11311
|
+
"SERVER_UNREACHABLE",
|
|
11312
|
+
`\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
11313
|
+
);
|
|
11314
|
+
}
|
|
11315
|
+
const text = await response.text();
|
|
11316
|
+
let parsed = null;
|
|
11317
|
+
try {
|
|
11318
|
+
parsed = text.length === 0 ? null : JSON.parse(text);
|
|
11319
|
+
} catch {
|
|
11320
|
+
parsed = null;
|
|
11321
|
+
}
|
|
11322
|
+
if (response.status !== 200) {
|
|
11323
|
+
const msg = parsed?.error;
|
|
11324
|
+
if (response.status === 401) {
|
|
11325
|
+
throw new CliError("SESSION_EXPIRED", "\u4F1A\u8BDD\u5DF2\u5931\u6548\uFF1A\u8BF7\u91CD\u65B0\u6267\u884C adep login \u540E\u518D\u4E0A\u4F20");
|
|
11326
|
+
}
|
|
11327
|
+
throw new CliError("TEMPLATE_PUBLISH_FAILED", msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`);
|
|
11328
|
+
}
|
|
11329
|
+
}
|
|
11330
|
+
function packageManifestEntry(pkg) {
|
|
11331
|
+
const entry = pkg.files.find((file) => file.path === "template.json");
|
|
11332
|
+
if (entry === void 0) return null;
|
|
11333
|
+
try {
|
|
11334
|
+
const parsed = JSON.parse(entry.content);
|
|
11335
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
11336
|
+
} catch {
|
|
11337
|
+
return null;
|
|
11338
|
+
}
|
|
11339
|
+
}
|
|
11340
|
+
async function assertPublishableTemplate(dir, expectedCode) {
|
|
11341
|
+
let info;
|
|
11342
|
+
try {
|
|
11343
|
+
info = await stat3(join3(dir, "template.json"));
|
|
11344
|
+
} catch {
|
|
11345
|
+
throw new CliError(
|
|
11346
|
+
"TEMPLATE_NOT_PUBLISHABLE",
|
|
11347
|
+
`\u76EE\u5F55 ${dir} \u7F3A template.json\uFF1A\u4E0D\u662F\u6A21\u677F\u5305\u76EE\u5F55\uFF08\u6A21\u677F = \u771F\u5B9E\u76EE\u5F55 + template.json \u6E05\u5355\uFF09`
|
|
11348
|
+
);
|
|
11349
|
+
}
|
|
11350
|
+
if (!info.isFile()) {
|
|
11351
|
+
throw new CliError("TEMPLATE_NOT_PUBLISHABLE", `\u76EE\u5F55 ${dir}/template.json \u4E0D\u662F\u6587\u4EF6`);
|
|
11352
|
+
}
|
|
11353
|
+
const manifest = packageManifestEntry({
|
|
11354
|
+
code: expectedCode,
|
|
11355
|
+
version: "",
|
|
11356
|
+
manifest: {},
|
|
11357
|
+
files: [{ path: "template.json", content: await readFile2(join3(dir, "template.json"), "utf8") }]
|
|
11358
|
+
});
|
|
11359
|
+
if (manifest === null) {
|
|
11360
|
+
throw new CliError("TEMPLATE_NOT_PUBLISHABLE", `\u76EE\u5F55 ${dir}/template.json \u4E0D\u662F\u5408\u6CD5 JSON`);
|
|
11361
|
+
}
|
|
11362
|
+
if (manifest["code"] !== expectedCode) {
|
|
11363
|
+
throw new CliError(
|
|
11364
|
+
"TEMPLATE_NOT_PUBLISHABLE",
|
|
11365
|
+
`\u6A21\u677F\u6E05\u5355 code "${String(manifest["code"])}" \u4E0E\u76EE\u5F55\u540D ${expectedCode} \u4E0D\u4E00\u81F4`
|
|
11366
|
+
);
|
|
11367
|
+
}
|
|
11368
|
+
if (typeof manifest["version"] !== "string") {
|
|
11369
|
+
throw new CliError("TEMPLATE_NOT_PUBLISHABLE", `\u6A21\u677F\u6E05\u5355 ${expectedCode} \u7F3A version \u5B57\u7B26\u4E32`);
|
|
11370
|
+
}
|
|
11371
|
+
return { manifest, version: manifest["version"] };
|
|
11372
|
+
}
|
|
11373
|
+
|
|
11042
11374
|
// packages/cli/src/commands/init.ts
|
|
11043
11375
|
function registerInit(program2, ctx) {
|
|
11044
11376
|
const templateHelp = `\u6A21\u677F\uFF1A${TEMPLATE_NAMES.join(" | ")}`;
|
|
11045
11377
|
program2.command("init").description(`\u521D\u59CB\u5316\u9879\u76EE\uFF08${templateHelp}\uFF09\uFF0C\u6216 --list \u4ECE\u5E73\u53F0\u53D6\u6A21\u677F\u6E05\u5355`).argument("[name]", "\u9879\u76EE\u76EE\u5F55\u540D\uFF08\u914D\u5408 --list \u65F6\u53EF\u7701\u7565\uFF09").option("-t, --template <template>", templateHelp, "fullstack").option("-l, --list", "\u4ECE\u5E73\u53F0 /api/v1/templates \u5217\u51FA\u53EF\u7528\u6A21\u677F\uFF08\u4E0D\u811A\u624B\u67B6\uFF09", false).option(
|
|
11046
11378
|
"-s, --server <url>",
|
|
11047
|
-
"\u5E73\u53F0\u5730\u5740\uFF08--list \u7528\uFF1B\u7F3A\u7701\u8BFB ADEP_SERVER \u6216 http://localhost:3000\uFF09"
|
|
11379
|
+
"\u5E73\u53F0\u5730\u5740\uFF08--list / \u5E73\u53F0\u6A21\u677F\u5305\u4E0B\u8F7D\u7528\uFF1B\u7F3A\u7701\u8BFB ADEP_SERVER \u6216 http://localhost:3000\uFF09"
|
|
11048
11380
|
).action(
|
|
11049
11381
|
async (name, flags) => {
|
|
11050
11382
|
const command = ctx.io("init");
|
|
11051
11383
|
await command.run(async () => {
|
|
11052
11384
|
if (flags.list === true) {
|
|
11053
|
-
const
|
|
11054
|
-
const templates = await fetchTemplates(
|
|
11385
|
+
const server2 = flags.server ?? resolveServer();
|
|
11386
|
+
const templates = await fetchTemplates(server2);
|
|
11055
11387
|
command.ok(
|
|
11056
11388
|
{ templates },
|
|
11057
11389
|
(data) => data.templates.map(
|
|
@@ -11072,18 +11404,81 @@ function registerInit(program2, ctx) {
|
|
|
11072
11404
|
`\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 ${TEMPLATE_NAMES.join(" | ")}`
|
|
11073
11405
|
);
|
|
11074
11406
|
}
|
|
11075
|
-
const
|
|
11407
|
+
const server = flags.server ?? resolveServer();
|
|
11408
|
+
let filesOverride;
|
|
11409
|
+
try {
|
|
11410
|
+
const summary = (await fetchTemplates(server)).find((tpl) => tpl.code === template);
|
|
11411
|
+
if (summary?.hasPackage === true && summary.version !== void 0) {
|
|
11412
|
+
const cached = await loadCachedPackage(ctx.paths, template, summary.version);
|
|
11413
|
+
const pkg = cached ?? await downloadTemplatePackage(server, template);
|
|
11414
|
+
if (cached === null) {
|
|
11415
|
+
await saveCachedPackage(ctx.paths, pkg);
|
|
11416
|
+
command.line(`\u5DF2\u4E0B\u8F7D\u5E73\u53F0\u6A21\u677F\u5305 ${pkg.code}@${pkg.version}\uFF08\u7F13\u5B58\u5230\u672C\u5730\uFF09`);
|
|
11417
|
+
}
|
|
11418
|
+
filesOverride = renderTemplatePackage(
|
|
11419
|
+
{
|
|
11420
|
+
code: pkg.code,
|
|
11421
|
+
version: pkg.version,
|
|
11422
|
+
manifest: pkg.manifest,
|
|
11423
|
+
files: pkg.files
|
|
11424
|
+
},
|
|
11425
|
+
name
|
|
11426
|
+
);
|
|
11427
|
+
}
|
|
11428
|
+
} catch (error) {
|
|
11429
|
+
command.line(`\u5E73\u53F0\u6A21\u677F\u5305\u4E0D\u53EF\u7528\uFF0C\u56DE\u9000\u672C\u5730\u5185\u7F6E\u6A21\u677F\uFF1A${error instanceof Error ? error.message : String(error)}`);
|
|
11430
|
+
}
|
|
11431
|
+
const result = await initProject(ctx.cwd, name, template, filesOverride);
|
|
11076
11432
|
command.ok(result, (data) => `\u5DF2\u521B\u5EFA ${data.projectPath}`);
|
|
11077
11433
|
});
|
|
11078
11434
|
}
|
|
11079
11435
|
);
|
|
11080
11436
|
}
|
|
11081
11437
|
|
|
11438
|
+
// packages/cli/src/commands/templates.ts
|
|
11439
|
+
init_auth();
|
|
11440
|
+
function registerTemplates(program2, ctx) {
|
|
11441
|
+
program2.command("templates").description("\u5E73\u53F0\u6258\u7BA1\u6A21\u677F\u5305\u7BA1\u7406\uFF08\u5F53\u524D\u4EC5 publish\uFF1A\u4E0A\u4F20\u672C\u5730\u6A21\u677F\u5305\u5230\u767B\u5F55\u7684\u5E73\u53F0\uFF09").command("publish").description("\u4E0A\u4F20\u672C\u5730\u6A21\u677F\u5305\uFF08\u9700\u767B\u5F55\uFF1Bcode \u7F3A\u7701 = \u5168\u90E8\u5185\u7F6E\u6A21\u677F\uFF09").argument("[code]", "\u6A21\u677F code\uFF08\u7F3A\u7701\u5168\u90E8\u5185\u7F6E\uFF1A" + TEMPLATE_CODES.join(" | ") + "\uFF09").option(
|
|
11442
|
+
"-d, --dir <dir>",
|
|
11443
|
+
"\u6A21\u677F\u76EE\u5F55\uFF08\u8986\u76D6\u9ED8\u8BA4 src/templates/<code>\uFF0C\u53D1\u5E03\u81EA\u5B9A\u4E49\u76EE\u5F55\u65F6\u7528\uFF09"
|
|
11444
|
+
).action(
|
|
11445
|
+
async (code, flags) => {
|
|
11446
|
+
const command = ctx.io("templates");
|
|
11447
|
+
await command.run(async () => {
|
|
11448
|
+
const codes = code === void 0 ? [...TEMPLATE_CODES] : [code];
|
|
11449
|
+
if (code !== void 0 && !TEMPLATE_CODES.includes(code)) {
|
|
11450
|
+
throw new CliError(
|
|
11451
|
+
"INVALID_TEMPLATE",
|
|
11452
|
+
`\u672A\u77E5\u6A21\u677F "${code}"\uFF1A\u5185\u7F6E\u53EF\u9009 ${TEMPLATE_CODES.join(" | ")}\uFF08-d \u53D1\u5E03\u81EA\u5B9A\u4E49\u76EE\u5F55\u65F6\u4ECD\u987B\u662F\u5185\u7F6E code\uFF09`
|
|
11453
|
+
);
|
|
11454
|
+
}
|
|
11455
|
+
const uploaded = [];
|
|
11456
|
+
for (const templateCode of codes) {
|
|
11457
|
+
const dir = flags.dir ?? localTemplateDir(templateCode);
|
|
11458
|
+
const { manifest, version } = await assertPublishableTemplate(dir, templateCode);
|
|
11459
|
+
const files = await collectTemplateDir(dir);
|
|
11460
|
+
await uploadTemplatePackage(ctx.paths, {
|
|
11461
|
+
code: templateCode,
|
|
11462
|
+
version,
|
|
11463
|
+
manifest,
|
|
11464
|
+
files
|
|
11465
|
+
});
|
|
11466
|
+
uploaded.push(`${templateCode}@${version}`);
|
|
11467
|
+
}
|
|
11468
|
+
command.ok(
|
|
11469
|
+
{ uploaded },
|
|
11470
|
+
(data) => `\u5DF2\u4E0A\u4F20\u6A21\u677F\u5305\uFF1A${data.uploaded.join("\u3001")}`
|
|
11471
|
+
);
|
|
11472
|
+
});
|
|
11473
|
+
}
|
|
11474
|
+
);
|
|
11475
|
+
}
|
|
11476
|
+
|
|
11082
11477
|
// packages/cli/src/import-cf.ts
|
|
11083
11478
|
init_adep_config();
|
|
11084
11479
|
init_regexp();
|
|
11085
|
-
import { copyFile, mkdir as
|
|
11086
|
-
import { basename, dirname as dirname4, join as
|
|
11480
|
+
import { copyFile, mkdir as mkdir4, readFile as readFile3, readdir as readdir2, stat as stat4, writeFile as writeFile3 } from "node:fs/promises";
|
|
11481
|
+
import { basename, dirname as dirname4, join as join4, relative, resolve as resolve2 } from "node:path";
|
|
11087
11482
|
var TomlSyntaxError = class extends Error {
|
|
11088
11483
|
constructor(message) {
|
|
11089
11484
|
super(message);
|
|
@@ -11337,13 +11732,13 @@ var SKIP_COPY_NAMES = /* @__PURE__ */ new Set([
|
|
|
11337
11732
|
async function copyWorkerDir(sourceDir, targetDir, mainFile) {
|
|
11338
11733
|
const copied = [];
|
|
11339
11734
|
const renamedIndex = [];
|
|
11340
|
-
const entries = await
|
|
11735
|
+
const entries = await readdir2(sourceDir, { withFileTypes: true });
|
|
11341
11736
|
for (const entry of entries) {
|
|
11342
|
-
const from =
|
|
11343
|
-
const to =
|
|
11737
|
+
const from = join4(sourceDir, entry.name);
|
|
11738
|
+
const to = join4(targetDir, entry.name);
|
|
11344
11739
|
if (SKIP_COPY_NAMES.has(entry.name)) continue;
|
|
11345
11740
|
if (entry.isDirectory()) {
|
|
11346
|
-
await
|
|
11741
|
+
await mkdir4(to, { recursive: true });
|
|
11347
11742
|
const sub = await copyWorkerDir(from, to, "");
|
|
11348
11743
|
copied.push(...sub.copied);
|
|
11349
11744
|
renamedIndex.push(...sub.renamedIndex);
|
|
@@ -11351,7 +11746,7 @@ async function copyWorkerDir(sourceDir, targetDir, mainFile) {
|
|
|
11351
11746
|
}
|
|
11352
11747
|
if (from === mainFile) continue;
|
|
11353
11748
|
if (entry.name === "index.ts") {
|
|
11354
|
-
await copyFile(from,
|
|
11749
|
+
await copyFile(from, join4(targetDir, "_index.ts"));
|
|
11355
11750
|
renamedIndex.push("_index.ts");
|
|
11356
11751
|
continue;
|
|
11357
11752
|
}
|
|
@@ -11362,7 +11757,7 @@ async function copyWorkerDir(sourceDir, targetDir, mainFile) {
|
|
|
11362
11757
|
}
|
|
11363
11758
|
async function readDevVars(sourceDir) {
|
|
11364
11759
|
try {
|
|
11365
|
-
const text = await
|
|
11760
|
+
const text = await readFile3(join4(sourceDir, ".dev.vars"), "utf8");
|
|
11366
11761
|
const vars = {};
|
|
11367
11762
|
for (const line of text.split(/\r?\n/)) {
|
|
11368
11763
|
const trimmed = line.trim();
|
|
@@ -11380,14 +11775,14 @@ async function readDevVars(sourceDir) {
|
|
|
11380
11775
|
async function copyAssetsToWeb(sourceDir, assetsDir, outDir) {
|
|
11381
11776
|
const files = [];
|
|
11382
11777
|
const from = resolve2(sourceDir, assetsDir);
|
|
11383
|
-
const target =
|
|
11384
|
-
await
|
|
11385
|
-
const entries = await
|
|
11778
|
+
const target = join4(outDir, "web");
|
|
11779
|
+
await mkdir4(target, { recursive: true });
|
|
11780
|
+
const entries = await readdir2(from, { withFileTypes: true });
|
|
11386
11781
|
for (const entry of entries) {
|
|
11387
|
-
const src =
|
|
11388
|
-
const dst =
|
|
11782
|
+
const src = join4(from, entry.name);
|
|
11783
|
+
const dst = join4(target, entry.name);
|
|
11389
11784
|
if (entry.isDirectory()) {
|
|
11390
|
-
await
|
|
11785
|
+
await mkdir4(dst, { recursive: true });
|
|
11391
11786
|
const sub = await copyAssetsToWeb(src, ".", outDir);
|
|
11392
11787
|
files.push(...sub);
|
|
11393
11788
|
continue;
|
|
@@ -11634,11 +12029,11 @@ function renderImportPackageJson(name) {
|
|
|
11634
12029
|
async function importCfProject(cwd, sourceDir, options = {}) {
|
|
11635
12030
|
let tomlText;
|
|
11636
12031
|
try {
|
|
11637
|
-
tomlText = await
|
|
12032
|
+
tomlText = await readFile3(join4(sourceDir, "wrangler.toml"), "utf8");
|
|
11638
12033
|
} catch {
|
|
11639
12034
|
throw new ImportCfError(
|
|
11640
12035
|
"NO_WRANGLER",
|
|
11641
|
-
`\u627E\u4E0D\u5230 ${
|
|
12036
|
+
`\u627E\u4E0D\u5230 ${join4(sourceDir, "wrangler.toml")}\uFF1A\u9700\u5728 Cloudflare \u9879\u76EE\u6839\u6267\u884C\u5BFC\u5165`
|
|
11642
12037
|
);
|
|
11643
12038
|
}
|
|
11644
12039
|
let config;
|
|
@@ -11653,7 +12048,7 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
11653
12048
|
const workerName = slugify(config.name ?? basename(sourceDir), "worker");
|
|
11654
12049
|
const outDir = resolve2(cwd, options.out ?? `imported-${workerName}`);
|
|
11655
12050
|
try {
|
|
11656
|
-
await
|
|
12051
|
+
await stat4(outDir);
|
|
11657
12052
|
throw new ImportCfError("DIR_EXISTS", `\u8F93\u51FA\u76EE\u5F55 ${outDir} \u5DF2\u5B58\u5728\uFF1A\u8BF7\u6362 --out \u6216\u5148\u5220\u9664`);
|
|
11658
12053
|
} catch (error) {
|
|
11659
12054
|
if (error instanceof ImportCfError) throw error;
|
|
@@ -11673,26 +12068,26 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
11673
12068
|
const configText = renderAdepConfig(adepConfig, {
|
|
11674
12069
|
header: "// \u7531 adep import cf \u751F\u6210\uFF08CF-015\uFF09\uFF1A\u7ED1\u5B9A\u58F0\u660E\u4E0E wrangler.toml \u5BF9\u5E94"
|
|
11675
12070
|
});
|
|
11676
|
-
await
|
|
11677
|
-
await
|
|
12071
|
+
await mkdir4(outDir, { recursive: true });
|
|
12072
|
+
await writeFile3(join4(outDir, "adep.config.ts"), configText, "utf8");
|
|
11678
12073
|
files.push("adep.config.ts");
|
|
11679
|
-
await
|
|
12074
|
+
await writeFile3(join4(outDir, "package.json"), renderImportPackageJson(workerName), "utf8");
|
|
11680
12075
|
files.push("package.json");
|
|
11681
12076
|
let mainCopied = false;
|
|
11682
12077
|
if (config.main !== void 0) {
|
|
11683
12078
|
const mainAbs = resolve2(sourceDir, config.main);
|
|
11684
12079
|
let mainStat;
|
|
11685
12080
|
try {
|
|
11686
|
-
mainStat = await
|
|
12081
|
+
mainStat = await stat4(mainAbs);
|
|
11687
12082
|
} catch {
|
|
11688
12083
|
throw new ImportCfError("MAIN_MISSING", `main \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${config.main}`);
|
|
11689
12084
|
}
|
|
11690
12085
|
if (!mainStat.isFile()) {
|
|
11691
12086
|
throw new ImportCfError("MAIN_NOT_FILE", `main \u4E0D\u662F\u6587\u4EF6\uFF1A${config.main}`);
|
|
11692
12087
|
}
|
|
11693
|
-
const fnDir =
|
|
11694
|
-
await
|
|
11695
|
-
await copyFile(mainAbs,
|
|
12088
|
+
const fnDir = join4(outDir, "functions", workerName);
|
|
12089
|
+
await mkdir4(fnDir, { recursive: true });
|
|
12090
|
+
await copyFile(mainAbs, join4(fnDir, "worker.ts"));
|
|
11696
12091
|
files.push(`functions/${workerName}/worker.ts`);
|
|
11697
12092
|
mainCopied = true;
|
|
11698
12093
|
const mainDir = dirname4(mainAbs);
|
|
@@ -11706,7 +12101,7 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
11706
12101
|
if (copied.length > 0) {
|
|
11707
12102
|
warnings.push(`\u5DF2\u590D\u5236\u540C\u76EE\u5F55\u4F9D\u8D56\u6A21\u5757 ${copied.length} \u4E2A\uFF08\u4FDD\u6301\u76F8\u5BF9 import\uFF09`);
|
|
11708
12103
|
}
|
|
11709
|
-
await
|
|
12104
|
+
await writeFile3(join4(fnDir, "index.ts"), renderFunctionEntry("worker", cfBindings), "utf8");
|
|
11710
12105
|
files.push(`functions/${workerName}/index.ts`);
|
|
11711
12106
|
}
|
|
11712
12107
|
let dosMigrated = 0;
|
|
@@ -11721,20 +12116,20 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
11721
12116
|
);
|
|
11722
12117
|
}
|
|
11723
12118
|
if (doBindings.length > 0) {
|
|
11724
|
-
const fnDir =
|
|
11725
|
-
const workerPath =
|
|
11726
|
-
const workerText = await
|
|
12119
|
+
const fnDir = join4(outDir, "functions", workerName);
|
|
12120
|
+
const workerPath = join4(fnDir, "worker.ts");
|
|
12121
|
+
const workerText = await readFile3(workerPath, "utf8");
|
|
11727
12122
|
const { text: stripped, removed } = stripDurableObjectClasses(
|
|
11728
12123
|
workerText,
|
|
11729
12124
|
doBindings.map((b) => b.className)
|
|
11730
12125
|
);
|
|
11731
|
-
await
|
|
12126
|
+
await writeFile3(workerPath, stripped, "utf8");
|
|
11732
12127
|
if (removed.length > 0) {
|
|
11733
|
-
await
|
|
12128
|
+
await mkdir4(join4(fnDir, "durable-objects"), { recursive: true });
|
|
11734
12129
|
await Promise.all(
|
|
11735
12130
|
removed.map(async (r) => {
|
|
11736
|
-
await
|
|
11737
|
-
|
|
12131
|
+
await writeFile3(
|
|
12132
|
+
join4(fnDir, "durable-objects", `${r.className}.ts`),
|
|
11738
12133
|
`${r.source}
|
|
11739
12134
|
`,
|
|
11740
12135
|
"utf8"
|
|
@@ -11744,8 +12139,8 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
11744
12139
|
);
|
|
11745
12140
|
}
|
|
11746
12141
|
if (removed.length > 0) {
|
|
11747
|
-
await
|
|
11748
|
-
|
|
12142
|
+
await writeFile3(
|
|
12143
|
+
join4(fnDir, "state-objects.ts"),
|
|
11749
12144
|
renderStateObjectDeclaration(doBindings, removed),
|
|
11750
12145
|
"utf8"
|
|
11751
12146
|
);
|
|
@@ -11790,7 +12185,7 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
11790
12185
|
unsupported,
|
|
11791
12186
|
warnings
|
|
11792
12187
|
});
|
|
11793
|
-
await
|
|
12188
|
+
await writeFile3(join4(outDir, "MIGRATION.md"), migration, "utf8");
|
|
11794
12189
|
files.push("MIGRATION.md");
|
|
11795
12190
|
if (!mainCopied) {
|
|
11796
12191
|
warnings.push("wrangler.toml \u672A\u58F0\u660E main\uFF1A\u672A\u751F\u6210\u51FD\u6570\uFF0C\u4EC5\u751F\u6210\u914D\u7F6E\u4E0E\u62A5\u544A");
|
|
@@ -11857,7 +12252,13 @@ function registerDevServers(program2, ctx) {
|
|
|
11857
12252
|
"\u70ED\u91CD\u8F7D\uFF1A\u76D1\u542C functions/ \u4E0E .env* \u53D8\u66F4\u81EA\u52A8\u751F\u6548\uFF0C\u51FD\u6570 console \u8F93\u51FA\u76F4\u8FBE\u7EC8\u7AEF\uFF08\u5F00\u53D1\u6001\u8C03\u8BD5\u7528\uFF09"
|
|
11858
12253
|
).option(
|
|
11859
12254
|
"--schema <file>",
|
|
11860
|
-
"\u6570\u636E\u5E93\u7ED3\u6784\u6587\u4EF6\uFF1A\u542F\u52A8\u65F6\u5BF9\u672C\u5730\
|
|
12255
|
+
"\u6570\u636E\u5E93\u7ED3\u6784\u6587\u4EF6\uFF1A\u542F\u52A8\u65F6\u5BF9\u672C\u5730\u5E93\u9010\u6761\u5E94\u7528\uFF08\u5EFA\u8868\u8BED\u53E5\u5EFA\u8BAE IF NOT EXISTS\uFF0C\u5E42\u7B49\u53EF\u91CD\u590D\u542F\u52A8\uFF09"
|
|
12256
|
+
).option(
|
|
12257
|
+
"--db <mode>",
|
|
12258
|
+
"\u6570\u636E\u5E93\u6A21\u5F0F\uFF1Asim\uFF08\u7F3A\u7701\uFF0C\u5185\u7F6E\u6A21\u62DF\u5F15\u64CE + .adep/sim/db.json\uFF09| sqlite\uFF08\u771F\u5B9E SQLite \u5E93\u6587\u4EF6\uFF0C\u9700 Bun \u6216 Node \u2265 22.5\uFF09"
|
|
12259
|
+
).option(
|
|
12260
|
+
"--db-file <path>",
|
|
12261
|
+
"sqlite \u6A21\u5F0F\u7684\u5E93\u6587\u4EF6\uFF08\u7F3A\u7701\u53D6 ADEP_SERVE_DB_FILE\uFF0C\u518D\u7F3A\u7701 .adep/data/project.sqlite\uFF09"
|
|
11861
12262
|
).option(
|
|
11862
12263
|
"--spa",
|
|
11863
12264
|
"SPA \u56DE\u9000\uFF1A\u9759\u6001\u8D44\u6E90\u672A\u547D\u4E2D\u65F6\u56DE\u9000 index.html\uFF08\u524D\u7AEF\u8DEF\u7531\u76F4\u8BBF /profile \u7B49\u9875\u9762\u9700\u8981\uFF09"
|
|
@@ -11873,6 +12274,8 @@ function registerDevServers(program2, ctx) {
|
|
|
11873
12274
|
...flags.static === void 0 ? {} : { staticDir: flags.static },
|
|
11874
12275
|
...flags.watch === void 0 ? {} : { watch: true },
|
|
11875
12276
|
...flags.schema === void 0 ? {} : { schemaFile: flags.schema },
|
|
12277
|
+
...flags.db === void 0 ? {} : { db: flags.db },
|
|
12278
|
+
...flags.dbFile === void 0 ? {} : { dbFile: flags.dbFile },
|
|
11876
12279
|
...flags.spa === void 0 ? {} : { spaFallback: true }
|
|
11877
12280
|
});
|
|
11878
12281
|
await new Promise(() => void 0);
|
|
@@ -11885,10 +12288,10 @@ function registerDevServers(program2, ctx) {
|
|
|
11885
12288
|
init_auth();
|
|
11886
12289
|
init_client();
|
|
11887
12290
|
init_deploy();
|
|
11888
|
-
import { stat as
|
|
11889
|
-
import { join as
|
|
12291
|
+
import { stat as stat9 } from "node:fs/promises";
|
|
12292
|
+
import { join as join17, resolve as resolve10 } from "node:path";
|
|
11890
12293
|
async function resolveProjectId2(client, cwd, slug) {
|
|
11891
|
-
const resolvedSlug = await resolveSlug(
|
|
12294
|
+
const resolvedSlug = await resolveSlug(resolve10(cwd), slug);
|
|
11892
12295
|
const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
11893
12296
|
const match = listed.projects.find((project2) => project2.slug === resolvedSlug);
|
|
11894
12297
|
if (match === void 0) {
|
|
@@ -11952,8 +12355,8 @@ async function runPublish(paths, io, cwd, flags) {
|
|
|
11952
12355
|
});
|
|
11953
12356
|
}
|
|
11954
12357
|
if (wantFrontend) {
|
|
11955
|
-
const webDir =
|
|
11956
|
-
const webStat = await
|
|
12358
|
+
const webDir = join17(cwd, "web");
|
|
12359
|
+
const webStat = await stat9(webDir).catch(() => null);
|
|
11957
12360
|
if (webStat !== null && webStat.isDirectory()) {
|
|
11958
12361
|
const { frontendSync: frontendSync2 } = await Promise.resolve().then(() => (init_frontend(), frontend_exports));
|
|
11959
12362
|
await frontendSync2(paths, {
|
|
@@ -12699,6 +13102,7 @@ function buildProgram(options = {}) {
|
|
|
12699
13102
|
const jsonMode = () => program2.opts()["json"] === true;
|
|
12700
13103
|
const ctx = createCliContext({ output, paths, cwd, json: jsonMode });
|
|
12701
13104
|
registerInit(program2, ctx);
|
|
13105
|
+
registerTemplates(program2, ctx);
|
|
12702
13106
|
registerImport(program2, ctx);
|
|
12703
13107
|
registerDevServers(program2, ctx);
|
|
12704
13108
|
registerPublish(program2, ctx);
|