@adep/cli 0.1.8 → 0.1.9

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
@@ -460,6 +460,16 @@ var init_prompt = __esm({
460
460
  }
461
461
  });
462
462
 
463
+ // packages/runtime/src/shared/regexp.ts
464
+ function escapeRegExp(text) {
465
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
466
+ }
467
+ var init_regexp = __esm({
468
+ "packages/runtime/src/shared/regexp.ts"() {
469
+ "use strict";
470
+ }
471
+ });
472
+
463
473
  // packages/runtime/src/shared/capability-keys.ts
464
474
  var RPC_CAPABILITY_KEY, CHAIN_CAPABILITY_KEY, DB_RPC, REALTIME_CAPABILITY_CODES, REALTIME_CAPABILITY_METHODS;
465
475
  var init_capability_keys = __esm({
@@ -1663,7 +1673,7 @@ var init_cloud = __esm({
1663
1673
  }
1664
1674
  });
1665
1675
 
1666
- // packages/cli/src/sim/sql-engine.ts
1676
+ // packages/runtime/src/sim/sql-engine.ts
1667
1677
  function ident(raw) {
1668
1678
  return raw.trim().replace(/^"|"$/g, "").trim();
1669
1679
  }
@@ -1685,7 +1695,7 @@ function parseCreateTable(ddl) {
1685
1695
  );
1686
1696
  if (m === null) return null;
1687
1697
  const name = ident(m[1]);
1688
- const body = m[2];
1698
+ const body = m[3];
1689
1699
  const columns = [];
1690
1700
  for (const part of body.split(",")) {
1691
1701
  const tokens = part.trim().split(/\s+/);
@@ -1775,9 +1785,9 @@ function matchValue(value, clause) {
1775
1785
  const right = clause.value;
1776
1786
  switch (op) {
1777
1787
  case "=":
1778
- return left === right;
1788
+ return left !== null && right !== null && left === right;
1779
1789
  case "!=":
1780
- return left !== right;
1790
+ return left !== null && right !== null && left !== right;
1781
1791
  case ">":
1782
1792
  return left !== null && right !== null && left > right;
1783
1793
  case ">=":
@@ -1828,7 +1838,7 @@ function project(rows, selectRaw) {
1828
1838
  }
1829
1839
  var SimDbError, ParamCursor, SimSqlEngine;
1830
1840
  var init_sql_engine = __esm({
1831
- "packages/cli/src/sim/sql-engine.ts"() {
1841
+ "packages/runtime/src/sim/sql-engine.ts"() {
1832
1842
  "use strict";
1833
1843
  SimDbError = class extends Error {
1834
1844
  constructor(code, message) {
@@ -2258,6 +2268,19 @@ function assertSafeStoragePath(path) {
2258
2268
  }
2259
2269
  return path;
2260
2270
  }
2271
+ function assertStoragePrefix(prefix) {
2272
+ if (prefix !== void 0 && prefix !== "") {
2273
+ const segments = prefix.split("/");
2274
+ if (prefix.startsWith("/") || /[\\]/.test(prefix) || segments.some((segment) => segment === "..")) {
2275
+ throw new StorageError(
2276
+ 400,
2277
+ STORAGE_CODES.invalidPath,
2278
+ `\u975E\u6CD5\u524D\u7F00 "${prefix}"\uFF08\u7981\u6B62 / \u5F00\u5934\u3001\u53CD\u659C\u6760\u6216 .. \u7A7F\u8D8A\uFF09`
2279
+ );
2280
+ }
2281
+ }
2282
+ return prefix ?? "";
2283
+ }
2261
2284
  var PROJECT_QUOTA_BYTES, StorageError, STORAGE_CODES;
2262
2285
  var init_driver = __esm({
2263
2286
  "packages/runtime/src/storage/driver.ts"() {
@@ -2682,16 +2705,7 @@ function createLocalStorageDriver(options) {
2682
2705
  await unlink(metaPath(projectId, path)).catch(() => void 0);
2683
2706
  },
2684
2707
  async list(projectId, prefix) {
2685
- if (prefix !== void 0 && prefix !== "") {
2686
- const segments = prefix.split("/");
2687
- if (prefix.startsWith("/") || /[\\]/.test(prefix) || segments.some((segment) => segment === "..")) {
2688
- throw new StorageError(
2689
- 400,
2690
- STORAGE_CODES.invalidPath,
2691
- `\u975E\u6CD5\u524D\u7F00 "${prefix}"\uFF08\u7981\u6B62 / \u5F00\u5934\u3001\u53CD\u659C\u6760\u6216 .. \u7A7F\u8D8A\uFF09`
2692
- );
2693
- }
2694
- }
2708
+ assertStoragePrefix(prefix);
2695
2709
  const root = bucketDir(projectId);
2696
2710
  const metas = [];
2697
2711
  const walk = async (dir, relative6) => {
@@ -2773,7 +2787,7 @@ var init_storage = __esm({
2773
2787
  }
2774
2788
  });
2775
2789
 
2776
- // packages/cli/src/sim/realtime.ts
2790
+ // packages/runtime/src/sim/realtime.ts
2777
2791
  function realtimeError(code, message) {
2778
2792
  return new Error(`[${code}] ${message}`);
2779
2793
  }
@@ -2854,7 +2868,7 @@ function createSimRealtimeCapability() {
2854
2868
  }
2855
2869
  var SimRealtime, MAX_BUFFERED_MESSAGES, MAX_SUBSCRIPTIONS, REALTIME_CODES;
2856
2870
  var init_realtime = __esm({
2857
- "packages/cli/src/sim/realtime.ts"() {
2871
+ "packages/runtime/src/sim/realtime.ts"() {
2858
2872
  "use strict";
2859
2873
  init_capability_keys();
2860
2874
  SimRealtime = class {
@@ -2902,12 +2916,7 @@ var init_realtime = __esm({
2902
2916
  }
2903
2917
  });
2904
2918
 
2905
- // packages/cli/src/sim/runtime.ts
2906
- import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
2907
- import { dirname as dirname6, join as join6 } from "node:path";
2908
- function simDir(cwd) {
2909
- return join6(cwd, ".adep", "sim");
2910
- }
2919
+ // packages/runtime/src/sim/merge.ts
2911
2920
  function mergeBundles(bundles) {
2912
2921
  const capabilities = [];
2913
2922
  const byName = /* @__PURE__ */ new Map();
@@ -2927,6 +2936,18 @@ function mergeBundles(bundles) {
2927
2936
  }
2928
2937
  return { capabilities, rpcHandlers };
2929
2938
  }
2939
+ var init_merge = __esm({
2940
+ "packages/runtime/src/sim/merge.ts"() {
2941
+ "use strict";
2942
+ }
2943
+ });
2944
+
2945
+ // packages/cli/src/sim/runtime.ts
2946
+ import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
2947
+ import { dirname as dirname6, join as join6 } from "node:path";
2948
+ function simDir(cwd) {
2949
+ return join6(cwd, ".adep", "sim");
2950
+ }
2930
2951
  function jsonStorage(cwd) {
2931
2952
  const file = join6(simDir(cwd), "db.json");
2932
2953
  return {
@@ -2974,6 +2995,7 @@ var init_runtime = __esm({
2974
2995
  init_kv();
2975
2996
  init_storage();
2976
2997
  init_realtime();
2998
+ init_merge();
2977
2999
  }
2978
3000
  });
2979
3001
 
@@ -3073,16 +3095,32 @@ var init_invoke = __esm({
3073
3095
  }
3074
3096
  });
3075
3097
 
3076
- // packages/cli/src/builtin-deps.ts
3077
- var LOCAL_STATE_OBJECTS_SPECIFIER, LOCAL_BUILTIN_DEPS;
3098
+ // shared/builtin-deps.ts
3099
+ var CF_COMPAT_SPECIFIER, STATE_OBJECTS_SPECIFIER, BUILTIN_DEPS, BUILTIN_DEPS_CSV;
3078
3100
  var init_builtin_deps = __esm({
3079
- "packages/cli/src/builtin-deps.ts"() {
3101
+ "shared/builtin-deps.ts"() {
3080
3102
  "use strict";
3081
- LOCAL_STATE_OBJECTS_SPECIFIER = "@adep/runtime/state-objects";
3082
- LOCAL_BUILTIN_DEPS = [
3083
- "@adep/cf-compat",
3084
- LOCAL_STATE_OBJECTS_SPECIFIER
3103
+ CF_COMPAT_SPECIFIER = "@adep/cf-compat";
3104
+ STATE_OBJECTS_SPECIFIER = "@adep/runtime/state-objects";
3105
+ BUILTIN_DEPS = [
3106
+ CF_COMPAT_SPECIFIER,
3107
+ STATE_OBJECTS_SPECIFIER,
3108
+ "axios",
3109
+ "lodash",
3110
+ "dayjs",
3111
+ "zod"
3085
3112
  ];
3113
+ BUILTIN_DEPS_CSV = BUILTIN_DEPS.join(",");
3114
+ }
3115
+ });
3116
+
3117
+ // packages/cli/src/builtin-deps.ts
3118
+ var LOCAL_BUILTIN_DEPS;
3119
+ var init_builtin_deps2 = __esm({
3120
+ "packages/cli/src/builtin-deps.ts"() {
3121
+ "use strict";
3122
+ init_builtin_deps();
3123
+ LOCAL_BUILTIN_DEPS = [CF_COMPAT_SPECIFIER, STATE_OBJECTS_SPECIFIER];
3086
3124
  }
3087
3125
  });
3088
3126
 
@@ -3629,7 +3667,7 @@ var init_sandbox = __esm({
3629
3667
 
3630
3668
  // packages/runtime/src/state-objects/loader.ts
3631
3669
  function resolveStateObjectSpecifier(request) {
3632
- if (request === STATE_OBJECTS_SPECIFIER) return { StateObject };
3670
+ if (request === STATE_OBJECTS_SPECIFIER2) return { StateObject };
3633
3671
  return void 0;
3634
3672
  }
3635
3673
  function defaultStateSandboxGlobals() {
@@ -3686,14 +3724,14 @@ function loadStateObjectClasses(files, entry = STATE_OBJECTS_ENTRY, options = {}
3686
3724
  const exportsObject = loadModule(entry, files, globals, /* @__PURE__ */ new Map(), options.resolveBare, /* @__PURE__ */ new Map());
3687
3725
  return collectStateObjectClasses(exportsObject);
3688
3726
  }
3689
- var STATE_OBJECTS_ENTRY, STATE_OBJECTS_SPECIFIER;
3727
+ var STATE_OBJECTS_ENTRY, STATE_OBJECTS_SPECIFIER2;
3690
3728
  var init_loader = __esm({
3691
3729
  "packages/runtime/src/state-objects/loader.ts"() {
3692
3730
  "use strict";
3693
3731
  init_runtime2();
3694
3732
  init_sandbox();
3695
3733
  STATE_OBJECTS_ENTRY = "state-objects.ts";
3696
- STATE_OBJECTS_SPECIFIER = "@adep/runtime/state-objects";
3734
+ STATE_OBJECTS_SPECIFIER2 = "@adep/runtime/state-objects";
3697
3735
  }
3698
3736
  });
3699
3737
 
@@ -3988,6 +4026,24 @@ var init_rpc_key = __esm({
3988
4026
  }
3989
4027
  });
3990
4028
 
4029
+ // packages/runtime/src/functions/runtime/rpc-wire.ts
4030
+ function wireRpcResponses(port, pending) {
4031
+ port.on?.((message) => {
4032
+ const reply = message;
4033
+ if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
4034
+ const entry = pending.get(reply.id);
4035
+ if (entry === void 0) return;
4036
+ pending.delete(reply.id);
4037
+ if (reply.ok === true) entry.resolve(reply.result);
4038
+ else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
4039
+ });
4040
+ }
4041
+ var init_rpc_wire = __esm({
4042
+ "packages/runtime/src/functions/runtime/rpc-wire.ts"() {
4043
+ "use strict";
4044
+ }
4045
+ });
4046
+
3991
4047
  // packages/runtime/src/functions/runtime/chain.ts
3992
4048
  function isChainCapability(value) {
3993
4049
  if (typeof value !== "object" || value === null) return false;
@@ -4098,13 +4154,10 @@ function errorMessageOf2(error) {
4098
4154
  }
4099
4155
  return String(error);
4100
4156
  }
4101
- function escapeRegExp2(text) {
4102
- return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4103
- }
4104
4157
  function firstUserFrame(stack, files) {
4105
4158
  for (const key of Object.keys(files)) {
4106
4159
  const match = new RegExp(
4107
- `(?<![\\w$/.])${escapeRegExp2(key)}:(\\d+)(?::(\\d+))?(?::(\\d+))?`
4160
+ `(?<![\\w$/.])${escapeRegExp(key)}:(\\d+)(?::(\\d+))?(?::(\\d+))?`
4108
4161
  ).exec(stack);
4109
4162
  if (match !== null) {
4110
4163
  return match[2] === void 0 ? `${key}:${match[1]}` : `${key}:${match[1]}:${match[2]}`;
@@ -4159,15 +4212,7 @@ function runWorker(input, port) {
4159
4212
  const container = createCloudContainer();
4160
4213
  const pending = /* @__PURE__ */ new Map();
4161
4214
  let rpcId = 0;
4162
- port.on?.((message) => {
4163
- const reply = message;
4164
- if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
4165
- const entry = pending.get(reply.id);
4166
- if (entry === void 0) return;
4167
- pending.delete(reply.id);
4168
- if (reply.ok === true) entry.resolve(reply.result);
4169
- else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
4170
- });
4215
+ wireRpcResponses(port, pending);
4171
4216
  for (const capability of input.capabilities ?? []) {
4172
4217
  container.register(
4173
4218
  capability.name,
@@ -4269,9 +4314,11 @@ var init_worker_entry = __esm({
4269
4314
  init_sandbox();
4270
4315
  init_sandbox_fetch();
4271
4316
  init_rpc_key();
4317
+ init_rpc_wire();
4272
4318
  init_chain();
4273
4319
  init_sandbox();
4274
4320
  init_manifest();
4321
+ init_regexp();
4275
4322
  workerPort = parentPort;
4276
4323
  if (workerPort !== null && workerData !== void 0) {
4277
4324
  const port = {
@@ -4286,41 +4333,35 @@ var init_worker_entry = __esm({
4286
4333
  }
4287
4334
  });
4288
4335
 
4289
- // packages/cli/src/dev.ts
4290
- var dev_exports = {};
4291
- __export(dev_exports, {
4292
- loadConfig: () => loadConfig,
4293
- parseEnvFile: () => parseEnvFile,
4294
- resolveRouteFnName: () => resolveRouteFnName,
4295
- startDevServer: () => startDevServer
4296
- });
4297
- import { createServer } from "node:http";
4298
- import { watch } from "node:fs";
4299
- import { mkdir as mkdir6, readdir as readdir3, readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises";
4300
- import { basename as basename2, join as join10, resolve as resolve4 } from "node:path";
4301
- async function loadConfig(cwd) {
4302
- const name = basename2(resolve4(cwd));
4303
- const config = await loadAdepConfigModule(cwd);
4304
- return {
4305
- name: config?.name ?? name,
4306
- functionsDir: config?.functionsDir ?? "functions",
4307
- functionsPrefix: config?.functions_prefix ?? "",
4308
- ...config?.environment === void 0 ? {} : { environment: config.environment }
4336
+ // packages/cli/src/dev-shared.ts
4337
+ import { readdir as readdir3, readFile as readFile7 } from "node:fs/promises";
4338
+ import { join as join10 } from "node:path";
4339
+ function bearerUserResolverFromEnv() {
4340
+ const raw = process.env.ADEP_AUTH_ISSUER;
4341
+ if (raw === void 0 || raw.trim() === "") return void 0;
4342
+ return createBearerUserResolver(raw.trim());
4343
+ }
4344
+ function createBearerUserResolver(issuer) {
4345
+ const userinfoUrl = `${issuer.replace(/\/+$/, "")}/oauth/userinfo`;
4346
+ return async (headers) => {
4347
+ const match = BEARER_TOKEN_RE.exec((headers["authorization"] ?? "").trim());
4348
+ const token = match?.[1]?.trim();
4349
+ if (token === void 0 || token === "") return null;
4350
+ try {
4351
+ const res = await fetch(userinfoUrl, { headers: { authorization: `Bearer ${token}` } });
4352
+ if (!res.ok) return null;
4353
+ const claims = await res.json();
4354
+ if (typeof claims.sub !== "string" || claims.sub.length === 0) return null;
4355
+ return {
4356
+ id: claims.sub,
4357
+ ...typeof claims.name === "string" ? { name: claims.name } : {},
4358
+ ...typeof claims.email === "string" ? { email: claims.email } : {}
4359
+ };
4360
+ } catch {
4361
+ return null;
4362
+ }
4309
4363
  };
4310
4364
  }
4311
- function parseEnvFile(content) {
4312
- const env = {};
4313
- for (const raw of content.split(/\r?\n/)) {
4314
- const line = raw.trim();
4315
- if (line.length === 0 || line.startsWith("#")) continue;
4316
- const eq = line.indexOf("=");
4317
- if (eq === -1) continue;
4318
- const key = line.slice(0, eq).trim();
4319
- if (key.length === 0) continue;
4320
- env[key] = line.slice(eq + 1).trim();
4321
- }
4322
- return env;
4323
- }
4324
4365
  async function collectFunctions(dir) {
4325
4366
  const files = {};
4326
4367
  const walk = async (sub, prefix) => {
@@ -4362,6 +4403,59 @@ function bodyOf(req) {
4362
4403
  req.on("error", rejectBody);
4363
4404
  });
4364
4405
  }
4406
+ function writeJson(res, status, payload) {
4407
+ res.writeHead(status, { "content-type": "application/json" });
4408
+ res.end(JSON.stringify(payload));
4409
+ }
4410
+ async function requestInput(url, req, readBody) {
4411
+ const query = {};
4412
+ for (const key of new Set(url.searchParams.keys())) {
4413
+ const values = url.searchParams.getAll(key);
4414
+ query[key] = values.length > 1 ? values.join(",") : values[0] ?? "";
4415
+ }
4416
+ const headers = {};
4417
+ for (const [key, value] of Object.entries(req.headers)) {
4418
+ if (typeof value === "string") headers[key] = value;
4419
+ }
4420
+ const body = req.method === "GET" || req.method === "HEAD" ? void 0 : await readBody(req);
4421
+ return {
4422
+ method: req.method ?? "GET",
4423
+ path: url.pathname,
4424
+ query,
4425
+ headers,
4426
+ ...body === void 0 ? {} : { body }
4427
+ };
4428
+ }
4429
+ var BEARER_TOKEN_RE;
4430
+ var init_dev_shared = __esm({
4431
+ "packages/cli/src/dev-shared.ts"() {
4432
+ "use strict";
4433
+ BEARER_TOKEN_RE = /^Bearer\s+(.+)$/i;
4434
+ }
4435
+ });
4436
+
4437
+ // packages/cli/src/dev.ts
4438
+ var dev_exports = {};
4439
+ __export(dev_exports, {
4440
+ loadConfig: () => loadConfig,
4441
+ parseEnvFile: () => parseEnvFile,
4442
+ resolveRouteFnName: () => resolveRouteFnName,
4443
+ startDevServer: () => startDevServer
4444
+ });
4445
+ import { createServer } from "node:http";
4446
+ import { watch } from "node:fs";
4447
+ import { mkdir as mkdir6, readFile as readFile8, writeFile as writeFile5 } from "node:fs/promises";
4448
+ import { basename as basename2, join as join11, resolve as resolve4 } from "node:path";
4449
+ async function loadConfig(cwd) {
4450
+ const name = basename2(resolve4(cwd));
4451
+ const config = await loadAdepConfigModule(cwd);
4452
+ return {
4453
+ name: config?.name ?? name,
4454
+ functionsDir: config?.functionsDir ?? "functions",
4455
+ functionsPrefix: config?.functions_prefix ?? "",
4456
+ ...config?.environment === void 0 ? {} : { environment: config.environment }
4457
+ };
4458
+ }
4365
4459
  function resolveRouteFnName(pathname, prefix) {
4366
4460
  const segments = pathname.split("/").filter((segment) => segment.length > 0);
4367
4461
  const normalizedPrefix = prefix.replace(/^\/+|\/+$/g, "");
@@ -4388,10 +4482,6 @@ function resolveRouteFnName(pathname, prefix) {
4388
4482
  }
4389
4483
  return { fnName: second };
4390
4484
  }
4391
- function writeJson(res, status, payload) {
4392
- res.writeHead(status, { "content-type": "application/json" });
4393
- res.end(JSON.stringify(payload));
4394
- }
4395
4485
  function printBoundaries(log) {
4396
4486
  log("[adep] \u80FD\u529B\u8FB9\u754C\uFF08\u6A21\u62DF\u8FD0\u884C\u65F6\u53EA\u66FF\u6362\u4F20\u8F93/\u6301\u4E45\u5316\uFF0C\u4E0D\u6539\u5199\u8BED\u4E49\uFF09\uFF1A");
4397
4487
  for (const b of SIM_BOUNDARIES) {
@@ -4399,8 +4489,8 @@ function printBoundaries(log) {
4399
4489
  }
4400
4490
  }
4401
4491
  async function ensureGitignore(cwd) {
4402
- const gitignorePath = join10(cwd, ".gitignore");
4403
- const existing = await readFile7(gitignorePath, "utf8").catch(() => "");
4492
+ const gitignorePath = join11(cwd, ".gitignore");
4493
+ const existing = await readFile8(gitignorePath, "utf8").catch(() => "");
4404
4494
  if (existing.split(/\r?\n/).includes(".adep/")) return;
4405
4495
  await writeFile5(gitignorePath, `${existing.replace(/\n+$/, "")}
4406
4496
  .adep/
@@ -4414,8 +4504,9 @@ async function startDevServer(options) {
4414
4504
  if (options.prefix !== void 0) {
4415
4505
  config.functionsPrefix = options.prefix.replace(/^\/+|\/+$/g, "");
4416
4506
  }
4417
- const functionsDir = join10(cwd, config.functionsDir);
4507
+ const functionsDir = join11(cwd, config.functionsDir);
4418
4508
  const coldStartAt = Date.now();
4509
+ const bearerUser = bearerUserResolverFromEnv();
4419
4510
  const executor = new WorkerFunctionExecutor({
4420
4511
  deps: { rootDir: cwd, builtin: LOCAL_BUILTIN_DEPS }
4421
4512
  });
@@ -4506,12 +4597,12 @@ async function startDevServer(options) {
4506
4597
  const reload = async () => {
4507
4598
  const [nextFiles, envText2] = await Promise.all([
4508
4599
  collectFunctions(functionsDir),
4509
- readFile7(join10(cwd, ".env.local"), "utf8").catch(() => "")
4600
+ readFile8(join11(cwd, ".env.local"), "utf8").catch(() => "")
4510
4601
  ]);
4511
4602
  files = nextFiles;
4512
4603
  env = { ...config.environment, ...parseEnvFile(envText2) };
4513
4604
  };
4514
- const envText = await readFile7(join10(cwd, ".env.local"), "utf8").catch(() => "");
4605
+ const envText = await readFile8(join11(cwd, ".env.local"), "utf8").catch(() => "");
4515
4606
  env = { ...config.environment, ...parseEnvFile(envText) };
4516
4607
  let debounceTimer;
4517
4608
  let watcher;
@@ -4526,29 +4617,15 @@ async function startDevServer(options) {
4526
4617
  watcher = void 0;
4527
4618
  }
4528
4619
  const buildInput = async (fnName, entry, url, req) => {
4529
- const query = {};
4530
- for (const key of new Set(url.searchParams.keys())) {
4531
- const values = url.searchParams.getAll(key);
4532
- query[key] = values.length > 1 ? values.join(",") : values[0] ?? "";
4533
- }
4534
- const headers = {};
4535
- for (const [key, value] of Object.entries(req.headers)) {
4536
- if (typeof value === "string") headers[key] = value;
4537
- }
4538
- const body = req.method === "GET" || req.method === "HEAD" ? void 0 : await bodyOf(req);
4539
4620
  const hasEnv = Object.keys(env).length > 0;
4621
+ const request = await requestInput(url, req, bodyOf);
4622
+ if (bearerUser !== void 0) request.user = await bearerUser(request.headers);
4540
4623
  return {
4541
4624
  project: { id: "local", slug: config.name },
4542
4625
  fn: { id: fnName, name: fnName },
4543
4626
  files,
4544
4627
  entry,
4545
- request: {
4546
- method: req.method ?? "GET",
4547
- path: url.pathname,
4548
- query,
4549
- headers,
4550
- ...body === void 0 ? {} : { body }
4551
- },
4628
+ request,
4552
4629
  // 模拟运行时能力:db / storage / realtime 各自只读复用线上装配,语义一致。
4553
4630
  capabilities: dbBundle.capabilities,
4554
4631
  rpcHandlers: {
@@ -4685,6 +4762,9 @@ async function startDevServer(options) {
4685
4762
  log(`[adep] dev server listening on ${baseUrl}\uFF08\u6A21\u62DF\u8FD0\u884C\u65F6\uFF0C\u51B7\u542F\u52A8 ${coldStartMs}ms\uFF09`);
4686
4763
  log(`[adep] curl \u793A\u4F8B\uFF1Acurl ${baseUrl}${curlPath}`);
4687
4764
  printBoundaries(log);
4765
+ if (bearerUser !== void 0) {
4766
+ log(`[adep] \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`);
4767
+ }
4688
4768
  log(`[adep] \u6A21\u62DF\u6570\u636E\u76EE\u5F55\uFF1A${simDir(cwd)}`);
4689
4769
  startStateAlarmScheduler();
4690
4770
  return {
@@ -4700,6 +4780,7 @@ async function startDevServer(options) {
4700
4780
  }
4701
4781
  };
4702
4782
  }
4783
+ var parseEnvFile;
4703
4784
  var init_dev = __esm({
4704
4785
  "packages/cli/src/dev.ts"() {
4705
4786
  "use strict";
@@ -4709,11 +4790,13 @@ var init_dev = __esm({
4709
4790
  init_runtime();
4710
4791
  init_env();
4711
4792
  init_invoke();
4712
- init_builtin_deps();
4793
+ init_builtin_deps2();
4713
4794
  init_boundary();
4714
4795
  init_ts_config();
4715
4796
  init_state_objects();
4716
4797
  init_worker_entry();
4798
+ init_dev_shared();
4799
+ parseEnvFile = parseEnv;
4717
4800
  }
4718
4801
  });
4719
4802
 
@@ -4832,7 +4915,7 @@ __export(db_exports, {
4832
4915
  dbStop: () => dbStop,
4833
4916
  splitSqlStatements: () => splitSqlStatements
4834
4917
  });
4835
- import { readFile as readFile8 } from "node:fs/promises";
4918
+ import { readFile as readFile9 } from "node:fs/promises";
4836
4919
  import { resolve as resolve5 } from "node:path";
4837
4920
  async function open2(paths, options) {
4838
4921
  const client = await createClient(paths);
@@ -4933,7 +5016,7 @@ function splitSqlStatements(source) {
4933
5016
  return statements;
4934
5017
  }
4935
5018
  async function dbMigrate(paths, options) {
4936
- const source = await readFile8(resolve5(options.file), "utf8");
5019
+ const source = await readFile9(resolve5(options.file), "utf8");
4937
5020
  const statements = splitSqlStatements(source);
4938
5021
  if (statements.length === 0) {
4939
5022
  throw new Error(`\u8FC1\u79FB\u6587\u4EF6\u6CA1\u6709\u53EF\u6267\u884C\u8BED\u53E5\uFF1A${options.file}`);
@@ -5039,12 +5122,13 @@ var init_banner = __esm({
5039
5122
  var server_exports = {};
5040
5123
  __export(server_exports, {
5041
5124
  isLoopback: () => isLoopback,
5125
+ resolveServePort: () => resolveServePort,
5042
5126
  startServeServer: () => startServeServer
5043
5127
  });
5044
5128
  import { createServer as createServer2 } from "node:http";
5045
5129
  import { watch as watch2 } from "node:fs";
5046
- import { mkdir as mkdir7, readdir as readdir4, readFile as readFile9, stat as stat6 } from "node:fs/promises";
5047
- import { extname, join as join11, relative as relative2, resolve as resolve6 } from "node:path";
5130
+ import { mkdir as mkdir7, readFile as readFile10, stat as stat6 } from "node:fs/promises";
5131
+ import { extname, join as join12, relative as relative2, resolve as resolve6 } from "node:path";
5048
5132
  function envNumber(name) {
5049
5133
  const raw = process.env[name];
5050
5134
  if (raw === void 0 || raw.trim() === "") return void 0;
@@ -5055,50 +5139,8 @@ function envString(name) {
5055
5139
  const raw = process.env[name];
5056
5140
  return raw === void 0 || raw.trim() === "" ? void 0 : raw.trim();
5057
5141
  }
5058
- async function collectFunctions2(dir) {
5059
- const files = {};
5060
- const walk = async (sub, prefix) => {
5061
- let entries;
5062
- try {
5063
- entries = await readdir4(sub, { withFileTypes: true });
5064
- } catch {
5065
- return;
5066
- }
5067
- for (const entry of entries) {
5068
- const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
5069
- const full = join11(sub, entry.name);
5070
- if (entry.isDirectory()) {
5071
- await walk(full, rel);
5072
- } else if (entry.isFile() && entry.name.endsWith(".ts")) {
5073
- files[rel] = await readFile9(full, "utf8");
5074
- }
5075
- }
5076
- };
5077
- await walk(dir, "");
5078
- return files;
5079
- }
5080
- function bodyOf2(req) {
5081
- return new Promise((resolveBody, rejectBody) => {
5082
- const chunks = [];
5083
- req.on("data", (chunk) => chunks.push(chunk));
5084
- req.on("end", () => {
5085
- const raw = Buffer.concat(chunks).toString("utf8");
5086
- if (raw.length === 0) {
5087
- resolveBody(void 0);
5088
- return;
5089
- }
5090
- try {
5091
- resolveBody(JSON.parse(raw));
5092
- } catch {
5093
- resolveBody(raw);
5094
- }
5095
- });
5096
- req.on("error", rejectBody);
5097
- });
5098
- }
5099
- function writeJson2(res, status, payload) {
5100
- res.writeHead(status, { "content-type": "application/json" });
5101
- res.end(JSON.stringify(payload));
5142
+ function resolveServePort(explicitPort) {
5143
+ return explicitPort ?? envNumber("PORT") ?? 8787;
5102
5144
  }
5103
5145
  function contentTypeFor(path) {
5104
5146
  const ext = path.slice(path.lastIndexOf(".")).toLowerCase();
@@ -5109,13 +5151,14 @@ async function startServeServer(options) {
5109
5151
  const log = options.log ?? ((line) => process.stdout.write(`${line}
5110
5152
  `));
5111
5153
  const host = options.host ?? envString("HOST") ?? "127.0.0.1";
5112
- const port = options.port ?? envNumber("PORT") ?? 8787;
5154
+ const port = resolveServePort(options.port);
5113
5155
  const staticDir = resolve6(
5114
5156
  cwd,
5115
5157
  options.staticDir ?? envString("ADEP_SERVE_STATIC_DIR") ?? "public"
5116
5158
  );
5117
5159
  const config = await loadConfig(cwd);
5118
- const functionsDir = join11(cwd, config.functionsDir);
5160
+ const functionsDir = join12(cwd, config.functionsDir);
5161
+ const bearerUser = bearerUserResolverFromEnv();
5119
5162
  let hasStatic = false;
5120
5163
  try {
5121
5164
  const publicStat = await stat6(staticDir);
@@ -5123,9 +5166,9 @@ async function startServeServer(options) {
5123
5166
  } catch {
5124
5167
  hasStatic = false;
5125
5168
  }
5126
- let files = await collectFunctions2(functionsDir);
5169
+ let files = await collectFunctions(functionsDir);
5127
5170
  let functionNames = listFunctionNames(files);
5128
- const envText = await readFile9(join11(cwd, ".env.local"), "utf8").catch(() => "");
5171
+ const envText = await readFile10(join12(cwd, ".env.local"), "utf8").catch(() => "");
5129
5172
  let env = parseEnvFile(envText);
5130
5173
  let simEnv = await loadSimEnv(cwd).catch(() => ({}));
5131
5174
  const runtime = await createSimRuntime({
@@ -5136,12 +5179,14 @@ async function startServeServer(options) {
5136
5179
  });
5137
5180
  if (options.schemaFile !== void 0) {
5138
5181
  const schemaPath = resolve6(cwd, options.schemaFile);
5139
- const schemaSource = await readFile9(schemaPath, "utf8").catch((error) => {
5140
- if (error.code === "ENOENT") {
5141
- throw new Error(`schema \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${schemaPath}`);
5182
+ const schemaSource = await readFile10(schemaPath, "utf8").catch(
5183
+ (error) => {
5184
+ if (error.code === "ENOENT") {
5185
+ throw new Error(`schema \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${schemaPath}`);
5186
+ }
5187
+ throw error;
5142
5188
  }
5143
- throw error;
5144
- });
5189
+ );
5145
5190
  const statements = splitSqlStatements(schemaSource);
5146
5191
  let applied = 0;
5147
5192
  let skipped = 0;
@@ -5171,8 +5216,8 @@ async function startServeServer(options) {
5171
5216
  if (options.watch === true) {
5172
5217
  const reload = async () => {
5173
5218
  const [nextFiles, envLocalText] = await Promise.all([
5174
- collectFunctions2(functionsDir),
5175
- readFile9(join11(cwd, ".env.local"), "utf8").catch(() => "")
5219
+ collectFunctions(functionsDir),
5220
+ readFile10(join12(cwd, ".env.local"), "utf8").catch(() => "")
5176
5221
  ]);
5177
5222
  files = nextFiles;
5178
5223
  env = parseEnvFile(envLocalText);
@@ -5205,30 +5250,16 @@ async function startServeServer(options) {
5205
5250
  };
5206
5251
  }
5207
5252
  const buildInput = async (fnName, entry, url, req) => {
5208
- const query = {};
5209
- for (const key of new Set(url.searchParams.keys())) {
5210
- const values = url.searchParams.getAll(key);
5211
- query[key] = values.length > 1 ? values.join(",") : values[0] ?? "";
5212
- }
5213
- const headers = {};
5214
- for (const [key, value] of Object.entries(req.headers)) {
5215
- if (typeof value === "string") headers[key] = value;
5216
- }
5217
- const body = req.method === "GET" || req.method === "HEAD" ? void 0 : await bodyOf2(req);
5218
5253
  const hasEnv = Object.keys(env).length > 0 || Object.keys(simEnv).length > 0 || Object.keys(config.environment ?? {}).length > 0;
5219
5254
  const mergedEnv = { ...config.environment, ...simEnv, ...env };
5255
+ const request = await requestInput(url, req, bodyOf);
5256
+ if (bearerUser !== void 0) request.user = await bearerUser(request.headers);
5220
5257
  return {
5221
5258
  project: { id: "local", slug: config.name },
5222
5259
  fn: { id: fnName, name: fnName },
5223
5260
  files,
5224
5261
  entry,
5225
- request: {
5226
- method: req.method ?? "GET",
5227
- path: url.pathname,
5228
- query,
5229
- headers,
5230
- ...body === void 0 ? {} : { body }
5231
- },
5262
+ request,
5232
5263
  capabilities: dbBundle.capabilities,
5233
5264
  rpcHandlers: {
5234
5265
  ...dbBundle.rpcHandlers,
@@ -5241,16 +5272,16 @@ async function startServeServer(options) {
5241
5272
  const serveStatic = async (pathname, res) => {
5242
5273
  if (!hasStatic) return false;
5243
5274
  const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
5244
- const filePath = join11(staticDir, safePath);
5245
- const resolvedPath = safePath === "" || safePath === "/" ? join11(filePath, "index.html") : filePath;
5275
+ const filePath = join12(staticDir, safePath);
5276
+ const resolvedPath = safePath === "" || safePath === "/" ? join12(filePath, "index.html") : filePath;
5246
5277
  try {
5247
5278
  const fileStat = await stat6(resolvedPath);
5248
5279
  if (fileStat.isDirectory()) {
5249
- const indexPath = join11(resolvedPath, "index.html");
5280
+ const indexPath = join12(resolvedPath, "index.html");
5250
5281
  try {
5251
5282
  const indexStat = await stat6(indexPath);
5252
5283
  if (indexStat.isFile()) {
5253
- const content2 = await readFile9(indexPath);
5284
+ const content2 = await readFile10(indexPath);
5254
5285
  res.writeHead(200, { "content-type": contentTypeFor(indexPath) });
5255
5286
  res.end(content2);
5256
5287
  return true;
@@ -5259,7 +5290,7 @@ async function startServeServer(options) {
5259
5290
  }
5260
5291
  return false;
5261
5292
  }
5262
- const content = await readFile9(resolvedPath);
5293
+ const content = await readFile10(resolvedPath);
5263
5294
  res.writeHead(200, { "content-type": contentTypeFor(resolvedPath) });
5264
5295
  res.end(content);
5265
5296
  return true;
@@ -5268,7 +5299,7 @@ async function startServeServer(options) {
5268
5299
  const ext = extname(pathname);
5269
5300
  if (ext === "" || ext === ".html") {
5270
5301
  try {
5271
- const indexContent = await readFile9(join11(staticDir, "index.html"));
5302
+ const indexContent = await readFile10(join12(staticDir, "index.html"));
5272
5303
  res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
5273
5304
  res.end(indexContent);
5274
5305
  return true;
@@ -5287,11 +5318,11 @@ async function startServeServer(options) {
5287
5318
  if (fnRest !== null) {
5288
5319
  const { fnName, error: routeError } = resolveRouteFnName(fnRest, "");
5289
5320
  if (routeError !== void 0) {
5290
- writeJson2(res, 400, { error: routeError });
5321
+ writeJson(res, 400, { error: routeError });
5291
5322
  return;
5292
5323
  }
5293
5324
  if (fnName === void 0 || fnName.length === 0) {
5294
- writeJson2(res, 400, {
5325
+ writeJson(res, 400, {
5295
5326
  error: { code: "FN_NAME_REQUIRED", message: "\u4EE5 /api/{fnName} \u8C03\u7528\u51FD\u6570" }
5296
5327
  });
5297
5328
  return;
@@ -5299,7 +5330,7 @@ async function startServeServer(options) {
5299
5330
  const entry = resolveFunctionEntry(files, fnName);
5300
5331
  if (entry === void 0) {
5301
5332
  log(`[serve] ${req.method ?? "GET"} ${pathname} -> 404\uFF08\u51FD\u6570\u4E0D\u5B58\u5728\uFF09`);
5302
- writeJson2(res, 404, { error: { code: "FN_NOT_FOUND", message: `\u51FD\u6570 "${fnName}" \u4E0D\u5B58\u5728` } });
5333
+ writeJson(res, 404, { error: { code: "FN_NOT_FOUND", message: `\u51FD\u6570 "${fnName}" \u4E0D\u5B58\u5728` } });
5303
5334
  return;
5304
5335
  }
5305
5336
  const input = await buildInput(fnName, entry, url, req);
@@ -5318,18 +5349,18 @@ async function startServeServer(options) {
5318
5349
  return;
5319
5350
  }
5320
5351
  log(`[serve] ${req.method ?? "GET"} ${pathname} -> 200 ${durationMs}ms`);
5321
- writeJson2(res, 200, result.body === void 0 ? null : result.body);
5352
+ writeJson(res, 200, result.body === void 0 ? null : result.body);
5322
5353
  } catch (error) {
5323
5354
  const durationMs = Math.round(performance.now() - startedAt);
5324
5355
  if (error instanceof ExecutorError) {
5325
5356
  log(
5326
5357
  `[serve] ${req.method ?? "GET"} ${pathname} -> ${error.status} ${durationMs}ms (${error.code})`
5327
5358
  );
5328
- writeJson2(res, error.status, { error: { code: error.code, message: error.message } });
5359
+ writeJson(res, error.status, { error: { code: error.code, message: error.message } });
5329
5360
  return;
5330
5361
  }
5331
5362
  log(`[serve] ${req.method ?? "GET"} ${pathname} -> 500 ${durationMs}ms`);
5332
- writeJson2(res, 500, {
5363
+ writeJson(res, 500, {
5333
5364
  error: {
5334
5365
  code: "FN_EXEC_ERROR",
5335
5366
  message: error instanceof Error ? error.message : "\u51FD\u6570\u6267\u884C\u5931\u8D25"
@@ -5339,7 +5370,7 @@ async function startServeServer(options) {
5339
5370
  return;
5340
5371
  }
5341
5372
  if (pathname === "/healthz") {
5342
- writeJson2(res, 200, {
5373
+ writeJson(res, 200, {
5343
5374
  status: "ok",
5344
5375
  service: "adep-serve",
5345
5376
  project: config.name
@@ -5349,7 +5380,7 @@ async function startServeServer(options) {
5349
5380
  const served = await serveStatic(pathname, res);
5350
5381
  if (served) return;
5351
5382
  if (pathname === "/" || pathname === "") {
5352
- writeJson2(res, 200, {
5383
+ writeJson(res, 200, {
5353
5384
  service: "adep-serve",
5354
5385
  mode: "development",
5355
5386
  project: config.name,
@@ -5364,13 +5395,13 @@ async function startServeServer(options) {
5364
5395
  });
5365
5396
  return;
5366
5397
  }
5367
- writeJson2(res, 404, { error: { code: "NOT_FOUND", message: `\u8DEF\u5F84 "${pathname}" \u4E0D\u5B58\u5728` } });
5398
+ writeJson(res, 404, { error: { code: "NOT_FOUND", message: `\u8DEF\u5F84 "${pathname}" \u4E0D\u5B58\u5728` } });
5368
5399
  };
5369
5400
  const server = createServer2((req, res) => {
5370
5401
  void handle(req, res).catch((error) => {
5371
5402
  log(`[serve] \u672A\u5904\u7406\u9519\u8BEF: ${error instanceof Error ? error.message : String(error)}`);
5372
5403
  if (!res.headersSent) {
5373
- writeJson2(res, 500, { error: { code: "INTERNAL_ERROR", message: "\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF" } });
5404
+ writeJson(res, 500, { error: { code: "INTERNAL_ERROR", message: "\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF" } });
5374
5405
  }
5375
5406
  });
5376
5407
  });
@@ -5399,6 +5430,9 @@ async function startServeServer(options) {
5399
5430
  if (options.watch === true) {
5400
5431
  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`);
5401
5432
  }
5433
+ if (bearerUser !== void 0) {
5434
+ 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`);
5435
+ }
5402
5436
  return {
5403
5437
  port: actualPort,
5404
5438
  host,
@@ -5418,13 +5452,14 @@ var init_server = __esm({
5418
5452
  init_executor();
5419
5453
  init_http_envelope();
5420
5454
  init_worker_executor();
5421
- init_builtin_deps();
5455
+ init_builtin_deps2();
5422
5456
  init_db2();
5423
5457
  init_runtime();
5424
5458
  init_env();
5425
5459
  init_invoke();
5426
5460
  init_dev();
5427
5461
  init_banner();
5462
+ init_dev_shared();
5428
5463
  MIME_TYPES = {
5429
5464
  ".html": "text/html; charset=utf-8",
5430
5465
  ".htm": "text/html; charset=utf-8",
@@ -5457,8 +5492,8 @@ __export(deploy_exports, {
5457
5492
  deploy: () => deploy
5458
5493
  });
5459
5494
  import { createHash as createHash2 } from "node:crypto";
5460
- import { readdir as readdir5, readFile as readFile10 } from "node:fs/promises";
5461
- import { join as join12, resolve as resolve7, basename as basename3, relative as relative3, sep } from "node:path";
5495
+ import { readdir as readdir4, readFile as readFile11 } from "node:fs/promises";
5496
+ import { join as join13, resolve as resolve7, basename as basename3, relative as relative3, sep } from "node:path";
5462
5497
  function functionUrlBase(prefix) {
5463
5498
  const raw = (prefix ?? "/api").trim();
5464
5499
  const normalized = raw === "/" ? "/" : raw.replace(/\/+$/, "");
@@ -5468,13 +5503,13 @@ async function collectEntries(functionsDir) {
5468
5503
  const entries = {};
5469
5504
  let names;
5470
5505
  try {
5471
- const dirents = await readdir5(functionsDir, { withFileTypes: true });
5506
+ const dirents = await readdir4(functionsDir, { withFileTypes: true });
5472
5507
  names = dirents.filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => basename3(entry.name, ".ts")).toSorted();
5473
5508
  } catch {
5474
5509
  return entries;
5475
5510
  }
5476
5511
  for (const name of names) {
5477
- entries[name] = await readFile10(join12(functionsDir, `${name}.ts`), "utf8");
5512
+ entries[name] = await readFile11(join13(functionsDir, `${name}.ts`), "utf8");
5478
5513
  }
5479
5514
  return entries;
5480
5515
  }
@@ -5482,25 +5517,25 @@ function sha256Hex(content) {
5482
5517
  return createHash2("sha256").update(content).digest("hex");
5483
5518
  }
5484
5519
  async function collectShared(functionsDir) {
5485
- const sharedDir = join12(functionsDir, "_shared");
5520
+ const sharedDir = join13(functionsDir, "_shared");
5486
5521
  const files = {};
5487
5522
  const walk = async (dir) => {
5488
5523
  let entries;
5489
5524
  try {
5490
- entries = await readdir5(dir, { withFileTypes: true });
5525
+ entries = await readdir4(dir, { withFileTypes: true });
5491
5526
  } catch {
5492
5527
  return;
5493
5528
  }
5494
5529
  for (const entry of entries) {
5495
5530
  if (entry.isDirectory()) {
5496
5531
  if (entry.name === "__tests__" || entry.name === "node_modules") continue;
5497
- await walk(join12(dir, entry.name));
5532
+ await walk(join13(dir, entry.name));
5498
5533
  continue;
5499
5534
  }
5500
5535
  if (!entry.name.endsWith(".ts") || entry.name.endsWith(".test.ts")) continue;
5501
- const full = join12(dir, entry.name);
5536
+ const full = join13(dir, entry.name);
5502
5537
  const rel = relative3(sharedDir, full).split(sep).join("/");
5503
- files[`_shared/${rel}`] = await readFile10(full, "utf8");
5538
+ files[`_shared/${rel}`] = await readFile11(full, "utf8");
5504
5539
  }
5505
5540
  };
5506
5541
  await walk(sharedDir);
@@ -5514,7 +5549,7 @@ async function deploy(paths, options) {
5514
5549
  const cwd = resolve7(options.cwd);
5515
5550
  const config = await loadConfig(cwd);
5516
5551
  const slug = options.slug ?? config.name;
5517
- const functionsDir = options.functionsDir === void 0 ? join12(cwd, config.functionsDir) : resolve7(cwd, options.functionsDir);
5552
+ const functionsDir = options.functionsDir === void 0 ? join13(cwd, config.functionsDir) : resolve7(cwd, options.functionsDir);
5518
5553
  const local = await collectEntries(functionsDir);
5519
5554
  if (Object.keys(local).length === 0) {
5520
5555
  throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
@@ -5602,13 +5637,24 @@ var init_deploy = __esm({
5602
5637
  }
5603
5638
  });
5604
5639
 
5640
+ // shared/frontend-draft.ts
5641
+ var FRONTEND_DRAFT_FILE_PATH_PATTERN, FRONTEND_DRAFT_MAX_TOTAL_SOURCE_BYTES, FRONTEND_DRAFT_MAX_FILES;
5642
+ var init_frontend_draft = __esm({
5643
+ "shared/frontend-draft.ts"() {
5644
+ "use strict";
5645
+ FRONTEND_DRAFT_FILE_PATH_PATTERN = /^[a-zA-Z0-9._][a-zA-Z0-9._/-]*$/;
5646
+ FRONTEND_DRAFT_MAX_TOTAL_SOURCE_BYTES = 256 * 1024;
5647
+ FRONTEND_DRAFT_MAX_FILES = 100;
5648
+ }
5649
+ });
5650
+
5605
5651
  // packages/cli/src/frontend.ts
5606
5652
  var frontend_exports = {};
5607
5653
  __export(frontend_exports, {
5608
5654
  frontendSync: () => frontendSync
5609
5655
  });
5610
- import { readdir as readdir6, readFile as readFile11, stat as stat7 } from "node:fs/promises";
5611
- import { join as join13, relative as relative4, sep as sep2 } from "node:path";
5656
+ import { readdir as readdir5, readFile as readFile12, stat as stat7 } from "node:fs/promises";
5657
+ import { join as join14, relative as relative4, sep as sep2 } from "node:path";
5612
5658
  async function resolveProjectId(client, cwd, slug) {
5613
5659
  const resolvedSlug = await resolveSlug(cwd, slug);
5614
5660
  const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
@@ -5624,16 +5670,16 @@ async function resolveProjectId(client, cwd, slug) {
5624
5670
  async function collectFiles(root, dir) {
5625
5671
  const files = /* @__PURE__ */ new Map();
5626
5672
  const skipped = [];
5627
- const entries = await readdir6(dir, { withFileTypes: true });
5673
+ const entries = await readdir5(dir, { withFileTypes: true });
5628
5674
  for (const entry of entries) {
5629
5675
  if (entry.isDirectory()) {
5630
5676
  if (IGNORED_DIRS.has(entry.name)) continue;
5631
- const nested = await collectFiles(root, join13(dir, entry.name));
5677
+ const nested = await collectFiles(root, join14(dir, entry.name));
5632
5678
  for (const [path, content] of nested.files) files.set(path, content);
5633
5679
  skipped.push(...nested.skipped);
5634
5680
  continue;
5635
5681
  }
5636
- const full = join13(dir, entry.name);
5682
+ const full = join14(dir, entry.name);
5637
5683
  const rel = relative4(root, full).split(sep2).join("/");
5638
5684
  const info = await stat7(full);
5639
5685
  if (info.size > 1024 * 1024) {
@@ -5641,7 +5687,7 @@ async function collectFiles(root, dir) {
5641
5687
  continue;
5642
5688
  }
5643
5689
  try {
5644
- const content = await readFile11(full, "utf8");
5690
+ const content = await readFile12(full, "utf8");
5645
5691
  if (content.includes("\0")) {
5646
5692
  skipped.push(rel);
5647
5693
  continue;
@@ -5656,7 +5702,7 @@ async function collectFiles(root, dir) {
5656
5702
  async function frontendSync(paths, options) {
5657
5703
  const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
5658
5704
  `));
5659
- const webDir = options.dir ?? join13(options.cwd, "web");
5705
+ const webDir = options.dir ?? join14(options.cwd, "web");
5660
5706
  const rootStat = await stat7(webDir).catch(() => null);
5661
5707
  if (rootStat === null || !rootStat.isDirectory()) {
5662
5708
  throw new CliError(
@@ -5709,9 +5755,10 @@ var init_frontend = __esm({
5709
5755
  "use strict";
5710
5756
  init_auth();
5711
5757
  init_client();
5712
- MAX_FILES = 100;
5713
- MAX_TOTAL_SOURCE_BYTES2 = 256 * 1024;
5714
- FILE_PATH_PATTERN = /^[a-zA-Z0-9._][a-zA-Z0-9._/-]*$/;
5758
+ init_frontend_draft();
5759
+ MAX_FILES = FRONTEND_DRAFT_MAX_FILES;
5760
+ MAX_TOTAL_SOURCE_BYTES2 = FRONTEND_DRAFT_MAX_TOTAL_SOURCE_BYTES;
5761
+ FILE_PATH_PATTERN = FRONTEND_DRAFT_FILE_PATH_PATTERN;
5715
5762
  IGNORED_DIRS = /* @__PURE__ */ new Set(["node_modules", "dist", ".git", ".adep", ".vite", "coverage"]);
5716
5763
  }
5717
5764
  });
@@ -5869,11 +5916,11 @@ var fs_exports = {};
5869
5916
  __export(fs_exports, {
5870
5917
  createExportFileSystem: () => createExportFileSystem
5871
5918
  });
5872
- import { mkdir as mkdir8, readFile as readFile12, rm as rm3, stat as stat9, writeFile as writeFile7 } from "node:fs/promises";
5873
- import { dirname as dirname7, join as join15 } from "node:path";
5919
+ import { mkdir as mkdir8, readFile as readFile13, rm as rm3, stat as stat9, writeFile as writeFile7 } from "node:fs/promises";
5920
+ import { dirname as dirname7, join as join16 } from "node:path";
5874
5921
  function createExportFileSystem() {
5875
5922
  return {
5876
- readFile: (path) => readFile12(path),
5923
+ readFile: (path) => readFile13(path),
5877
5924
  writeFile: (path, content) => writeFile7(path, content),
5878
5925
  // 同时用于清理解压临时目录(${zip}.tmp 是个目录)——递归强制删除,缺失不报错。
5879
5926
  deleteFile: async (path) => {
@@ -5891,9 +5938,9 @@ function createExportFileSystem() {
5891
5938
  await mkdir8(path, { recursive: true });
5892
5939
  },
5893
5940
  unzip: async (zipPath, targetDir) => {
5894
- const entries = zipRead(await readFile12(zipPath));
5941
+ const entries = zipRead(await readFile13(zipPath));
5895
5942
  for (const [name, data] of entries) {
5896
- const dest = join15(targetDir, name);
5943
+ const dest = join16(targetDir, name);
5897
5944
  await mkdir8(dirname7(dest), { recursive: true });
5898
5945
  await writeFile7(dest, data);
5899
5946
  }
@@ -6411,8 +6458,8 @@ __export(storage_exports, {
6411
6458
  storageRemove: () => storageRemove,
6412
6459
  storageUpload: () => storageUpload
6413
6460
  });
6414
- import { mkdir as mkdir9, readFile as readFile13, stat as stat10, writeFile as writeFile8 } from "node:fs/promises";
6415
- import { basename as basename4, dirname as dirname8, extname as extname2, join as join16, resolve as resolve9 } from "node:path";
6461
+ import { mkdir as mkdir9, readFile as readFile14, stat as stat10, writeFile as writeFile8 } from "node:fs/promises";
6462
+ import { basename as basename4, dirname as dirname8, extname as extname2, join as join17, resolve as resolve9 } from "node:path";
6416
6463
  async function open3(paths, options) {
6417
6464
  const client = await createClient(paths);
6418
6465
  const project2 = await resolveSlug(resolve9(options.cwd), options.slug);
@@ -6454,7 +6501,7 @@ async function storageUpload(paths, options) {
6454
6501
  throw new CliError("FILE_NOT_FOUND", `\u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${local}`);
6455
6502
  }
6456
6503
  const visibility = options.visibility ?? "private";
6457
- const bytes = await readFile13(local);
6504
+ const bytes = await readFile14(local);
6458
6505
  const form = new FormData();
6459
6506
  form.set("path", options.path);
6460
6507
  form.set("visibility", visibility);
@@ -6495,7 +6542,7 @@ async function storageDownload(paths, options) {
6495
6542
  const url = await resolveDownloadUrl(client, project2, options.path);
6496
6543
  const response = await client.download(url, "STORAGE_DOWNLOAD_FAILED");
6497
6544
  const bytes = Buffer.from(await response.arrayBuffer());
6498
- const output = resolve9(options.output ?? join16(resolve9(options.cwd), basename4(options.path)));
6545
+ const output = resolve9(options.output ?? join17(resolve9(options.cwd), basename4(options.path)));
6499
6546
  await mkdir9(dirname8(output), { recursive: true });
6500
6547
  await writeFile8(output, bytes);
6501
6548
  return { path: options.path, output, size: bytes.length };
@@ -6745,6 +6792,7 @@ var init_mcp = __esm({
6745
6792
  var projects_exports = {};
6746
6793
  __export(projects_exports, {
6747
6794
  projectsCreate: () => projectsCreate,
6795
+ projectsDelete: () => projectsDelete,
6748
6796
  projectsInfo: () => projectsInfo,
6749
6797
  projectsList: () => projectsList
6750
6798
  });
@@ -6800,6 +6848,32 @@ async function projectsInfo(paths, options) {
6800
6848
  }
6801
6849
  return match;
6802
6850
  }
6851
+ async function projectsDelete(paths, options) {
6852
+ await requireNetworkGuard();
6853
+ const slug = requireSlug(options.slug, "adep projects delete <slug>");
6854
+ if (options.confirmed !== true) {
6855
+ throw new CliError(
6856
+ "CONFIRM_REQUIRED",
6857
+ `\u5220\u9664\u9879\u76EE\u4E0D\u53EF\u64A4\u9500\uFF0C\u786E\u8BA4\u540E\u52A0 --yes \u91CD\u8DD1\uFF1Aadep projects delete ${slug} --yes`
6858
+ );
6859
+ }
6860
+ const client = await createClient(paths);
6861
+ const list = await client.request(
6862
+ "/api/v1/projects",
6863
+ {},
6864
+ "PROJECT_LIST_FAILED"
6865
+ );
6866
+ const match = list.projects.find((project2) => project2.slug === slug);
6867
+ if (match === void 0) {
6868
+ throw new CliError("PROJECT_NOT_FOUND", `\u9879\u76EE "${slug}" \u4E0D\u5B58\u5728\u6216\u4F60\u6CA1\u6709\u8BBF\u95EE\u6743\u9650`);
6869
+ }
6870
+ await client.request(
6871
+ `/api/v1/projects/${match.id}`,
6872
+ { method: "DELETE" },
6873
+ "PROJECT_DELETE_FAILED"
6874
+ );
6875
+ return { id: match.id, slug: match.slug };
6876
+ }
6803
6877
  async function requireNetworkGuard() {
6804
6878
  const { requireNetwork: requireNetwork2 } = await Promise.resolve().then(() => (init_net(), net_exports));
6805
6879
  await requireNetwork2("adep projects");
@@ -6879,21 +6953,10 @@ var init_git = __esm({
6879
6953
  // packages/cli/src/functions.ts
6880
6954
  var functions_exports = {};
6881
6955
  __export(functions_exports, {
6882
- functionsDeploy: () => functionsDeploy,
6883
6956
  functionsList: () => functionsList,
6884
6957
  functionsLogs: () => functionsLogs
6885
6958
  });
6886
6959
  import { resolve as resolve11 } from "node:path";
6887
- async function functionsDeploy(paths, options) {
6888
- const startedAt = Date.now();
6889
- const result = await deploy(paths, {
6890
- cwd: options.cwd,
6891
- ...options.slug === void 0 ? {} : { slug: options.slug },
6892
- ...options.dir === void 0 ? {} : { functionsDir: resolve11(options.cwd, options.dir) },
6893
- silent: true
6894
- });
6895
- return { ...result, elapsedSeconds: (Date.now() - startedAt) / 1e3 };
6896
- }
6897
6960
  async function functionsList(paths, options) {
6898
6961
  const client = await createClient(paths);
6899
6962
  const project2 = await resolveProject2(client, options);
@@ -6955,7 +7018,6 @@ var init_functions = __esm({
6955
7018
  "use strict";
6956
7019
  init_auth();
6957
7020
  init_client();
6958
- init_deploy();
6959
7021
  }
6960
7022
  });
6961
7023
 
@@ -6967,8 +7029,8 @@ __export(hosting_exports, {
6967
7029
  hostingInfo: () => hostingInfo,
6968
7030
  hostingPull: () => hostingPull
6969
7031
  });
6970
- import { readdir as readdir7, readFile as readFile14, stat as stat12 } from "node:fs/promises";
6971
- import { dirname as dirname9, join as join17, relative as relative5, resolve as resolve12, sep as sep3 } from "node:path";
7032
+ import { readdir as readdir6, readFile as readFile15, stat as stat12 } from "node:fs/promises";
7033
+ import { dirname as dirname9, join as join18, relative as relative5, resolve as resolve12, sep as sep3 } from "node:path";
6972
7034
  async function open4(paths, options) {
6973
7035
  const client = await createClient(paths);
6974
7036
  const project2 = await resolveSlug(resolve12(options.cwd), options.slug);
@@ -6989,12 +7051,12 @@ async function collectSiteFiles(dir) {
6989
7051
  const walk = async (sub) => {
6990
7052
  let entries;
6991
7053
  try {
6992
- entries = await readdir7(sub, { withFileTypes: true });
7054
+ entries = await readdir6(sub, { withFileTypes: true });
6993
7055
  } catch {
6994
7056
  return;
6995
7057
  }
6996
7058
  for (const entry of entries) {
6997
- const full = join17(sub, entry.name);
7059
+ const full = join18(sub, entry.name);
6998
7060
  if (entry.isDirectory()) {
6999
7061
  await walk(full);
7000
7062
  } else if (entry.isFile()) {
@@ -7018,7 +7080,7 @@ async function hostingDeploy(paths, options) {
7018
7080
  for (const [rel, full] of files) {
7019
7081
  log(`[adep] \u4E0A\u4F20 site/${rel}`);
7020
7082
  const info2 = await stat12(full);
7021
- const bytes = await readFile14(full);
7083
+ const bytes = await readFile15(full);
7022
7084
  const form = new FormData();
7023
7085
  form.set("path", `site/${rel}`);
7024
7086
  form.set("visibility", "public");
@@ -7056,7 +7118,7 @@ async function hostingPull(paths, options) {
7056
7118
  const response = await client.download(url, "HOSTING_DOWNLOAD_FAILED");
7057
7119
  const bytes = Buffer.from(await response.arrayBuffer());
7058
7120
  const rel = entry.path.replace(/^site\//, "");
7059
- const target = join17(outputDir, ...rel.split("/"));
7121
+ const target = join18(outputDir, ...rel.split("/"));
7060
7122
  await mkdir10(dirname9(target), { recursive: true });
7061
7123
  await writeFile9(target, bytes);
7062
7124
  files.push({ path: entry.path, size: bytes.length });
@@ -7377,6 +7439,16 @@ var ADEP_TSCONFIG_JSON = `{
7377
7439
  // packages/cli/src/init.ts
7378
7440
  init_adep_config();
7379
7441
 
7442
+ // shared/sdk/function-template.ts
7443
+ var HELLO_FUNCTION_SOURCE = `// \u793A\u4F8B\u4E91\u51FD\u6570\uFF1A\u90E8\u7F72\u540E\u7ECF /api/hello \u89E6\u53D1\uFF08\u672C\u5730\u5F00\u53D1\u7531 vite \u63D2\u4EF6\u4EE3\u7406\u540C\u4E00\u8DEF\u5F84\uFF09\u3002
7444
+ // \u7528\u6237\u51FD\u6570\u9ED8\u8BA4\u5BFC\u51FA (ctx: AdepContext) \u5F62\u72B6\u7684\u5904\u7406\u5668\uFF0Cctx \u5951\u7EA6\u89C1 adep.d.ts
7445
+ //\uFF08method / path / query / headers / body / files / user / cloud.*\uFF09\u3002
7446
+ export default async (ctx: AdepContext) => {
7447
+ const name = (ctx.query['name'] as string | undefined) ?? 'world'
7448
+ return { message: \`hello \${name}\` }
7449
+ }
7450
+ `;
7451
+
7380
7452
  // shared/sdk/web-project-template.ts
7381
7453
  var ADEP_CLIENT_VERSION = "^0.2.0";
7382
7454
  var ADEP_VITE_PLUGIN_VERSION = "^0.1.0";
@@ -9684,7 +9756,12 @@ onMounted(() => {
9684
9756
  ];
9685
9757
 
9686
9758
  // packages/cli/src/init.ts
9687
- var TEMPLATE_NAMES = ["empty", "function", "fullstack", "countdown"];
9759
+ var TEMPLATE_NAMES = [
9760
+ "empty",
9761
+ "function",
9762
+ "fullstack",
9763
+ "countdown"
9764
+ ];
9688
9765
  var InitError = class extends Error {
9689
9766
  constructor(code, message) {
9690
9767
  super(message);
@@ -9920,14 +9997,6 @@ console.log(result.message)
9920
9997
  \`web/src/\` \u5B58\u653E\u524D\u7AEF\u6E90\u7801\uFF08\`main.ts\` / \`App.vue\`\uFF09\uFF0C\u4E0E Web IDE \u5185 \`web/\` \u5DE5\u7A0B\u7684 \`src/\`
9921
9998
  \u5B8C\u5168\u540C\u6784\uFF1Bvite \u5DE5\u7A0B\u6839\u5728\u9879\u76EE\u6839\u76EE\u5F55\uFF08\`vite.config.ts\` / \`index.html\` / \`package.json\`\uFF09\u3002
9922
9999
  `;
9923
- var HELLO_FUNCTION = `// \u793A\u4F8B\u51FD\u6570\uFF1Aadep deploy \u540E\u7ECF https://<project-slug>.<platform-domain>/api/hello \u89E6\u53D1\u3002
9924
- // \u7528\u6237\u51FD\u6570\u5373 functions/ \u4E0B\u7684\u72EC\u7ACB\u6587\u4EF6\uFF0C\u9ED8\u8BA4\u5BFC\u51FA (ctx: AdepContext) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668
9925
- //\uFF08ctx \u5951\u7EA6\u89C1 adep.d.ts\uFF1Amethod / path / query / headers / body / files / user / cloud.*\uFF09\u3002
9926
- export default async (ctx: AdepContext) => {
9927
- const name = (ctx.query['name'] as string | undefined) ?? 'world'
9928
- return { message: \`hello \${name}\` }
9929
- }
9930
- `;
9931
10000
  var FUNCTION_INDEX = `// \u51FD\u6570\u6A21\u5757\u5165\u53E3\uFF1A\u9879\u76EE\u91CC\u7684\u6BCF\u4E2A\u51FD\u6570\u662F functions/ \u4E0B\u7684\u72EC\u7ACB\u6587\u4EF6\uFF0C
9932
10001
  // \u9ED8\u8BA4\u5BFC\u51FA (ctx: AdepContext) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668\uFF08\u5951\u7EA6\u89C1 adep.d.ts\uFF09\u3002
9933
10002
  `;
@@ -10010,10 +10079,10 @@ async function initProject(cwd, name, template) {
10010
10079
  { path: ".gitignore", content: "node_modules/\ndata/\n.adep/\nsite/\n" }
10011
10080
  ];
10012
10081
  if (template === "function") {
10013
- files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION });
10082
+ files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION_SOURCE });
10014
10083
  files.push({ path: "functions/README.md", content: FUNCTION_INDEX });
10015
10084
  } else if (template === "fullstack") {
10016
- files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION });
10085
+ files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION_SOURCE });
10017
10086
  files.push({ path: "functions/README.md", content: FUNCTION_INDEX });
10018
10087
  files.push({ path: "database/schema.sql", content: SCHEMA_SQL });
10019
10088
  files.push({ path: "index.html", content: INDEX_HTML });
@@ -10247,6 +10316,7 @@ function registerInit(program2, ctx) {
10247
10316
 
10248
10317
  // packages/cli/src/import-cf.ts
10249
10318
  init_adep_config();
10319
+ init_regexp();
10250
10320
  import { copyFile, mkdir as mkdir3, readFile as readFile2, readdir, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
10251
10321
  import { basename, dirname as dirname3, join as join2, relative, resolve as resolve2 } from "node:path";
10252
10322
  var TomlSyntaxError = class extends Error {
@@ -10588,9 +10658,6 @@ function bindingsFromWrangler(config) {
10588
10658
  function collectDurableObjectBindings(config) {
10589
10659
  return (config.durable_objects?.bindings ?? []).filter((b) => b.class_name !== void 0).map((b) => ({ name: b.name, className: b.class_name }));
10590
10660
  }
10591
- function escapeRegExp(text) {
10592
- return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10593
- }
10594
10661
  function findClosingBrace(text, openIdx) {
10595
10662
  let depth = 0;
10596
10663
  let i = openIdx;
@@ -11052,7 +11119,7 @@ init_auth();
11052
11119
  init_client();
11053
11120
  init_deploy();
11054
11121
  import { stat as stat8 } from "node:fs/promises";
11055
- import { join as join14, resolve as resolve8 } from "node:path";
11122
+ import { join as join15, resolve as resolve8 } from "node:path";
11056
11123
  async function resolveProjectId2(client, cwd, slug) {
11057
11124
  const resolvedSlug = await resolveSlug(resolve8(cwd), slug);
11058
11125
  const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
@@ -11118,7 +11185,7 @@ async function runPublish(paths, io, cwd, flags) {
11118
11185
  });
11119
11186
  }
11120
11187
  if (wantFrontend) {
11121
- const webDir = join14(cwd, "web");
11188
+ const webDir = join15(cwd, "web");
11122
11189
  const webStat = await stat8(webDir).catch(() => null);
11123
11190
  if (webStat !== null && webStat.isDirectory()) {
11124
11191
  const { frontendSync: frontendSync2 } = await Promise.resolve().then(() => (init_frontend(), frontend_exports));
@@ -11623,6 +11690,17 @@ function registerProjects(program2, ctx) {
11623
11690
  });
11624
11691
  });
11625
11692
  });
11693
+ projects.command("delete").description("\u5220\u9664\u9879\u76EE\uFF08\u7EA7\u8054\u6E05\u7406\u5168\u90E8\u8D44\u6E90\uFF0C\u4E0D\u53EF\u64A4\u9500\uFF1B\u9700 --yes \u786E\u8BA4\uFF09").argument("<slug>", "\u9879\u76EE slug").option("-y, --yes", "\u786E\u8BA4\u5220\u9664\uFF08\u7F3A\u7701\u62D2\u7EDD\u6267\u884C\uFF09").action(async (slug, flags) => {
11694
+ const command = ctx.io("projects delete");
11695
+ await command.run(async () => {
11696
+ const { projectsDelete: projectsDelete2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
11697
+ const deleted = await projectsDelete2(ctx.paths, { slug, confirmed: flags.yes === true });
11698
+ command.ok(deleted, (data) => {
11699
+ const d = data;
11700
+ return `\u2713 Project deleted \xB7 ${d.slug}`;
11701
+ });
11702
+ });
11703
+ });
11626
11704
  }
11627
11705
 
11628
11706
  // packages/cli/src/commands/git.ts