@adep/cli 0.1.11 → 0.1.13

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
@@ -54,7 +54,8 @@ async function loadCredentials(paths) {
54
54
  return {
55
55
  server: parsed["server"],
56
56
  email: parsed["email"],
57
- encodedToken: parsed["encodedToken"]
57
+ encodedToken: parsed["encodedToken"],
58
+ ...typeof parsed["cookieName"] === "string" ? { cookieName: parsed["cookieName"] } : {}
58
59
  };
59
60
  } catch {
60
61
  return null;
@@ -69,6 +70,10 @@ function encodeToken(token) {
69
70
  function decodeToken(encoded) {
70
71
  return Buffer.from(encoded, "base64").toString("utf8");
71
72
  }
73
+ function sessionCookieHeader(credentials) {
74
+ const name = credentials.cookieName ?? (credentials.server.startsWith("https://") ? "__Secure-better-auth.session_token" : "better-auth.session_token");
75
+ return `${name}=${decodeToken(credentials.encodedToken)}`;
76
+ }
72
77
  var init_credentials = __esm({
73
78
  "packages/cli/src/credentials.ts"() {
74
79
  "use strict";
@@ -149,7 +154,7 @@ var init_net = __esm({
149
154
  // packages/cli/src/auth.ts
150
155
  function sessionCookieOf(setCookie) {
151
156
  const line = setCookie.find(
152
- (entry) => entry.startsWith("better-auth.session_token=") && !/max-age=0/i.test(entry)
157
+ (entry) => !/max-age=0/i.test(entry) && /^(?:__Secure-)?better-auth\.session_token=/.test(entry)
153
158
  );
154
159
  if (line === void 0) {
155
160
  throw new CliError("LOGIN_FAILED", "\u767B\u5F55\u6210\u529F\u4F46\u672A\u8FD4\u56DE\u4F1A\u8BDD token\uFF0C\u8BF7\u68C0\u67E5\u5E73\u53F0\u7248\u672C");
@@ -176,11 +181,14 @@ async function login(paths, input) {
176
181
  throw new CliError("LOGIN_FAILED", "\u767B\u5F55\u5931\u8D25\uFF1A\u90AE\u7BB1\u6216\u5BC6\u7801\u4E0D\u6B63\u786E\uFF08\u6216\u8BE5\u8D26\u53F7\u672A\u6CE8\u518C\uFF09");
177
182
  }
178
183
  const cookie = sessionCookieOf(response.headers.getSetCookie());
179
- const token = cookie.slice(cookie.indexOf("=") + 1);
184
+ const eq = cookie.indexOf("=");
185
+ const cookieName = cookie.slice(0, eq);
186
+ const token = cookie.slice(eq + 1);
180
187
  await saveCredentials(paths, {
181
188
  server,
182
189
  email: input.email,
183
- encodedToken: encodeToken(token)
190
+ encodedToken: encodeToken(token),
191
+ cookieName
184
192
  });
185
193
  return { email: input.email };
186
194
  }
@@ -191,7 +199,7 @@ async function whoami(paths) {
191
199
  throw new CliError("NOT_LOGGED_IN", "\u672A\u767B\u5F55\uFF1A\u8BF7\u5148\u6267\u884C adep login");
192
200
  }
193
201
  const response = await fetch(`${credentials.server}/api/auth/get-session`, {
194
- headers: { cookie: `better-auth.session_token=${decodeToken(credentials.encodedToken)}` }
202
+ headers: { cookie: sessionCookieHeader(credentials) }
195
203
  });
196
204
  if (response.status !== 200) {
197
205
  throw new CliError("SESSION_EXPIRED", "\u4F1A\u8BDD\u5DF2\u5931\u6548\uFF1A\u8BF7\u91CD\u65B0\u6267\u884C adep login");
@@ -209,7 +217,7 @@ async function logout(paths) {
209
217
  try {
210
218
  await fetch(`${credentials.server}/api/auth/sign-out`, {
211
219
  method: "POST",
212
- headers: { cookie: `better-auth.session_token=${decodeToken(credentials.encodedToken)}` }
220
+ headers: { cookie: sessionCookieHeader(credentials) }
213
221
  });
214
222
  } catch {
215
223
  }
@@ -707,20 +715,20 @@ var init_resolve = __esm({
707
715
  // packages/runtime/src/functions/runtime/worker-executor.ts
708
716
  import { readFileSync as readFileSync2 } from "node:fs";
709
717
  import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
710
- import { dirname as dirname5, join as join4 } from "node:path";
718
+ import { dirname as dirname5, join as join5 } from "node:path";
711
719
  import { Worker } from "node:worker_threads";
712
720
  function resolveWorkerEntry(baseDir = fileURLToPath2(new URL(".", import.meta.url))) {
713
721
  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")
722
+ join5(baseDir, "worker-entry.js"),
723
+ join5(baseDir, "worker-entry.ts"),
724
+ join5(baseDir, "domains/functions/runtime/worker-entry.js"),
725
+ join5(baseDir, "domains/functions/runtime/worker-entry.ts")
718
726
  ];
719
727
  let current = baseDir;
720
728
  for (let depth = 0; depth < 8; depth += 1) {
721
729
  candidates.push(
722
- join4(current, "packages/runtime/src/functions/runtime/worker-entry.js"),
723
- join4(current, "packages/runtime/src/functions/runtime/worker-entry.ts")
730
+ join5(current, "packages/runtime/src/functions/runtime/worker-entry.js"),
731
+ join5(current, "packages/runtime/src/functions/runtime/worker-entry.ts")
724
732
  );
725
733
  const parent = dirname5(current);
726
734
  if (parent === current) break;
@@ -764,7 +772,7 @@ var init_worker_executor = __esm({
764
772
  const entry = input.entry ?? "index.ts";
765
773
  const deps = this.depsConfig === void 0 ? void 0 : resolveExecutionDeps(this.depsConfig, input.project.id, input.files["package.json"]);
766
774
  const logs = [];
767
- return new Promise((resolve13, reject) => {
775
+ return new Promise((resolve15, reject) => {
768
776
  let worker;
769
777
  try {
770
778
  worker = new Worker(resolveWorkerEntry(), {
@@ -826,7 +834,7 @@ var init_worker_executor = __esm({
826
834
  if (message.type === "result") {
827
835
  clearTimeout(timer);
828
836
  void worker.terminate();
829
- resolve13({ body: message.body, logs });
837
+ resolve15({ body: message.body, logs });
830
838
  return;
831
839
  }
832
840
  if (message.type === "error") {
@@ -1683,6 +1691,10 @@ function toNumber(raw) {
1683
1691
  const n = Number(t);
1684
1692
  return Number.isNaN(n) ? null : n;
1685
1693
  }
1694
+ function arithmeticOperand(v) {
1695
+ const n = Number(v);
1696
+ return Number.isFinite(n) ? n : 0;
1697
+ }
1686
1698
  function stripQuotes(raw) {
1687
1699
  const t = raw.trim();
1688
1700
  if (/^'.*'$/.test(t)) return t.slice(1, -1);
@@ -1837,10 +1849,6 @@ function resolveSetValue(value, existing, row) {
1837
1849
  return value;
1838
1850
  }
1839
1851
  function evalArithmetic(src, existing, row) {
1840
- const num = (v) => {
1841
- const n2 = Number(v);
1842
- return Number.isFinite(n2) ? n2 : 0;
1843
- };
1844
1852
  let i = 0;
1845
1853
  const n = src.length;
1846
1854
  const skip = () => {
@@ -1885,7 +1893,7 @@ function evalArithmetic(src, existing, row) {
1885
1893
  const id = parseIdent();
1886
1894
  if (id !== null) {
1887
1895
  const v = id.excluded ? row[id.col] : existing[id.col];
1888
- return num(v);
1896
+ return arithmeticOperand(v);
1889
1897
  }
1890
1898
  return 0;
1891
1899
  };
@@ -2035,6 +2043,9 @@ function parseSelectItem(raw) {
2035
2043
  const plain = unqualifyColumn(ident(name));
2036
2044
  return { name: plain, qualified, alias: as === null ? plain : ident(as[1] ?? ""), star: false };
2037
2045
  }
2046
+ function projectValueOf(row, item) {
2047
+ return item.qualified !== "" && row[item.qualified] !== void 0 ? row[item.qualified] : row[item.name];
2048
+ }
2038
2049
  function project(rows, selectRaw) {
2039
2050
  if (/^count\s*\(\s*\*/i.test(selectRaw) || /^count\s*\(\s*1\)/i.test(selectRaw)) {
2040
2051
  const alias = selectRaw.match(/\bAS\s+([A-Za-z_][A-Za-z0-9_]*)/i)?.[1] ?? "n";
@@ -2046,20 +2057,19 @@ function project(rows, selectRaw) {
2046
2057
  }
2047
2058
  if (selectRaw.trim() === "*") return rows;
2048
2059
  const items = selectRaw.split(",").map(parseSelectItem);
2049
- const valueOf = (row, item) => item.qualified !== "" && row[item.qualified] !== void 0 ? row[item.qualified] : row[item.name];
2050
2060
  if (items.some((item) => item.star)) {
2051
2061
  return rows.map((row) => {
2052
2062
  const out = { ...row };
2053
2063
  for (const item of items) {
2054
2064
  if (item.star) continue;
2055
- out[item.alias] = valueOf(row, item);
2065
+ out[item.alias] = projectValueOf(row, item);
2056
2066
  }
2057
2067
  return out;
2058
2068
  });
2059
2069
  }
2060
2070
  return rows.map((row) => {
2061
2071
  const out = {};
2062
- for (const item of items) out[item.alias] = valueOf(row, item);
2072
+ for (const item of items) out[item.alias] = projectValueOf(row, item);
2063
2073
  return out;
2064
2074
  });
2065
2075
  }
@@ -2581,7 +2591,7 @@ var init_driver = __esm({
2581
2591
  function compress(h, block, w) {
2582
2592
  for (let i = 0; i < 16; i += 1) {
2583
2593
  const j = i * 4;
2584
- w[i] = (block[j] ?? 0) << 24 | (block[j + 1] ?? 0) << 16 | (block[j + 2] ?? 0) << 8 | (block[j + 3] ?? 0);
2594
+ w[i] = block[j] << 24 | block[j + 1] << 16 | block[j + 2] << 8 | block[j + 3];
2585
2595
  }
2586
2596
  for (let i = 16; i < 64; i += 1) {
2587
2597
  const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ w[i - 15] >>> 3;
@@ -2838,15 +2848,15 @@ var init_cloud2 = __esm({
2838
2848
  });
2839
2849
 
2840
2850
  // 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";
2851
+ import { mkdir as mkdir5, readFile as readFile4, readdir as readdir3, rm as rm2, stat as stat5, unlink, writeFile as writeFile4 } from "node:fs/promises";
2852
+ import { dirname as dirname6, join as join6 } from "node:path";
2843
2853
  function createLocalStorageDriver(options) {
2844
2854
  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}`);
2855
+ const bucketDir = (projectId) => join6(options.dir, projectId);
2856
+ const objectPath = (projectId, path) => join6(bucketDir(projectId), path);
2857
+ const metaPath = (projectId, path) => join6(dirname6(objectPath(projectId, path)), `${path.split("/").pop() ?? ""}${META_SUFFIX}`);
2848
2858
  const readStoredMeta = async (projectId, path) => {
2849
- const raw = await readFile3(metaPath(projectId, path), "utf8");
2859
+ const raw = await readFile4(metaPath(projectId, path), "utf8");
2850
2860
  return JSON.parse(raw);
2851
2861
  };
2852
2862
  const writeStoredMeta = async (projectId, path, meta) => {
@@ -2856,7 +2866,7 @@ function createLocalStorageDriver(options) {
2856
2866
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2857
2867
  ...meta.contentType === void 0 ? {} : { contentType: meta.contentType }
2858
2868
  };
2859
- await writeFile3(metaPath(projectId, path), JSON.stringify(payload), "utf8");
2869
+ await writeFile4(metaPath(projectId, path), JSON.stringify(payload), "utf8");
2860
2870
  };
2861
2871
  const totalSize = async (projectId) => {
2862
2872
  const root = bucketDir(projectId);
@@ -2864,20 +2874,20 @@ function createLocalStorageDriver(options) {
2864
2874
  const walk = async (dir) => {
2865
2875
  let entries;
2866
2876
  try {
2867
- entries = await readdir2(dir, { withFileTypes: true });
2877
+ entries = await readdir3(dir, { withFileTypes: true });
2868
2878
  } catch {
2869
2879
  return;
2870
2880
  }
2871
2881
  const tasks = [];
2872
2882
  for (const entry of entries) {
2873
- const full = join5(dir, entry.name);
2883
+ const full = join6(dir, entry.name);
2874
2884
  if (entry.isDirectory()) {
2875
2885
  tasks.push(walk(full));
2876
2886
  } else if (entry.isFile() && !entry.name.endsWith(META_SUFFIX)) {
2877
2887
  tasks.push(
2878
2888
  (async () => {
2879
2889
  try {
2880
- const info = await stat4(full);
2890
+ const info = await stat5(full);
2881
2891
  total += info.size;
2882
2892
  } catch {
2883
2893
  }
@@ -2899,7 +2909,7 @@ function createLocalStorageDriver(options) {
2899
2909
  const used = await totalSize(projectId);
2900
2910
  let existingSize = 0;
2901
2911
  try {
2902
- existingSize = (await stat4(objectPath(projectId, path))).size;
2912
+ existingSize = (await stat5(objectPath(projectId, path))).size;
2903
2913
  } catch {
2904
2914
  existingSize = 0;
2905
2915
  }
@@ -2914,8 +2924,8 @@ function createLocalStorageDriver(options) {
2914
2924
  );
2915
2925
  }
2916
2926
  const dest = objectPath(projectId, path);
2917
- await mkdir4(dirname6(dest), { recursive: true });
2918
- await writeFile3(dest, data);
2927
+ await mkdir5(dirname6(dest), { recursive: true });
2928
+ await writeFile4(dest, data);
2919
2929
  await writeStoredMeta(projectId, path, {
2920
2930
  visibility: putOptions.visibility,
2921
2931
  size: data.byteLength,
@@ -2938,7 +2948,7 @@ function createLocalStorageDriver(options) {
2938
2948
  } catch {
2939
2949
  throw new StorageError(404, STORAGE_CODES.notFound, `\u6587\u4EF6 "${path}" \u4E0D\u5B58\u5728`);
2940
2950
  }
2941
- const data = await readFile3(objectPath(projectId, path));
2951
+ const data = await readFile4(objectPath(projectId, path));
2942
2952
  const result = {
2943
2953
  path,
2944
2954
  size: meta.size,
@@ -2969,7 +2979,7 @@ function createLocalStorageDriver(options) {
2969
2979
  assertSafeStoragePath(path);
2970
2980
  let exists = true;
2971
2981
  try {
2972
- await stat4(objectPath(projectId, path));
2982
+ await stat5(objectPath(projectId, path));
2973
2983
  } catch {
2974
2984
  exists = false;
2975
2985
  }
@@ -2986,14 +2996,14 @@ function createLocalStorageDriver(options) {
2986
2996
  const walk = async (dir, relative6) => {
2987
2997
  let entries;
2988
2998
  try {
2989
- entries = await readdir2(dir, { withFileTypes: true });
2999
+ entries = await readdir3(dir, { withFileTypes: true });
2990
3000
  } catch {
2991
3001
  return;
2992
3002
  }
2993
3003
  const tasks = [];
2994
3004
  for (const entry of entries) {
2995
3005
  if (entry.name.endsWith(META_SUFFIX)) continue;
2996
- const full = join5(dir, entry.name);
3006
+ const full = join6(dir, entry.name);
2997
3007
  const rel = relative6 === "" ? entry.name : `${relative6}/${entry.name}`;
2998
3008
  if (entry.isFile()) {
2999
3009
  if (prefix !== void 0 && !rel.startsWith(prefix)) continue;
@@ -3001,7 +3011,7 @@ function createLocalStorageDriver(options) {
3001
3011
  (async () => {
3002
3012
  try {
3003
3013
  const payload = JSON.parse(
3004
- await readFile3(full + META_SUFFIX, "utf8")
3014
+ await readFile4(full + META_SUFFIX, "utf8")
3005
3015
  );
3006
3016
  metas.push({
3007
3017
  path: rel,
@@ -3043,9 +3053,9 @@ var init_local = __esm({
3043
3053
  });
3044
3054
 
3045
3055
  // packages/cli/src/sim/storage.ts
3046
- import { join as join6 } from "node:path";
3056
+ import { join as join7 } from "node:path";
3047
3057
  function createSimStorageCapability(options) {
3048
- const dir = join6(options.cwd, ".adep", "sim", "storage");
3058
+ const dir = join7(options.cwd, ".adep", "sim", "storage");
3049
3059
  const driver = createLocalStorageDriver({ dir });
3050
3060
  const signer = {
3051
3061
  secret: options.secret ?? "adep-sim-secret",
@@ -3218,33 +3228,33 @@ var init_merge = __esm({
3218
3228
  });
3219
3229
 
3220
3230
  // 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";
3231
+ import { mkdir as mkdir6, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
3232
+ import { dirname as dirname7, join as join8 } from "node:path";
3223
3233
  function simDir(cwd) {
3224
- return join7(cwd, ".adep", "sim");
3234
+ return join8(cwd, ".adep", "sim");
3225
3235
  }
3226
3236
  function jsonStorage(cwd) {
3227
- const file = join7(simDir(cwd), "db.json");
3237
+ const file = join8(simDir(cwd), "db.json");
3228
3238
  return {
3229
3239
  async load() {
3230
3240
  try {
3231
- const raw = await readFile4(file, "utf8");
3241
+ const raw = await readFile5(file, "utf8");
3232
3242
  return JSON.parse(raw);
3233
3243
  } catch {
3234
3244
  return null;
3235
3245
  }
3236
3246
  },
3237
3247
  async save(tables) {
3238
- await mkdir5(dirname7(file), { recursive: true });
3239
- await writeFile4(file, JSON.stringify(tables), "utf8");
3248
+ await mkdir6(dirname7(file), { recursive: true });
3249
+ await writeFile5(file, JSON.stringify(tables), "utf8");
3240
3250
  }
3241
3251
  };
3242
3252
  }
3243
3253
  async function createSimRuntime(options) {
3244
- const db = createSimDbCapability({
3254
+ const db = options.driver === void 0 ? createSimDbCapability({
3245
3255
  storage: options.dbStorage ?? jsonStorage(options.cwd),
3246
3256
  ...options.log === void 0 ? {} : { log: options.log }
3247
- });
3257
+ }) : { bundle: createDbCapability(options.driver), driver: options.driver, engine: null };
3248
3258
  const storage = createSimStorageCapability({
3249
3259
  cwd: options.cwd,
3250
3260
  ...options.baseUrl === void 0 ? {} : { baseUrl: options.baseUrl },
@@ -3253,7 +3263,7 @@ async function createSimRuntime(options) {
3253
3263
  const simRealtime = createSimRealtimeCapability();
3254
3264
  const kvBundle = createKvCapability(db.driver);
3255
3265
  const bundle = mergeBundles([db.bundle, storage.bundle, kvBundle, simRealtime.bundle]);
3256
- await db.engine.load();
3266
+ if (db.engine !== null) await db.engine.load();
3257
3267
  return {
3258
3268
  bundle,
3259
3269
  realtime: simRealtime.realtime,
@@ -3266,6 +3276,7 @@ async function createSimRuntime(options) {
3266
3276
  var init_runtime = __esm({
3267
3277
  "packages/cli/src/sim/runtime.ts"() {
3268
3278
  "use strict";
3279
+ init_cloud();
3269
3280
  init_db();
3270
3281
  init_kv();
3271
3282
  init_storage();
@@ -3275,8 +3286,8 @@ var init_runtime = __esm({
3275
3286
  });
3276
3287
 
3277
3288
  // packages/cli/src/sim/env.ts
3278
- import { readFile as readFile5 } from "node:fs/promises";
3279
- import { join as join8 } from "node:path";
3289
+ import { readFile as readFile6 } from "node:fs/promises";
3290
+ import { join as join9 } from "node:path";
3280
3291
  function parseEnv(content) {
3281
3292
  const env = {};
3282
3293
  for (const raw of content.split(/\r?\n/)) {
@@ -3291,8 +3302,8 @@ function parseEnv(content) {
3291
3302
  return env;
3292
3303
  }
3293
3304
  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(() => "");
3305
+ const envRoot = await readFile6(join9(cwd, ".env"), "utf8").catch(() => "");
3306
+ const envLocal = await readFile6(join9(cwd, ".env.local"), "utf8").catch(() => "");
3296
3307
  const merged = { ...parseEnv(envRoot), ...parseEnv(envLocal) };
3297
3308
  for (const secret of config.secrets ?? []) {
3298
3309
  if (merged[secret] !== void 0) continue;
@@ -3435,12 +3446,12 @@ var init_boundary = __esm({
3435
3446
  });
3436
3447
 
3437
3448
  // 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";
3449
+ import { stat as stat6, readFile as readFile7 } from "node:fs/promises";
3450
+ import { join as join10 } from "node:path";
3440
3451
  async function loadAdepConfigModule(cwd) {
3441
- const configPath = join9(cwd, "adep.config.ts");
3452
+ const configPath = join10(cwd, "adep.config.ts");
3442
3453
  try {
3443
- await stat5(configPath);
3454
+ await stat6(configPath);
3444
3455
  } catch {
3445
3456
  return null;
3446
3457
  }
@@ -3452,7 +3463,7 @@ async function loadAdepConfigModule(cwd) {
3452
3463
  rawDefault = mod.default;
3453
3464
  } else {
3454
3465
  const { transform } = await import("esbuild");
3455
- const source = await readFile6(configPath, "utf8");
3466
+ const source = await readFile7(configPath, "utf8");
3456
3467
  const { code } = await transform(source, {
3457
3468
  loader: "ts",
3458
3469
  format: "esm",
@@ -4326,9 +4337,9 @@ function isChainCapability(value) {
4326
4337
  return typeof spec === "object" && spec !== null && Array.isArray(spec.stepMethods) && Array.isArray(spec.terminalMethods);
4327
4338
  }
4328
4339
  function createChainClient(capability, port, pending, nextId, spec) {
4329
- const call = (method, args) => new Promise((resolve13, reject) => {
4340
+ const call = (method, args) => new Promise((resolve15, reject) => {
4330
4341
  const id = nextId();
4331
- pending.set(id, { resolve: resolve13, reject });
4342
+ pending.set(id, { resolve: resolve15, reject });
4332
4343
  port.postMessage({ type: "rpc", id, capability, method, args });
4333
4344
  });
4334
4345
  const makeChainable = (rootArgs, steps, txId) => new Proxy(
@@ -4400,7 +4411,7 @@ var init_chain = __esm({
4400
4411
  // packages/runtime/src/functions/runtime/worker-entry.ts
4401
4412
  import { parentPort, workerData } from "node:worker_threads";
4402
4413
  import { createRequire } from "node:module";
4403
- import { join as join10 } from "node:path";
4414
+ import { join as join11 } from "node:path";
4404
4415
  function isRpcCapability(value) {
4405
4416
  return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
4406
4417
  }
@@ -4412,8 +4423,8 @@ function createRpcClient(capability, port, pending, nextId) {
4412
4423
  if (typeof method !== "string") return void 0;
4413
4424
  return (...args) => {
4414
4425
  const id = nextId();
4415
- return new Promise((resolve13, reject) => {
4416
- pending.set(id, { resolve: resolve13, reject });
4426
+ return new Promise((resolve15, reject) => {
4427
+ pending.set(id, { resolve: resolve15, reject });
4417
4428
  port.postMessage({ type: "rpc", id, capability, method, args });
4418
4429
  });
4419
4430
  };
@@ -4449,7 +4460,7 @@ function errorMessageWithLocation(error, files) {
4449
4460
  }
4450
4461
  function createBareResolver(deps) {
4451
4462
  const platformRequire = createRequire(import.meta.url);
4452
- const depsRequire = deps.dir === null ? null : createRequire(join10(deps.dir, "__deps__.js"));
4463
+ const depsRequire = deps.dir === null ? null : createRequire(join11(deps.dir, "__deps__.js"));
4453
4464
  return (request) => {
4454
4465
  if (deps.builtin.includes(request)) return platformRequire(request);
4455
4466
  const root = splitBareSpecifier(request);
@@ -4640,8 +4651,8 @@ var init_shared_source = __esm({
4640
4651
  });
4641
4652
 
4642
4653
  // 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";
4654
+ import { readdir as readdir4, readFile as readFile8 } from "node:fs/promises";
4655
+ import { join as join12 } from "node:path";
4645
4656
  function bearerUserResolverFromEnv() {
4646
4657
  const raw = process.env.ADEP_AUTH_ISSUER;
4647
4658
  if (raw === void 0 || raw.trim() === "") return void 0;
@@ -4676,17 +4687,17 @@ async function collectFunctions(dir) {
4676
4687
  const walk = async (sub, prefix) => {
4677
4688
  let entries;
4678
4689
  try {
4679
- entries = await readdir3(sub, { withFileTypes: true });
4690
+ entries = await readdir4(sub, { withFileTypes: true });
4680
4691
  } catch {
4681
4692
  return;
4682
4693
  }
4683
4694
  for (const entry of entries) {
4684
4695
  const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
4685
- const full = join11(sub, entry.name);
4696
+ const full = join12(sub, entry.name);
4686
4697
  if (entry.isDirectory()) {
4687
4698
  await walk(full, rel);
4688
4699
  } else if (entry.isFile() && isRuntimeSource(entry.name)) {
4689
- files[rel] = await readFile7(full, "utf8");
4700
+ files[rel] = await readFile8(full, "utf8");
4690
4701
  }
4691
4702
  }
4692
4703
  };
@@ -4774,8 +4785,8 @@ __export(dev_exports, {
4774
4785
  });
4775
4786
  import { createServer } from "node:http";
4776
4787
  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";
4788
+ import { mkdir as mkdir7, readFile as readFile9, writeFile as writeFile6 } from "node:fs/promises";
4789
+ import { basename as basename2, join as join13, resolve as resolve4 } from "node:path";
4779
4790
  async function loadConfig(cwd) {
4780
4791
  const name = basename2(resolve4(cwd));
4781
4792
  const config = await loadAdepConfigModule(cwd);
@@ -4819,10 +4830,10 @@ function printBoundaries(log) {
4819
4830
  }
4820
4831
  }
4821
4832
  async function ensureGitignore(cwd) {
4822
- const gitignorePath = join12(cwd, ".gitignore");
4823
- const existing = await readFile8(gitignorePath, "utf8").catch(() => "");
4833
+ const gitignorePath = join13(cwd, ".gitignore");
4834
+ const existing = await readFile9(gitignorePath, "utf8").catch(() => "");
4824
4835
  if (existing.split(/\r?\n/).includes(".adep/")) return;
4825
- await writeFile5(gitignorePath, `${existing.replace(/\n+$/, "")}
4836
+ await writeFile6(gitignorePath, `${existing.replace(/\n+$/, "")}
4826
4837
  .adep/
4827
4838
  `, "utf8");
4828
4839
  }
@@ -4834,13 +4845,13 @@ async function startDevServer(options) {
4834
4845
  if (options.prefix !== void 0) {
4835
4846
  config.functionsPrefix = options.prefix.replace(/^\/+|\/+$/g, "");
4836
4847
  }
4837
- const functionsDir = join12(cwd, config.functionsDir);
4848
+ const functionsDir = join13(cwd, config.functionsDir);
4838
4849
  const coldStartAt = Date.now();
4839
4850
  const bearerUser = bearerUserResolverFromEnv();
4840
4851
  const executor = new WorkerFunctionExecutor({
4841
4852
  deps: { rootDir: cwd, builtin: LOCAL_BUILTIN_DEPS }
4842
4853
  });
4843
- await mkdir6(functionsDir, { recursive: true });
4854
+ await mkdir7(functionsDir, { recursive: true });
4844
4855
  const runtime = await createSimRuntime({
4845
4856
  cwd,
4846
4857
  projectId: "local",
@@ -4927,12 +4938,12 @@ async function startDevServer(options) {
4927
4938
  const reload = async () => {
4928
4939
  const [nextFiles, envText2] = await Promise.all([
4929
4940
  collectFunctions(functionsDir).then(mergeSharedIntoFunctions),
4930
- readFile8(join12(cwd, ".env.local"), "utf8").catch(() => "")
4941
+ readFile9(join13(cwd, ".env.local"), "utf8").catch(() => "")
4931
4942
  ]);
4932
4943
  files = nextFiles;
4933
4944
  env = { ...config.environment, ...parseEnvFile(envText2) };
4934
4945
  };
4935
- const envText = await readFile8(join12(cwd, ".env.local"), "utf8").catch(() => "");
4946
+ const envText = await readFile9(join13(cwd, ".env.local"), "utf8").catch(() => "");
4936
4947
  env = { ...config.environment, ...parseEnvFile(envText) };
4937
4948
  let debounceTimer;
4938
4949
  let watcher;
@@ -5158,7 +5169,7 @@ async function createClient(paths) {
5158
5169
  throw new CliError("NOT_LOGGED_IN", "\u672A\u767B\u5F55\uFF1A\u8BF7\u5148\u6267\u884C adep login");
5159
5170
  }
5160
5171
  const server = credentials.server;
5161
- const cookie = `better-auth.session_token=${decodeToken(credentials.encodedToken)}`;
5172
+ const cookie = sessionCookieHeader(credentials);
5162
5173
  const request = async (path, init = {}, fallbackCode = "API_REQUEST_FAILED") => {
5163
5174
  const method = init.method ?? (init.body === void 0 ? "GET" : "POST");
5164
5175
  let response;
@@ -5245,7 +5256,7 @@ __export(db_exports, {
5245
5256
  dbStop: () => dbStop,
5246
5257
  splitSqlStatements: () => splitSqlStatements
5247
5258
  });
5248
- import { readFile as readFile9 } from "node:fs/promises";
5259
+ import { readFile as readFile10 } from "node:fs/promises";
5249
5260
  import { resolve as resolve5 } from "node:path";
5250
5261
  async function open2(paths, options) {
5251
5262
  const client = await createClient(paths);
@@ -5353,7 +5364,7 @@ function splitSqlStatements(source) {
5353
5364
  return statements;
5354
5365
  }
5355
5366
  async function dbMigrate(paths, options) {
5356
- const source = await readFile9(resolve5(options.file), "utf8");
5367
+ const source = await readFile10(resolve5(options.file), "utf8");
5357
5368
  const statements = splitSqlStatements(source);
5358
5369
  if (statements.length === 0) {
5359
5370
  throw new Error(`\u8FC1\u79FB\u6587\u4EF6\u6CA1\u6709\u53EF\u6267\u884C\u8BED\u53E5\uFF1A${options.file}`);
@@ -5423,6 +5434,10 @@ function renderBanner(options) {
5423
5434
  lines.push(` - \u9759\u6001\u6258\u7BA1: \u65E0\uFF08${staticDir} \u76EE\u5F55\u4E0D\u5B58\u5728\uFF09`);
5424
5435
  }
5425
5436
  lines.push(" - \u7EC4\u4EF6\u9884\u89C8: Widget / Page \u4EA7\u7269\uFF08\u5982\u5DF2\u6784\u5EFA\uFF09");
5437
+ if (options.dbMode !== void 0) {
5438
+ 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";
5439
+ lines.push(` - \u6570\u636E\u5E93: ${label} \u2192 ${options.dbTarget ?? "\uFF08\u672A\u6807\u6CE8\uFF09"}`);
5440
+ }
5426
5441
  lines.push(` - \u5065\u5EB7\u68C0\u67E5: ${baseUrl}/healthz`);
5427
5442
  lines.push("");
5428
5443
  lines.push(" \u8FB9\u754C\uFF08\u5F00\u53D1\u6001\u9ED8\u8BA4\u503C\uFF0C\u4E0D\u53EF\u5728\u6B64\u6A21\u5F0F\u4E0B\u5F00\u542F\uFF09:");
@@ -5455,6 +5470,132 @@ var init_banner = __esm({
5455
5470
  }
5456
5471
  });
5457
5472
 
5473
+ // packages/cli/src/serve/db-mode.ts
5474
+ import { resolve as resolve6 } from "node:path";
5475
+ function isServeDbMode(value) {
5476
+ return SERVE_DB_MODES.includes(value.trim().toLowerCase());
5477
+ }
5478
+ function parseServeDbMode(raw, source) {
5479
+ const value = raw.trim().toLowerCase();
5480
+ if (!isServeDbMode(value)) {
5481
+ throw new Error(
5482
+ `${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`
5483
+ );
5484
+ }
5485
+ return value;
5486
+ }
5487
+ function resolveServeDbMode(explicit) {
5488
+ if (explicit !== void 0) return parseServeDbMode(explicit, "--db");
5489
+ const fromEnv = process.env["ADEP_SERVE_DB"];
5490
+ if (fromEnv !== void 0 && fromEnv.trim() !== "") {
5491
+ return parseServeDbMode(fromEnv, "ADEP_SERVE_DB");
5492
+ }
5493
+ return DEFAULT_SERVE_DB_MODE;
5494
+ }
5495
+ function resolveServeDbFile(cwd, explicit) {
5496
+ const raw = explicit ?? envDbFile() ?? DEFAULT_SQLITE_DB_FILE;
5497
+ return raw === ":memory:" ? raw : resolve6(cwd, raw);
5498
+ }
5499
+ function envDbFile() {
5500
+ const raw = process.env["ADEP_SERVE_DB_FILE"];
5501
+ return raw === void 0 || raw.trim() === "" ? void 0 : raw.trim();
5502
+ }
5503
+ var SERVE_DB_MODES, DEFAULT_SERVE_DB_MODE, DEFAULT_SQLITE_DB_FILE;
5504
+ var init_db_mode = __esm({
5505
+ "packages/cli/src/serve/db-mode.ts"() {
5506
+ "use strict";
5507
+ SERVE_DB_MODES = ["sim", "sqlite"];
5508
+ DEFAULT_SERVE_DB_MODE = "sim";
5509
+ DEFAULT_SQLITE_DB_FILE = ".adep/data/project.sqlite";
5510
+ }
5511
+ });
5512
+
5513
+ // packages/cli/src/serve/sqlite-driver.ts
5514
+ import { mkdir as mkdir8 } from "node:fs/promises";
5515
+ import { dirname as dirname8, resolve as resolve7 } from "node:path";
5516
+ function isBun(versions) {
5517
+ return versions["bun"] !== void 0 && versions["bun"] !== "";
5518
+ }
5519
+ function detectSqliteRuntime(versions = process.versions) {
5520
+ if (isBun(versions)) return "bun";
5521
+ const raw = versions["node"];
5522
+ if (raw === void 0) return null;
5523
+ const [majorText, minorText] = raw.split(".");
5524
+ const major = Number(majorText);
5525
+ const minor = Number(minorText ?? "0");
5526
+ if (!Number.isInteger(major) || !Number.isInteger(minor)) return null;
5527
+ if (major > NODE_SQLITE_MIN.major) return "node";
5528
+ if (major === NODE_SQLITE_MIN.major && minor >= NODE_SQLITE_MIN.minor) return "node";
5529
+ return null;
5530
+ }
5531
+ function sqliteModuleName(runtime) {
5532
+ return runtime === "bun" ? "bun:sqlite" : "node:sqlite";
5533
+ }
5534
+ function sqliteRuntimeRequirementMessage(versions = process.versions) {
5535
+ const current = isBun(versions) ? `Bun ${versions["bun"] ?? ""}`.trim() : `Node ${versions["node"] ?? "\u672A\u77E5"}`;
5536
+ 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`;
5537
+ }
5538
+ async function openSqliteProjectDriver(file, options = {}) {
5539
+ const runtime = options.runtime ?? detectSqliteRuntime();
5540
+ if (runtime === null) throw new Error(sqliteRuntimeRequirementMessage());
5541
+ const moduleName = sqliteModuleName(runtime);
5542
+ const ctorName = runtime === "bun" ? "Database" : "DatabaseSync";
5543
+ let mod;
5544
+ try {
5545
+ const specifier = moduleName;
5546
+ mod = await import(
5547
+ /* @vite-ignore */
5548
+ specifier
5549
+ );
5550
+ } catch (error) {
5551
+ throw new Error(
5552
+ `${sqliteRuntimeRequirementMessage()}
5553
+ \uFF08\u8F7D\u5165 ${moduleName} \u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}\uFF09`,
5554
+ { cause: error }
5555
+ );
5556
+ }
5557
+ const Ctor = mod[ctorName];
5558
+ if (Ctor === void 0) {
5559
+ throw new Error(`${moduleName} \u672A\u5BFC\u51FA ${ctorName}\uFF1A\u5F53\u524D\u8FD0\u884C\u65F6\u7684 SQLite \u5185\u5EFA\u6A21\u5757\u4E0D\u53EF\u7528`);
5560
+ }
5561
+ const target = file === ":memory:" ? file : resolve7(file);
5562
+ if (target !== ":memory:") await mkdir8(dirname8(target), { recursive: true });
5563
+ const database = new Ctor(target);
5564
+ database.exec("PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;");
5565
+ return {
5566
+ engine: "sqlite",
5567
+ async run(sql, params = []) {
5568
+ if (params.length === 0) {
5569
+ database.exec(sql);
5570
+ return { changes: 0 };
5571
+ }
5572
+ const result = database.prepare(sql).run(...params);
5573
+ return { changes: Number(result.changes) };
5574
+ },
5575
+ async all(sql, params = []) {
5576
+ const statement = database.prepare(sql);
5577
+ statement.setReturnArrays?.(false);
5578
+ return statement.all(...params);
5579
+ },
5580
+ async get(sql, params = []) {
5581
+ const statement = database.prepare(sql);
5582
+ statement.setReturnArrays?.(false);
5583
+ const row = statement.get(...params);
5584
+ return row ?? null;
5585
+ },
5586
+ async close() {
5587
+ database.close();
5588
+ }
5589
+ };
5590
+ }
5591
+ var NODE_SQLITE_MIN;
5592
+ var init_sqlite_driver = __esm({
5593
+ "packages/cli/src/serve/sqlite-driver.ts"() {
5594
+ "use strict";
5595
+ NODE_SQLITE_MIN = { major: 22, minor: 5 };
5596
+ }
5597
+ });
5598
+
5458
5599
  // packages/cli/src/serve/server.ts
5459
5600
  var server_exports = {};
5460
5601
  __export(server_exports, {
@@ -5464,8 +5605,8 @@ __export(server_exports, {
5464
5605
  });
5465
5606
  import { createServer as createServer2 } from "node:http";
5466
5607
  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";
5608
+ import { mkdir as mkdir9, readFile as readFile11, stat as stat7 } from "node:fs/promises";
5609
+ import { extname, join as join14, relative as relative2, resolve as resolve8 } from "node:path";
5469
5610
  function envNumber(name) {
5470
5611
  const raw = process.env[name];
5471
5612
  if (raw === void 0 || raw.trim() === "") return void 0;
@@ -5483,22 +5624,29 @@ function contentTypeFor(path) {
5483
5624
  const ext = path.slice(path.lastIndexOf(".")).toLowerCase();
5484
5625
  return MIME_TYPES[ext] ?? "application/octet-stream";
5485
5626
  }
5627
+ function displayPath(cwd, target) {
5628
+ if (target === ":memory:") return target;
5629
+ const rel = relative2(cwd, target);
5630
+ return rel.startsWith("..") ? target : rel;
5631
+ }
5486
5632
  async function startServeServer(options) {
5487
- const cwd = resolve6(options.cwd);
5633
+ const cwd = resolve8(options.cwd);
5488
5634
  const log = options.log ?? ((line) => process.stdout.write(`${line}
5489
5635
  `));
5490
5636
  const host = options.host ?? envString("HOST") ?? "127.0.0.1";
5491
5637
  const port = resolveServePort(options.port);
5492
- const staticDir = resolve6(
5638
+ const staticDir = resolve8(
5493
5639
  cwd,
5494
5640
  options.staticDir ?? envString("ADEP_SERVE_STATIC_DIR") ?? "public"
5495
5641
  );
5642
+ const dbMode = resolveServeDbMode(options.db);
5643
+ const sqliteFile = dbMode === "sqlite" ? resolveServeDbFile(cwd, options.dbFile) : null;
5496
5644
  const config = await loadConfig(cwd);
5497
- const functionsDir = join13(cwd, config.functionsDir);
5645
+ const functionsDir = join14(cwd, config.functionsDir);
5498
5646
  const bearerUser = bearerUserResolverFromEnv();
5499
5647
  let hasStatic = false;
5500
5648
  try {
5501
- const publicStat = await stat6(staticDir);
5649
+ const publicStat = await stat7(staticDir);
5502
5650
  hasStatic = publicStat.isDirectory();
5503
5651
  } catch {
5504
5652
  hasStatic = false;
@@ -5506,18 +5654,27 @@ async function startServeServer(options) {
5506
5654
  const loadFunctionFiles = async () => mergeSharedIntoFunctions(await collectFunctions(functionsDir));
5507
5655
  let files = await loadFunctionFiles();
5508
5656
  let functionNames = listFunctionNames(files);
5509
- const envText = await readFile10(join13(cwd, ".env.local"), "utf8").catch(() => "");
5657
+ const envText = await readFile11(join14(cwd, ".env.local"), "utf8").catch(() => "");
5510
5658
  let env = parseEnvFile(envText);
5511
5659
  let simEnv = await loadSimEnv(cwd).catch(() => ({}));
5660
+ let sqliteModule = null;
5661
+ let sqliteDriver = null;
5662
+ if (sqliteFile !== null) {
5663
+ const runtimeName = detectSqliteRuntime();
5664
+ if (runtimeName === null) throw new Error(sqliteRuntimeRequirementMessage());
5665
+ sqliteModule = sqliteModuleName(runtimeName);
5666
+ sqliteDriver = await openSqliteProjectDriver(sqliteFile, { runtime: runtimeName });
5667
+ }
5512
5668
  const runtime = await createSimRuntime({
5513
5669
  cwd,
5514
5670
  projectId: "local",
5515
5671
  baseUrl: `http://${host}:${port}`,
5516
- log
5672
+ log,
5673
+ ...sqliteDriver === null ? {} : { driver: sqliteDriver }
5517
5674
  });
5518
5675
  if (options.schemaFile !== void 0) {
5519
- const schemaPath = resolve6(cwd, options.schemaFile);
5520
- const schemaSource = await readFile10(schemaPath, "utf8").catch(
5676
+ const schemaPath = resolve8(cwd, options.schemaFile);
5677
+ const schemaSource = await readFile11(schemaPath, "utf8").catch(
5521
5678
  (error) => {
5522
5679
  if (error.code === "ENOENT") {
5523
5680
  throw new Error(`schema \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${schemaPath}`);
@@ -5528,18 +5685,23 @@ async function startServeServer(options) {
5528
5685
  const statements = splitSqlStatements(schemaSource);
5529
5686
  let applied = 0;
5530
5687
  let skipped = 0;
5531
- for (const statement of statements) {
5688
+ for (const [index, statement] of statements.entries()) {
5532
5689
  try {
5533
- await runtime.db.engine.run(statement);
5690
+ await runtime.db.driver.run(statement);
5534
5691
  applied += 1;
5535
5692
  } catch (error) {
5536
5693
  const isUnsupported = error instanceof Error && "code" in error && error.code === "DB_UNSAFE_OP";
5537
- if (isUnsupported) {
5694
+ if (dbMode === "sim" && isUnsupported) {
5538
5695
  skipped += 1;
5539
5696
  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;
5697
+ continue;
5542
5698
  }
5699
+ const detail = error instanceof Error ? error.message : String(error);
5700
+ throw new Error(
5701
+ `schema \u8BED\u53E5\u6267\u884C\u5931\u8D25\uFF08--schema ${options.schemaFile}\uFF0C\u7B2C ${index + 1} \u6761\uFF0Cdb \u6A21\u5F0F ${dbMode}\uFF09\uFF1A${detail}
5702
+ \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" : ""),
5703
+ { cause: error }
5704
+ );
5543
5705
  }
5544
5706
  }
5545
5707
  const skipNote = skipped > 0 ? `\uFF0C\u8DF3\u8FC7 ${skipped} \u6761` : "";
@@ -5555,7 +5717,7 @@ async function startServeServer(options) {
5555
5717
  const reload = async () => {
5556
5718
  const [nextFiles, envLocalText] = await Promise.all([
5557
5719
  loadFunctionFiles(),
5558
- readFile10(join13(cwd, ".env.local"), "utf8").catch(() => "")
5720
+ readFile11(join14(cwd, ".env.local"), "utf8").catch(() => "")
5559
5721
  ]);
5560
5722
  files = nextFiles;
5561
5723
  env = parseEnvFile(envLocalText);
@@ -5572,7 +5734,7 @@ async function startServeServer(options) {
5572
5734
  void reload();
5573
5735
  }, 120);
5574
5736
  };
5575
- await mkdir7(functionsDir, { recursive: true }).catch(() => void 0);
5737
+ await mkdir9(functionsDir, { recursive: true }).catch(() => void 0);
5576
5738
  try {
5577
5739
  watchers.push(watch2(functionsDir, { recursive: true }, scheduleReload));
5578
5740
  } catch {
@@ -5610,16 +5772,16 @@ async function startServeServer(options) {
5610
5772
  const serveStatic = async (pathname, res) => {
5611
5773
  if (!hasStatic) return false;
5612
5774
  const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
5613
- const filePath = join13(staticDir, safePath);
5614
- const resolvedPath = safePath === "" || safePath === "/" ? join13(filePath, "index.html") : filePath;
5775
+ const filePath = join14(staticDir, safePath);
5776
+ const resolvedPath = safePath === "" || safePath === "/" ? join14(filePath, "index.html") : filePath;
5615
5777
  try {
5616
- const fileStat = await stat6(resolvedPath);
5778
+ const fileStat = await stat7(resolvedPath);
5617
5779
  if (fileStat.isDirectory()) {
5618
- const indexPath = join13(resolvedPath, "index.html");
5780
+ const indexPath = join14(resolvedPath, "index.html");
5619
5781
  try {
5620
- const indexStat = await stat6(indexPath);
5782
+ const indexStat = await stat7(indexPath);
5621
5783
  if (indexStat.isFile()) {
5622
- const content2 = await readFile10(indexPath);
5784
+ const content2 = await readFile11(indexPath);
5623
5785
  res.writeHead(200, { "content-type": contentTypeFor(indexPath) });
5624
5786
  res.end(content2);
5625
5787
  return true;
@@ -5628,7 +5790,7 @@ async function startServeServer(options) {
5628
5790
  }
5629
5791
  return false;
5630
5792
  }
5631
- const content = await readFile10(resolvedPath);
5793
+ const content = await readFile11(resolvedPath);
5632
5794
  res.writeHead(200, { "content-type": contentTypeFor(resolvedPath) });
5633
5795
  res.end(content);
5634
5796
  return true;
@@ -5637,7 +5799,7 @@ async function startServeServer(options) {
5637
5799
  const ext = extname(pathname);
5638
5800
  if (ext === "" || ext === ".html") {
5639
5801
  try {
5640
- const indexContent = await readFile10(join13(staticDir, "index.html"));
5802
+ const indexContent = await readFile11(join14(staticDir, "index.html"));
5641
5803
  res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
5642
5804
  res.end(indexContent);
5643
5805
  return true;
@@ -5724,6 +5886,8 @@ async function startServeServer(options) {
5724
5886
  project: config.name,
5725
5887
  functions: functionNames,
5726
5888
  static: hasStatic,
5889
+ // CLI-020:当前数据面(换模式即换库,这里让脚本/e2e 有可断言的读数)。
5890
+ db: sqliteFile === null ? { mode: "sim", file: displayPath(cwd, join14(simDir(cwd), "db.json")) } : { mode: "sqlite", file: displayPath(cwd, sqliteFile), driver: sqliteModule },
5727
5891
  endpoints: {
5728
5892
  functions: "/api/{fn}",
5729
5893
  static: `/ \u2192 ${staticDir}`,
@@ -5762,14 +5926,19 @@ async function startServeServer(options) {
5762
5926
  functions: functionNames,
5763
5927
  functionsPrefix: config.functionsPrefix,
5764
5928
  hasStatic,
5765
- staticDir: relative2(cwd, staticDir).length > 0 ? relative2(cwd, staticDir) : staticDir
5929
+ staticDir: relative2(cwd, staticDir).length > 0 ? relative2(cwd, staticDir) : staticDir,
5930
+ dbMode,
5931
+ dbTarget: sqliteFile === null ? displayPath(cwd, join14(simDir(cwd), "db.json")) : displayPath(cwd, sqliteFile),
5932
+ ...sqliteModule === null ? {} : { dbDriver: sqliteModule }
5766
5933
  });
5767
5934
  log(banner);
5768
5935
  if (options.watch === true) {
5769
5936
  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
5937
  }
5771
5938
  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`);
5939
+ log(
5940
+ `[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`
5941
+ );
5773
5942
  }
5774
5943
  return {
5775
5944
  port: actualPort,
@@ -5780,6 +5949,7 @@ async function startServeServer(options) {
5780
5949
  await new Promise((resolveClose) => {
5781
5950
  server.close(() => resolveClose());
5782
5951
  });
5952
+ await runtime.dispose();
5783
5953
  }
5784
5954
  };
5785
5955
  }
@@ -5797,6 +5967,8 @@ var init_server = __esm({
5797
5967
  init_invoke();
5798
5968
  init_dev();
5799
5969
  init_banner();
5970
+ init_db_mode();
5971
+ init_sqlite_driver();
5800
5972
  init_dev_shared();
5801
5973
  MIME_TYPES = {
5802
5974
  ".html": "text/html; charset=utf-8",
@@ -5831,8 +6003,8 @@ __export(deploy_exports, {
5831
6003
  deploy: () => deploy
5832
6004
  });
5833
6005
  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";
6006
+ import { readdir as readdir5, readFile as readFile12 } from "node:fs/promises";
6007
+ import { join as join15, resolve as resolve9, basename as basename3, relative as relative3, sep } from "node:path";
5836
6008
  function functionUrlBase(prefix) {
5837
6009
  const raw = (prefix ?? "/api").trim();
5838
6010
  const normalized = raw === "/" ? "/" : raw.replace(/\/+$/, "");
@@ -5844,7 +6016,7 @@ function isRuntimeSource2(name) {
5844
6016
  async function collectFunctionFiles(functionsDir) {
5845
6017
  let dirents;
5846
6018
  try {
5847
- dirents = await readdir4(functionsDir, { withFileTypes: true });
6019
+ dirents = await readdir5(functionsDir, { withFileTypes: true });
5848
6020
  } catch {
5849
6021
  return {};
5850
6022
  }
@@ -5858,10 +6030,10 @@ async function collectFunctionFiles(functionsDir) {
5858
6030
  if (conflicting.length > 0) throw new AmbiguousFunctionError(functionsDir, conflicting);
5859
6031
  const out = {};
5860
6032
  for (const name of flatNames) {
5861
- out[name] = { "index.ts": await readFile11(join14(functionsDir, `${name}.ts`), "utf8") };
6033
+ out[name] = { "index.ts": await readFile12(join15(functionsDir, `${name}.ts`), "utf8") };
5862
6034
  }
5863
6035
  for (const name of dirNames) {
5864
- const files = await collectFunctionDir(join14(functionsDir, name));
6036
+ const files = await collectFunctionDir(join15(functionsDir, name));
5865
6037
  if (files["index.ts"] === void 0) continue;
5866
6038
  out[name] = files;
5867
6039
  }
@@ -5872,7 +6044,7 @@ async function collectFunctionDir(absDir) {
5872
6044
  const walk = async (dir, prefix) => {
5873
6045
  let entries;
5874
6046
  try {
5875
- entries = await readdir4(dir, { withFileTypes: true });
6047
+ entries = await readdir5(dir, { withFileTypes: true });
5876
6048
  } catch {
5877
6049
  return;
5878
6050
  }
@@ -5880,11 +6052,11 @@ async function collectFunctionDir(absDir) {
5880
6052
  const rel = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
5881
6053
  if (entry.isDirectory()) {
5882
6054
  if (entry.name === "__tests__" || IGNORED_DIRS.has(entry.name)) continue;
5883
- await walk(join14(dir, entry.name), rel);
6055
+ await walk(join15(dir, entry.name), rel);
5884
6056
  continue;
5885
6057
  }
5886
6058
  if (!isRuntimeSource2(entry.name)) continue;
5887
- files[rel] = await readFile11(join14(dir, entry.name), "utf8");
6059
+ files[rel] = await readFile12(join15(dir, entry.name), "utf8");
5888
6060
  }
5889
6061
  };
5890
6062
  await walk(absDir, "");
@@ -5894,25 +6066,25 @@ function sha256Hex(content) {
5894
6066
  return createHash2("sha256").update(content).digest("hex");
5895
6067
  }
5896
6068
  async function collectShared(functionsDir) {
5897
- const sharedDir = join14(functionsDir, "_shared");
6069
+ const sharedDir = join15(functionsDir, "_shared");
5898
6070
  const files = {};
5899
6071
  const walk = async (dir) => {
5900
6072
  let entries;
5901
6073
  try {
5902
- entries = await readdir4(dir, { withFileTypes: true });
6074
+ entries = await readdir5(dir, { withFileTypes: true });
5903
6075
  } catch {
5904
6076
  return;
5905
6077
  }
5906
6078
  for (const entry of entries) {
5907
6079
  if (entry.isDirectory()) {
5908
6080
  if (entry.name === "__tests__" || entry.name === "node_modules") continue;
5909
- await walk(join14(dir, entry.name));
6081
+ await walk(join15(dir, entry.name));
5910
6082
  continue;
5911
6083
  }
5912
6084
  if (!isRuntimeSource2(entry.name)) continue;
5913
- const full = join14(dir, entry.name);
6085
+ const full = join15(dir, entry.name);
5914
6086
  const rel = relative3(sharedDir, full).split(sep).join("/");
5915
- files[`${SHARED_SOURCE_ROOT3}${rel}`] = await readFile11(full, "utf8");
6087
+ files[`${SHARED_SOURCE_ROOT3}${rel}`] = await readFile12(full, "utf8");
5916
6088
  }
5917
6089
  };
5918
6090
  await walk(sharedDir);
@@ -5923,10 +6095,10 @@ async function deploy(paths, options) {
5923
6095
  const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
5924
6096
  `));
5925
6097
  const client = await createClient(paths);
5926
- const cwd = resolve7(options.cwd);
6098
+ const cwd = resolve9(options.cwd);
5927
6099
  const config = await loadConfig(cwd);
5928
6100
  const slug = options.slug ?? config.name;
5929
- const functionsDir = options.functionsDir === void 0 ? join14(cwd, config.functionsDir) : resolve7(cwd, options.functionsDir);
6101
+ const functionsDir = options.functionsDir === void 0 ? join15(cwd, config.functionsDir) : resolve9(cwd, options.functionsDir);
5930
6102
  const local = await collectFunctionFiles(functionsDir);
5931
6103
  if (Object.keys(local).length === 0) {
5932
6104
  throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
@@ -6057,8 +6229,8 @@ var frontend_exports = {};
6057
6229
  __export(frontend_exports, {
6058
6230
  frontendSync: () => frontendSync
6059
6231
  });
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";
6232
+ import { readdir as readdir6, readFile as readFile13, stat as stat8 } from "node:fs/promises";
6233
+ import { join as join16, relative as relative4, sep as sep2 } from "node:path";
6062
6234
  async function resolveProjectId(client, cwd, slug) {
6063
6235
  const resolvedSlug = await resolveSlug(cwd, slug);
6064
6236
  const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
@@ -6074,24 +6246,24 @@ async function resolveProjectId(client, cwd, slug) {
6074
6246
  async function collectFiles(root, dir) {
6075
6247
  const files = /* @__PURE__ */ new Map();
6076
6248
  const skipped = [];
6077
- const entries = await readdir5(dir, { withFileTypes: true });
6249
+ const entries = await readdir6(dir, { withFileTypes: true });
6078
6250
  for (const entry of entries) {
6079
6251
  if (entry.isDirectory()) {
6080
6252
  if (IGNORED_DIRS2.has(entry.name)) continue;
6081
- const nested = await collectFiles(root, join15(dir, entry.name));
6253
+ const nested = await collectFiles(root, join16(dir, entry.name));
6082
6254
  for (const [path, content] of nested.files) files.set(path, content);
6083
6255
  skipped.push(...nested.skipped);
6084
6256
  continue;
6085
6257
  }
6086
- const full = join15(dir, entry.name);
6258
+ const full = join16(dir, entry.name);
6087
6259
  const rel = relative4(root, full).split(sep2).join("/");
6088
- const info = await stat7(full);
6260
+ const info = await stat8(full);
6089
6261
  if (info.size > 1024 * 1024) {
6090
6262
  skipped.push(rel);
6091
6263
  continue;
6092
6264
  }
6093
6265
  try {
6094
- const content = await readFile12(full, "utf8");
6266
+ const content = await readFile13(full, "utf8");
6095
6267
  if (content.includes("\0")) {
6096
6268
  skipped.push(rel);
6097
6269
  continue;
@@ -6106,8 +6278,8 @@ async function collectFiles(root, dir) {
6106
6278
  async function frontendSync(paths, options) {
6107
6279
  const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
6108
6280
  `));
6109
- const webDir = options.dir ?? join15(options.cwd, "web");
6110
- const rootStat = await stat7(webDir).catch(() => null);
6281
+ const webDir = options.dir ?? join16(options.cwd, "web");
6282
+ const rootStat = await stat8(webDir).catch(() => null);
6111
6283
  if (rootStat === null || !rootStat.isDirectory()) {
6112
6284
  throw new CliError(
6113
6285
  "FRONTEND_DIR_MISSING",
@@ -6172,7 +6344,7 @@ var client_exports2 = {};
6172
6344
  __export(client_exports2, {
6173
6345
  createExportApiClient: () => createExportApiClient
6174
6346
  });
6175
- import { writeFile as writeFile6 } from "node:fs/promises";
6347
+ import { writeFile as writeFile7 } from "node:fs/promises";
6176
6348
  function toExportJob(view) {
6177
6349
  return {
6178
6350
  id: view.id,
@@ -6223,7 +6395,7 @@ async function createExportApiClient(paths) {
6223
6395
  }
6224
6396
  const response = await client.download(download.downloadUrl, "EXPORT_DOWNLOAD_FAILED");
6225
6397
  const bytes = Buffer.from(await response.arrayBuffer());
6226
- await writeFile6(outputPath, bytes);
6398
+ await writeFile7(outputPath, bytes);
6227
6399
  return { path: outputPath, size: bytes.length };
6228
6400
  }
6229
6401
  };
@@ -6320,33 +6492,33 @@ var fs_exports = {};
6320
6492
  __export(fs_exports, {
6321
6493
  createExportFileSystem: () => createExportFileSystem
6322
6494
  });
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";
6495
+ import { mkdir as mkdir10, readFile as readFile14, rm as rm3, stat as stat10, writeFile as writeFile8 } from "node:fs/promises";
6496
+ import { dirname as dirname9, join as join18 } from "node:path";
6325
6497
  function createExportFileSystem() {
6326
6498
  return {
6327
- readFile: (path) => readFile13(path),
6328
- writeFile: (path, content) => writeFile7(path, content),
6499
+ readFile: (path) => readFile14(path),
6500
+ writeFile: (path, content) => writeFile8(path, content),
6329
6501
  // 同时用于清理解压临时目录(${zip}.tmp 是个目录)——递归强制删除,缺失不报错。
6330
6502
  deleteFile: async (path) => {
6331
6503
  await rm3(path, { recursive: true, force: true });
6332
6504
  },
6333
6505
  fileExists: async (path) => {
6334
6506
  try {
6335
- await stat9(path);
6507
+ await stat10(path);
6336
6508
  return true;
6337
6509
  } catch {
6338
6510
  return false;
6339
6511
  }
6340
6512
  },
6341
6513
  mkdir: async (path) => {
6342
- await mkdir8(path, { recursive: true });
6514
+ await mkdir10(path, { recursive: true });
6343
6515
  },
6344
6516
  unzip: async (zipPath, targetDir) => {
6345
- const entries = zipRead(await readFile13(zipPath));
6517
+ const entries = zipRead(await readFile14(zipPath));
6346
6518
  for (const [name, data] of entries) {
6347
- const dest = join17(targetDir, name);
6348
- await mkdir8(dirname8(dest), { recursive: true });
6349
- await writeFile7(dest, data);
6519
+ const dest = join18(targetDir, name);
6520
+ await mkdir10(dirname9(dest), { recursive: true });
6521
+ await writeFile8(dest, data);
6350
6522
  }
6351
6523
  }
6352
6524
  };
@@ -6847,7 +7019,7 @@ ${detail}`);
6847
7019
  * @param ms 毫秒数
6848
7020
  */
6849
7021
  sleep(ms) {
6850
- return new Promise((resolve13) => setTimeout(resolve13, ms));
7022
+ return new Promise((resolve15) => setTimeout(resolve15, ms));
6851
7023
  }
6852
7024
  };
6853
7025
  }
@@ -6862,11 +7034,11 @@ __export(storage_exports, {
6862
7034
  storageRemove: () => storageRemove,
6863
7035
  storageUpload: () => storageUpload
6864
7036
  });
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";
7037
+ import { mkdir as mkdir11, readFile as readFile15, stat as stat11, writeFile as writeFile9 } from "node:fs/promises";
7038
+ import { basename as basename4, dirname as dirname10, extname as extname2, join as join19, resolve as resolve11 } from "node:path";
6867
7039
  async function open3(paths, options) {
6868
7040
  const client = await createClient(paths);
6869
- const project2 = await resolveSlug(resolve9(options.cwd), options.slug);
7041
+ const project2 = await resolveSlug(resolve11(options.cwd), options.slug);
6870
7042
  return { client, project: project2 };
6871
7043
  }
6872
7044
  function contentTypeOf(path) {
@@ -6899,13 +7071,13 @@ function contentTypeOf(path) {
6899
7071
  }
6900
7072
  async function storageUpload(paths, options) {
6901
7073
  const { client, project: project2 } = await open3(paths, options);
6902
- const local = resolve9(options.file);
6903
- const info = await stat10(local).catch(() => null);
7074
+ const local = resolve11(options.file);
7075
+ const info = await stat11(local).catch(() => null);
6904
7076
  if (info === null || !info.isFile()) {
6905
7077
  throw new CliError("FILE_NOT_FOUND", `\u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${local}`);
6906
7078
  }
6907
7079
  const visibility = options.visibility ?? "private";
6908
- const bytes = await readFile14(local);
7080
+ const bytes = await readFile15(local);
6909
7081
  const form = new FormData();
6910
7082
  form.set("path", options.path);
6911
7083
  form.set("visibility", visibility);
@@ -6946,9 +7118,9 @@ async function storageDownload(paths, options) {
6946
7118
  const url = await resolveDownloadUrl(client, project2, options.path);
6947
7119
  const response = await client.download(url, "STORAGE_DOWNLOAD_FAILED");
6948
7120
  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);
7121
+ const output = resolve11(options.output ?? join19(resolve11(options.cwd), basename4(options.path)));
7122
+ await mkdir11(dirname10(output), { recursive: true });
7123
+ await writeFile9(output, bytes);
6952
7124
  return { path: options.path, output, size: bytes.length };
6953
7125
  }
6954
7126
  async function storageRemove(paths, options) {
@@ -6972,7 +7144,7 @@ __export(doctor_exports, {
6972
7144
  formatDoctorReport: () => formatDoctorReport,
6973
7145
  runDoctor: () => runDoctor
6974
7146
  });
6975
- import { stat as stat11 } from "node:fs/promises";
7147
+ import { stat as stat12 } from "node:fs/promises";
6976
7148
  async function probeServer(server) {
6977
7149
  const controller = new AbortController();
6978
7150
  const timer = setTimeout(() => controller.abort(), SERVER_PROBE_TIMEOUT_MS);
@@ -6990,7 +7162,7 @@ async function probeServer(server) {
6990
7162
  }
6991
7163
  async function credentialMode(file) {
6992
7164
  try {
6993
- const info = await stat11(file);
7165
+ const info = await stat12(file);
6994
7166
  return (info.mode & 511).toString(8).padStart(3, "0");
6995
7167
  } catch {
6996
7168
  return void 0;
@@ -7079,7 +7251,7 @@ __export(mcp_exports, {
7079
7251
  mcpPublish: () => mcpPublish,
7080
7252
  mcpUnpublish: () => mcpUnpublish
7081
7253
  });
7082
- import { resolve as resolve10 } from "node:path";
7254
+ import { resolve as resolve12 } from "node:path";
7083
7255
  async function mcpPublish(paths, options) {
7084
7256
  const fn = requireFunctionName(options.fn);
7085
7257
  const client = await createClient(paths);
@@ -7160,7 +7332,7 @@ function requireFunctionName(fn) {
7160
7332
  return fn.trim();
7161
7333
  }
7162
7334
  async function resolveProject(client, options) {
7163
- const slug = await resolveSlug(resolve10(options.cwd), options.slug);
7335
+ const slug = await resolveSlug(resolve12(options.cwd), options.slug);
7164
7336
  const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
7165
7337
  const match = listed.projects.find((project2) => project2.slug === slug);
7166
7338
  if (match === void 0) {
@@ -7360,7 +7532,7 @@ __export(functions_exports, {
7360
7532
  functionsList: () => functionsList,
7361
7533
  functionsLogs: () => functionsLogs
7362
7534
  });
7363
- import { resolve as resolve11 } from "node:path";
7535
+ import { resolve as resolve13 } from "node:path";
7364
7536
  async function functionsList(paths, options) {
7365
7537
  const client = await createClient(paths);
7366
7538
  const project2 = await resolveProject2(client, options);
@@ -7402,7 +7574,7 @@ async function functionsLogs(paths, options) {
7402
7574
  return { functionId: target.id, name: target.name, logs: result.logs };
7403
7575
  }
7404
7576
  async function resolveProject2(client, options) {
7405
- const slug = await resolveSlug(resolve11(options.cwd), options.slug);
7577
+ const slug = await resolveSlug(resolve13(options.cwd), options.slug);
7406
7578
  const projects = await projectsListFrom(client);
7407
7579
  const match = projects.find((project2) => project2.slug === slug);
7408
7580
  if (match === void 0) {
@@ -7433,11 +7605,11 @@ __export(hosting_exports, {
7433
7605
  hostingInfo: () => hostingInfo,
7434
7606
  hostingPull: () => hostingPull
7435
7607
  });
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";
7608
+ import { readdir as readdir7, readFile as readFile16, stat as stat13 } from "node:fs/promises";
7609
+ import { dirname as dirname11, join as join20, relative as relative5, resolve as resolve14, sep as sep3 } from "node:path";
7438
7610
  async function open4(paths, options) {
7439
7611
  const client = await createClient(paths);
7440
- const project2 = await resolveSlug(resolve12(options.cwd), options.slug);
7612
+ const project2 = await resolveSlug(resolve14(options.cwd), options.slug);
7441
7613
  return { client, project: project2 };
7442
7614
  }
7443
7615
  async function hostingInfo(paths, options) {
@@ -7450,17 +7622,17 @@ async function hostingInfo(paths, options) {
7450
7622
  };
7451
7623
  }
7452
7624
  async function collectSiteFiles(dir) {
7453
- const root = resolve12(dir);
7625
+ const root = resolve14(dir);
7454
7626
  const files = /* @__PURE__ */ new Map();
7455
7627
  const walk = async (sub) => {
7456
7628
  let entries;
7457
7629
  try {
7458
- entries = await readdir6(sub, { withFileTypes: true });
7630
+ entries = await readdir7(sub, { withFileTypes: true });
7459
7631
  } catch {
7460
7632
  return;
7461
7633
  }
7462
7634
  for (const entry of entries) {
7463
- const full = join19(sub, entry.name);
7635
+ const full = join20(sub, entry.name);
7464
7636
  if (entry.isDirectory()) {
7465
7637
  await walk(full);
7466
7638
  } else if (entry.isFile()) {
@@ -7478,13 +7650,13 @@ async function hostingDeploy(paths, options) {
7478
7650
  `));
7479
7651
  const files = await collectSiteFiles(options.dir);
7480
7652
  if (files.size === 0) {
7481
- throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${resolve12(options.dir)}`);
7653
+ throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${resolve14(options.dir)}`);
7482
7654
  }
7483
7655
  const uploaded = [];
7484
7656
  for (const [rel, full] of files) {
7485
7657
  log(`[adep] \u4E0A\u4F20 site/${rel}`);
7486
- const info2 = await stat12(full);
7487
- const bytes = await readFile15(full);
7658
+ const info2 = await stat13(full);
7659
+ const bytes = await readFile16(full);
7488
7660
  const form = new FormData();
7489
7661
  form.set("path", `site/${rel}`);
7490
7662
  form.set("visibility", "public");
@@ -7511,8 +7683,8 @@ async function hostingPull(paths, options) {
7511
7683
  const log = options.log ?? ((line) => process.stdout.write(`${line}
7512
7684
  `));
7513
7685
  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");
7686
+ const outputDir = resolve14(options.output ?? resolve14(options.cwd));
7687
+ const { mkdir: mkdir12, writeFile: writeFile10 } = await import("node:fs/promises");
7516
7688
  const files = [];
7517
7689
  for (const entry of info.files) {
7518
7690
  if (entry.visibility !== "public" || entry.path === HOSTING_CONFIG_PATH) continue;
@@ -7522,9 +7694,9 @@ async function hostingPull(paths, options) {
7522
7694
  const response = await client.download(url, "HOSTING_DOWNLOAD_FAILED");
7523
7695
  const bytes = Buffer.from(await response.arrayBuffer());
7524
7696
  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);
7697
+ const target = join20(outputDir, ...rel.split("/"));
7698
+ await mkdir12(dirname11(target), { recursive: true });
7699
+ await writeFile10(target, bytes);
7528
7700
  files.push({ path: entry.path, size: bytes.length });
7529
7701
  }
7530
7702
  return { siteUrl: info.siteUrl, outputDir, files };
@@ -10808,19 +10980,30 @@ function cliVersionOf() {
10808
10980
  const pkg = JSON.parse(readFileSync(findCliPackageJson(), "utf8"));
10809
10981
  return pkg.version;
10810
10982
  }
10983
+ function cliPackageRoot() {
10984
+ return dirname2(findCliPackageJson());
10985
+ }
10986
+ function localTemplateDir(code) {
10987
+ return join(cliPackageRoot(), "src", "templates", code);
10988
+ }
10811
10989
  function templateFiles(code, name) {
10812
10990
  const generated = GENERATED_TEMPLATES[code];
10813
10991
  if (generated === void 0) {
10814
10992
  throw new Error(`\u672A\u77E5\u6A21\u677F "${code}"\uFF1A\u53EF\u9009 ${TEMPLATE_NAMES.join(" | ")}`);
10815
10993
  }
10816
10994
  const { manifest, files } = generated;
10817
- const vars = { name, template: code };
10818
- const dirFiles = renderTemplateFiles(files, vars, manifest);
10995
+ return renderTemplatePackage({ code, version: manifest.version, manifest, files }, name);
10996
+ }
10997
+ function renderTemplatePackage(pkg, name) {
10998
+ const manifest = pkg.manifest;
10999
+ const vars = { name, template: pkg.code };
11000
+ const dirFiles = renderTemplateFiles(pkg.files, vars, manifest);
11001
+ const code = pkg.code;
10819
11002
  const ctx = { name, template: code, cliVersion: cliVersionOf() };
10820
11003
  const sharedFiles = (manifest.sharedAssets ?? []).flatMap((assetName) => {
10821
11004
  const asset = SHARED_ASSETS[assetName];
10822
11005
  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`);
11006
+ 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
11007
  }
10825
11008
  return asset(ctx);
10826
11009
  });
@@ -10835,7 +11018,7 @@ var InitError = class extends Error {
10835
11018
  this.name = "InitError";
10836
11019
  }
10837
11020
  };
10838
- async function initProject(cwd, name, template) {
11021
+ async function initProject(cwd, name, template, filesOverride) {
10839
11022
  if (!/^[a-z][a-z0-9-]{0,62}$/.test(name)) {
10840
11023
  throw new InitError(
10841
11024
  "INVALID_NAME",
@@ -10858,7 +11041,7 @@ async function initProject(cwd, name, template) {
10858
11041
  if (existing !== null) {
10859
11042
  throw new InitError("DIR_EXISTS", `\u76EE\u5F55 ${projectPath} \u5DF2\u5B58\u5728\uFF1A\u8BF7\u6362\u4E00\u4E2A\u540D\u5B57\u6216\u5148\u5220\u9664`);
10860
11043
  }
10861
- const files = templateFiles(template, name);
11044
+ const files = filesOverride ?? templateFiles(template, name);
10862
11045
  await mkdir2(projectPath, { recursive: true });
10863
11046
  await Promise.all(
10864
11047
  files.map(async (file) => {
@@ -11039,19 +11222,178 @@ async function fetchTemplates(server) {
11039
11222
  return templates ?? [];
11040
11223
  }
11041
11224
 
11225
+ // packages/cli/src/template-package.ts
11226
+ init_auth();
11227
+ init_credentials();
11228
+ import { mkdir as mkdir3, readFile as readFile2, readdir, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
11229
+ import { join as join3 } from "node:path";
11230
+ function cachedPackagePath(paths, code, version) {
11231
+ return join3(paths.home, "templates", `${code}-${version}.json`);
11232
+ }
11233
+ async function collectTemplateDir(dir) {
11234
+ const files = [];
11235
+ async function walk(current, prefix) {
11236
+ const entries = await readdir(current, { withFileTypes: true });
11237
+ for (const entry of entries) {
11238
+ const full = join3(current, entry.name);
11239
+ const rel = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
11240
+ if (entry.isDirectory()) {
11241
+ await walk(full, rel);
11242
+ } else {
11243
+ files.push({ path: rel, content: await readFile2(full, "utf8") });
11244
+ }
11245
+ }
11246
+ }
11247
+ await walk(dir, "");
11248
+ files.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
11249
+ return files;
11250
+ }
11251
+ async function loadCachedPackage(paths, code, version) {
11252
+ let text;
11253
+ try {
11254
+ text = await readFile2(cachedPackagePath(paths, code, version), "utf8");
11255
+ } catch {
11256
+ return null;
11257
+ }
11258
+ let raw;
11259
+ try {
11260
+ raw = JSON.parse(text);
11261
+ } catch {
11262
+ return null;
11263
+ }
11264
+ if (typeof raw !== "object" || raw === null) return null;
11265
+ const pkg = raw;
11266
+ if (pkg.code !== code || pkg.version !== version || !Array.isArray(pkg.files)) return null;
11267
+ return pkg;
11268
+ }
11269
+ async function saveCachedPackage(paths, pkg) {
11270
+ await mkdir3(join3(paths.home, "templates"), { recursive: true });
11271
+ await writeFile2(cachedPackagePath(paths, pkg.code, pkg.version), JSON.stringify(pkg), "utf8");
11272
+ }
11273
+ async function downloadTemplatePackage(server, code) {
11274
+ let response;
11275
+ try {
11276
+ response = await fetch(`${server}/api/v1/templates/${code}/package`);
11277
+ } catch (error) {
11278
+ throw new CliError(
11279
+ "SERVER_UNREACHABLE",
11280
+ `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
11281
+ );
11282
+ }
11283
+ const text = await response.text();
11284
+ let parsed = null;
11285
+ try {
11286
+ parsed = text.length === 0 ? null : JSON.parse(text);
11287
+ } catch {
11288
+ parsed = null;
11289
+ }
11290
+ if (response.status !== 200) {
11291
+ const msg = parsed?.error;
11292
+ throw new CliError(
11293
+ "TEMPLATE_PACKAGE_FAILED",
11294
+ msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}\uFF08\u6A21\u677F ${code} \u53EF\u80FD\u6682\u65E0\u6258\u7BA1\u5305\uFF09`
11295
+ );
11296
+ }
11297
+ const pkg = parsed;
11298
+ if (typeof pkg.code !== "string" || typeof pkg.version !== "string" || !Array.isArray(pkg.files)) {
11299
+ throw new CliError("TEMPLATE_PACKAGE_FAILED", `\u5E73\u53F0\u8FD4\u56DE\u7684\u6A21\u677F\u5305 ${code} \u5F62\u72B6\u975E\u6CD5`);
11300
+ }
11301
+ return pkg;
11302
+ }
11303
+ async function uploadTemplatePackage(paths, pkg) {
11304
+ const credentials = await loadCredentials(paths);
11305
+ if (credentials === null) {
11306
+ 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");
11307
+ }
11308
+ const server = credentials.server;
11309
+ let response;
11310
+ try {
11311
+ response = await fetch(`${server}/api/v1/templates/${pkg.code}/package`, {
11312
+ method: "PUT",
11313
+ headers: {
11314
+ "content-type": "application/json",
11315
+ cookie: `better-auth.session_token=${decodeToken(credentials.encodedToken)}`
11316
+ },
11317
+ body: JSON.stringify(pkg)
11318
+ });
11319
+ } catch (error) {
11320
+ throw new CliError(
11321
+ "SERVER_UNREACHABLE",
11322
+ `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
11323
+ );
11324
+ }
11325
+ const text = await response.text();
11326
+ let parsed = null;
11327
+ try {
11328
+ parsed = text.length === 0 ? null : JSON.parse(text);
11329
+ } catch {
11330
+ parsed = null;
11331
+ }
11332
+ if (response.status !== 200) {
11333
+ const msg = parsed?.error;
11334
+ if (response.status === 401) {
11335
+ throw new CliError("SESSION_EXPIRED", "\u4F1A\u8BDD\u5DF2\u5931\u6548\uFF1A\u8BF7\u91CD\u65B0\u6267\u884C adep login \u540E\u518D\u4E0A\u4F20");
11336
+ }
11337
+ throw new CliError("TEMPLATE_PUBLISH_FAILED", msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`);
11338
+ }
11339
+ }
11340
+ function packageManifestEntry(pkg) {
11341
+ const entry = pkg.files.find((file) => file.path === "template.json");
11342
+ if (entry === void 0) return null;
11343
+ try {
11344
+ const parsed = JSON.parse(entry.content);
11345
+ return typeof parsed === "object" && parsed !== null ? parsed : null;
11346
+ } catch {
11347
+ return null;
11348
+ }
11349
+ }
11350
+ async function assertPublishableTemplate(dir, expectedCode) {
11351
+ let info;
11352
+ try {
11353
+ info = await stat3(join3(dir, "template.json"));
11354
+ } catch {
11355
+ throw new CliError(
11356
+ "TEMPLATE_NOT_PUBLISHABLE",
11357
+ `\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`
11358
+ );
11359
+ }
11360
+ if (!info.isFile()) {
11361
+ throw new CliError("TEMPLATE_NOT_PUBLISHABLE", `\u76EE\u5F55 ${dir}/template.json \u4E0D\u662F\u6587\u4EF6`);
11362
+ }
11363
+ const manifest = packageManifestEntry({
11364
+ code: expectedCode,
11365
+ version: "",
11366
+ manifest: {},
11367
+ files: [{ path: "template.json", content: await readFile2(join3(dir, "template.json"), "utf8") }]
11368
+ });
11369
+ if (manifest === null) {
11370
+ throw new CliError("TEMPLATE_NOT_PUBLISHABLE", `\u76EE\u5F55 ${dir}/template.json \u4E0D\u662F\u5408\u6CD5 JSON`);
11371
+ }
11372
+ if (manifest["code"] !== expectedCode) {
11373
+ throw new CliError(
11374
+ "TEMPLATE_NOT_PUBLISHABLE",
11375
+ `\u6A21\u677F\u6E05\u5355 code "${String(manifest["code"])}" \u4E0E\u76EE\u5F55\u540D ${expectedCode} \u4E0D\u4E00\u81F4`
11376
+ );
11377
+ }
11378
+ if (typeof manifest["version"] !== "string") {
11379
+ throw new CliError("TEMPLATE_NOT_PUBLISHABLE", `\u6A21\u677F\u6E05\u5355 ${expectedCode} \u7F3A version \u5B57\u7B26\u4E32`);
11380
+ }
11381
+ return { manifest, version: manifest["version"] };
11382
+ }
11383
+
11042
11384
  // packages/cli/src/commands/init.ts
11043
11385
  function registerInit(program2, ctx) {
11044
11386
  const templateHelp = `\u6A21\u677F\uFF1A${TEMPLATE_NAMES.join(" | ")}`;
11045
11387
  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
11388
  "-s, --server <url>",
11047
- "\u5E73\u53F0\u5730\u5740\uFF08--list \u7528\uFF1B\u7F3A\u7701\u8BFB ADEP_SERVER \u6216 http://localhost:3000\uFF09"
11389
+ "\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
11390
  ).action(
11049
11391
  async (name, flags) => {
11050
11392
  const command = ctx.io("init");
11051
11393
  await command.run(async () => {
11052
11394
  if (flags.list === true) {
11053
- const server = flags.server ?? resolveServer();
11054
- const templates = await fetchTemplates(server);
11395
+ const server2 = flags.server ?? resolveServer();
11396
+ const templates = await fetchTemplates(server2);
11055
11397
  command.ok(
11056
11398
  { templates },
11057
11399
  (data) => data.templates.map(
@@ -11072,18 +11414,81 @@ function registerInit(program2, ctx) {
11072
11414
  `\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 ${TEMPLATE_NAMES.join(" | ")}`
11073
11415
  );
11074
11416
  }
11075
- const result = await initProject(ctx.cwd, name, template);
11417
+ const server = flags.server ?? resolveServer();
11418
+ let filesOverride;
11419
+ try {
11420
+ const summary = (await fetchTemplates(server)).find((tpl) => tpl.code === template);
11421
+ if (summary?.hasPackage === true && summary.version !== void 0) {
11422
+ const cached = await loadCachedPackage(ctx.paths, template, summary.version);
11423
+ const pkg = cached ?? await downloadTemplatePackage(server, template);
11424
+ if (cached === null) {
11425
+ await saveCachedPackage(ctx.paths, pkg);
11426
+ command.line(`\u5DF2\u4E0B\u8F7D\u5E73\u53F0\u6A21\u677F\u5305 ${pkg.code}@${pkg.version}\uFF08\u7F13\u5B58\u5230\u672C\u5730\uFF09`);
11427
+ }
11428
+ filesOverride = renderTemplatePackage(
11429
+ {
11430
+ code: pkg.code,
11431
+ version: pkg.version,
11432
+ manifest: pkg.manifest,
11433
+ files: pkg.files
11434
+ },
11435
+ name
11436
+ );
11437
+ }
11438
+ } catch (error) {
11439
+ 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)}`);
11440
+ }
11441
+ const result = await initProject(ctx.cwd, name, template, filesOverride);
11076
11442
  command.ok(result, (data) => `\u5DF2\u521B\u5EFA ${data.projectPath}`);
11077
11443
  });
11078
11444
  }
11079
11445
  );
11080
11446
  }
11081
11447
 
11448
+ // packages/cli/src/commands/templates.ts
11449
+ init_auth();
11450
+ function registerTemplates(program2, ctx) {
11451
+ 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(
11452
+ "-d, --dir <dir>",
11453
+ "\u6A21\u677F\u76EE\u5F55\uFF08\u8986\u76D6\u9ED8\u8BA4 src/templates/<code>\uFF0C\u53D1\u5E03\u81EA\u5B9A\u4E49\u76EE\u5F55\u65F6\u7528\uFF09"
11454
+ ).action(
11455
+ async (code, flags) => {
11456
+ const command = ctx.io("templates");
11457
+ await command.run(async () => {
11458
+ const codes = code === void 0 ? [...TEMPLATE_CODES] : [code];
11459
+ if (code !== void 0 && !TEMPLATE_CODES.includes(code)) {
11460
+ throw new CliError(
11461
+ "INVALID_TEMPLATE",
11462
+ `\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`
11463
+ );
11464
+ }
11465
+ const uploaded = [];
11466
+ for (const templateCode of codes) {
11467
+ const dir = flags.dir ?? localTemplateDir(templateCode);
11468
+ const { manifest, version } = await assertPublishableTemplate(dir, templateCode);
11469
+ const files = await collectTemplateDir(dir);
11470
+ await uploadTemplatePackage(ctx.paths, {
11471
+ code: templateCode,
11472
+ version,
11473
+ manifest,
11474
+ files
11475
+ });
11476
+ uploaded.push(`${templateCode}@${version}`);
11477
+ }
11478
+ command.ok(
11479
+ { uploaded },
11480
+ (data) => `\u5DF2\u4E0A\u4F20\u6A21\u677F\u5305\uFF1A${data.uploaded.join("\u3001")}`
11481
+ );
11482
+ });
11483
+ }
11484
+ );
11485
+ }
11486
+
11082
11487
  // packages/cli/src/import-cf.ts
11083
11488
  init_adep_config();
11084
11489
  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";
11490
+ import { copyFile, mkdir as mkdir4, readFile as readFile3, readdir as readdir2, stat as stat4, writeFile as writeFile3 } from "node:fs/promises";
11491
+ import { basename, dirname as dirname4, join as join4, relative, resolve as resolve2 } from "node:path";
11087
11492
  var TomlSyntaxError = class extends Error {
11088
11493
  constructor(message) {
11089
11494
  super(message);
@@ -11337,13 +11742,13 @@ var SKIP_COPY_NAMES = /* @__PURE__ */ new Set([
11337
11742
  async function copyWorkerDir(sourceDir, targetDir, mainFile) {
11338
11743
  const copied = [];
11339
11744
  const renamedIndex = [];
11340
- const entries = await readdir(sourceDir, { withFileTypes: true });
11745
+ const entries = await readdir2(sourceDir, { withFileTypes: true });
11341
11746
  for (const entry of entries) {
11342
- const from = join3(sourceDir, entry.name);
11343
- const to = join3(targetDir, entry.name);
11747
+ const from = join4(sourceDir, entry.name);
11748
+ const to = join4(targetDir, entry.name);
11344
11749
  if (SKIP_COPY_NAMES.has(entry.name)) continue;
11345
11750
  if (entry.isDirectory()) {
11346
- await mkdir3(to, { recursive: true });
11751
+ await mkdir4(to, { recursive: true });
11347
11752
  const sub = await copyWorkerDir(from, to, "");
11348
11753
  copied.push(...sub.copied);
11349
11754
  renamedIndex.push(...sub.renamedIndex);
@@ -11351,7 +11756,7 @@ async function copyWorkerDir(sourceDir, targetDir, mainFile) {
11351
11756
  }
11352
11757
  if (from === mainFile) continue;
11353
11758
  if (entry.name === "index.ts") {
11354
- await copyFile(from, join3(targetDir, "_index.ts"));
11759
+ await copyFile(from, join4(targetDir, "_index.ts"));
11355
11760
  renamedIndex.push("_index.ts");
11356
11761
  continue;
11357
11762
  }
@@ -11362,7 +11767,7 @@ async function copyWorkerDir(sourceDir, targetDir, mainFile) {
11362
11767
  }
11363
11768
  async function readDevVars(sourceDir) {
11364
11769
  try {
11365
- const text = await readFile2(join3(sourceDir, ".dev.vars"), "utf8");
11770
+ const text = await readFile3(join4(sourceDir, ".dev.vars"), "utf8");
11366
11771
  const vars = {};
11367
11772
  for (const line of text.split(/\r?\n/)) {
11368
11773
  const trimmed = line.trim();
@@ -11380,14 +11785,14 @@ async function readDevVars(sourceDir) {
11380
11785
  async function copyAssetsToWeb(sourceDir, assetsDir, outDir) {
11381
11786
  const files = [];
11382
11787
  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 });
11788
+ const target = join4(outDir, "web");
11789
+ await mkdir4(target, { recursive: true });
11790
+ const entries = await readdir2(from, { withFileTypes: true });
11386
11791
  for (const entry of entries) {
11387
- const src = join3(from, entry.name);
11388
- const dst = join3(target, entry.name);
11792
+ const src = join4(from, entry.name);
11793
+ const dst = join4(target, entry.name);
11389
11794
  if (entry.isDirectory()) {
11390
- await mkdir3(dst, { recursive: true });
11795
+ await mkdir4(dst, { recursive: true });
11391
11796
  const sub = await copyAssetsToWeb(src, ".", outDir);
11392
11797
  files.push(...sub);
11393
11798
  continue;
@@ -11634,11 +12039,11 @@ function renderImportPackageJson(name) {
11634
12039
  async function importCfProject(cwd, sourceDir, options = {}) {
11635
12040
  let tomlText;
11636
12041
  try {
11637
- tomlText = await readFile2(join3(sourceDir, "wrangler.toml"), "utf8");
12042
+ tomlText = await readFile3(join4(sourceDir, "wrangler.toml"), "utf8");
11638
12043
  } catch {
11639
12044
  throw new ImportCfError(
11640
12045
  "NO_WRANGLER",
11641
- `\u627E\u4E0D\u5230 ${join3(sourceDir, "wrangler.toml")}\uFF1A\u9700\u5728 Cloudflare \u9879\u76EE\u6839\u6267\u884C\u5BFC\u5165`
12046
+ `\u627E\u4E0D\u5230 ${join4(sourceDir, "wrangler.toml")}\uFF1A\u9700\u5728 Cloudflare \u9879\u76EE\u6839\u6267\u884C\u5BFC\u5165`
11642
12047
  );
11643
12048
  }
11644
12049
  let config;
@@ -11653,7 +12058,7 @@ async function importCfProject(cwd, sourceDir, options = {}) {
11653
12058
  const workerName = slugify(config.name ?? basename(sourceDir), "worker");
11654
12059
  const outDir = resolve2(cwd, options.out ?? `imported-${workerName}`);
11655
12060
  try {
11656
- await stat3(outDir);
12061
+ await stat4(outDir);
11657
12062
  throw new ImportCfError("DIR_EXISTS", `\u8F93\u51FA\u76EE\u5F55 ${outDir} \u5DF2\u5B58\u5728\uFF1A\u8BF7\u6362 --out \u6216\u5148\u5220\u9664`);
11658
12063
  } catch (error) {
11659
12064
  if (error instanceof ImportCfError) throw error;
@@ -11673,26 +12078,26 @@ async function importCfProject(cwd, sourceDir, options = {}) {
11673
12078
  const configText = renderAdepConfig(adepConfig, {
11674
12079
  header: "// \u7531 adep import cf \u751F\u6210\uFF08CF-015\uFF09\uFF1A\u7ED1\u5B9A\u58F0\u660E\u4E0E wrangler.toml \u5BF9\u5E94"
11675
12080
  });
11676
- await mkdir3(outDir, { recursive: true });
11677
- await writeFile2(join3(outDir, "adep.config.ts"), configText, "utf8");
12081
+ await mkdir4(outDir, { recursive: true });
12082
+ await writeFile3(join4(outDir, "adep.config.ts"), configText, "utf8");
11678
12083
  files.push("adep.config.ts");
11679
- await writeFile2(join3(outDir, "package.json"), renderImportPackageJson(workerName), "utf8");
12084
+ await writeFile3(join4(outDir, "package.json"), renderImportPackageJson(workerName), "utf8");
11680
12085
  files.push("package.json");
11681
12086
  let mainCopied = false;
11682
12087
  if (config.main !== void 0) {
11683
12088
  const mainAbs = resolve2(sourceDir, config.main);
11684
12089
  let mainStat;
11685
12090
  try {
11686
- mainStat = await stat3(mainAbs);
12091
+ mainStat = await stat4(mainAbs);
11687
12092
  } catch {
11688
12093
  throw new ImportCfError("MAIN_MISSING", `main \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${config.main}`);
11689
12094
  }
11690
12095
  if (!mainStat.isFile()) {
11691
12096
  throw new ImportCfError("MAIN_NOT_FILE", `main \u4E0D\u662F\u6587\u4EF6\uFF1A${config.main}`);
11692
12097
  }
11693
- const fnDir = join3(outDir, "functions", workerName);
11694
- await mkdir3(fnDir, { recursive: true });
11695
- await copyFile(mainAbs, join3(fnDir, "worker.ts"));
12098
+ const fnDir = join4(outDir, "functions", workerName);
12099
+ await mkdir4(fnDir, { recursive: true });
12100
+ await copyFile(mainAbs, join4(fnDir, "worker.ts"));
11696
12101
  files.push(`functions/${workerName}/worker.ts`);
11697
12102
  mainCopied = true;
11698
12103
  const mainDir = dirname4(mainAbs);
@@ -11706,7 +12111,7 @@ async function importCfProject(cwd, sourceDir, options = {}) {
11706
12111
  if (copied.length > 0) {
11707
12112
  warnings.push(`\u5DF2\u590D\u5236\u540C\u76EE\u5F55\u4F9D\u8D56\u6A21\u5757 ${copied.length} \u4E2A\uFF08\u4FDD\u6301\u76F8\u5BF9 import\uFF09`);
11708
12113
  }
11709
- await writeFile2(join3(fnDir, "index.ts"), renderFunctionEntry("worker", cfBindings), "utf8");
12114
+ await writeFile3(join4(fnDir, "index.ts"), renderFunctionEntry("worker", cfBindings), "utf8");
11710
12115
  files.push(`functions/${workerName}/index.ts`);
11711
12116
  }
11712
12117
  let dosMigrated = 0;
@@ -11721,20 +12126,20 @@ async function importCfProject(cwd, sourceDir, options = {}) {
11721
12126
  );
11722
12127
  }
11723
12128
  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");
12129
+ const fnDir = join4(outDir, "functions", workerName);
12130
+ const workerPath = join4(fnDir, "worker.ts");
12131
+ const workerText = await readFile3(workerPath, "utf8");
11727
12132
  const { text: stripped, removed } = stripDurableObjectClasses(
11728
12133
  workerText,
11729
12134
  doBindings.map((b) => b.className)
11730
12135
  );
11731
- await writeFile2(workerPath, stripped, "utf8");
12136
+ await writeFile3(workerPath, stripped, "utf8");
11732
12137
  if (removed.length > 0) {
11733
- await mkdir3(join3(fnDir, "durable-objects"), { recursive: true });
12138
+ await mkdir4(join4(fnDir, "durable-objects"), { recursive: true });
11734
12139
  await Promise.all(
11735
12140
  removed.map(async (r) => {
11736
- await writeFile2(
11737
- join3(fnDir, "durable-objects", `${r.className}.ts`),
12141
+ await writeFile3(
12142
+ join4(fnDir, "durable-objects", `${r.className}.ts`),
11738
12143
  `${r.source}
11739
12144
  `,
11740
12145
  "utf8"
@@ -11744,8 +12149,8 @@ async function importCfProject(cwd, sourceDir, options = {}) {
11744
12149
  );
11745
12150
  }
11746
12151
  if (removed.length > 0) {
11747
- await writeFile2(
11748
- join3(fnDir, "state-objects.ts"),
12152
+ await writeFile3(
12153
+ join4(fnDir, "state-objects.ts"),
11749
12154
  renderStateObjectDeclaration(doBindings, removed),
11750
12155
  "utf8"
11751
12156
  );
@@ -11790,7 +12195,7 @@ async function importCfProject(cwd, sourceDir, options = {}) {
11790
12195
  unsupported,
11791
12196
  warnings
11792
12197
  });
11793
- await writeFile2(join3(outDir, "MIGRATION.md"), migration, "utf8");
12198
+ await writeFile3(join4(outDir, "MIGRATION.md"), migration, "utf8");
11794
12199
  files.push("MIGRATION.md");
11795
12200
  if (!mainCopied) {
11796
12201
  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 +12262,13 @@ function registerDevServers(program2, ctx) {
11857
12262
  "\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
12263
  ).option(
11859
12264
  "--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"
12265
+ "\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"
12266
+ ).option(
12267
+ "--db <mode>",
12268
+ "\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"
12269
+ ).option(
12270
+ "--db-file <path>",
12271
+ "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
12272
  ).option(
11862
12273
  "--spa",
11863
12274
  "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 +12284,8 @@ function registerDevServers(program2, ctx) {
11873
12284
  ...flags.static === void 0 ? {} : { staticDir: flags.static },
11874
12285
  ...flags.watch === void 0 ? {} : { watch: true },
11875
12286
  ...flags.schema === void 0 ? {} : { schemaFile: flags.schema },
12287
+ ...flags.db === void 0 ? {} : { db: flags.db },
12288
+ ...flags.dbFile === void 0 ? {} : { dbFile: flags.dbFile },
11876
12289
  ...flags.spa === void 0 ? {} : { spaFallback: true }
11877
12290
  });
11878
12291
  await new Promise(() => void 0);
@@ -11885,10 +12298,10 @@ function registerDevServers(program2, ctx) {
11885
12298
  init_auth();
11886
12299
  init_client();
11887
12300
  init_deploy();
11888
- import { stat as stat8 } from "node:fs/promises";
11889
- import { join as join16, resolve as resolve8 } from "node:path";
12301
+ import { stat as stat9 } from "node:fs/promises";
12302
+ import { join as join17, resolve as resolve10 } from "node:path";
11890
12303
  async function resolveProjectId2(client, cwd, slug) {
11891
- const resolvedSlug = await resolveSlug(resolve8(cwd), slug);
12304
+ const resolvedSlug = await resolveSlug(resolve10(cwd), slug);
11892
12305
  const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
11893
12306
  const match = listed.projects.find((project2) => project2.slug === resolvedSlug);
11894
12307
  if (match === void 0) {
@@ -11952,8 +12365,8 @@ async function runPublish(paths, io, cwd, flags) {
11952
12365
  });
11953
12366
  }
11954
12367
  if (wantFrontend) {
11955
- const webDir = join16(cwd, "web");
11956
- const webStat = await stat8(webDir).catch(() => null);
12368
+ const webDir = join17(cwd, "web");
12369
+ const webStat = await stat9(webDir).catch(() => null);
11957
12370
  if (webStat !== null && webStat.isDirectory()) {
11958
12371
  const { frontendSync: frontendSync2 } = await Promise.resolve().then(() => (init_frontend(), frontend_exports));
11959
12372
  await frontendSync2(paths, {
@@ -12699,6 +13112,7 @@ function buildProgram(options = {}) {
12699
13112
  const jsonMode = () => program2.opts()["json"] === true;
12700
13113
  const ctx = createCliContext({ output, paths, cwd, json: jsonMode });
12701
13114
  registerInit(program2, ctx);
13115
+ registerTemplates(program2, ctx);
12702
13116
  registerImport(program2, ctx);
12703
13117
  registerDevServers(program2, ctx);
12704
13118
  registerPublish(program2, ctx);