@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/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 join4 } from "node:path";
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
- join4(baseDir, "worker-entry.js"),
715
- join4(baseDir, "worker-entry.ts"),
716
- join4(baseDir, "domains/functions/runtime/worker-entry.js"),
717
- join4(baseDir, "domains/functions/runtime/worker-entry.ts")
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
- join4(current, "packages/runtime/src/functions/runtime/worker-entry.js"),
723
- join4(current, "packages/runtime/src/functions/runtime/worker-entry.ts")
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((resolve13, reject) => {
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
- resolve13({ body: message.body, logs });
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 mkdir4, readFile as readFile3, readdir as readdir2, rm as rm2, stat as stat4, unlink, writeFile as writeFile3 } from "node:fs/promises";
2842
- import { dirname as dirname6, join as join5 } from "node:path";
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) => join5(options.dir, projectId);
2846
- const objectPath = (projectId, path) => join5(bucketDir(projectId), path);
2847
- const metaPath = (projectId, path) => join5(dirname6(objectPath(projectId, path)), `${path.split("/").pop() ?? ""}${META_SUFFIX}`);
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 readFile3(metaPath(projectId, path), "utf8");
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 writeFile3(metaPath(projectId, path), JSON.stringify(payload), "utf8");
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 readdir2(dir, { withFileTypes: true });
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 = join5(dir, entry.name);
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 stat4(full);
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 stat4(objectPath(projectId, path))).size;
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 mkdir4(dirname6(dest), { recursive: true });
2918
- await writeFile3(dest, data);
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 readFile3(objectPath(projectId, path));
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 stat4(objectPath(projectId, path));
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 readdir2(dir, { withFileTypes: true });
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 = join5(dir, entry.name);
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 readFile3(full + META_SUFFIX, "utf8")
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 join6 } from "node:path";
3046
+ import { join as join7 } from "node:path";
3047
3047
  function createSimStorageCapability(options) {
3048
- const dir = join6(options.cwd, ".adep", "sim", "storage");
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 mkdir5, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
3222
- import { dirname as dirname7, join as join7 } from "node:path";
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 join7(cwd, ".adep", "sim");
3224
+ return join8(cwd, ".adep", "sim");
3225
3225
  }
3226
3226
  function jsonStorage(cwd) {
3227
- const file = join7(simDir(cwd), "db.json");
3227
+ const file = join8(simDir(cwd), "db.json");
3228
3228
  return {
3229
3229
  async load() {
3230
3230
  try {
3231
- const raw = await readFile4(file, "utf8");
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 mkdir5(dirname7(file), { recursive: true });
3239
- await writeFile4(file, JSON.stringify(tables), "utf8");
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 readFile5 } from "node:fs/promises";
3279
- import { join as join8 } from "node:path";
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 readFile5(join8(cwd, ".env"), "utf8").catch(() => "");
3295
- const envLocal = await readFile5(join8(cwd, ".env.local"), "utf8").catch(() => "");
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 stat5, readFile as readFile6 } from "node:fs/promises";
3439
- import { join as join9 } from "node:path";
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 = join9(cwd, "adep.config.ts");
3442
+ const configPath = join10(cwd, "adep.config.ts");
3442
3443
  try {
3443
- await stat5(configPath);
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 readFile6(configPath, "utf8");
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((resolve13, reject) => {
4330
+ const call = (method, args) => new Promise((resolve15, reject) => {
4330
4331
  const id = nextId();
4331
- pending.set(id, { resolve: resolve13, reject });
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 join10 } from "node:path";
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((resolve13, reject) => {
4416
- pending.set(id, { resolve: resolve13, reject });
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(join10(deps.dir, "__deps__.js"));
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 readdir3, readFile as readFile7 } from "node:fs/promises";
4644
- import { join as join11 } from "node:path";
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 readdir3(sub, { withFileTypes: true });
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 = join11(sub, entry.name);
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 readFile7(full, "utf8");
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 mkdir6, readFile as readFile8, writeFile as writeFile5 } from "node:fs/promises";
4778
- import { basename as basename2, join as join12, resolve as resolve4 } from "node:path";
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 = join12(cwd, ".gitignore");
4823
- const existing = await readFile8(gitignorePath, "utf8").catch(() => "");
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 writeFile5(gitignorePath, `${existing.replace(/\n+$/, "")}
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 = join12(cwd, config.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 mkdir6(functionsDir, { recursive: true });
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
- readFile8(join12(cwd, ".env.local"), "utf8").catch(() => "")
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 readFile8(join12(cwd, ".env.local"), "utf8").catch(() => "");
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 readFile9 } from "node:fs/promises";
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 readFile9(resolve5(options.file), "utf8");
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 mkdir7, readFile as readFile10, stat as stat6 } from "node:fs/promises";
5468
- import { extname, join as join13, relative as relative2, resolve as resolve6 } from "node:path";
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 = resolve6(options.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 = resolve6(
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 = join13(cwd, config.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 stat6(staticDir);
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 readFile10(join13(cwd, ".env.local"), "utf8").catch(() => "");
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 = resolve6(cwd, options.schemaFile);
5520
- const schemaSource = await readFile10(schemaPath, "utf8").catch(
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.engine.run(statement);
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
- } else {
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
- readFile10(join13(cwd, ".env.local"), "utf8").catch(() => "")
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 mkdir7(functionsDir, { recursive: true }).catch(() => void 0);
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 = join13(staticDir, safePath);
5614
- const resolvedPath = safePath === "" || safePath === "/" ? join13(filePath, "index.html") : filePath;
5765
+ const filePath = join14(staticDir, safePath);
5766
+ const resolvedPath = safePath === "" || safePath === "/" ? join14(filePath, "index.html") : filePath;
5615
5767
  try {
5616
- const fileStat = await stat6(resolvedPath);
5768
+ const fileStat = await stat7(resolvedPath);
5617
5769
  if (fileStat.isDirectory()) {
5618
- const indexPath = join13(resolvedPath, "index.html");
5770
+ const indexPath = join14(resolvedPath, "index.html");
5619
5771
  try {
5620
- const indexStat = await stat6(indexPath);
5772
+ const indexStat = await stat7(indexPath);
5621
5773
  if (indexStat.isFile()) {
5622
- const content2 = await readFile10(indexPath);
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 readFile10(resolvedPath);
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 readFile10(join13(staticDir, "index.html"));
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(`[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`);
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 readdir4, readFile as readFile11 } from "node:fs/promises";
5835
- import { join as join14, resolve as resolve7, basename as basename3, relative as relative3, sep } from "node:path";
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 readdir4(functionsDir, { withFileTypes: true });
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 readFile11(join14(functionsDir, `${name}.ts`), "utf8") };
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(join14(functionsDir, name));
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 readdir4(dir, { withFileTypes: true });
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(join14(dir, entry.name), rel);
6045
+ await walk(join15(dir, entry.name), rel);
5884
6046
  continue;
5885
6047
  }
5886
6048
  if (!isRuntimeSource2(entry.name)) continue;
5887
- files[rel] = await readFile11(join14(dir, entry.name), "utf8");
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 = join14(functionsDir, "_shared");
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 readdir4(dir, { withFileTypes: true });
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(join14(dir, entry.name));
6071
+ await walk(join15(dir, entry.name));
5910
6072
  continue;
5911
6073
  }
5912
6074
  if (!isRuntimeSource2(entry.name)) continue;
5913
- const full = join14(dir, entry.name);
6075
+ const full = join15(dir, entry.name);
5914
6076
  const rel = relative3(sharedDir, full).split(sep).join("/");
5915
- files[`${SHARED_SOURCE_ROOT3}${rel}`] = await readFile11(full, "utf8");
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 = resolve7(options.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 ? join14(cwd, config.functionsDir) : resolve7(cwd, options.functionsDir);
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 readdir5, readFile as readFile12, stat as stat7 } from "node:fs/promises";
6061
- import { join as join15, relative as relative4, sep as sep2 } from "node:path";
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 readdir5(dir, { withFileTypes: true });
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, join15(dir, entry.name));
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 = join15(dir, entry.name);
6248
+ const full = join16(dir, entry.name);
6087
6249
  const rel = relative4(root, full).split(sep2).join("/");
6088
- const info = await stat7(full);
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 readFile12(full, "utf8");
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 ?? join15(options.cwd, "web");
6110
- const rootStat = await stat7(webDir).catch(() => null);
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 writeFile6 } from "node:fs/promises";
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 writeFile6(outputPath, bytes);
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 mkdir8, readFile as readFile13, rm as rm3, stat as stat9, writeFile as writeFile7 } from "node:fs/promises";
6324
- import { dirname as dirname8, join as join17 } from "node:path";
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) => readFile13(path),
6328
- writeFile: (path, content) => writeFile7(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 stat9(path);
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 mkdir8(path, { recursive: true });
6504
+ await mkdir10(path, { recursive: true });
6343
6505
  },
6344
6506
  unzip: async (zipPath, targetDir) => {
6345
- const entries = zipRead(await readFile13(zipPath));
6507
+ const entries = zipRead(await readFile14(zipPath));
6346
6508
  for (const [name, data] of entries) {
6347
- const dest = join17(targetDir, name);
6348
- await mkdir8(dirname8(dest), { recursive: true });
6349
- await writeFile7(dest, data);
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((resolve13) => setTimeout(resolve13, ms));
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 mkdir9, readFile as readFile14, stat as stat10, writeFile as writeFile8 } from "node:fs/promises";
6866
- import { basename as basename4, dirname as dirname9, extname as extname2, join as join18, resolve as resolve9 } from "node:path";
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(resolve9(options.cwd), options.slug);
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 = resolve9(options.file);
6903
- const info = await stat10(local).catch(() => null);
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 readFile14(local);
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 = resolve9(options.output ?? join18(resolve9(options.cwd), basename4(options.path)));
6950
- await mkdir9(dirname9(output), { recursive: true });
6951
- await writeFile8(output, bytes);
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 stat11 } from "node:fs/promises";
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 stat11(file);
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 resolve10 } from "node:path";
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(resolve10(options.cwd), options.slug);
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 resolve11 } from "node:path";
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(resolve11(options.cwd), options.slug);
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 readdir6, readFile as readFile15, stat as stat12 } from "node:fs/promises";
7437
- import { dirname as dirname10, join as join19, relative as relative5, resolve as resolve12, sep as sep3 } from "node:path";
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(resolve12(options.cwd), options.slug);
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 = resolve12(dir);
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 readdir6(sub, { withFileTypes: true });
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 = join19(sub, entry.name);
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${resolve12(options.dir)}`);
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 stat12(full);
7487
- const bytes = await readFile15(full);
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 = resolve12(options.output ?? resolve12(options.cwd));
7515
- const { mkdir: mkdir10, writeFile: writeFile9 } = await import("node:fs/promises");
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 = join19(outputDir, ...rel.split("/"));
7526
- await mkdir10(dirname10(target), { recursive: true });
7527
- await writeFile9(target, bytes);
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
- const vars = { name, template: code };
10818
- const dirFiles = renderTemplateFiles(files, vars, manifest);
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 server = flags.server ?? resolveServer();
11054
- const templates = await fetchTemplates(server);
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 result = await initProject(ctx.cwd, name, template);
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 mkdir3, readFile as readFile2, readdir, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
11086
- import { basename, dirname as dirname4, join as join3, relative, resolve as resolve2 } from "node:path";
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 readdir(sourceDir, { withFileTypes: true });
11735
+ const entries = await readdir2(sourceDir, { withFileTypes: true });
11341
11736
  for (const entry of entries) {
11342
- const from = join3(sourceDir, entry.name);
11343
- const to = join3(targetDir, entry.name);
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 mkdir3(to, { recursive: true });
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, join3(targetDir, "_index.ts"));
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 readFile2(join3(sourceDir, ".dev.vars"), "utf8");
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 = join3(outDir, "web");
11384
- await mkdir3(target, { recursive: true });
11385
- const entries = await readdir(from, { withFileTypes: true });
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 = join3(from, entry.name);
11388
- const dst = join3(target, entry.name);
11782
+ const src = join4(from, entry.name);
11783
+ const dst = join4(target, entry.name);
11389
11784
  if (entry.isDirectory()) {
11390
- await mkdir3(dst, { recursive: true });
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 readFile2(join3(sourceDir, "wrangler.toml"), "utf8");
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 ${join3(sourceDir, "wrangler.toml")}\uFF1A\u9700\u5728 Cloudflare \u9879\u76EE\u6839\u6267\u884C\u5BFC\u5165`
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 stat3(outDir);
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 mkdir3(outDir, { recursive: true });
11677
- await writeFile2(join3(outDir, "adep.config.ts"), configText, "utf8");
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 writeFile2(join3(outDir, "package.json"), renderImportPackageJson(workerName), "utf8");
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 stat3(mainAbs);
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 = join3(outDir, "functions", workerName);
11694
- await mkdir3(fnDir, { recursive: true });
11695
- await copyFile(mainAbs, join3(fnDir, "worker.ts"));
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 writeFile2(join3(fnDir, "index.ts"), renderFunctionEntry("worker", cfBindings), "utf8");
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 = join3(outDir, "functions", workerName);
11725
- const workerPath = join3(fnDir, "worker.ts");
11726
- const workerText = await readFile2(workerPath, "utf8");
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 writeFile2(workerPath, stripped, "utf8");
12126
+ await writeFile3(workerPath, stripped, "utf8");
11732
12127
  if (removed.length > 0) {
11733
- await mkdir3(join3(fnDir, "durable-objects"), { recursive: true });
12128
+ await mkdir4(join4(fnDir, "durable-objects"), { recursive: true });
11734
12129
  await Promise.all(
11735
12130
  removed.map(async (r) => {
11736
- await writeFile2(
11737
- join3(fnDir, "durable-objects", `${r.className}.ts`),
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 writeFile2(
11748
- join3(fnDir, "state-objects.ts"),
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 writeFile2(join3(outDir, "MIGRATION.md"), migration, "utf8");
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\u6A21\u62DF\u5E93\u9010\u6761\u5E94\u7528\uFF08\u5EFA\u8868\u8BED\u53E5\u5EFA\u8BAE IF NOT EXISTS\uFF0C\u5E42\u7B49\u53EF\u91CD\u590D\u542F\u52A8\uFF09"
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 stat8 } from "node:fs/promises";
11889
- import { join as join16, resolve as resolve8 } from "node:path";
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(resolve8(cwd), slug);
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 = join16(cwd, "web");
11956
- const webStat = await stat8(webDir).catch(() => null);
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);