@supacloud/cli 0.68.2 → 0.69.0

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.
Files changed (2) hide show
  1. package/dist/index.js +253 -201
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -216908,7 +216908,7 @@ function registerAiTools(server2) {
216908
216908
  // src/shared/tools/app-tools.ts
216909
216909
  import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
216910
216910
  import { mkdir as mkdir6, readFile as readFile9, readdir as readdir6, writeFile as writeFile5 } from "node:fs/promises";
216911
- import { basename as basename8, dirname as dirname13, join as join16, relative as relative13, resolve as resolve21 } from "node:path";
216911
+ import { basename as basename8, dirname as dirname13, join as join16, relative as relative13, resolve as resolve23 } from "node:path";
216912
216912
 
216913
216913
  // node_modules/@supacloud/compiler/dist/index.js
216914
216914
  import { dirname as dirname22, relative as relative6, sep as sep4 } from "node:path";
@@ -216919,8 +216919,8 @@ var ts10 = __toESM(require_typescript(), 1);
216919
216919
  var ts11 = __toESM(require_typescript(), 1);
216920
216920
  var import_graphql64 = __toESM(require_graphql2(), 1);
216921
216921
  import { extname as extname3 } from "node:path";
216922
- import { resolve as resolve42 } from "node:path";
216923
216922
  import { resolve as resolve52 } from "node:path";
216923
+ import { resolve as resolve62 } from "node:path";
216924
216924
  import { createHash as createHash52 } from "node:crypto";
216925
216925
  import { readFile as readFile2 } from "node:fs/promises";
216926
216926
  import { relative as relative42, sep as sep42 } from "node:path";
@@ -219314,14 +219314,14 @@ var findTransformedDefinitions = (visitedResult) => {
219314
219314
  import { createHash as createHash7 } from "node:crypto";
219315
219315
  import { constants as constants2 } from "node:fs";
219316
219316
  import { lstat as lstat2, mkdir as mkdir22, open as open3, readFile as readFile3, readdir as readdir3, realpath as realpath3, rename as rename22, rm as rm2, writeFile as writeFile22 } from "node:fs/promises";
219317
- import { dirname as dirname42, isAbsolute as isAbsolute5, join as join52, relative as relative52, resolve as resolve72, sep as sep5 } from "node:path";
219317
+ import { dirname as dirname42, isAbsolute as isAbsolute5, join as join52, relative as relative52, resolve as resolve82, sep as sep5 } from "node:path";
219318
219318
  import { existsSync as existsSync32 } from "node:fs";
219319
219319
  import { dirname as dirname52, join as join62, relative as relative62, sep as sep6 } from "node:path";
219320
219320
  import { isAbsolute as isAbsolute22 } from "node:path";
219321
219321
  var ts15 = __toESM(require_typescript(), 1);
219322
219322
  import { createHash as createHash8, randomUUID } from "node:crypto";
219323
219323
  import { lstat as lstat22, readFile as readFile6, realpath as realpath4, rename as rename4, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
219324
- import { dirname as dirname8, isAbsolute as isAbsolute32, relative as relative8, resolve as resolve122, sep as sep8 } from "node:path";
219324
+ import { dirname as dirname8, isAbsolute as isAbsolute32, relative as relative8, resolve as resolve13, sep as sep8 } from "node:path";
219325
219325
  var ts17 = __toESM(require_typescript(), 1);
219326
219326
  var ts7 = __toESM(require_typescript(), 1);
219327
219327
  var ts2 = __toESM(require_typescript(), 1);
@@ -219334,7 +219334,7 @@ import { createHash as createHash32 } from "node:crypto";
219334
219334
  import { relative as relative22, resolve as resolvePath, sep as sep22 } from "node:path";
219335
219335
  import { createHash as createHash22 } from "node:crypto";
219336
219336
  import { existsSync as existsSync10, readFileSync as readFileSync8 } from "node:fs";
219337
- import { dirname as dirname6, join as join10, resolve as resolve13 } from "node:path";
219337
+ import { dirname as dirname6, join as join10, resolve as resolve14 } from "node:path";
219338
219338
  import { createHash as createHash9 } from "node:crypto";
219339
219339
  import { resolve as resolve22 } from "node:path";
219340
219340
  var ts9 = __toESM(require_typescript(), 1);
@@ -219345,21 +219345,22 @@ import { access as access2, readFile as readFile22 } from "node:fs/promises";
219345
219345
  import { join as join42 } from "node:path";
219346
219346
  import { existsSync as existsSync22, readFileSync as readFileSync22 } from "node:fs";
219347
219347
  import { dirname as dirname32, join as join32, relative as relative32, resolve as resolve32, sep as sep32 } from "node:path";
219348
+ import { resolve as resolve42 } from "node:path";
219348
219349
  import { mkdir as mkdir3, mkdtemp, readFile as readFile5, realpath as realpath32, rename as rename3, rm as rm22 } from "node:fs/promises";
219349
219350
  import { readFileSync as readFileSync32 } from "node:fs";
219350
- import { dirname as dirname7, join as join92, relative as relative7, resolve as resolve112, sep as sep7 } from "node:path";
219351
+ import { dirname as dirname7, join as join92, relative as relative7, resolve as resolve122, sep as sep7 } from "node:path";
219351
219352
  var ts13 = __toESM(require_typescript(), 1);
219352
219353
  var ts12 = __toESM(require_typescript(), 1);
219353
- import { join as join72, resolve as resolve82 } from "node:path";
219354
- import { resolve as resolve102 } from "node:path";
219354
+ import { join as join72, resolve as resolve92 } from "node:path";
219355
+ import { resolve as resolve112 } from "node:path";
219355
219356
  import { existsSync as existsSync42, watch } from "node:fs";
219356
- import { dirname as dirname9, relative as relative10, resolve as resolve14, sep as sep10 } from "node:path";
219357
+ import { dirname as dirname9, relative as relative10, resolve as resolve15, sep as sep10 } from "node:path";
219357
219358
  import { createHash as createHash92 } from "node:crypto";
219358
219359
  import { access as access3, readdir as readdir32, readFile as readFile7 } from "node:fs/promises";
219359
- import { isAbsolute as isAbsolute42, relative as relative9, resolve as resolve132, sep as sep9 } from "node:path";
219360
+ import { isAbsolute as isAbsolute42, relative as relative9, resolve as resolve142, sep as sep9 } from "node:path";
219360
219361
  var ts16 = __toESM(require_typescript(), 1);
219361
219362
  import { existsSync as existsSync52 } from "node:fs";
219362
- import { join as join11, resolve as resolve19 } from "node:path";
219363
+ import { join as join11, resolve as resolve20 } from "node:path";
219363
219364
  import { pathToFileURL as pathToFileURL2 } from "node:url";
219364
219365
  var __defProp2 = Object.defineProperty;
219365
219366
  var __returnValue2 = (v) => v;
@@ -220734,9 +220735,9 @@ function renderApplication(graph, options) {
220734
220735
  "}",
220735
220736
  "",
220736
220737
  "export async function initializeApplication(services: Record<string, unknown>): Promise<void> {",
220737
- ' const initializers = [services.environmentInitializer ?? services["supacloud.environment-initializer"], services.appInitializer ?? services["supacloud.app-initializer"]];',
220738
+ ' const initializers = [services["environmentInitializer"] ?? services["supacloud.environment-initializer"], services["appInitializer"] ?? services["supacloud.app-initializer"]];',
220738
220739
  " for (const group of initializers) {",
220739
- " if (Array.isArray(group)) {",
220740
+ " if (isUnknownArray(group)) {",
220740
220741
  " for (const init of group) {",
220741
220742
  " if (isFunction(init)) await init();",
220742
220743
  " }",
@@ -220747,21 +220748,21 @@ function renderApplication(graph, options) {
220747
220748
  "}",
220748
220749
  "",
220749
220750
  "export async function destroyApplication(services: Record<string, unknown>): Promise<void> {",
220750
- ' const destroyRef = (Object.prototype.propertyIsEnumerable.call(services, "destroyRef") ? services.destroyRef : undefined)',
220751
+ ' const destroyRef = (Object.prototype.propertyIsEnumerable.call(services, "destroyRef") ? services["destroyRef"] : undefined)',
220751
220752
  ' ?? (Object.prototype.propertyIsEnumerable.call(services, "supacloud.destroy-ref") ? services["supacloud.destroy-ref"] : undefined);',
220752
- " if (isRecord(destroyRef) && isFunction(destroyRef.destroy)) {",
220753
- " await destroyRef.destroy();",
220754
- " } else if (isRecord(destroyRef) && Array.isArray(destroyRef._teardowns)) {",
220755
- " for (const teardown of [...destroyRef._teardowns].reverse()) {",
220753
+ ' if (isRecord(destroyRef) && isFunction(destroyRef["destroy"])) {',
220754
+ ' await destroyRef["destroy"]();',
220755
+ ' } else if (isRecord(destroyRef) && isUnknownArray(destroyRef["_teardowns"])) {',
220756
+ ' for (const teardown of [...destroyRef["_teardowns"]].reverse()) {',
220756
220757
  " if (isFunction(teardown)) await teardown();",
220757
220758
  " }",
220758
220759
  " }",
220759
220760
  " const instances = Object.values(services);",
220760
220761
  " for (const inst of instances.reverse()) {",
220761
- " if (isRecord(inst) && isFunction(inst.onDestroy)) {",
220762
- " await inst.onDestroy();",
220763
- " } else if (isRecord(inst) && isFunction(inst.ngOnDestroy)) {",
220764
- " await inst.ngOnDestroy();",
220762
+ ' if (isRecord(inst) && isFunction(inst["onDestroy"])) {',
220763
+ ' await inst["onDestroy"]();',
220764
+ ' } else if (isRecord(inst) && isFunction(inst["ngOnDestroy"])) {',
220765
+ ' await inst["ngOnDestroy"]();',
220765
220766
  " }",
220766
220767
  " }",
220767
220768
  "}",
@@ -221155,7 +221156,7 @@ class ModuleGenerator {
221155
221156
  return "undefined";
221156
221157
  });
221157
221158
  const callArgs = invokerArgs.length > 0 ? invokerArgs.join(", ") : "req";
221158
- fields.push(`invoker: async (ctrl: unknown, req: { params?: Record<string, unknown>; query?: Record<string, unknown>; body?: unknown; headers?: Record<string, unknown>; cookie?: Record<string, unknown>; context?: unknown }) => { ` + `if (!isRecord(ctrl)) throw new TypeError("Route controller is not an object"); ` + `const handler = ctrl[${JSON.stringify(route.handler)}]; ` + `if (typeof handler !== "function") throw new TypeError("Route handler ${route.handler} is not callable"); ` + `return await Reflect.apply(handler, ctrl, [${callArgs}]); }`);
221159
+ fields.push(`invoker: async (ctrl: unknown, req: { params?: Record<string, unknown>; query?: Record<string, unknown>; body?: unknown; headers?: Record<string, unknown>; cookie?: Record<string, unknown>; context?: unknown }) => { ` + `if (!isRecord(ctrl)) throw new TypeError("Route controller is not an object"); ` + `const handler = ctrl[${JSON.stringify(route.handler)}]; ` + `if (!isFunction(handler)) throw new TypeError("Route handler ${route.handler} is not callable"); ` + `return await Reflect.apply(handler, ctrl, [${callArgs}]); }`);
221159
221160
  if (route.contract !== undefined) {
221160
221161
  fields.push(`contract: ${JSON.stringify(route.contract)}`);
221161
221162
  }
@@ -221327,7 +221328,7 @@ ${indent3(item, 2)}`).join(",")}
221327
221328
  if (emitted.constLine)
221328
221329
  lines.push(emitted.constLine);
221329
221330
  if (scoped) {
221330
- lines.push(`scope[${JSON.stringify(emitted.key)}] = [...(Array.isArray(scope[${JSON.stringify(emitted.key)}]) ? scope[${JSON.stringify(emitted.key)}] : []), ${emitted.expr}];`);
221331
+ lines.push(`scope[${JSON.stringify(emitted.key)}] = [...(isUnknownArray(scope[${JSON.stringify(emitted.key)}]) ? scope[${JSON.stringify(emitted.key)}] : []), ${emitted.expr}];`);
221331
221332
  }
221332
221333
  const list = multiGroups.get(emitted.key) ?? [];
221333
221334
  list.push(emitted.expr);
@@ -221369,14 +221370,14 @@ ${indent3(item, 2)}`).join(",")}
221369
221370
  continue;
221370
221371
  const key = camelName(token);
221371
221372
  const expression = this.depExpr(token, scopeKind, this.depOptions(node, token));
221372
- if (expression === `services.${key}` || expression === `(services.${key} ?? undefined)`) {
221373
+ if (expression === `services[${JSON.stringify(key)}]` || expression === `(services[${JSON.stringify(key)}] ?? undefined)`) {
221373
221374
  if (!returns.has(key))
221374
221375
  borrowed.add(key);
221375
221376
  }
221376
221377
  }
221377
221378
  }
221378
221379
  if (borrowed.size > 0) {
221379
- const descriptors = [...borrowed].map((key) => `${key}: { value: deps.${key} }`);
221380
+ const descriptors = [...borrowed].map((key) => `${key}: { value: deps[${JSON.stringify(key)}] }`);
221380
221381
  lines.push(`return retainPlatformDependencies(Object.defineProperties({ ${entries.join(", ")} }, { ${descriptors.join(", ")} }), deps);`);
221381
221382
  } else {
221382
221383
  lines.push(`return retainPlatformDependencies({ ${entries.join(", ")} }, deps);`);
@@ -221482,34 +221483,34 @@ ${indent3(item, 2)}`).join(",")}
221482
221483
  }
221483
221484
  }
221484
221485
  if (own && factoryOfScope(own.scope) === "services" && kind !== "services" && !isSkipSelf && !isSelf) {
221485
- return `services.${camelName(token)}`;
221486
+ return `services[${JSON.stringify(camelName(token))}]`;
221486
221487
  }
221487
221488
  if (isSelf) {
221488
- return isOptional ? "undefined" : `services.${camelName(token)}`;
221489
+ return isOptional ? "undefined" : `services[${JSON.stringify(camelName(token))}]`;
221489
221490
  }
221490
221491
  for (const importName of this.module.imports) {
221491
221492
  const imported = this.graph.modules.find((m) => m.name === importName);
221492
221493
  if (!imported?.exports.includes(token))
221493
221494
  continue;
221494
221495
  if (kind === "services")
221495
- return `imported.${importName}.${camelName(token)}`;
221496
- return `imported.${importName}.${camelName(token)}`;
221496
+ return `imported[${JSON.stringify(importName)}][${JSON.stringify(camelName(token))}]`;
221497
+ return `imported[${JSON.stringify(importName)}][${JSON.stringify(camelName(token))}]`;
221497
221498
  }
221498
221499
  for (const mod of this.graph.modules) {
221499
221500
  const rootProv = mod.providers.find((p) => p.token === token && p.providedIn === "root");
221500
221501
  if (rootProv) {
221501
- return `imported.${mod.name}.${camelName(token)}`;
221502
+ return `imported[${JSON.stringify(mod.name)}][${JSON.stringify(camelName(token))}]`;
221502
221503
  }
221503
221504
  }
221504
221505
  if (isSelf)
221505
- return isOptional ? "undefined" : `services.${camelName(token)}`;
221506
+ return isOptional ? "undefined" : `services[${JSON.stringify(camelName(token))}]`;
221506
221507
  if (kind === "services")
221507
- return isOptional ? `(deps.${camelName(token)} ?? undefined)` : `deps.${camelName(token)}`;
221508
+ return isOptional ? `(deps[${JSON.stringify(camelName(token))}] ?? undefined)` : `deps[${JSON.stringify(camelName(token))}]`;
221508
221509
  if (isSkipSelf) {
221509
- const external = `platformDependencies.get(services)?.${camelName(token)}`;
221510
+ const external = `platformDependencies.get(services)?.[${JSON.stringify(camelName(token))}]`;
221510
221511
  return isOptional ? `(${external} ?? undefined)` : external;
221511
221512
  }
221512
- return isOptional ? `(services.${camelName(token)} ?? undefined)` : `services.${camelName(token)}`;
221513
+ return isOptional ? `(services[${JSON.stringify(camelName(token))}] ?? undefined)` : `services[${JSON.stringify(camelName(token))}]`;
221513
221514
  }
221514
221515
  }
221515
221516
  function orderProviders(providers) {
@@ -223026,9 +223027,13 @@ function isFunction(value: unknown): value is (...args: unknown[]) => unknown {
223026
223027
  return typeof value === "function";
223027
223028
  }
223028
223029
 
223030
+ function isUnknownArray(value: unknown): value is unknown[] {
223031
+ return Array.isArray(value);
223032
+ }
223033
+
223029
223034
  function resolveFactoryValue(value: unknown): unknown {
223030
- if (!isRecord(value) || !isFunction(value.factory)) return undefined;
223031
- return value.factory();
223035
+ if (!isRecord(value) || !isFunction(value["factory"])) return undefined;
223036
+ return value["factory"]();
223032
223037
  }
223033
223038
 
223034
223039
  const scopeDestructions = new WeakMap<object, Promise<void>>();
@@ -223051,14 +223056,14 @@ function destroyScopeInstances(
223051
223056
  for (const entry of [...plan].reverse()) {
223052
223057
  const value = scope[entry.key];
223053
223058
  const instance = entry.index === undefined ? value
223054
- : Array.isArray(value) ? value[entry.index] : undefined;
223059
+ : isUnknownArray(value) ? value[entry.index] : undefined;
223055
223060
  if (seen.has(instance)) continue;
223056
223061
  seen.add(instance);
223057
223062
  try {
223058
- if (isRecord(instance) && isFunction(instance.onDestroy)) {
223059
- await instance.onDestroy();
223060
- } else if (isRecord(instance) && isFunction(instance.ngOnDestroy)) {
223061
- await instance.ngOnDestroy();
223063
+ if (isRecord(instance) && isFunction(instance["onDestroy"])) {
223064
+ await instance["onDestroy"]();
223065
+ } else if (isRecord(instance) && isFunction(instance["ngOnDestroy"])) {
223066
+ await instance["ngOnDestroy"]();
223062
223067
  }
223063
223068
  } catch (error) {
223064
223069
  errors.push(error);
@@ -223081,11 +223086,11 @@ async function initializeServiceInstances(
223081
223086
  const value = services[entry.key];
223082
223087
  const instance = entry.index === undefined
223083
223088
  ? value
223084
- : Array.isArray(value) ? value[entry.index] : undefined;
223089
+ : isUnknownArray(value) ? value[entry.index] : undefined;
223085
223090
  if (seen.has(instance)) continue;
223086
223091
  seen.add(instance);
223087
- if (!isRecord(instance) || !isFunction(instance.onInit)) continue;
223088
- await instance.onInit();
223092
+ if (!isRecord(instance) || !isFunction(instance["onInit"])) continue;
223093
+ await instance["onInit"]();
223089
223094
  }
223090
223095
  }
223091
223096
 
@@ -223099,13 +223104,13 @@ async function destroyServiceInstances(
223099
223104
  const value = services[entry.key];
223100
223105
  const instance = entry.index === undefined
223101
223106
  ? value
223102
- : Array.isArray(value) ? value[entry.index] : undefined;
223107
+ : isUnknownArray(value) ? value[entry.index] : undefined;
223103
223108
  if (seen.has(instance)) continue;
223104
223109
  seen.add(instance);
223105
223110
  if (!isRecord(instance)) continue;
223106
- const hook = isFunction(instance.onDestroy)
223107
- ? instance.onDestroy
223108
- : isFunction(instance.ngOnDestroy) ? instance.ngOnDestroy : undefined;
223111
+ const hook = isFunction(instance["onDestroy"])
223112
+ ? instance["onDestroy"]
223113
+ : isFunction(instance["ngOnDestroy"]) ? instance["ngOnDestroy"] : undefined;
223109
223114
  if (!hook) continue;
223110
223115
  try {
223111
223116
  await hook.call(instance);
@@ -223337,16 +223342,16 @@ function graphqlInputPaths(options) {
223337
223342
  } catch {
223338
223343
  return [];
223339
223344
  }
223340
- const root = resolve42(options.rootDir);
223341
- const schema = resolve42(root, options.graphql.schema);
223342
- const documents = ts10.sys.readDirectory(root, [".graphql", ".gql"], ["**/node_modules/**", "**/.git/**", resolve42(options.outDir)], options.graphql.documents ?? ["**/*.graphql", "**/*.gql"]).map((path) => resolve42(path)).filter((path) => path !== schema);
223345
+ const root = resolve52(options.rootDir);
223346
+ const schema = resolve52(root, options.graphql.schema);
223347
+ const documents = ts10.sys.readDirectory(root, [".graphql", ".gql"], ["**/node_modules/**", "**/.git/**", resolve52(options.outDir)], options.graphql.documents ?? ["**/*.graphql", "**/*.gql"]).map((path) => resolve52(path)).filter((path) => path !== schema);
223343
223348
  return [schema, ...[...new Set(documents)].sort()];
223344
223349
  }
223345
223350
  var init_graphql_inputs = __esm2(() => {
223346
223351
  init_graphql_options();
223347
223352
  });
223348
223353
  function renderGraphqlValidators(source, operationNames) {
223349
- const fileName = resolve52("/__supacloud_graphql__/contracts.ts");
223354
+ const fileName = resolve62("/__supacloud_graphql__/contracts.ts");
223350
223355
  const options = {
223351
223356
  strict: true,
223352
223357
  noUncheckedIndexedAccess: true,
@@ -223362,7 +223367,7 @@ function renderGraphqlValidators(source, operationNames) {
223362
223367
  };
223363
223368
  const host = ts11.createCompilerHost(options);
223364
223369
  const getSourceFile = host.getSourceFile.bind(host);
223365
- host.getSourceFile = (path, languageVersion, onError, shouldCreateNewSourceFile) => resolve52(path) === fileName ? ts11.createSourceFile(path, source, languageVersion, true) : getSourceFile(path, languageVersion, onError, shouldCreateNewSourceFile);
223370
+ host.getSourceFile = (path, languageVersion, onError, shouldCreateNewSourceFile) => resolve62(path) === fileName ? ts11.createSourceFile(path, source, languageVersion, true) : getSourceFile(path, languageVersion, onError, shouldCreateNewSourceFile);
223366
223371
  const program = ts11.createProgram([fileName], options, host);
223367
223372
  const diagnostics = ts11.getPreEmitDiagnostics(program);
223368
223373
  if (diagnostics.length) {
@@ -232775,7 +232780,7 @@ async function reserveOutput(project, requested) {
232775
232780
  if (!inside2(project, requested))
232776
232781
  throw new Error("Delivery output must be inside the application project.");
232777
232782
  const base = await realpath3(project);
232778
- const path = resolve72(base, relative52(project, requested));
232783
+ const path = resolve82(base, relative52(project, requested));
232779
232784
  if (relative52(base, path).split(sep5).some((part) => part === ".git" || part === "node_modules")) {
232780
232785
  throw new Error("Delivery output cannot use repository or dependency internals.");
232781
232786
  }
@@ -234074,7 +234079,7 @@ async function applyDiagnosticFix(fix, options = {}) {
234074
234079
  if (!fix || typeof fix.targetFile !== "string")
234075
234080
  throw new Error("Invalid DiagnosticFix");
234076
234081
  const root = await realpath4(options.rootDir ?? process.cwd());
234077
- const file = resolve122(root, fix.targetFile);
234082
+ const file = resolve13(root, fix.targetFile);
234078
234083
  const stat = await lstat22(file);
234079
234084
  const resolved = await realpath4(file);
234080
234085
  const relativePath = relative8(root, resolved);
@@ -234247,8 +234252,8 @@ function moduleObjects(source) {
234247
234252
  }
234248
234253
  function importSymbol(source, path, symbol) {
234249
234254
  identifier2(symbol);
234250
- const current = resolve122(source.fileName).replace(/\.(tsx?|mts|cts)$/, "");
234251
- const target = resolve122(dirname8(source.fileName), path).replace(/\.(tsx?|mts|cts)$/, "");
234255
+ const current = resolve13(source.fileName).replace(/\.(tsx?|mts|cts)$/, "");
234256
+ const target = resolve13(dirname8(source.fileName), path).replace(/\.(tsx?|mts|cts)$/, "");
234252
234257
  if (current === target)
234253
234258
  return source.text;
234254
234259
  const matches = source.statements.filter((item) => ts15.isImportDeclaration(item) && ts15.isStringLiteral(item.moduleSpecifier) && item.moduleSpecifier.text === path);
@@ -234464,7 +234469,7 @@ function decoratedDeclaration(decorator) {
234464
234469
  };
234465
234470
  }
234466
234471
  function createIncrementalProgramSession(projectRoot) {
234467
- const rootDir = resolve13(projectRoot);
234472
+ const rootDir = resolve14(projectRoot);
234468
234473
  let projectConfig = readProjectConfig(rootDir);
234469
234474
  let projectConfigKey = configKey(projectConfig);
234470
234475
  let builder;
@@ -234493,8 +234498,8 @@ function createIncrementalProgramSession(projectRoot) {
234493
234498
  }
234494
234499
  projectConfig = nextProjectConfig;
234495
234500
  projectConfigKey = nextProjectConfigKey;
234496
- const normalizedRoots = [...new Set(rootNames.map((file) => resolve13(rootDir, file)))].sort();
234497
- const normalizedChanged = [...new Set(changedPaths.map((file) => resolve13(rootDir, file)))];
234501
+ const normalizedRoots = [...new Set(rootNames.map((file) => resolve14(rootDir, file)))].sort();
234502
+ const normalizedChanged = [...new Set(changedPaths.map((file) => resolve14(rootDir, file)))];
234498
234503
  const invalidatedPaths = new Set(normalizedChanged.map(canonical3));
234499
234504
  for (const sourceFile of oldSourceFiles.values()) {
234500
234505
  if (sourceVersion(sourceFile.fileName) !== sourceFileVersion(sourceFile)) {
@@ -234595,7 +234600,7 @@ function createHost(options, rootDir, sourceFileCache, invalidatedPaths, invalid
234595
234600
  return host;
234596
234601
  }
234597
234602
  function canonical3(fileName) {
234598
- const normalized = resolve13(fileName);
234603
+ const normalized = resolve14(fileName);
234599
234604
  return ts2.sys.useCaseSensitiveFileNames ? normalized : normalized.toLowerCase();
234600
234605
  }
234601
234606
  function sourceFileParseKey(languageVersion) {
@@ -237651,6 +237656,50 @@ function isAnyKeyword(node) {
237651
237656
  return node.kind === ts9.SyntaxKind.AnyKeyword;
237652
237657
  }
237653
237658
  init_route_contracts();
237659
+ function validateClientSchemaBoundaries(graph, options) {
237660
+ if (!options.generateClient)
237661
+ return [];
237662
+ const identity = (path) => resolve42(options.rootDir, path).replace(/\.(?:[cm]?ts|[cm]?js)$/, "");
237663
+ const runtimeModules = new Set(graph.modules.flatMap((module) => [
237664
+ module.file,
237665
+ ...module.controllers.map((controller) => controller.file),
237666
+ ...module.providers.map((provider) => provider.file)
237667
+ ]).filter((file) => typeof file === "string").map(identity));
237668
+ const diagnostics = [];
237669
+ const seen = new Set;
237670
+ for (const module of graph.modules) {
237671
+ for (const controller of module.controllers) {
237672
+ for (const route of controller.routes) {
237673
+ const symbols = [
237674
+ route.body,
237675
+ route.params,
237676
+ route.query,
237677
+ route.headers,
237678
+ route.cookie,
237679
+ ...route.responses && Object.keys(route.responses).length ? Object.values(route.responses) : [route.response]
237680
+ ];
237681
+ for (const symbol of symbols) {
237682
+ if (!symbol)
237683
+ continue;
237684
+ const importedFrom = controller.schemaImports?.[symbol];
237685
+ if (!importedFrom || !runtimeModules.has(identity(importedFrom)))
237686
+ continue;
237687
+ const key = `${identity(importedFrom)}:${symbol}`;
237688
+ if (seen.has(key))
237689
+ continue;
237690
+ seen.add(key);
237691
+ diagnostics.push({
237692
+ severity: "warn",
237693
+ code: "client-schema-runtime-import",
237694
+ file: controller.file,
237695
+ message: `Generated client schema "${symbol}" imports application runtime module "${importedFrom}". Move the schema to a shared contract-only module and import it into the controller. This also avoids checking server decorators in the browser TypeScript project.`
237696
+ });
237697
+ }
237698
+ }
237699
+ }
237700
+ }
237701
+ return diagnostics;
237702
+ }
237654
237703
  function withDefaultGovernance(options) {
237655
237704
  return options.commandCapabilities === undefined ? { ...options, commandCapabilities: {
237656
237705
  requirePersistentAdapters: true,
@@ -237668,7 +237717,8 @@ async function compileProject(options) {
237668
237717
  const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
237669
237718
  const diagnostics = [
237670
237719
  ...graph.diagnostics ?? [],
237671
- ...validateGraph(graph, options)
237720
+ ...validateGraph(graph, options),
237721
+ ...validateClientSchemaBoundaries(graph, options)
237672
237722
  ];
237673
237723
  if (diagnostics.some((item) => item.code === "runtime-injection-disallowed")) {
237674
237724
  return { diagnostics, graph, written: [] };
@@ -237731,7 +237781,8 @@ async function checkProject(options) {
237731
237781
  const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
237732
237782
  const diagnostics = [
237733
237783
  ...graph.diagnostics ?? [],
237734
- ...validateGraph(graph, options)
237784
+ ...validateGraph(graph, options),
237785
+ ...validateClientSchemaBoundaries(graph, options)
237735
237786
  ];
237736
237787
  if (diagnostics.some((item) => item.code === "runtime-injection-disallowed")) {
237737
237788
  return { diagnostics, graph, upToDate: false, mismatches: ["Runtime DI must be migrated to constructor injection."] };
@@ -238463,7 +238514,7 @@ async function prepareDeliveryMigrations(project, generatedRoot, declarations =
238463
238514
  const inputs = new Map;
238464
238515
  let totalBytes = 0;
238465
238516
  for (const declaration of [...declarations].sort((a, b) => BigInt(a.version) < BigInt(b.version) ? -1 : BigInt(a.version) > BigInt(b.version) ? 1 : 0)) {
238466
- const source = resolve102(project, declaration.source);
238517
+ const source = resolve112(project, declaration.source);
238467
238518
  if (!inside2(project, source) || inside2(generatedRoot, source))
238468
238519
  throw new Error("Invalid migration source.");
238469
238520
  const bytes = await readBoundedOwned2(project, source, 1048576);
@@ -238512,7 +238563,7 @@ async function buildDeliveryProject(options, delivery) {
238512
238563
  const settings = parseDeliveryOptions(delivery);
238513
238564
  if (typeof Bun === "undefined")
238514
238565
  throw new Error("Independent delivery builds require Bun.");
238515
- const configPath = ts14.findConfigFile(resolve112(options.rootDir), ts14.sys.fileExists);
238566
+ const configPath = ts14.findConfigFile(resolve122(options.rootDir), ts14.sys.fileExists);
238516
238567
  if (!configPath)
238517
238568
  throw new Error("Independent delivery builds require a project tsconfig.json.");
238518
238569
  const lexicalProject = dirname7(configPath);
@@ -238520,11 +238571,11 @@ async function buildDeliveryProject(options, delivery) {
238520
238571
  const sourceRoot = await realpath32(options.rootDir);
238521
238572
  if (!inside2(project, sourceRoot))
238522
238573
  throw new Error("Application sources must be inside the project.");
238523
- const requested = resolve112(options.outDir, "delivery");
238574
+ const requested = resolve122(options.outDir, "delivery");
238524
238575
  if (!inside2(lexicalProject, requested))
238525
238576
  throw new Error("Output must be inside the application project.");
238526
- const buildRoot = resolve112(project, relative7(lexicalProject, requested));
238527
- const generatedRoot = resolve112(project, relative7(lexicalProject, options.outDir));
238577
+ const buildRoot = resolve122(project, relative7(lexicalProject, requested));
238578
+ const generatedRoot = resolve122(project, relative7(lexicalProject, options.outDir));
238528
238579
  if (inside2(generatedRoot, sourceRoot))
238529
238580
  throw new Error("Output must not contain the application source root.");
238530
238581
  const configInputs = new Map;
@@ -238532,7 +238583,7 @@ async function buildDeliveryProject(options, delivery) {
238532
238583
  ...ts14.sys,
238533
238584
  readFile(path) {
238534
238585
  const contents = readFileSync32(path, "utf8");
238535
- configInputs.set(resolve112(path), digest3(contents));
238586
+ configInputs.set(resolve122(path), digest3(contents));
238536
238587
  return contents;
238537
238588
  },
238538
238589
  onUnRecoverableConfigFileDiagnostic() {
@@ -238570,7 +238621,7 @@ async function buildDeliveryProject(options, delivery) {
238570
238621
  if (!target || (kind === "worker" ? target.kind !== "jobs" : target.kind === "jobs")) {
238571
238622
  throw new Error("Delivery host kind does not match its target.");
238572
238623
  }
238573
- const path = resolve112(sourceRoot, app.source);
238624
+ const path = resolve122(sourceRoot, app.source);
238574
238625
  if (inside2(generatedRoot, path) || !/\.[cm]?ts$/.test(path))
238575
238626
  throw new Error("Hosts require application TypeScript source.");
238576
238627
  hosts.set(app.target, { path, kind, hash: digest3(await readOwned(sourceRoot, path)) });
@@ -238697,7 +238748,7 @@ async function buildDeliveryProject(options, delivery) {
238697
238748
  }));
238698
238749
  const assetInputs = {};
238699
238750
  for (const asset of assets.filter((asset) => asset.target === target.name)) {
238700
- const path = resolve112(sourceRoot, asset.source);
238751
+ const path = resolve122(sourceRoot, asset.source);
238701
238752
  const bytes = await readOwned(sourceRoot, path);
238702
238753
  const hash = digest3(bytes);
238703
238754
  const previousHash = snapshots.get(path);
@@ -238904,11 +238955,11 @@ async function readSourceBytes(path) {
238904
238955
  return readFile7(path);
238905
238956
  }
238906
238957
  async function updateSnapshot(previous, options, changedPaths) {
238907
- const rootDir = resolve132(options.rootDir);
238908
- const outDir = resolve132(options.outDir);
238958
+ const rootDir = resolve142(options.rootDir);
238959
+ const outDir = resolve142(options.outDir);
238909
238960
  const files = { ...previous.files };
238910
238961
  await Promise.all(changedPaths.map(async (changedPath) => {
238911
- const absolutePath = isAbsolute42(changedPath) ? resolve132(changedPath) : resolve132(rootDir, changedPath);
238962
+ const absolutePath = isAbsolute42(changedPath) ? resolve142(changedPath) : resolve142(rootDir, changedPath);
238912
238963
  const relativeChangedPath = relative9(rootDir, absolutePath);
238913
238964
  if (relativeChangedPath === ".." || relativeChangedPath.startsWith(`..${sep9}`))
238914
238965
  return;
@@ -238926,8 +238977,8 @@ async function updateSnapshot(previous, options, changedPaths) {
238926
238977
  return { files, optionsKey: optionsKeyOf(options) };
238927
238978
  }
238928
238979
  async function createSnapshot(options) {
238929
- const rootDir = resolve132(options.rootDir);
238930
- const outDir = resolve132(options.outDir);
238980
+ const rootDir = resolve142(options.rootDir);
238981
+ const outDir = resolve142(options.outDir);
238931
238982
  const paths = await listSourceFiles(rootDir, outDir);
238932
238983
  const files = {};
238933
238984
  const entries = await Promise.all(paths.map(async (path) => {
@@ -238950,8 +239001,8 @@ async function createSnapshot(options) {
238950
239001
  }
238951
239002
  function optionsKeyOf(options) {
238952
239003
  return JSON.stringify({
238953
- rootDir: resolve132(options.rootDir),
238954
- outDir: resolve132(options.outDir),
239004
+ rootDir: resolve142(options.rootDir),
239005
+ outDir: resolve142(options.outDir),
238955
239006
  include: options.include,
238956
239007
  strict: options.strict,
238957
239008
  writeOnError: options.writeOnError,
@@ -238975,7 +239026,7 @@ async function listSourceFiles(rootDir, outDir) {
238975
239026
  const result = [];
238976
239027
  const visit = async (directory) => {
238977
239028
  for (const entry of await readdir32(directory, { withFileTypes: true })) {
238978
- const path = resolve132(directory, entry.name);
239029
+ const path = resolve142(directory, entry.name);
238979
239030
  if (entry.isDirectory()) {
238980
239031
  if (entry.name === "node_modules" || entry.name === ".git" || path === outDir)
238981
239032
  continue;
@@ -239108,8 +239159,8 @@ function isCompilerConfigurationPath(rootDir, changedPath) {
239108
239159
  ].includes(relativePath) || /^tsconfig\.[^/]+\.json$/.test(relativePath);
239109
239160
  }
239110
239161
  function watchProject(options) {
239111
- const rootDir = resolve14(options.rootDir);
239112
- const outDir = resolve14(options.outDir);
239162
+ const rootDir = resolve15(options.rootDir);
239163
+ const outDir = resolve15(options.outDir);
239113
239164
  const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
239114
239165
  let timer;
239115
239166
  let closed = false;
@@ -239119,7 +239170,7 @@ function watchProject(options) {
239119
239170
  const pendingPaths = new Set;
239120
239171
  let watcher;
239121
239172
  let schemaWatcher;
239122
- const schemaPath = options.graphql ? resolve14(rootDir, options.graphql.schema) : undefined;
239173
+ const schemaPath = options.graphql ? resolve15(rootDir, options.graphql.schema) : undefined;
239123
239174
  const incremental = createIncrementalCompiler();
239124
239175
  let initialEvent;
239125
239176
  let resolveReady = () => {
@@ -239229,7 +239280,7 @@ function watchProject(options) {
239229
239280
  watcher = watch(rootDir, { recursive: true }, (_eventType, filename) => {
239230
239281
  if (!filename)
239231
239282
  return schedule();
239232
- const changedPath = resolve14(rootDir, filename.toString());
239283
+ const changedPath = resolve15(rootDir, filename.toString());
239233
239284
  const relativePath = relative10(outDir, changedPath);
239234
239285
  if (!relativePath.startsWith("..") && relativePath !== "")
239235
239286
  return;
@@ -239242,7 +239293,7 @@ function watchProject(options) {
239242
239293
  while (!existsSync42(directory) && dirname9(directory) !== directory)
239243
239294
  directory = dirname9(directory);
239244
239295
  schemaWatcher = watch(directory, { recursive: true }, (_eventType, filename) => {
239245
- if (!filename || resolve14(directory, filename.toString()) === schemaPath)
239296
+ if (!filename || resolve15(directory, filename.toString()) === schemaPath)
239246
239297
  schedule(schemaPath);
239247
239298
  });
239248
239299
  }
@@ -239367,8 +239418,8 @@ function validateGovernanceConfig(config) {
239367
239418
  function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
239368
239419
  const resolved = defineSupacloudConfig(config);
239369
239420
  return {
239370
- rootDir: resolve19(cwd, resolved.root ?? DEFAULT_SUPACLOUD_CONFIG.root),
239371
- outDir: resolve19(cwd, resolved.outDir ?? DEFAULT_SUPACLOUD_CONFIG.outDir),
239421
+ rootDir: resolve20(cwd, resolved.root ?? DEFAULT_SUPACLOUD_CONFIG.root),
239422
+ outDir: resolve20(cwd, resolved.outDir ?? DEFAULT_SUPACLOUD_CONFIG.outDir),
239372
239423
  include: resolved.include ?? [...DEFAULT_SUPACLOUD_CONFIG.include],
239373
239424
  strict: resolved.strict ?? DEFAULT_SUPACLOUD_CONFIG.strict,
239374
239425
  requireRouteContracts: resolved.requireRouteContracts ?? DEFAULT_SUPACLOUD_CONFIG.requireRouteContracts,
@@ -239386,7 +239437,7 @@ function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
239386
239437
  treeShakeUnusedProviders: resolved.treeShakeUnusedProviders ?? DEFAULT_SUPACLOUD_CONFIG.treeShakeUnusedProviders,
239387
239438
  graphql: resolved.graphql ? {
239388
239439
  ...resolved.graphql,
239389
- schema: resolve19(cwd, resolved.graphql.schema)
239440
+ schema: resolve20(cwd, resolved.graphql.schema)
239390
239441
  } : undefined
239391
239442
  };
239392
239443
  }
@@ -239530,7 +239581,7 @@ var starter_metadata_default = {
239530
239581
  generatedBy: "supacloud/starter-metadata-v1",
239531
239582
  packages: {
239532
239583
  compiler: {
239533
- version: "0.38.2"
239584
+ version: "0.39.0"
239534
239585
  },
239535
239586
  app: {
239536
239587
  version: "0.23.0",
@@ -239539,7 +239590,7 @@ var starter_metadata_default = {
239539
239590
  }
239540
239591
  },
239541
239592
  elysia: {
239542
- version: "0.25.0"
239593
+ version: "0.26.0"
239543
239594
  },
239544
239595
  commands: {
239545
239596
  version: "0.9.1"
@@ -239657,7 +239708,7 @@ test("cancelled stream consumers release their subscription", async () => {
239657
239708
 
239658
239709
  // src/shared/tools/app-starter.ts
239659
239710
  import { lstat as lstat3, mkdir as mkdir4, readdir as readdir4, writeFile as writeFile4 } from "node:fs/promises";
239660
- import { basename as basename7, dirname as dirname10, join as join12, resolve as resolve15 } from "node:path";
239711
+ import { basename as basename7, dirname as dirname10, join as join12, resolve as resolve16 } from "node:path";
239661
239712
 
239662
239713
  // src/shared/tools/app-starter-environment.ts
239663
239714
  var STARTER_ENVIRONMENT = String.raw`import { existsSync, readFileSync } from "node:fs";
@@ -239959,14 +240010,15 @@ export default defineSupacloudConfig({
239959
240010
  function httpTemplate(name) {
239960
240011
  return {
239961
240012
  ...baseFiles(name),
239962
- "src/orders/orders.ts": `import { Body, Controller, Get, Param, Post, defineFeatureSlice } from "@supacloud/app";
239963
- import { status, t } from "elysia";
239964
-
240013
+ "src/orders/contracts.ts": `import { t } from "elysia";
239965
240014
  export const OrderParams = t.Object({ id: t.String({ minLength: 1 }) });
239966
240015
  export const CreateOrderBody = t.Object({ name: t.String({ minLength: 1 }) });
239967
240016
  export const OrderResult = t.Object({ id: t.String(), name: t.String() });
239968
240017
  export const HealthResult = t.Object({ ok: t.Boolean() });
239969
-
240018
+ `,
240019
+ "src/orders/orders.ts": `import { Body, Controller, Get, Param, Post, defineFeatureSlice } from "@supacloud/app";
240020
+ import { status } from "elysia";
240021
+ import { OrderParams, CreateOrderBody, OrderResult, HealthResult } from "./contracts";
239970
240022
  @Controller("/orders")
239971
240023
  export class OrdersController {
239972
240024
  @Get("/health", { responses: { 200: HealthResult } })
@@ -240148,11 +240200,11 @@ supacloud doctor --root .
240148
240200
  function minimalTemplate(name, sdkDependencies) {
240149
240201
  return {
240150
240202
  ...baseFiles(name, sdkDependencies),
240151
- "src/features/health/health.ts": `import { Controller, Get, Module } from "@supacloud/app/core";
240152
- import { t } from "elysia";
240153
-
240203
+ "src/features/health/contracts.ts": `import { t } from "elysia";
240154
240204
  export const HealthResult = t.Object({ ok: t.Boolean() });
240155
-
240205
+ `,
240206
+ "src/features/health/health.ts": `import { Controller, Get, Module } from "@supacloud/app/core";
240207
+ import { HealthResult } from "./contracts";
240156
240208
  @Controller("/health")
240157
240209
  export class HealthController {
240158
240210
  @Get("/", { responses: { 200: HealthResult } })
@@ -240693,7 +240745,7 @@ export async function createDeliveryWorker(modules: CompiledModule[], lifecycle:
240693
240745
  // src/shared/tools/app-starter-upload.ts
240694
240746
  var STARTER_UPLOAD_FEATURE = `import { Body, Controller, Inject, Injectable, Param, Post, DB_CLIENT, REQUEST_CONTEXT } from "@supacloud/app";
240695
240747
  import { ApplicationError } from "@supacloud/elysia";
240696
- import { t } from "elysia";
240748
+ import { UploadBody, UploadLocation, UploadParams, UploadResult } from "./contracts";
240697
240749
 
240698
240750
  export interface ReviewUploadInput { reviewId: string; artifactId: string; expectedVersion: number }
240699
240751
  export interface ReviewUploadLocation { artifactId: string; bucketId: string; objectPath: string }
@@ -240702,18 +240754,6 @@ export interface ReviewUploadPort {
240702
240754
  previewUpload(context: unknown, input: ReviewUploadInput): Promise<ReviewUploadLocation>;
240703
240755
  registerUpload(context: unknown, input: ReviewUploadInput): Promise<ReviewUploadResult>;
240704
240756
  }
240705
- export const UploadParams = t.Object({ id: t.String({ format: "uuid" }) });
240706
- export const UploadBody = t.Object({
240707
- artifactId: t.String({ format: "uuid" }), expectedVersion: t.Integer({ minimum: 1 }),
240708
- }, { additionalProperties: false });
240709
- export const UploadLocation = t.Object({
240710
- artifactId: t.String({ format: "uuid" }), bucketId: t.String(), objectPath: t.String(),
240711
- });
240712
- export const UploadResult = t.Object({
240713
- artifactId: t.String({ format: "uuid" }), runId: t.String({ format: "uuid" }),
240714
- objectPath: t.String(), sha256: t.String({ pattern: "^[a-f0-9]{64}$" }), bytes: t.Integer({ minimum: 1, maximum: 1048576 }),
240715
- });
240716
-
240717
240757
  @Injectable({ scope: "request" })
240718
240758
  export class ReviewUploads {
240719
240759
  constructor(@Inject(DB_CLIENT) private readonly store: Partial<ReviewUploadPort>,
@@ -241706,7 +241746,7 @@ export function createCompiledModules(): never {
241706
241746
  defineFeatureSlice, defineFeatureSpec, type Aspect,
241707
241747
  } from "@supacloud/app";
241708
241748
  import { ApplicationError, assertFeatureTransition } from "@supacloud/elysia";
241709
- import { t } from "elysia";
241749
+ import { ApproveBody, HealthResult, Params, ReviewResult } from "./contracts";
241710
241750
  import { VerifyReviewAttachment } from "./attachment";
241711
241751
  import { ReviewUploads, ReviewUploadsController, type ReviewUploadPort } from "./uploads";
241712
241752
  import type { ReviewRow } from "../../db/schema";
@@ -241731,14 +241771,6 @@ export interface ReviewStore extends Partial<ReviewUploadPort> {
241731
241771
  set(table: string, key: string, value: Review): void | Promise<void>;
241732
241772
  }
241733
241773
 
241734
- export const Params = t.Object({ id: t.String({ minLength: 1 }) });
241735
- export const ApproveBody = t.Object({ expectedVersion: t.Integer({ minimum: 1 }) });
241736
- export const ReviewResult = t.Object({
241737
- state: t.Union([t.Literal("draft"), t.Literal("approved")]),
241738
- version: t.Integer({ minimum: 1 }),
241739
- });
241740
- export const HealthResult = t.Object({ ok: t.Boolean() });
241741
-
241742
241774
  // Explicit, statically compiled AOP. Do not log identity, request bodies or secrets.
241743
241775
  export const requireRequest: Aspect = (context, next) => {
241744
241776
  if (!context.request) throw new ApplicationError("Request context required", { code: "REQUEST_REQUIRED" });
@@ -241795,6 +241827,26 @@ export const ReviewFeature = defineFeatureSlice({
241795
241827
  });
241796
241828
  `,
241797
241829
  "src/review/attachment.ts": STARTER_REVIEW_JOB,
241830
+ "src/review/contracts.ts": `import { t } from "elysia";
241831
+ export const Params = t.Object({ id: t.String({ minLength: 1 }) });
241832
+ export const ApproveBody = t.Object({ expectedVersion: t.Integer({ minimum: 1 }) });
241833
+ export const ReviewResult = t.Object({
241834
+ state: t.Union([t.Literal("draft"), t.Literal("approved")]),
241835
+ version: t.Integer({ minimum: 1 }),
241836
+ });
241837
+ export const HealthResult = t.Object({ ok: t.Boolean() });
241838
+ export const UploadParams = t.Object({ id: t.String({ format: "uuid" }) });
241839
+ export const UploadBody = t.Object({
241840
+ artifactId: t.String({ format: "uuid" }), expectedVersion: t.Integer({ minimum: 1 }),
241841
+ }, { additionalProperties: false });
241842
+ export const UploadLocation = t.Object({
241843
+ artifactId: t.String({ format: "uuid" }), bucketId: t.String(), objectPath: t.String(),
241844
+ });
241845
+ export const UploadResult = t.Object({
241846
+ artifactId: t.String({ format: "uuid" }), runId: t.String({ format: "uuid" }),
241847
+ objectPath: t.String(), sha256: t.String({ pattern: "^[a-f0-9]{64}$" }), bytes: t.Integer({ minimum: 1, maximum: 1048576 }),
241848
+ });
241849
+ `,
241798
241850
  "src/review/uploads.ts": STARTER_UPLOAD_FEATURE,
241799
241851
  "src/host/review-uploads.ts": STARTER_UPLOAD_ADAPTER,
241800
241852
  "src/host/review-postgres.ts": STARTER_REVIEW_POSTGRES,
@@ -242199,7 +242251,7 @@ and governance; TypeScript checks both application and generated source.
242199
242251
  };
242200
242252
  }
242201
242253
  async function initializeAppProject(options) {
242202
- const root = resolve15(options.root ?? process.cwd());
242254
+ const root = resolve16(options.root ?? process.cwd());
242203
242255
  const name = options.name ?? basename7(root);
242204
242256
  if (!/^[a-z][a-z0-9-]*$/.test(name) || name.length > 100) {
242205
242257
  throw new Error("Project name must be lowercase kebab-case (1-100 characters)");
@@ -242226,7 +242278,7 @@ async function initializeAppProject(options) {
242226
242278
 
242227
242279
  // src/shared/tools/app-database-check.ts
242228
242280
  import { existsSync as existsSync11 } from "node:fs";
242229
- import { join as join13, resolve as resolve16 } from "node:path";
242281
+ import { join as join13, resolve as resolve17 } from "node:path";
242230
242282
  var CHECK_ENTRY = `
242231
242283
  import { createRequire } from "node:module";
242232
242284
  import { join } from "node:path";
@@ -242237,7 +242289,7 @@ process.argv = [process.execPath, cli, "check", "--root", root];
242237
242289
  await import(pathToFileURL(cli).href);
242238
242290
  `;
242239
242291
  function checkAppDatabaseSources(projectRoot) {
242240
- const root = resolve16(projectRoot);
242292
+ const root = resolve17(projectRoot);
242241
242293
  if (!existsSync11(join13(root, "database.sources.json")))
242242
242294
  return;
242243
242295
  const name = "database-source-contracts";
@@ -242369,7 +242421,7 @@ test("${name} controller preserves an asynchronous read failure", async () => {
242369
242421
  // src/shared/tools/app-local-dev.ts
242370
242422
  import { spawn } from "node:child_process";
242371
242423
  import { readFile as readFile4 } from "node:fs/promises";
242372
- import { join as join14, resolve as resolve17 } from "node:path";
242424
+ import { join as join14, resolve as resolve18 } from "node:path";
242373
242425
  function localDatabaseUrl(value) {
242374
242426
  try {
242375
242427
  if (!value || /[\x00-\x20\x7f]/.test(value))
@@ -242416,7 +242468,7 @@ async function probeDatabase(url, signal) {
242416
242468
  }
242417
242469
  }
242418
242470
  async function runLocalDevelopment(options) {
242419
- const root = resolve17(options.root);
242471
+ const root = resolve18(options.root);
242420
242472
  const profile = options.profile ?? "fast";
242421
242473
  if (profile !== "fast" && profile !== "integration")
242422
242474
  throw new Error("Unknown development profile");
@@ -242517,7 +242569,7 @@ async function runLocalDevelopment(options) {
242517
242569
 
242518
242570
  // src/shared/tools/app-verification-plan.ts
242519
242571
  import { readdir as readdir5, realpath as realpath5 } from "node:fs/promises";
242520
- import { dirname as dirname11, isAbsolute as isAbsolute6, relative as relative11, resolve as resolve18 } from "node:path";
242572
+ import { dirname as dirname11, isAbsolute as isAbsolute6, relative as relative11, resolve as resolve19 } from "node:path";
242521
242573
  function inside3(root, file) {
242522
242574
  const path = relative11(root, file).replaceAll("\\", "/");
242523
242575
  return path !== ".." && !path.startsWith("../") && !isAbsolute6(path);
@@ -242528,13 +242580,13 @@ async function createVerificationPlan(root, graph, target, sourceRoot = root) {
242528
242580
  throw new Error("Select one unambiguous module or owned symbol for verification");
242529
242581
  const owner = owners[0];
242530
242582
  const project = await realpath5(root);
242531
- const requestedRoot = resolve18(root);
242583
+ const requestedRoot = resolve19(root);
242532
242584
  const sources = [
242533
242585
  owner.file,
242534
242586
  ...owner.providers.map((item) => item.file),
242535
242587
  ...owner.controllers.map((item) => item.file)
242536
242588
  ].filter((file) => typeof file === "string");
242537
- const directories = [...new Set(sources.map((file) => dirname11(resolve18(sourceRoot, file))))].sort();
242589
+ const directories = [...new Set(sources.map((file) => dirname11(resolve19(sourceRoot, file))))].sort();
242538
242590
  const tests = new Set;
242539
242591
  const manual = [];
242540
242592
  for (const directory of directories) {
@@ -242549,7 +242601,7 @@ async function createVerificationPlan(root, graph, target, sourceRoot = root) {
242549
242601
  }
242550
242602
  for (const entry of await readdir5(actual, { withFileTypes: true })) {
242551
242603
  if (entry.isFile() && /\.(test|spec)\.[cm]?[jt]sx?$/.test(entry.name)) {
242552
- tests.add(relative11(project, resolve18(actual, entry.name)).replaceAll("\\", "/"));
242604
+ tests.add(relative11(project, resolve19(actual, entry.name)).replaceAll("\\", "/"));
242553
242605
  }
242554
242606
  }
242555
242607
  }
@@ -242563,7 +242615,7 @@ async function createVerificationPlan(root, graph, target, sourceRoot = root) {
242563
242615
  source: "declaration",
242564
242616
  target: owner.name,
242565
242617
  ready: manual.length === 0,
242566
- files: [...new Set(sources.map((file) => relative11(requestedRoot, resolve18(sourceRoot, file)).replaceAll("\\", "/")))].sort(),
242618
+ files: [...new Set(sources.map((file) => relative11(requestedRoot, resolve19(sourceRoot, file)).replaceAll("\\", "/")))].sort(),
242567
242619
  tests: selected.slice(0, 32),
242568
242620
  commands: selected.length <= 32 ? [
242569
242621
  ...selected.map((file) => ["bun", "test", `./${file}`]),
@@ -242578,7 +242630,7 @@ async function createVerificationPlan(root, graph, target, sourceRoot = root) {
242578
242630
  // src/shared/tools/app-scaffold-writes.ts
242579
242631
  import { randomUUID as randomUUID2 } from "node:crypto";
242580
242632
  import { link, lstat as lstat4, mkdir as mkdir5, open as open4, readFile as readFile8, realpath as realpath6, rename as rename5, rmdir, unlink as unlink3 } from "node:fs/promises";
242581
- import { dirname as dirname12, isAbsolute as isAbsolute7, join as join15, relative as relative12, resolve as resolve20, sep as sep11, win32 } from "node:path";
242633
+ import { dirname as dirname12, isAbsolute as isAbsolute7, join as join15, relative as relative12, resolve as resolve21, sep as sep11, win32 } from "node:path";
242582
242634
 
242583
242635
  class ScaffoldError extends Error {
242584
242636
  code;
@@ -242599,7 +242651,7 @@ function scaffoldPath(root, path) {
242599
242651
  if (parts.some((part) => /[<>:"|?*\u0000-\u001f]/.test(part) || /[ .]$/.test(part) && part !== "." && part !== ".." || /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(part) || part.toLowerCase() === ".git" || part.toLowerCase() === ".supacloud-generate.lock")) {
242600
242652
  throw new ScaffoldError("SCAFFOLD_PATH_INVALID", "Scaffold path is reserved or not portable");
242601
242653
  }
242602
- const target = resolve20(root, path);
242654
+ const target = resolve21(root, path);
242603
242655
  const local = relative12(root, target);
242604
242656
  if (!local || local === ".." || local.startsWith(`..${sep11}`) || isAbsolute7(local)) {
242605
242657
  throw new ScaffoldError("SCAFFOLD_PATH_INVALID", "Scaffold path is outside the project root");
@@ -242638,7 +242690,7 @@ function sameFile(a, b) {
242638
242690
  return a === null ? b === null : b !== null && a.content === b.content && a.dev === b.dev && a.ino === b.ino && a.mode === b.mode;
242639
242691
  }
242640
242692
  async function planScaffoldWrites(root, writes) {
242641
- const canonical = await realpath6(resolve20(root));
242693
+ const canonical = await realpath6(resolve21(root));
242642
242694
  const targets = new Set;
242643
242695
  const planned = [];
242644
242696
  for (const write of writes) {
@@ -242898,7 +242950,7 @@ async function generateScaffold(args) {
242898
242950
  throw new ScaffoldError("SCAFFOLD_OPTION_INVALID", `--${flag.replaceAll("_", "-")} must be boolean`);
242899
242951
  }
242900
242952
  }
242901
- const root = resolve21(args.root || process.cwd());
242953
+ const root = resolve23(args.root || process.cwd());
242902
242954
  const dir = args.dir ?? "src/features";
242903
242955
  if (dir !== ".")
242904
242956
  scaffoldPath(root, dir);
@@ -242945,7 +242997,7 @@ async function generateScaffold(args) {
242945
242997
  if (new RegExp(`\\b${moduleSymbol}\\b`).test(original)) {
242946
242998
  throw new ScaffoldError("SCAFFOLD_REGISTRATION_CONFLICT", `Registration target already references ${moduleSymbol}; review the import manually`);
242947
242999
  }
242948
- let importPath = relative13(dirname13(target), resolve21(root, modulePath)).replaceAll("\\", "/").replace(/\.ts$/, "");
243000
+ let importPath = relative13(dirname13(target), resolve23(root, modulePath)).replaceAll("\\", "/").replace(/\.ts$/, "");
242949
243001
  if (!importPath.startsWith("."))
242950
243002
  importPath = `./${importPath}`;
242951
243003
  const edit = await applyDiagnosticFix({
@@ -243016,13 +243068,13 @@ function sourceRoot(args, root, configured) {
243016
243068
  return args.root && !hasConfig ? "." : configured;
243017
243069
  }
243018
243070
  async function projectCompileConfig(args) {
243019
- const root = resolve21(args.root || process.cwd());
243071
+ const root = resolve23(args.root || process.cwd());
243020
243072
  const configFile = ["ts", "mts", "js", "mjs"].map((extension) => join16(root, `supacloud.config.${extension}`)).find((candidate) => existsSync12(candidate)) ?? null;
243021
243073
  const loadedConfig = await loadSupacloudConfig(root);
243022
243074
  const defaults = resolveSupacloudConfig(loadedConfig, root);
243023
243075
  const configuredRoot = sourceRoot(args, root, loadedConfig.root);
243024
243076
  const include = parseInclude(args.include) ?? loadedConfig.include;
243025
- const outDir = args.out_dir ? resolve21(root, args.out_dir) : defaults.outDir;
243077
+ const outDir = args.out_dir ? resolve23(root, args.out_dir) : defaults.outDir;
243026
243078
  const compileOptions = compileOptionsFromConfig({
243027
243079
  ...loadedConfig,
243028
243080
  ...configuredRoot === undefined ? {} : { root: configuredRoot },
@@ -243186,11 +243238,11 @@ async function runDoctor(args) {
243186
243238
  `), doctor.errors > 0);
243187
243239
  }
243188
243240
  async function runFix(args) {
243189
- const root = resolve21(args.root || process.cwd());
243241
+ const root = resolve23(args.root || process.cwd());
243190
243242
  const fixPath = args.fix?.trim();
243191
243243
  if (!fixPath)
243192
243244
  throw new Error("app fix requires --fix <path-to-diagnostic-fix.json>");
243193
- const parsed = JSON.parse(await readFile9(resolve21(root, fixPath), "utf8"));
243245
+ const parsed = JSON.parse(await readFile9(resolve23(root, fixPath), "utf8"));
243194
243246
  const write = args.write === true;
243195
243247
  const applied = await applyDiagnosticFix(parsed, { rootDir: root, dryRun: !write });
243196
243248
  return textResult(JSON.stringify({
@@ -243276,12 +243328,12 @@ async function runAppDev(args, options) {
243276
243328
  throw new ScaffoldError("SCAFFOLD_OPTION_INVALID", "app dev --profile must be fast or integration");
243277
243329
  }
243278
243330
  const database = devDatabase(profile, args.database_url);
243279
- const root = resolve21(args.root || process.cwd());
243331
+ const root = resolve23(args.root || process.cwd());
243280
243332
  const loadedConfig = await loadSupacloudConfig(root);
243281
243333
  const defaults = resolveSupacloudConfig(loadedConfig, root);
243282
243334
  const configuredRoot = sourceRoot(args, root, loadedConfig.root);
243283
243335
  const include = parseInclude(args.include) ?? loadedConfig.include;
243284
- const outDir = args.out_dir ? resolve21(root, args.out_dir) : defaults.outDir;
243336
+ const outDir = args.out_dir ? resolve23(root, args.out_dir) : defaults.outDir;
243285
243337
  const watch = args.once !== true && args.watch !== false;
243286
243338
  const compileOptions = compileOptionsFromConfig({
243287
243339
  ...loadedConfig,
@@ -243367,7 +243419,7 @@ async function runAppDev(args, options) {
243367
243419
  return report(lastEvent, "stopped");
243368
243420
  }
243369
243421
  async function runCompile(args) {
243370
- const root = resolve21(args.root || process.cwd());
243422
+ const root = resolve23(args.root || process.cwd());
243371
243423
  const loadedConfig = await loadSupacloudConfig(root);
243372
243424
  const defaults = resolveSupacloudConfig(loadedConfig, root);
243373
243425
  const configuredRoot = sourceRoot(args, root, loadedConfig.root);
@@ -243376,7 +243428,7 @@ async function runCompile(args) {
243376
243428
  ...compileOptionsFromConfig({
243377
243429
  ...loadedConfig,
243378
243430
  ...configuredRoot === undefined ? {} : { root: configuredRoot },
243379
- outDir: args.out_dir ? resolve21(root, args.out_dir) : defaults.outDir,
243431
+ outDir: args.out_dir ? resolve23(root, args.out_dir) : defaults.outDir,
243380
243432
  ...include === undefined ? {} : { include },
243381
243433
  strict: args.strict ?? loadedConfig.strict ?? false
243382
243434
  }, root),
@@ -243400,7 +243452,7 @@ async function runCompile(args) {
243400
243452
  return textResult(text, hasError);
243401
243453
  }
243402
243454
  async function runCheck(args) {
243403
- const root = resolve21(args.root || process.cwd());
243455
+ const root = resolve23(args.root || process.cwd());
243404
243456
  const database = checkAppDatabaseSources(root);
243405
243457
  const loadedConfig = await loadSupacloudConfig(root);
243406
243458
  const defaults = resolveSupacloudConfig(loadedConfig, root);
@@ -243409,7 +243461,7 @@ async function runCheck(args) {
243409
243461
  const config = compileOptionsFromConfig({
243410
243462
  ...loadedConfig,
243411
243463
  ...configuredRoot === undefined ? {} : { root: configuredRoot },
243412
- outDir: args.out_dir ? resolve21(root, args.out_dir) : defaults.outDir,
243464
+ outDir: args.out_dir ? resolve23(root, args.out_dir) : defaults.outDir,
243413
243465
  ...include === undefined ? {} : { include },
243414
243466
  strict: args.strict ?? loadedConfig.strict ?? false
243415
243467
  }, root);
@@ -243439,7 +243491,7 @@ async function runCheck(args) {
243439
243491
  }
243440
243492
  async function readManifest(root, args) {
243441
243493
  const config = await loadSupacloudConfig(root);
243442
- const outDir = args.out_dir ? resolve21(root, args.out_dir) : resolveSupacloudConfig(config, root).outDir;
243494
+ const outDir = args.out_dir ? resolve23(root, args.out_dir) : resolveSupacloudConfig(config, root).outDir;
243443
243495
  const manifestPath = join16(outDir, "app.manifest.json");
243444
243496
  if (!existsSync12(manifestPath)) {
243445
243497
  throw new Error(`Manifest not found: ${manifestPath}(先运行 app compile 生成)`);
@@ -243484,7 +243536,7 @@ function formatGraphText(manifest) {
243484
243536
  `);
243485
243537
  }
243486
243538
  async function runGraph(args) {
243487
- const root = resolve21(args.root || process.cwd());
243539
+ const root = resolve23(args.root || process.cwd());
243488
243540
  const manifest = await readManifest(root, args);
243489
243541
  if (args.format === "json")
243490
243542
  return textResult(JSON.stringify(manifest, null, 2));
@@ -243552,7 +243604,7 @@ async function runExplain(args) {
243552
243604
  const target = args.target?.trim();
243553
243605
  if (!target)
243554
243606
  throw new Error("app explain requires --target(provider 类名 / token 名 / command 名 / job 名)");
243555
- const root = resolve21(args.root || process.cwd());
243607
+ const root = resolve23(args.root || process.cwd());
243556
243608
  const manifest = await readManifest(root, args);
243557
243609
  for (const module of manifest.modules) {
243558
243610
  const job = module.jobs?.find((entry) => entry.name === target || entry.className === target);
@@ -243627,10 +243679,10 @@ async function runExplain(args) {
243627
243679
  return textResult(`未找到对象: ${target}`, true);
243628
243680
  }
243629
243681
  async function runExportTools(args) {
243630
- const root = resolve21(args.root || process.cwd());
243682
+ const root = resolve23(args.root || process.cwd());
243631
243683
  const manifest = await readManifest(root, { ...args, out_dir: undefined });
243632
243684
  const definitions = buildToolDefinitions(manifest);
243633
- const outDir = resolve21(args.out_dir || join16(root, "generated"));
243685
+ const outDir = resolve23(args.out_dir || join16(root, "generated"));
243634
243686
  if (args.format === "json") {
243635
243687
  return textResult(JSON.stringify(definitions, null, 2));
243636
243688
  }
@@ -243651,7 +243703,7 @@ async function runExportTools(args) {
243651
243703
  return textResult(summary);
243652
243704
  }
243653
243705
  async function runDelivery(args) {
243654
- const root = resolve21(args.root || process.cwd());
243706
+ const root = resolve23(args.root || process.cwd());
243655
243707
  if (args.action === "build") {
243656
243708
  const database = checkAppDatabaseSources(root);
243657
243709
  if (database && !database.ok) {
@@ -243661,7 +243713,7 @@ async function runDelivery(args) {
243661
243713
  const loaded = await loadSupacloudConfig(root);
243662
243714
  const options = compileOptionsFromConfig({
243663
243715
  ...loaded,
243664
- ...args.out_dir === undefined ? {} : { outDir: resolve21(root, args.out_dir) },
243716
+ ...args.out_dir === undefined ? {} : { outDir: resolve23(root, args.out_dir) },
243665
243717
  ...args.include === undefined ? {} : { include: parseInclude(args.include) },
243666
243718
  ...args.strict === undefined ? {} : { strict: args.strict }
243667
243719
  }, root);
@@ -243831,7 +243883,7 @@ function registerAppAliases(server2) {
243831
243883
 
243832
243884
  // src/shared/tools/db-governance-tools.ts
243833
243885
  import { existsSync as existsSync13 } from "node:fs";
243834
- import { join as join17, resolve as resolve23 } from "node:path";
243886
+ import { join as join17, resolve as resolve24 } from "node:path";
243835
243887
 
243836
243888
  // node_modules/@supacloud/db/dist/index.js
243837
243889
  var TABLES_SQL = `
@@ -244283,7 +244335,7 @@ function normalizeModule(candidate, sourcePath) {
244283
244335
  };
244284
244336
  }
244285
244337
  async function loadDatabaseModules(root, moduleFile) {
244286
- const filePath = moduleFile ? resolve23(root, moduleFile) : join17(root, "db", "modules.ts");
244338
+ const filePath = moduleFile ? resolve24(root, moduleFile) : join17(root, "db", "modules.ts");
244287
244339
  if (!existsSync13(filePath)) {
244288
244340
  throw new Error(moduleFile ? `Module file not found: ${filePath}` : `Module file not found: ${filePath}(用 --module_file 指定一个导出 defineDatabaseModule(...) 的文件)`);
244289
244341
  }
@@ -244332,7 +244384,7 @@ async function runLint(args, root) {
244332
244384
  const issues = [];
244333
244385
  for (const module of selected) {
244334
244386
  const readSqlFile = async (path) => {
244335
- const absolute = resolve23(root, path);
244387
+ const absolute = resolve24(root, path);
244336
244388
  try {
244337
244389
  return await Bun.file(absolute).text();
244338
244390
  } catch (error) {
@@ -244368,14 +244420,14 @@ var defaultLiteSpawn = async (command, cwd) => {
244368
244420
  return { exitCode, stdout, stderr };
244369
244421
  };
244370
244422
  async function runModuleCheckLite(args, root, spawn, liteBinary) {
244371
- const projectDir = resolve23(args.project_dir?.trim() || root);
244423
+ const projectDir = resolve24(args.project_dir?.trim() || root);
244372
244424
  const binary = liteBinary === undefined ? Bun.which("supacloud-lite") : liteBinary;
244373
244425
  if (!binary) {
244374
244426
  throw new Error("db module_check --lite 需要本机可用的 supacloud-lite(npm i -g @supacloud/lite,或加入 PATH)");
244375
244427
  }
244376
244428
  const command = [binary, "db", "check", "--project-dir", projectDir];
244377
244429
  if (args.module_file?.trim())
244378
- command.push("--module-file", resolve23(root, args.module_file.trim()));
244430
+ command.push("--module-file", resolve24(root, args.module_file.trim()));
244379
244431
  const result = await spawn(command, projectDir);
244380
244432
  const output = [result.stdout.trim(), result.stderr.trim()].filter(Boolean).join(`
244381
244433
  `);
@@ -244426,7 +244478,7 @@ function registerDbGovernanceTools(server2, options = {}) {
244426
244478
  lite: optional(Boolean2(), "[module_check] Reconcile against a local SupaCloud Lite project (runs supacloud-lite db check)"),
244427
244479
  project_dir: optional(String2(), "[module_check] Lite project directory (with --lite; default: --root)")
244428
244480
  }, async (request) => {
244429
- const root = resolve23(request.root || fallbackRoot);
244481
+ const root = resolve24(request.root || fallbackRoot);
244430
244482
  switch (request.action) {
244431
244483
  case "lint":
244432
244484
  return runLint(request, root);
@@ -244443,7 +244495,7 @@ function registerDbGovernanceTools(server2, options = {}) {
244443
244495
  // src/shared/tools/scheduled-function-tools.ts
244444
244496
  import { randomUUID as randomUUID3 } from "node:crypto";
244445
244497
  import { readFileSync as readFileSync10, statSync as statSync7 } from "node:fs";
244446
- import { resolve as resolve24 } from "node:path";
244498
+ import { resolve as resolve25 } from "node:path";
244447
244499
  import { isDeepStrictEqual } from "node:util";
244448
244500
  var HEADER_NAME_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$/;
244449
244501
  var ENVIRONMENT_NAME_PATTERN2 = /^[A-Za-z_][A-Za-z0-9_]{0,255}$/;
@@ -244527,7 +244579,7 @@ function validScheduledFunctionCron(expression) {
244527
244579
  function readScheduleBodyFile(bodyPathInput) {
244528
244580
  if (!bodyPathInput.trim())
244529
244581
  throw new Error("'body_file' must be a path");
244530
- const bodyPath = resolve24(bodyPathInput);
244582
+ const bodyPath = resolve25(bodyPathInput);
244531
244583
  const bodyStat = statSync7(bodyPath);
244532
244584
  if (!bodyStat.isFile() || bodyStat.size > MAX_BODY_FILE_BYTES) {
244533
244585
  throw new Error("Scheduled Function body file must be a regular file no larger than 1 MiB");
@@ -245110,7 +245162,7 @@ var MUTATION_TOOL_SCHEMA = {
245110
245162
  // src/shared/tools/release-tools.ts
245111
245163
  import { createHash as createHash10 } from "node:crypto";
245112
245164
  import { existsSync as existsSync14, mkdirSync as mkdirSync4, readdirSync as readdirSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "node:fs";
245113
- import { dirname as dirname14, join as join18, relative as relative14, resolve as resolve25 } from "node:path";
245165
+ import { dirname as dirname14, join as join18, relative as relative14, resolve as resolve26 } from "node:path";
245114
245166
  var SAFE_PROJECT_REF = /^[A-Za-z0-9_-]{1,64}$/;
245115
245167
  var BACKUP_ID = /^logical-full_[A-Za-z0-9_-]{1,64}_[a-f0-9]{32}$/;
245116
245168
  var SHA256 = /^[a-f0-9]{64}$/;
@@ -245398,13 +245450,13 @@ function collectScopeFiles(cwd, file, files, dir, task) {
245398
245450
  const results = [];
245399
245451
  const resolvePathWithFallbacks = (filePath) => {
245400
245452
  const trimmed = filePath.trim();
245401
- const resolved = resolve25(cwd, trimmed);
245453
+ const resolved = resolve26(cwd, trimmed);
245402
245454
  if (existsSync14(resolved))
245403
245455
  return resolved;
245404
245456
  const candidates = [
245405
- resolve25(cwd, "supacloud/fa/release-scopes", trimmed),
245406
- resolve25(cwd, "release-scopes", trimmed),
245407
- resolve25(cwd, "scopes", trimmed)
245457
+ resolve26(cwd, "supacloud/fa/release-scopes", trimmed),
245458
+ resolve26(cwd, "release-scopes", trimmed),
245459
+ resolve26(cwd, "scopes", trimmed)
245408
245460
  ];
245409
245461
  const found = candidates.find(existsSync14);
245410
245462
  if (found)
@@ -245427,10 +245479,10 @@ function collectScopeFiles(cwd, file, files, dir, task) {
245427
245479
  if (!taskFilter && (!dir || typeof dir !== "string" || !dir.trim())) {
245428
245480
  throw new Error("At least one of --file, --files, or --task is required for scope_rebind");
245429
245481
  }
245430
- const candidates = typeof dir === "string" && dir.trim() ? [resolve25(cwd, dir.trim())] : [
245431
- resolve25(cwd, "supacloud/fa/release-scopes"),
245432
- resolve25(cwd, "release-scopes"),
245433
- resolve25(cwd, "scopes")
245482
+ const candidates = typeof dir === "string" && dir.trim() ? [resolve26(cwd, dir.trim())] : [
245483
+ resolve26(cwd, "supacloud/fa/release-scopes"),
245484
+ resolve26(cwd, "release-scopes"),
245485
+ resolve26(cwd, "scopes")
245434
245486
  ];
245435
245487
  for (const directory of candidates) {
245436
245488
  if (existsSync14(directory)) {
@@ -245464,7 +245516,7 @@ function collectScopeFiles(cwd, file, files, dir, task) {
245464
245516
  return [...new Set(results)];
245465
245517
  }
245466
245518
  function handleScopeRebind(args) {
245467
- const cwd = typeof args.cwd === "string" && args.cwd.trim() ? resolve25(args.cwd.trim()) : process.cwd();
245519
+ const cwd = typeof args.cwd === "string" && args.cwd.trim() ? resolve26(args.cwd.trim()) : process.cwd();
245468
245520
  const targetBaseCommit = resolveGitBaseCommit(cwd, args.base_commit);
245469
245521
  const scopeFiles = collectScopeFiles(cwd, args.file, args.files, args.dir, args.task);
245470
245522
  const dryRun = args.dry_run === true;
@@ -245516,17 +245568,17 @@ function handleScopeRebind(args) {
245516
245568
  });
245517
245569
  }
245518
245570
  function handleScopeInspect(args) {
245519
- const cwd = typeof args.cwd === "string" && args.cwd.trim() ? resolve25(args.cwd.trim()) : process.cwd();
245571
+ const cwd = typeof args.cwd === "string" && args.cwd.trim() ? resolve26(args.cwd.trim()) : process.cwd();
245520
245572
  if (typeof args.file !== "string" || !args.file.trim()) {
245521
245573
  throw new Error("'file' is required for scope_inspect");
245522
245574
  }
245523
245575
  const trimmed = args.file.trim();
245524
- let filePath = resolve25(cwd, trimmed);
245576
+ let filePath = resolve26(cwd, trimmed);
245525
245577
  if (!existsSync14(filePath)) {
245526
245578
  const candidates = [
245527
- resolve25(cwd, "supacloud/fa/release-scopes", trimmed),
245528
- resolve25(cwd, "release-scopes", trimmed),
245529
- resolve25(cwd, "scopes", trimmed)
245579
+ resolve26(cwd, "supacloud/fa/release-scopes", trimmed),
245580
+ resolve26(cwd, "release-scopes", trimmed),
245581
+ resolve26(cwd, "scopes", trimmed)
245530
245582
  ];
245531
245583
  const found = candidates.find(existsSync14);
245532
245584
  if (found)
@@ -245586,7 +245638,7 @@ function parseCommaList(value) {
245586
245638
  return [];
245587
245639
  }
245588
245640
  function handleScopeCreate(args, fallbackRef) {
245589
- const cwd = typeof args.cwd === "string" && args.cwd.trim() ? resolve25(args.cwd.trim()) : process.cwd();
245641
+ const cwd = typeof args.cwd === "string" && args.cwd.trim() ? resolve26(args.cwd.trim()) : process.cwd();
245590
245642
  if (typeof args.file !== "string" || !args.file.trim()) {
245591
245643
  throw new Error("'file' is required for scope_create");
245592
245644
  }
@@ -245601,7 +245653,7 @@ function handleScopeCreate(args, fallbackRef) {
245601
245653
  throw new Error("'ref' is invalid for release controls");
245602
245654
  }
245603
245655
  const targetBaseCommit = resolveGitBaseCommit(cwd, args.base_commit);
245604
- const filePath = resolve25(cwd, args.file.trim());
245656
+ const filePath = resolve26(cwd, args.file.trim());
245605
245657
  mkdirSync4(dirname14(filePath), { recursive: true });
245606
245658
  const scope = {
245607
245659
  baseCommit: targetBaseCommit,
@@ -245826,7 +245878,7 @@ function registerReleaseTools(server2, http, options = {}) {
245826
245878
  import { access as access4, lstat as lstat5, mkdtemp as mkdtemp2, opendir, readFile as readFile10, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
245827
245879
  import { createHash as createHash11 } from "node:crypto";
245828
245880
  import { tmpdir as tmpdir2 } from "node:os";
245829
- import { basename as basename9, dirname as dirname15, join as join19, relative as relative15, resolve as resolve26, sep as sep12 } from "node:path";
245881
+ import { basename as basename9, dirname as dirname15, join as join19, relative as relative15, resolve as resolve27, sep as sep12 } from "node:path";
245830
245882
 
245831
245883
  // node_modules/fflate/esm/index.mjs
245832
245884
  import { createRequire as createRequire3 } from "module";
@@ -246517,13 +246569,13 @@ async function readJson(path) {
246517
246569
  }
246518
246570
  }
246519
246571
  async function findDeployConfigRoot(startDirectory) {
246520
- let directory = resolve26(startDirectory);
246572
+ let directory = resolve27(startDirectory);
246521
246573
  while (true) {
246522
246574
  if (await pathExists(join19(directory, "supacloud.json")))
246523
246575
  return directory;
246524
246576
  const parent = dirname15(directory);
246525
246577
  if (parent === directory)
246526
- return resolve26(startDirectory);
246578
+ return resolve27(startDirectory);
246527
246579
  directory = parent;
246528
246580
  }
246529
246581
  }
@@ -246641,9 +246693,9 @@ function selectDeployment(deployments, requestedId, projectName) {
246641
246693
  throw new Error(deployments.length === 0 ? "No frontend deployments exist for this project" : `Multiple frontend deployments found (${ids}). Set frontend.id in supacloud.json or pass --id`);
246642
246694
  }
246643
246695
  function targetRoot(configRoot, target, name) {
246644
- const root = resolve26(configRoot, target.root || (name === "frontend" ? "." : name));
246645
- const prefix = `${resolve26(configRoot)}${sep12}`;
246646
- if (root !== resolve26(configRoot) && !root.startsWith(prefix)) {
246696
+ const root = resolve27(configRoot, target.root || (name === "frontend" ? "." : name));
246697
+ const prefix = `${resolve27(configRoot)}${sep12}`;
246698
+ if (root !== resolve27(configRoot) && !root.startsWith(prefix)) {
246647
246699
  throw new Error(`Deploy target '${name}' root must stay inside the repository root`);
246648
246700
  }
246649
246701
  return root;
@@ -246694,8 +246746,8 @@ function defaultOutputDirectory(framework) {
246694
246746
  }
246695
246747
  }
246696
246748
  function resolveInsideProject(projectDirectory, candidate, allowRoot = false) {
246697
- const resolved = resolve26(projectDirectory, candidate);
246698
- const projectRoot = resolve26(projectDirectory);
246749
+ const resolved = resolve27(projectDirectory, candidate);
246750
+ const projectRoot = resolve27(projectDirectory);
246699
246751
  const projectPrefix = `${projectRoot}${sep12}`;
246700
246752
  if (!allowRoot && resolved === projectRoot || resolved !== projectRoot && !resolved.startsWith(projectPrefix)) {
246701
246753
  throw new Error("Frontend output directory must stay inside the project directory");
@@ -246805,7 +246857,7 @@ function deployResponse(result, json) {
246805
246857
  }
246806
246858
  function registerDeployTools(server2, http, options = {}) {
246807
246859
  server2.tool("deploy", "Build and publish the linked frontend with one command", deployToolSchema, async (args) => {
246808
- const invocationDirectory = resolve26(String(args.cwd || options.cwd || process.cwd()));
246860
+ const invocationDirectory = resolve27(String(args.cwd || options.cwd || process.cwd()));
246809
246861
  const projectRef = String(args.ref || options.projectRef || "").trim();
246810
246862
  if (!projectRef)
246811
246863
  throw new Error("A linked project ref is required. Set SUPACLOUD_PROJECT_REF or pass --ref");
@@ -246981,7 +247033,7 @@ import { existsSync as existsSync15 } from "node:fs";
246981
247033
  import { readFile as readFile11 } from "node:fs/promises";
246982
247034
  import { readdir as readdir7 } from "node:fs/promises";
246983
247035
  import { createHash as createHash12 } from "node:crypto";
246984
- import { join as join20, resolve as resolve27 } from "node:path";
247036
+ import { join as join20, resolve as resolve28 } from "node:path";
246985
247037
  var SAFE_TOKEN = /^[A-Za-z0-9._:@/+,-]+$/;
246986
247038
  var SAFE_REMOTE_ROOT = /^\/(?:[A-Za-z0-9._-]+\/)*[A-Za-z0-9._-]+\/?$/;
246987
247039
  var remoteDevToolSchema = {
@@ -247022,12 +247074,12 @@ function toolFailed(value) {
247022
247074
  return value?.isError === true || value?.content?.some((chunk) => typeof chunk?.text === "string" && chunk.text.trimStart().startsWith("❌"));
247023
247075
  }
247024
247076
  async function migrateDatabase(args, options) {
247025
- const root = resolve27(String(args.project_dir || options.cwd || process.cwd()));
247077
+ const root = resolve28(String(args.project_dir || options.cwd || process.cwd()));
247026
247078
  const projectConfig = await readProjectConfig3(root);
247027
247079
  const config = projectConfig.dev || {};
247028
247080
  const database = config.database || {};
247029
247081
  const execute = options.execute || ((command, commandArgs, cwd) => runProcess(command, commandArgs, cwd));
247030
- const drizzleConfig = resolve27(root, String(args.drizzle_config || database.drizzleConfig || "drizzle.config.ts"));
247082
+ const drizzleConfig = resolve28(root, String(args.drizzle_config || database.drizzleConfig || "drizzle.config.ts"));
247031
247083
  const migrationsDir = String(args.migrations_dir || database.migrationsDir || "supabase/migrations");
247032
247084
  if (!existsSync15(drizzleConfig))
247033
247085
  throw new Error(`Drizzle config not found: ${drizzleConfig}`);
@@ -247098,13 +247150,13 @@ function targetDirectory(root, target, functionSlug, config = {}) {
247098
247150
  if (target === "functions") {
247099
247151
  const targets = config.targets && typeof config.targets === "object" ? config.targets : {};
247100
247152
  const match = Object.values(targets).find((entry) => entry?.type === "edge_function" && (!functionSlug || String(entry.slug || "") === functionSlug));
247101
- const base = match?.root ? resolve27(root, String(match.root)) : join20(root, "supabase", "functions");
247153
+ const base = match?.root ? resolve28(root, String(match.root)) : join20(root, "supabase", "functions");
247102
247154
  return match?.root ? base : functionSlug ? join20(base, safeToken(functionSlug, "function")) : base;
247103
247155
  }
247104
247156
  if (target === "frontend") {
247105
247157
  const targets = config.targets && typeof config.targets === "object" ? config.targets : {};
247106
247158
  const match = Object.values(targets).find((entry) => entry?.type === "frontend");
247107
- return match?.root ? resolve27(root, String(match.root)) : join20(root, "apps", "web");
247159
+ return match?.root ? resolve28(root, String(match.root)) : join20(root, "apps", "web");
247108
247160
  }
247109
247161
  return root;
247110
247162
  }
@@ -247143,10 +247195,10 @@ function reloadCommand(config, target, projectRef, functionSlug) {
247143
247195
  return [...command.split(" "), "--project-ref", safeToken(projectRef || "test", "project_ref"), "--target", targetConfigPath(target), ...functionSlug ? ["--function", safeToken(functionSlug, "function")] : []];
247144
247196
  }
247145
247197
  function sshArgs(connection, remoteCommand) {
247146
- return ["-p", String(connection.port), "-i", resolve27(connection.key), "-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=yes", `${connection.user}@${connection.host}`, ...remoteCommand];
247198
+ return ["-p", String(connection.port), "-i", resolve28(connection.key), "-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=yes", `${connection.user}@${connection.host}`, ...remoteCommand];
247147
247199
  }
247148
247200
  function rsyncArgs(connection, source, destination, excludes, deleteRemote) {
247149
- const args = ["-az", "--checksum", "--partial", "--protect-args", "-e", `ssh -p ${connection.port} -i ${resolve27(connection.key)} -o BatchMode=yes -o StrictHostKeyChecking=yes`];
247201
+ const args = ["-az", "--checksum", "--partial", "--protect-args", "-e", `ssh -p ${connection.port} -i ${resolve28(connection.key)} -o BatchMode=yes -o StrictHostKeyChecking=yes`];
247150
247202
  if (deleteRemote)
247151
247203
  args.push("--delete-delay");
247152
247204
  for (const exclude of excludes) {
@@ -247158,7 +247210,7 @@ function rsyncArgs(connection, source, destination, excludes, deleteRemote) {
247158
247210
  return args;
247159
247211
  }
247160
247212
  async function syncOnce(args, options) {
247161
- const root = resolve27(String(args.project_dir || options.cwd || process.cwd()));
247213
+ const root = resolve28(String(args.project_dir || options.cwd || process.cwd()));
247162
247214
  const projectConfig = await readProjectConfig3(root);
247163
247215
  const config = projectConfig.dev || {};
247164
247216
  const target = String(args.target || "project");
@@ -247167,8 +247219,8 @@ async function syncOnce(args, options) {
247167
247219
  throw new Error(`Dev source directory not found: ${source}`);
247168
247220
  let compiled = false;
247169
247221
  if (config.compile === true && target !== "db") {
247170
- const compileRoot = resolve27(root, config.compileRoot || ".");
247171
- const compileOutDir = resolve27(root, config.compileOutDir || "generated");
247222
+ const compileRoot = resolve28(root, config.compileRoot || ".");
247223
+ const compileOutDir = resolve28(root, config.compileOutDir || "generated");
247172
247224
  const compilation = await compileProject({
247173
247225
  rootDir: compileRoot,
247174
247226
  outDir: compileOutDir,
@@ -247206,7 +247258,7 @@ function registerRemoteDevTools(server2, options = {}) {
247206
247258
  if (["production", "prod"].includes((options.environment || "").toLowerCase()))
247207
247259
  throw new Error("Remote dev mode is forbidden for production environments");
247208
247260
  if (args.action === "status") {
247209
- const root = resolve27(String(args.project_dir || options.cwd || process.cwd()));
247261
+ const root = resolve28(String(args.project_dir || options.cwd || process.cwd()));
247210
247262
  const config = await readDevConfig(root);
247211
247263
  const connection = connectionArgs(options, config, args);
247212
247264
  const execute = options.execute || ((command, commandArgs, cwd) => runProcess(command, commandArgs, cwd));
@@ -247220,7 +247272,7 @@ function registerRemoteDevTools(server2, options = {}) {
247220
247272
  return { content: [{ type: "text", text: JSON.stringify(await migrateDatabase(args, options), null, 2) }] };
247221
247273
  }
247222
247274
  if (args.action === "watch") {
247223
- const root = resolve27(String(args.project_dir || options.cwd || process.cwd()));
247275
+ const root = resolve28(String(args.project_dir || options.cwd || process.cwd()));
247224
247276
  const interval = Math.max(100, Math.min(1e4, Number(args.interval_ms || 300)));
247225
247277
  let fingerprint = "";
247226
247278
  let lastSync = null;
@@ -247241,7 +247293,7 @@ function registerRemoteDevTools(server2, options = {}) {
247241
247293
  // package.json
247242
247294
  var package_default = {
247243
247295
  name: "@supacloud/cli",
247244
- version: "0.68.2",
247296
+ version: "0.69.0",
247245
247297
  description: "Project-scoped CLI for SupaCloud users",
247246
247298
  type: "module",
247247
247299
  main: "./dist/index.js",
@@ -247275,7 +247327,7 @@ var package_default = {
247275
247327
  directory: "packages/cli"
247276
247328
  },
247277
247329
  dependencies: {
247278
- "@supacloud/compiler": "^0.38.2",
247330
+ "@supacloud/compiler": "^0.39.0",
247279
247331
  "@supacloud/delivery": "0.8.0",
247280
247332
  "@supacloud/db": "^0.2.0",
247281
247333
  fflate: "^0.8.3",