@supacloud/compiler 0.38.2 → 0.39.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.
package/dist/cli.js CHANGED
@@ -1433,9 +1433,9 @@ function renderApplication(graph, options) {
1433
1433
  "}",
1434
1434
  "",
1435
1435
  "export async function initializeApplication(services: Record<string, unknown>): Promise<void> {",
1436
- ' const initializers = [services.environmentInitializer ?? services["supacloud.environment-initializer"], services.appInitializer ?? services["supacloud.app-initializer"]];',
1436
+ ' const initializers = [services["environmentInitializer"] ?? services["supacloud.environment-initializer"], services["appInitializer"] ?? services["supacloud.app-initializer"]];',
1437
1437
  " for (const group of initializers) {",
1438
- " if (Array.isArray(group)) {",
1438
+ " if (isUnknownArray(group)) {",
1439
1439
  " for (const init of group) {",
1440
1440
  " if (isFunction(init)) await init();",
1441
1441
  " }",
@@ -1446,21 +1446,21 @@ function renderApplication(graph, options) {
1446
1446
  "}",
1447
1447
  "",
1448
1448
  "export async function destroyApplication(services: Record<string, unknown>): Promise<void> {",
1449
- ' const destroyRef = (Object.prototype.propertyIsEnumerable.call(services, "destroyRef") ? services.destroyRef : undefined)',
1449
+ ' const destroyRef = (Object.prototype.propertyIsEnumerable.call(services, "destroyRef") ? services["destroyRef"] : undefined)',
1450
1450
  ' ?? (Object.prototype.propertyIsEnumerable.call(services, "supacloud.destroy-ref") ? services["supacloud.destroy-ref"] : undefined);',
1451
- " if (isRecord(destroyRef) && isFunction(destroyRef.destroy)) {",
1452
- " await destroyRef.destroy();",
1453
- " } else if (isRecord(destroyRef) && Array.isArray(destroyRef._teardowns)) {",
1454
- " for (const teardown of [...destroyRef._teardowns].reverse()) {",
1451
+ ' if (isRecord(destroyRef) && isFunction(destroyRef["destroy"])) {',
1452
+ ' await destroyRef["destroy"]();',
1453
+ ' } else if (isRecord(destroyRef) && isUnknownArray(destroyRef["_teardowns"])) {',
1454
+ ' for (const teardown of [...destroyRef["_teardowns"]].reverse()) {',
1455
1455
  " if (isFunction(teardown)) await teardown();",
1456
1456
  " }",
1457
1457
  " }",
1458
1458
  " const instances = Object.values(services);",
1459
1459
  " for (const inst of instances.reverse()) {",
1460
- " if (isRecord(inst) && isFunction(inst.onDestroy)) {",
1461
- " await inst.onDestroy();",
1462
- " } else if (isRecord(inst) && isFunction(inst.ngOnDestroy)) {",
1463
- " await inst.ngOnDestroy();",
1460
+ ' if (isRecord(inst) && isFunction(inst["onDestroy"])) {',
1461
+ ' await inst["onDestroy"]();',
1462
+ ' } else if (isRecord(inst) && isFunction(inst["ngOnDestroy"])) {',
1463
+ ' await inst["ngOnDestroy"]();',
1464
1464
  " }",
1465
1465
  " }",
1466
1466
  "}",
@@ -1857,7 +1857,7 @@ class ModuleGenerator {
1857
1857
  return "undefined";
1858
1858
  });
1859
1859
  const callArgs = invokerArgs.length > 0 ? invokerArgs.join(", ") : "req";
1860
- 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}]); }`);
1860
+ 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}]); }`);
1861
1861
  if (route.contract !== undefined) {
1862
1862
  fields.push(`contract: ${JSON.stringify(route.contract)}`);
1863
1863
  }
@@ -2029,7 +2029,7 @@ ${indent(item, 2)}`).join(",")}
2029
2029
  if (emitted.constLine)
2030
2030
  lines.push(emitted.constLine);
2031
2031
  if (scoped) {
2032
- lines.push(`scope[${JSON.stringify(emitted.key)}] = [...(Array.isArray(scope[${JSON.stringify(emitted.key)}]) ? scope[${JSON.stringify(emitted.key)}] : []), ${emitted.expr}];`);
2032
+ lines.push(`scope[${JSON.stringify(emitted.key)}] = [...(isUnknownArray(scope[${JSON.stringify(emitted.key)}]) ? scope[${JSON.stringify(emitted.key)}] : []), ${emitted.expr}];`);
2033
2033
  }
2034
2034
  const list = multiGroups.get(emitted.key) ?? [];
2035
2035
  list.push(emitted.expr);
@@ -2071,14 +2071,14 @@ ${indent(item, 2)}`).join(",")}
2071
2071
  continue;
2072
2072
  const key = camelName(token);
2073
2073
  const expression = this.depExpr(token, scopeKind, this.depOptions(node, token));
2074
- if (expression === `services.${key}` || expression === `(services.${key} ?? undefined)`) {
2074
+ if (expression === `services[${JSON.stringify(key)}]` || expression === `(services[${JSON.stringify(key)}] ?? undefined)`) {
2075
2075
  if (!returns.has(key))
2076
2076
  borrowed.add(key);
2077
2077
  }
2078
2078
  }
2079
2079
  }
2080
2080
  if (borrowed.size > 0) {
2081
- const descriptors = [...borrowed].map((key) => `${key}: { value: deps.${key} }`);
2081
+ const descriptors = [...borrowed].map((key) => `${key}: { value: deps[${JSON.stringify(key)}] }`);
2082
2082
  lines.push(`return retainPlatformDependencies(Object.defineProperties({ ${entries.join(", ")} }, { ${descriptors.join(", ")} }), deps);`);
2083
2083
  } else {
2084
2084
  lines.push(`return retainPlatformDependencies({ ${entries.join(", ")} }, deps);`);
@@ -2184,34 +2184,34 @@ ${indent(item, 2)}`).join(",")}
2184
2184
  }
2185
2185
  }
2186
2186
  if (own && factoryOfScope(own.scope) === "services" && kind !== "services" && !isSkipSelf && !isSelf) {
2187
- return `services.${camelName(token)}`;
2187
+ return `services[${JSON.stringify(camelName(token))}]`;
2188
2188
  }
2189
2189
  if (isSelf) {
2190
- return isOptional ? "undefined" : `services.${camelName(token)}`;
2190
+ return isOptional ? "undefined" : `services[${JSON.stringify(camelName(token))}]`;
2191
2191
  }
2192
2192
  for (const importName of this.module.imports) {
2193
2193
  const imported = this.graph.modules.find((m) => m.name === importName);
2194
2194
  if (!imported?.exports.includes(token))
2195
2195
  continue;
2196
2196
  if (kind === "services")
2197
- return `imported.${importName}.${camelName(token)}`;
2198
- return `imported.${importName}.${camelName(token)}`;
2197
+ return `imported[${JSON.stringify(importName)}][${JSON.stringify(camelName(token))}]`;
2198
+ return `imported[${JSON.stringify(importName)}][${JSON.stringify(camelName(token))}]`;
2199
2199
  }
2200
2200
  for (const mod of this.graph.modules) {
2201
2201
  const rootProv = mod.providers.find((p) => p.token === token && p.providedIn === "root");
2202
2202
  if (rootProv) {
2203
- return `imported.${mod.name}.${camelName(token)}`;
2203
+ return `imported[${JSON.stringify(mod.name)}][${JSON.stringify(camelName(token))}]`;
2204
2204
  }
2205
2205
  }
2206
2206
  if (isSelf)
2207
- return isOptional ? "undefined" : `services.${camelName(token)}`;
2207
+ return isOptional ? "undefined" : `services[${JSON.stringify(camelName(token))}]`;
2208
2208
  if (kind === "services")
2209
- return isOptional ? `(deps.${camelName(token)} ?? undefined)` : `deps.${camelName(token)}`;
2209
+ return isOptional ? `(deps[${JSON.stringify(camelName(token))}] ?? undefined)` : `deps[${JSON.stringify(camelName(token))}]`;
2210
2210
  if (isSkipSelf) {
2211
- const external = `platformDependencies.get(services)?.${camelName(token)}`;
2211
+ const external = `platformDependencies.get(services)?.[${JSON.stringify(camelName(token))}]`;
2212
2212
  return isOptional ? `(${external} ?? undefined)` : external;
2213
2213
  }
2214
- return isOptional ? `(services.${camelName(token)} ?? undefined)` : `services.${camelName(token)}`;
2214
+ return isOptional ? `(services[${JSON.stringify(camelName(token))}] ?? undefined)` : `services[${JSON.stringify(camelName(token))}]`;
2215
2215
  }
2216
2216
  }
2217
2217
  function orderProviders(providers) {
@@ -3726,9 +3726,13 @@ function isFunction(value: unknown): value is (...args: unknown[]) => unknown {
3726
3726
  return typeof value === "function";
3727
3727
  }
3728
3728
 
3729
+ function isUnknownArray(value: unknown): value is unknown[] {
3730
+ return Array.isArray(value);
3731
+ }
3732
+
3729
3733
  function resolveFactoryValue(value: unknown): unknown {
3730
- if (!isRecord(value) || !isFunction(value.factory)) return undefined;
3731
- return value.factory();
3734
+ if (!isRecord(value) || !isFunction(value["factory"])) return undefined;
3735
+ return value["factory"]();
3732
3736
  }
3733
3737
 
3734
3738
  const scopeDestructions = new WeakMap<object, Promise<void>>();
@@ -3751,14 +3755,14 @@ function destroyScopeInstances(
3751
3755
  for (const entry of [...plan].reverse()) {
3752
3756
  const value = scope[entry.key];
3753
3757
  const instance = entry.index === undefined ? value
3754
- : Array.isArray(value) ? value[entry.index] : undefined;
3758
+ : isUnknownArray(value) ? value[entry.index] : undefined;
3755
3759
  if (seen.has(instance)) continue;
3756
3760
  seen.add(instance);
3757
3761
  try {
3758
- if (isRecord(instance) && isFunction(instance.onDestroy)) {
3759
- await instance.onDestroy();
3760
- } else if (isRecord(instance) && isFunction(instance.ngOnDestroy)) {
3761
- await instance.ngOnDestroy();
3762
+ if (isRecord(instance) && isFunction(instance["onDestroy"])) {
3763
+ await instance["onDestroy"]();
3764
+ } else if (isRecord(instance) && isFunction(instance["ngOnDestroy"])) {
3765
+ await instance["ngOnDestroy"]();
3762
3766
  }
3763
3767
  } catch (error) {
3764
3768
  errors.push(error);
@@ -3781,11 +3785,11 @@ async function initializeServiceInstances(
3781
3785
  const value = services[entry.key];
3782
3786
  const instance = entry.index === undefined
3783
3787
  ? value
3784
- : Array.isArray(value) ? value[entry.index] : undefined;
3788
+ : isUnknownArray(value) ? value[entry.index] : undefined;
3785
3789
  if (seen.has(instance)) continue;
3786
3790
  seen.add(instance);
3787
- if (!isRecord(instance) || !isFunction(instance.onInit)) continue;
3788
- await instance.onInit();
3791
+ if (!isRecord(instance) || !isFunction(instance["onInit"])) continue;
3792
+ await instance["onInit"]();
3789
3793
  }
3790
3794
  }
3791
3795
 
@@ -3799,13 +3803,13 @@ async function destroyServiceInstances(
3799
3803
  const value = services[entry.key];
3800
3804
  const instance = entry.index === undefined
3801
3805
  ? value
3802
- : Array.isArray(value) ? value[entry.index] : undefined;
3806
+ : isUnknownArray(value) ? value[entry.index] : undefined;
3803
3807
  if (seen.has(instance)) continue;
3804
3808
  seen.add(instance);
3805
3809
  if (!isRecord(instance)) continue;
3806
- const hook = isFunction(instance.onDestroy)
3807
- ? instance.onDestroy
3808
- : isFunction(instance.ngOnDestroy) ? instance.ngOnDestroy : undefined;
3810
+ const hook = isFunction(instance["onDestroy"])
3811
+ ? instance["onDestroy"]
3812
+ : isFunction(instance["ngOnDestroy"]) ? instance["ngOnDestroy"] : undefined;
3809
3813
  if (!hook) continue;
3810
3814
  try {
3811
3815
  await hook.call(instance);
@@ -4037,7 +4041,7 @@ var init_graphql_options = __esm(() => {
4037
4041
  });
4038
4042
 
4039
4043
  // src/graphql-inputs.ts
4040
- import { resolve as resolve4 } from "node:path";
4044
+ import { resolve as resolve5 } from "node:path";
4041
4045
  import * as ts10 from "@typescript/typescript6";
4042
4046
  function graphqlInputPaths(options) {
4043
4047
  if (!options.graphql)
@@ -4047,9 +4051,9 @@ function graphqlInputPaths(options) {
4047
4051
  } catch {
4048
4052
  return [];
4049
4053
  }
4050
- const root = resolve4(options.rootDir);
4051
- const schema = resolve4(root, options.graphql.schema);
4052
- const documents = ts10.sys.readDirectory(root, [".graphql", ".gql"], ["**/node_modules/**", "**/.git/**", resolve4(options.outDir)], options.graphql.documents ?? ["**/*.graphql", "**/*.gql"]).map((path) => resolve4(path)).filter((path) => path !== schema);
4054
+ const root = resolve5(options.rootDir);
4055
+ const schema = resolve5(root, options.graphql.schema);
4056
+ const documents = ts10.sys.readDirectory(root, [".graphql", ".gql"], ["**/node_modules/**", "**/.git/**", resolve5(options.outDir)], options.graphql.documents ?? ["**/*.graphql", "**/*.gql"]).map((path) => resolve5(path)).filter((path) => path !== schema);
4053
4057
  return [schema, ...[...new Set(documents)].sort()];
4054
4058
  }
4055
4059
  var init_graphql_inputs = __esm(() => {
@@ -4058,9 +4062,9 @@ var init_graphql_inputs = __esm(() => {
4058
4062
 
4059
4063
  // src/graphql-runtime.ts
4060
4064
  import * as ts11 from "@typescript/typescript6";
4061
- import { resolve as resolve5 } from "node:path";
4065
+ import { resolve as resolve6 } from "node:path";
4062
4066
  function renderGraphqlValidators(source, operationNames) {
4063
- const fileName = resolve5("/__supacloud_graphql__/contracts.ts");
4067
+ const fileName = resolve6("/__supacloud_graphql__/contracts.ts");
4064
4068
  const options = {
4065
4069
  strict: true,
4066
4070
  noUncheckedIndexedAccess: true,
@@ -4076,7 +4080,7 @@ function renderGraphqlValidators(source, operationNames) {
4076
4080
  };
4077
4081
  const host = ts11.createCompilerHost(options);
4078
4082
  const getSourceFile = host.getSourceFile.bind(host);
4079
- host.getSourceFile = (path, languageVersion, onError, shouldCreateNewSourceFile) => resolve5(path) === fileName ? ts11.createSourceFile(path, source, languageVersion, true) : getSourceFile(path, languageVersion, onError, shouldCreateNewSourceFile);
4083
+ host.getSourceFile = (path, languageVersion, onError, shouldCreateNewSourceFile) => resolve6(path) === fileName ? ts11.createSourceFile(path, source, languageVersion, true) : getSourceFile(path, languageVersion, onError, shouldCreateNewSourceFile);
4080
4084
  const program = ts11.createProgram([fileName], options, host);
4081
4085
  const diagnostics = ts11.getPreEmitDiagnostics(program);
4082
4086
  if (diagnostics.length) {
@@ -15727,7 +15731,7 @@ var init_delivery_schema = __esm(() => {
15727
15731
  import { createHash as createHash6 } from "node:crypto";
15728
15732
  import { constants as constants2 } from "node:fs";
15729
15733
  import { lstat, mkdir as mkdir2, open as open3, readFile as readFile3, readdir, realpath, rename as rename2, rm, writeFile as writeFile2 } from "node:fs/promises";
15730
- import { dirname as dirname5, isAbsolute as isAbsolute2, join as join6, relative as relative6, resolve as resolve7, sep as sep6 } from "node:path";
15734
+ import { dirname as dirname5, isAbsolute as isAbsolute2, join as join6, relative as relative6, resolve as resolve8, sep as sep6 } from "node:path";
15731
15735
  function canonical2(value) {
15732
15736
  return JSON.stringify(value, (_key, item) => item !== null && typeof item === "object" && !Array.isArray(item) ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) : item);
15733
15737
  }
@@ -15790,7 +15794,7 @@ async function reserveOutput(project, requested) {
15790
15794
  if (!inside(project, requested))
15791
15795
  throw new Error("Delivery output must be inside the application project.");
15792
15796
  const base = await realpath(project);
15793
- const path = resolve7(base, relative6(project, requested));
15797
+ const path = resolve8(base, relative6(project, requested));
15794
15798
  if (relative6(base, path).split(sep6).some((part) => part === ".git" || part === "node_modules")) {
15795
15799
  throw new Error("Delivery output cannot use repository or dependency internals.");
15796
15800
  }
@@ -15998,9 +16002,9 @@ var init_delivery_build_schema = __esm(() => {
15998
16002
 
15999
16003
  // node_modules/@supacloud/delivery/src/delivery-artifact.ts
16000
16004
  import { readdir as readdir2, realpath as realpath2 } from "node:fs/promises";
16001
- import { basename, dirname as dirname6, join as join7, resolve as resolve8 } from "node:path";
16005
+ import { basename, dirname as dirname6, join as join7, resolve as resolve9 } from "node:path";
16002
16006
  async function readDeliveryManifest(manifestPath) {
16003
- const selected = resolve8(manifestPath);
16007
+ const selected = resolve9(manifestPath);
16004
16008
  const root = await realpath2(dirname6(selected));
16005
16009
  const manifest = parseDeliveryBuildManifest(JSON.parse((await readBoundedOwned(root, join7(root, basename(selected)), JSON_LIMIT)).toString("utf8")));
16006
16010
  return { root, manifest };
@@ -16152,13 +16156,13 @@ var init_delivery_context = __esm(() => {
16152
16156
  // src/fixes.ts
16153
16157
  import { createHash as createHash8, randomUUID } from "node:crypto";
16154
16158
  import { lstat as lstat2, readFile as readFile5, realpath as realpath3, rename as rename3, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
16155
- import { dirname as dirname8, isAbsolute as isAbsolute4, relative as relative9, resolve as resolve12, sep as sep9 } from "node:path";
16159
+ import { dirname as dirname8, isAbsolute as isAbsolute4, relative as relative9, resolve as resolve13, sep as sep9 } from "node:path";
16156
16160
  import * as ts12 from "@typescript/typescript6";
16157
16161
  async function applyDiagnosticFix(fix, options = {}) {
16158
16162
  if (!fix || typeof fix.targetFile !== "string")
16159
16163
  throw new Error("Invalid DiagnosticFix");
16160
16164
  const root = await realpath3(options.rootDir ?? process.cwd());
16161
- const file = resolve12(root, fix.targetFile);
16165
+ const file = resolve13(root, fix.targetFile);
16162
16166
  const stat = await lstat2(file);
16163
16167
  const resolved = await realpath3(file);
16164
16168
  const relativePath = relative9(root, resolved);
@@ -16331,8 +16335,8 @@ function moduleObjects(source) {
16331
16335
  }
16332
16336
  function importSymbol(source, path, symbol) {
16333
16337
  identifier2(symbol);
16334
- const current = resolve12(source.fileName).replace(/\.(tsx?|mts|cts)$/, "");
16335
- const target = resolve12(dirname8(source.fileName), path).replace(/\.(tsx?|mts|cts)$/, "");
16338
+ const current = resolve13(source.fileName).replace(/\.(tsx?|mts|cts)$/, "");
16339
+ const target = resolve13(dirname8(source.fileName), path).replace(/\.(tsx?|mts|cts)$/, "");
16336
16340
  if (current === target)
16337
16341
  return source.text;
16338
16342
  const matches = source.statements.filter((item) => ts12.isImportDeclaration(item) && ts12.isStringLiteral(item.moduleSpecifier) && item.moduleSpecifier.text === path);
@@ -16830,7 +16834,7 @@ var init_release_evidence = __esm(() => {
16830
16834
  });
16831
16835
 
16832
16836
  // src/release-evidence-cli.ts
16833
- import { resolve as resolve20 } from "node:path";
16837
+ import { resolve as resolve21 } from "node:path";
16834
16838
  async function runReleaseEvidenceCommand(args) {
16835
16839
  try {
16836
16840
  const values = new Map;
@@ -16854,7 +16858,7 @@ async function runReleaseEvidenceCommand(args) {
16854
16858
  if (!manifest || !target || manifest.length > 4096 || !/^[a-z][a-z0-9-]{0,62}$/.test(target)) {
16855
16859
  throw new ReleaseEvidenceError("RELEASE_EVIDENCE_INVALID");
16856
16860
  }
16857
- const evidence = await createReleaseEvidence(resolve20(manifest), target);
16861
+ const evidence = await createReleaseEvidence(resolve21(manifest), target);
16858
16862
  console.log(json ? JSON.stringify(evidence, null, 2) : formatReleaseEvidence(evidence));
16859
16863
  } catch (error) {
16860
16864
  console.error(`Error: ${error instanceof ReleaseEvidenceError ? error.code : "RELEASE_EVIDENCE_INVALID"}`);
@@ -16868,7 +16872,7 @@ var init_release_evidence_cli = __esm(() => {
16868
16872
  // src/database-contracts.ts
16869
16873
  import { createHash as createHash11 } from "node:crypto";
16870
16874
  import { mkdir as mkdir5, readFile as readFile12 } from "node:fs/promises";
16871
- import { dirname as dirname11, relative as relative12, resolve as resolve21 } from "node:path";
16875
+ import { dirname as dirname11, relative as relative12, resolve as resolve22 } from "node:path";
16872
16876
  import * as ts17 from "@typescript/typescript6";
16873
16877
  function hash3(value) {
16874
16878
  return createHash11("sha256").update(value).digest("hex");
@@ -16896,18 +16900,18 @@ function parseDatabaseContractsOptions(value, directory) {
16896
16900
  throw new TypeError("migrations must be an ordered list of SQL files");
16897
16901
  }
16898
16902
  return {
16899
- rootDir: resolve21(directory, field("rootDir")),
16900
- outDir: resolve21(directory, field("outDir")),
16901
- postgrestTypes: resolve21(directory, field("postgrestTypes")),
16902
- drizzleSchema: resolve21(directory, field("drizzleSchema")),
16903
+ rootDir: resolve22(directory, field("rootDir")),
16904
+ outDir: resolve22(directory, field("outDir")),
16905
+ postgrestTypes: resolve22(directory, field("postgrestTypes")),
16906
+ drizzleSchema: resolve22(directory, field("drizzleSchema")),
16903
16907
  role: field("role"),
16904
- graphql: { ...graphql, schema: resolve21(directory, graphql.schema) },
16905
- migrations: migrations.map((file) => resolve21(directory, file))
16908
+ graphql: { ...graphql, schema: resolve22(directory, graphql.schema) },
16909
+ migrations: migrations.map((file) => resolve22(directory, file))
16906
16910
  };
16907
16911
  }
16908
16912
  async function generateDatabaseContracts(options, check = false) {
16909
- const rootDir = resolve21(options.rootDir), outDir = resolve21(options.outDir);
16910
- const postgrestTypes = resolve21(rootDir, options.postgrestTypes), drizzleSchema = resolve21(rootDir, options.drizzleSchema);
16913
+ const rootDir = resolve22(options.rootDir), outDir = resolve22(options.outDir);
16914
+ const postgrestTypes = resolve22(rootDir, options.postgrestTypes), drizzleSchema = resolve22(rootDir, options.drizzleSchema);
16911
16915
  const snapshot = await readFile12(postgrestTypes, "utf8");
16912
16916
  const syntax = ts17.createSourceFile(postgrestTypes, snapshot, ts17.ScriptTarget.Latest, true);
16913
16917
  const database = syntax.statements.find((node) => (ts17.isTypeAliasDeclaration(node) || ts17.isInterfaceDeclaration(node)) && node.name.text === "Database" && node.modifiers?.some((modifier) => modifier.kind === ts17.SyntaxKind.ExportKeyword));
@@ -16935,7 +16939,7 @@ async function generateDatabaseContracts(options, check = false) {
16935
16939
  }
16936
16940
  const inputs = {};
16937
16941
  const addInput = async (path) => {
16938
- const absolute = resolve21(rootDir, path);
16942
+ const absolute = resolve22(rootDir, path);
16939
16943
  inputs[relative12(rootDir, absolute).replaceAll("\\", "/")] = hash3(await readFile12(absolute, "utf8"));
16940
16944
  };
16941
16945
  await addInput(postgrestTypes);
@@ -16952,8 +16956,8 @@ async function generateDatabaseContracts(options, check = false) {
16952
16956
  if (!source.isDeclarationFile && !source.fileName.includes("/node_modules/"))
16953
16957
  await addInput(source.fileName);
16954
16958
  }
16955
- await addInput(resolve21(rootDir, options.graphql.schema));
16956
- if (new Set(options.migrations.map((path) => resolve21(rootDir, path))).size !== options.migrations.length) {
16959
+ await addInput(resolve22(rootDir, options.graphql.schema));
16960
+ if (new Set(options.migrations.map((path) => resolve22(rootDir, path))).size !== options.migrations.length) {
16957
16961
  throw new Error("Duplicate migration in database contracts configuration");
16958
16962
  }
16959
16963
  for (const path of options.migrations)
@@ -16974,14 +16978,14 @@ async function generateDatabaseContracts(options, check = false) {
16974
16978
  version: 1,
16975
16979
  role: options.role,
16976
16980
  inputs: Object.fromEntries(Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b))),
16977
- migrationOrder: options.migrations.map((path) => relative12(rootDir, resolve21(rootDir, path)).replaceAll("\\", "/")),
16981
+ migrationOrder: options.migrations.map((path) => relative12(rootDir, resolve22(rootDir, path)).replaceAll("\\", "/")),
16978
16982
  outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file, hash3(text)]))
16979
16983
  };
16980
16984
  files["database.manifest.json"] = JSON.stringify(manifest, null, 2) + `
16981
16985
  `;
16982
16986
  const mismatches = [];
16983
16987
  for (const [file, content] of Object.entries(files)) {
16984
- const path = resolve21(outDir, file);
16988
+ const path = resolve22(outDir, file);
16985
16989
  let current;
16986
16990
  try {
16987
16991
  current = await readFile12(path, "utf8");
@@ -16995,12 +16999,12 @@ async function generateDatabaseContracts(options, check = false) {
16995
16999
  if (!check) {
16996
17000
  await mkdir5(outDir, { recursive: true });
16997
17001
  for (const [file, content] of Object.entries(files))
16998
- await writeFileIfChanged(resolve21(outDir, file), content);
17002
+ await writeFileIfChanged(resolve22(outDir, file), content);
16999
17003
  }
17000
17004
  return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest };
17001
17005
  }
17002
17006
  async function runDatabaseContractsFile(path, check = false) {
17003
- const absolute = resolve21(path);
17007
+ const absolute = resolve22(path);
17004
17008
  const value = JSON.parse(await readFile12(absolute, "utf8"));
17005
17009
  return generateDatabaseContracts(parseDatabaseContractsOptions(value, dirname11(absolute)), check);
17006
17010
  }
@@ -17012,7 +17016,7 @@ var init_database_contracts = __esm(() => {
17012
17016
 
17013
17017
  // src/graphql-schema.ts
17014
17018
  import { mkdir as mkdir6, readFile as readFile13 } from "node:fs/promises";
17015
- import { dirname as dirname12, resolve as resolve22 } from "node:path";
17019
+ import { dirname as dirname12, resolve as resolve23 } from "node:path";
17016
17020
  async function pullGraphqlSchema(options) {
17017
17021
  assertGraphqlOptions({ schema: options.output });
17018
17022
  const endpoint = new URL(options.url);
@@ -17052,7 +17056,7 @@ async function pullGraphqlSchema(options) {
17052
17056
  throw new Error("GraphQL schema export failed. Verify caller grants and enable introspection only in the intended development environment.");
17053
17057
  }
17054
17058
  const schema = lexicographicSortSchema(buildClientSchema(data));
17055
- const path = resolve22(options.output);
17059
+ const path = resolve23(options.output);
17056
17060
  const content = path.endsWith(".json") ? JSON.stringify(introspectionFromSchema(schema), null, 2) + `
17057
17061
  ` : `# GENERATED BY supacloud-compiler graphql-schema. DO NOT EDIT.
17058
17062
  # Database First: change database declarations, apply migrations, then re-export for the intended role.
@@ -17080,7 +17084,7 @@ var init_graphql_schema = __esm(() => {
17080
17084
  });
17081
17085
 
17082
17086
  // src/cli.ts
17083
- import { resolve as resolve23 } from "node:path";
17087
+ import { resolve as resolve24 } from "node:path";
17084
17088
  import { readFile as readFile14 } from "node:fs/promises";
17085
17089
 
17086
17090
  // src/analyze.ts
@@ -20515,6 +20519,55 @@ function isAnyKeyword(node) {
20515
20519
 
20516
20520
  // src/compile.ts
20517
20521
  init_route_contracts();
20522
+
20523
+ // src/client-schema-boundaries.ts
20524
+ import { resolve as resolve4 } from "node:path";
20525
+ function validateClientSchemaBoundaries(graph, options) {
20526
+ if (!options.generateClient)
20527
+ return [];
20528
+ const identity = (path) => resolve4(options.rootDir, path).replace(/\.(?:[cm]?ts|[cm]?js)$/, "");
20529
+ const runtimeModules = new Set(graph.modules.flatMap((module) => [
20530
+ module.file,
20531
+ ...module.controllers.map((controller) => controller.file),
20532
+ ...module.providers.map((provider) => provider.file)
20533
+ ]).filter((file) => typeof file === "string").map(identity));
20534
+ const diagnostics = [];
20535
+ const seen = new Set;
20536
+ for (const module of graph.modules) {
20537
+ for (const controller of module.controllers) {
20538
+ for (const route of controller.routes) {
20539
+ const symbols = [
20540
+ route.body,
20541
+ route.params,
20542
+ route.query,
20543
+ route.headers,
20544
+ route.cookie,
20545
+ ...route.responses && Object.keys(route.responses).length ? Object.values(route.responses) : [route.response]
20546
+ ];
20547
+ for (const symbol of symbols) {
20548
+ if (!symbol)
20549
+ continue;
20550
+ const importedFrom = controller.schemaImports?.[symbol];
20551
+ if (!importedFrom || !runtimeModules.has(identity(importedFrom)))
20552
+ continue;
20553
+ const key = `${identity(importedFrom)}:${symbol}`;
20554
+ if (seen.has(key))
20555
+ continue;
20556
+ seen.add(key);
20557
+ diagnostics.push({
20558
+ severity: "warn",
20559
+ code: "client-schema-runtime-import",
20560
+ file: controller.file,
20561
+ 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.`
20562
+ });
20563
+ }
20564
+ }
20565
+ }
20566
+ }
20567
+ return diagnostics;
20568
+ }
20569
+
20570
+ // src/compile.ts
20518
20571
  function withDefaultGovernance(options) {
20519
20572
  return options.commandCapabilities === undefined ? { ...options, commandCapabilities: {
20520
20573
  requirePersistentAdapters: true,
@@ -20532,7 +20585,8 @@ async function compileProject(options) {
20532
20585
  const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
20533
20586
  const diagnostics = [
20534
20587
  ...graph.diagnostics ?? [],
20535
- ...validateGraph(graph, options)
20588
+ ...validateGraph(graph, options),
20589
+ ...validateClientSchemaBoundaries(graph, options)
20536
20590
  ];
20537
20591
  if (diagnostics.some((item) => item.code === "runtime-injection-disallowed")) {
20538
20592
  return { diagnostics, graph, written: [] };
@@ -20595,7 +20649,8 @@ async function checkProject(options) {
20595
20649
  const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
20596
20650
  const diagnostics = [
20597
20651
  ...graph.diagnostics ?? [],
20598
- ...validateGraph(graph, options)
20652
+ ...validateGraph(graph, options),
20653
+ ...validateClientSchemaBoundaries(graph, options)
20599
20654
  ];
20600
20655
  if (diagnostics.some((item) => item.code === "runtime-injection-disallowed")) {
20601
20656
  return { diagnostics, graph, upToDate: false, mismatches: ["Runtime DI must be migrated to constructor injection."] };
@@ -20929,12 +20984,12 @@ init_delivery_context();
20929
20984
 
20930
20985
  // src/watch.ts
20931
20986
  import { existsSync as existsSync4, watch } from "node:fs";
20932
- import { dirname as dirname7, relative as relative8, resolve as resolve10, sep as sep8 } from "node:path";
20987
+ import { dirname as dirname7, relative as relative8, resolve as resolve11, sep as sep8 } from "node:path";
20933
20988
 
20934
20989
  // src/incremental.ts
20935
20990
  import { createHash as createHash7 } from "node:crypto";
20936
20991
  import { access as access3, readdir as readdir3, readFile as readFile4 } from "node:fs/promises";
20937
- import { isAbsolute as isAbsolute3, relative as relative7, resolve as resolve9, sep as sep7 } from "node:path";
20992
+ import { isAbsolute as isAbsolute3, relative as relative7, resolve as resolve10, sep as sep7 } from "node:path";
20938
20993
  init_graphql_inputs();
20939
20994
  function createDependencyGraphCache() {
20940
20995
  return {
@@ -21015,11 +21070,11 @@ async function readSourceBytes(path) {
21015
21070
  return readFile4(path);
21016
21071
  }
21017
21072
  async function updateSnapshot(previous, options, changedPaths) {
21018
- const rootDir = resolve9(options.rootDir);
21019
- const outDir = resolve9(options.outDir);
21073
+ const rootDir = resolve10(options.rootDir);
21074
+ const outDir = resolve10(options.outDir);
21020
21075
  const files = { ...previous.files };
21021
21076
  await Promise.all(changedPaths.map(async (changedPath) => {
21022
- const absolutePath = isAbsolute3(changedPath) ? resolve9(changedPath) : resolve9(rootDir, changedPath);
21077
+ const absolutePath = isAbsolute3(changedPath) ? resolve10(changedPath) : resolve10(rootDir, changedPath);
21023
21078
  const relativeChangedPath = relative7(rootDir, absolutePath);
21024
21079
  if (relativeChangedPath === ".." || relativeChangedPath.startsWith(`..${sep7}`))
21025
21080
  return;
@@ -21037,8 +21092,8 @@ async function updateSnapshot(previous, options, changedPaths) {
21037
21092
  return { files, optionsKey: optionsKeyOf(options) };
21038
21093
  }
21039
21094
  async function createSnapshot(options) {
21040
- const rootDir = resolve9(options.rootDir);
21041
- const outDir = resolve9(options.outDir);
21095
+ const rootDir = resolve10(options.rootDir);
21096
+ const outDir = resolve10(options.outDir);
21042
21097
  const paths = await listSourceFiles(rootDir, outDir);
21043
21098
  const files = {};
21044
21099
  const entries = await Promise.all(paths.map(async (path) => {
@@ -21061,8 +21116,8 @@ async function createSnapshot(options) {
21061
21116
  }
21062
21117
  function optionsKeyOf(options) {
21063
21118
  return JSON.stringify({
21064
- rootDir: resolve9(options.rootDir),
21065
- outDir: resolve9(options.outDir),
21119
+ rootDir: resolve10(options.rootDir),
21120
+ outDir: resolve10(options.outDir),
21066
21121
  include: options.include,
21067
21122
  strict: options.strict,
21068
21123
  writeOnError: options.writeOnError,
@@ -21086,7 +21141,7 @@ async function listSourceFiles(rootDir, outDir) {
21086
21141
  const result = [];
21087
21142
  const visit = async (directory) => {
21088
21143
  for (const entry of await readdir3(directory, { withFileTypes: true })) {
21089
- const path = resolve9(directory, entry.name);
21144
+ const path = resolve10(directory, entry.name);
21090
21145
  if (entry.isDirectory()) {
21091
21146
  if (entry.name === "node_modules" || entry.name === ".git" || path === outDir)
21092
21147
  continue;
@@ -21221,8 +21276,8 @@ function isCompilerConfigurationPath(rootDir, changedPath) {
21221
21276
  ].includes(relativePath) || /^tsconfig\.[^/]+\.json$/.test(relativePath);
21222
21277
  }
21223
21278
  function watchProject(options) {
21224
- const rootDir = resolve10(options.rootDir);
21225
- const outDir = resolve10(options.outDir);
21279
+ const rootDir = resolve11(options.rootDir);
21280
+ const outDir = resolve11(options.outDir);
21226
21281
  const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
21227
21282
  let timer;
21228
21283
  let closed = false;
@@ -21232,7 +21287,7 @@ function watchProject(options) {
21232
21287
  const pendingPaths = new Set;
21233
21288
  let watcher;
21234
21289
  let schemaWatcher;
21235
- const schemaPath = options.graphql ? resolve10(rootDir, options.graphql.schema) : undefined;
21290
+ const schemaPath = options.graphql ? resolve11(rootDir, options.graphql.schema) : undefined;
21236
21291
  const incremental = createIncrementalCompiler();
21237
21292
  let initialEvent;
21238
21293
  let resolveReady = () => {
@@ -21342,7 +21397,7 @@ function watchProject(options) {
21342
21397
  watcher = watch(rootDir, { recursive: true }, (_eventType, filename) => {
21343
21398
  if (!filename)
21344
21399
  return schedule();
21345
- const changedPath = resolve10(rootDir, filename.toString());
21400
+ const changedPath = resolve11(rootDir, filename.toString());
21346
21401
  const relativePath = relative8(outDir, changedPath);
21347
21402
  if (!relativePath.startsWith("..") && relativePath !== "")
21348
21403
  return;
@@ -21355,7 +21410,7 @@ function watchProject(options) {
21355
21410
  while (!existsSync4(directory) && dirname7(directory) !== directory)
21356
21411
  directory = dirname7(directory);
21357
21412
  schemaWatcher = watch(directory, { recursive: true }, (_eventType, filename) => {
21358
- if (!filename || resolve10(directory, filename.toString()) === schemaPath)
21413
+ if (!filename || resolve11(directory, filename.toString()) === schemaPath)
21359
21414
  schedule(schemaPath);
21360
21415
  });
21361
21416
  }
@@ -21380,7 +21435,7 @@ function watchProject(options) {
21380
21435
  // src/config.ts
21381
21436
  init_graphql_options();
21382
21437
  import { existsSync as existsSync5 } from "node:fs";
21383
- import { join as join8, resolve as resolve11 } from "node:path";
21438
+ import { join as join8, resolve as resolve12 } from "node:path";
21384
21439
  import { pathToFileURL } from "node:url";
21385
21440
 
21386
21441
  // src/delivery-schema.ts
@@ -21478,8 +21533,8 @@ function validateGovernanceConfig(config) {
21478
21533
  function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
21479
21534
  const resolved = defineSupacloudConfig(config);
21480
21535
  return {
21481
- rootDir: resolve11(cwd, resolved.root ?? DEFAULT_SUPACLOUD_CONFIG.root),
21482
- outDir: resolve11(cwd, resolved.outDir ?? DEFAULT_SUPACLOUD_CONFIG.outDir),
21536
+ rootDir: resolve12(cwd, resolved.root ?? DEFAULT_SUPACLOUD_CONFIG.root),
21537
+ outDir: resolve12(cwd, resolved.outDir ?? DEFAULT_SUPACLOUD_CONFIG.outDir),
21483
21538
  include: resolved.include ?? [...DEFAULT_SUPACLOUD_CONFIG.include],
21484
21539
  strict: resolved.strict ?? DEFAULT_SUPACLOUD_CONFIG.strict,
21485
21540
  requireRouteContracts: resolved.requireRouteContracts ?? DEFAULT_SUPACLOUD_CONFIG.requireRouteContracts,
@@ -21497,7 +21552,7 @@ function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
21497
21552
  treeShakeUnusedProviders: resolved.treeShakeUnusedProviders ?? DEFAULT_SUPACLOUD_CONFIG.treeShakeUnusedProviders,
21498
21553
  graphql: resolved.graphql ? {
21499
21554
  ...resolved.graphql,
21500
- schema: resolve11(cwd, resolved.graphql.schema)
21555
+ schema: resolve12(cwd, resolved.graphql.schema)
21501
21556
  } : undefined
21502
21557
  };
21503
21558
  }
@@ -21825,7 +21880,7 @@ function formatDeliveryPlan(result) {
21825
21880
  // src/delivery-build.ts
21826
21881
  import { mkdir as mkdir3, mkdtemp, readFile as readFile7, realpath as realpath4, rename as rename4, rm as rm2 } from "node:fs/promises";
21827
21882
  import { readFileSync as readFileSync3 } from "node:fs";
21828
- import { dirname as dirname9, join as join10, relative as relative10, resolve as resolve15, sep as sep10 } from "node:path";
21883
+ import { dirname as dirname9, join as join10, relative as relative10, resolve as resolve16, sep as sep10 } from "node:path";
21829
21884
  import * as ts15 from "@typescript/typescript6";
21830
21885
 
21831
21886
  // src/delivery-build-schema.ts
@@ -21867,7 +21922,7 @@ function renderDeliveryTarget(graph, target, options) {
21867
21922
  init_delivery_files2();
21868
21923
  import { isBuiltin } from "node:module";
21869
21924
  import { readFile as readFile6 } from "node:fs/promises";
21870
- import { join as join9, resolve as resolve13 } from "node:path";
21925
+ import { join as join9, resolve as resolve14 } from "node:path";
21871
21926
  import * as ts14 from "@typescript/typescript6";
21872
21927
 
21873
21928
  // src/delivery-imports.ts
@@ -22044,7 +22099,7 @@ async function bundleDeliveryTarget(name, code, project, generatedDirectory, opt
22044
22099
  async function bundleDeliveryTargetInProcess(name, code, project, generatedDirectory, options) {
22045
22100
  const inputs = new Map;
22046
22101
  const workingDirectory = process.cwd();
22047
- const entry = resolve13(generatedDirectory, `delivery-${name}.ts`);
22102
+ const entry = resolve14(generatedDirectory, `delivery-${name}.ts`);
22048
22103
  const entryPattern = new RegExp(`^${entry.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`);
22049
22104
  const result = await Bun.build({
22050
22105
  entrypoints: [entry],
@@ -22067,7 +22122,7 @@ async function bundleDeliveryTargetInProcess(name, code, project, generatedDirec
22067
22122
  if (args.path === entry)
22068
22123
  return { contents: code, loader: "ts" };
22069
22124
  const bytes = await readFile6(args.path);
22070
- inputs.set(resolve13(args.path), digest(bytes));
22125
+ inputs.set(resolve14(args.path), digest(bytes));
22071
22126
  return { contents: staticDeliveryImports(args.path, bytes), loader: args.loader };
22072
22127
  });
22073
22128
  }
@@ -22077,7 +22132,7 @@ async function bundleDeliveryTargetInProcess(name, code, project, generatedDirec
22077
22132
  throw new Error("Independent bundle failed or has no dependency metadata.");
22078
22133
  const runtimeImports = new Set;
22079
22134
  for (const [path, metadata] of Object.entries(result.metafile.inputs)) {
22080
- if (resolve13(workingDirectory, path) !== entry && !inputs.has(resolve13(workingDirectory, path))) {
22135
+ if (resolve14(workingDirectory, path) !== entry && !inputs.has(resolve14(workingDirectory, path))) {
22081
22136
  throw new Error("Bundler reported an input that was not captured by the delivery snapshot.");
22082
22137
  }
22083
22138
  for (const imported of metadata.imports) {
@@ -22416,14 +22471,14 @@ interface DeliveryWorkerHost {
22416
22471
 
22417
22472
  // src/delivery-migrations.ts
22418
22473
  init_delivery_files2();
22419
- import { resolve as resolve14 } from "node:path";
22474
+ import { resolve as resolve15 } from "node:path";
22420
22475
  async function prepareDeliveryMigrations(project, generatedRoot, declarations = []) {
22421
22476
  const entries = [];
22422
22477
  const files = new Map;
22423
22478
  const inputs = new Map;
22424
22479
  let totalBytes = 0;
22425
22480
  for (const declaration of [...declarations].sort((a, b) => BigInt(a.version) < BigInt(b.version) ? -1 : BigInt(a.version) > BigInt(b.version) ? 1 : 0)) {
22426
- const source = resolve14(project, declaration.source);
22481
+ const source = resolve15(project, declaration.source);
22427
22482
  if (!inside(project, source) || inside(generatedRoot, source))
22428
22483
  throw new Error("Invalid migration source.");
22429
22484
  const bytes = await readBoundedOwned(project, source, 1048576);
@@ -22474,7 +22529,7 @@ async function buildDeliveryProject(options, delivery) {
22474
22529
  const settings = parseDeliveryOptions(delivery);
22475
22530
  if (typeof Bun === "undefined")
22476
22531
  throw new Error("Independent delivery builds require Bun.");
22477
- const configPath = ts15.findConfigFile(resolve15(options.rootDir), ts15.sys.fileExists);
22532
+ const configPath = ts15.findConfigFile(resolve16(options.rootDir), ts15.sys.fileExists);
22478
22533
  if (!configPath)
22479
22534
  throw new Error("Independent delivery builds require a project tsconfig.json.");
22480
22535
  const lexicalProject = dirname9(configPath);
@@ -22482,11 +22537,11 @@ async function buildDeliveryProject(options, delivery) {
22482
22537
  const sourceRoot = await realpath4(options.rootDir);
22483
22538
  if (!inside(project, sourceRoot))
22484
22539
  throw new Error("Application sources must be inside the project.");
22485
- const requested = resolve15(options.outDir, "delivery");
22540
+ const requested = resolve16(options.outDir, "delivery");
22486
22541
  if (!inside(lexicalProject, requested))
22487
22542
  throw new Error("Output must be inside the application project.");
22488
- const buildRoot = resolve15(project, relative10(lexicalProject, requested));
22489
- const generatedRoot = resolve15(project, relative10(lexicalProject, options.outDir));
22543
+ const buildRoot = resolve16(project, relative10(lexicalProject, requested));
22544
+ const generatedRoot = resolve16(project, relative10(lexicalProject, options.outDir));
22490
22545
  if (inside(generatedRoot, sourceRoot))
22491
22546
  throw new Error("Output must not contain the application source root.");
22492
22547
  const configInputs = new Map;
@@ -22494,7 +22549,7 @@ async function buildDeliveryProject(options, delivery) {
22494
22549
  ...ts15.sys,
22495
22550
  readFile(path) {
22496
22551
  const contents = readFileSync3(path, "utf8");
22497
- configInputs.set(resolve15(path), digest(contents));
22552
+ configInputs.set(resolve16(path), digest(contents));
22498
22553
  return contents;
22499
22554
  },
22500
22555
  onUnRecoverableConfigFileDiagnostic() {
@@ -22532,7 +22587,7 @@ async function buildDeliveryProject(options, delivery) {
22532
22587
  if (!target || (kind === "worker" ? target.kind !== "jobs" : target.kind === "jobs")) {
22533
22588
  throw new Error("Delivery host kind does not match its target.");
22534
22589
  }
22535
- const path = resolve15(sourceRoot, app.source);
22590
+ const path = resolve16(sourceRoot, app.source);
22536
22591
  if (inside(generatedRoot, path) || !/\.[cm]?ts$/.test(path))
22537
22592
  throw new Error("Hosts require application TypeScript source.");
22538
22593
  hosts.set(app.target, { path, kind, hash: digest(await readOwned(sourceRoot, path)) });
@@ -22659,7 +22714,7 @@ async function buildDeliveryProject(options, delivery) {
22659
22714
  }));
22660
22715
  const assetInputs = {};
22661
22716
  for (const asset of assets.filter((asset) => asset.target === target.name)) {
22662
- const path = resolve15(sourceRoot, asset.source);
22717
+ const path = resolve16(sourceRoot, asset.source);
22663
22718
  const bytes = await readOwned(sourceRoot, path);
22664
22719
  const hash = digest(bytes);
22665
22720
  const previousHash = snapshots.get(path);
@@ -22769,19 +22824,19 @@ async function buildDeliveryProject(options, delivery) {
22769
22824
 
22770
22825
  // src/migrations.ts
22771
22826
  import { rename as rename5, readFile as readFile9, writeFile as writeFile4, rm as rm3 } from "node:fs/promises";
22772
- import { relative as relative11, resolve as resolve17 } from "node:path";
22827
+ import { relative as relative11, resolve as resolve18 } from "node:path";
22773
22828
  import * as ts16 from "@typescript/typescript6";
22774
22829
 
22775
22830
  // src/migration-policy.ts
22776
22831
  import { readFile as readFile8 } from "node:fs/promises";
22777
22832
  import { readFileSync as readFileSync4 } from "node:fs";
22778
- import { resolve as resolve16 } from "node:path";
22833
+ import { resolve as resolve17 } from "node:path";
22779
22834
 
22780
22835
  // src/migration-app-version.ts
22781
22836
  var MIGRATION_APP_VERSION = "0.23.0";
22782
22837
 
22783
22838
  // src/migration-elysia-version.ts
22784
- var MIGRATION_ELYSIA_VERSION = "0.25.0";
22839
+ var MIGRATION_ELYSIA_VERSION = "0.26.0";
22785
22840
 
22786
22841
  // src/migration-policy.ts
22787
22842
  var cachedCompilerVersion;
@@ -22808,7 +22863,7 @@ async function checkMigrationDependencies(rootDir) {
22808
22863
  const problems = [];
22809
22864
  for (const [name, expected] of Object.entries(migrationDependencies())) {
22810
22865
  try {
22811
- const manifest = JSON.parse(await readFile8(resolve16(rootDir, "node_modules", name, "package.json"), "utf8"));
22866
+ const manifest = JSON.parse(await readFile8(resolve17(rootDir, "node_modules", name, "package.json"), "utf8"));
22812
22867
  if (!manifest || typeof manifest !== "object" || !("name" in manifest) || manifest.name !== name || !("version" in manifest) || manifest.version !== expected) {
22813
22868
  problems.push(`${name}: requires tested installed version ${expected}`);
22814
22869
  }
@@ -22923,10 +22978,10 @@ function createMigrationProgram(fileNames, sourceOverrides, rootDir) {
22923
22978
  const fileExists = host.fileExists.bind(host);
22924
22979
  const readFile = host.readFile.bind(host);
22925
22980
  const currentDirectory = host.getCurrentDirectory.bind(host);
22926
- host.fileExists = (fileName) => sourceOverrides.has(resolve17(fileName)) || fileExists(fileName);
22927
- host.readFile = (fileName) => sourceOverrides.get(resolve17(fileName)) ?? readFile(fileName);
22981
+ host.fileExists = (fileName) => sourceOverrides.has(resolve18(fileName)) || fileExists(fileName);
22982
+ host.readFile = (fileName) => sourceOverrides.get(resolve18(fileName)) ?? readFile(fileName);
22928
22983
  host.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
22929
- const source = sourceOverrides.get(resolve17(fileName));
22984
+ const source = sourceOverrides.get(resolve18(fileName));
22930
22985
  return source === undefined ? getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) : ts16.createSourceFile(fileName, source, languageVersion, true);
22931
22986
  };
22932
22987
  host.getCurrentDirectory = () => rootDir ?? currentDirectory();
@@ -22952,7 +23007,7 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
22952
23007
  issues.push(issue);
22953
23008
  };
22954
23009
  for (const sourceFile of sourceFiles) {
22955
- const sourcePath = resolve17(sourceFile.fileName);
23010
+ const sourcePath = resolve18(sourceFile.fileName);
22956
23011
  if (!includedFiles.has(sourcePath))
22957
23012
  continue;
22958
23013
  const visit = (node) => {
@@ -22960,7 +23015,7 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
22960
23015
  const options = node.arguments[1];
22961
23016
  const object = options && resolveStaticObjectLiteral2(options, checker);
22962
23017
  if (object) {
22963
- const objectPath = resolve17(object.getSourceFile().fileName);
23018
+ const objectPath = resolve18(object.getSourceFile().fileName);
22964
23019
  const properties = routeResponseProperties(object);
22965
23020
  if (properties.response) {
22966
23021
  if (!includedFiles.has(objectPath)) {
@@ -23003,13 +23058,13 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
23003
23058
  line: lineOf2(sourceFile, response)
23004
23059
  });
23005
23060
  } else {
23006
- const replacements = replacementsByFile.get(resolve17(sourceFile.fileName)) ?? [];
23061
+ const replacements = replacementsByFile.get(resolve18(sourceFile.fileName)) ?? [];
23007
23062
  replacements.push({
23008
23063
  start: response.getStart(sourceFile),
23009
23064
  end: response.getEnd(),
23010
23065
  text: `responses: { 200: ${response.initializer.getText(sourceFile)} }`
23011
23066
  });
23012
- replacementsByFile.set(resolve17(sourceFile.fileName), replacements);
23067
+ replacementsByFile.set(resolve18(sourceFile.fileName), replacements);
23013
23068
  }
23014
23069
  }
23015
23070
  return { replacementsByFile, issues };
@@ -23022,7 +23077,7 @@ function applyReplacements(source, replacements) {
23022
23077
  return content;
23023
23078
  }
23024
23079
  function migrateRouteResponse(source, fileName) {
23025
- const absoluteFile = resolve17(fileName);
23080
+ const absoluteFile = resolve18(fileName);
23026
23081
  const sourceOverrides = new Map([[absoluteFile, source]]);
23027
23082
  const program = createMigrationProgram([absoluteFile], sourceOverrides);
23028
23083
  const sourceFile = program.getSourceFile(absoluteFile);
@@ -23038,7 +23093,7 @@ function migrateRouteResponse(source, fileName) {
23038
23093
  }]
23039
23094
  };
23040
23095
  }
23041
- const plan = planRouteResponseMigration([sourceFile], program.getTypeChecker(), resolve17("."), new Set([absoluteFile]));
23096
+ const plan = planRouteResponseMigration([sourceFile], program.getTypeChecker(), resolve18("."), new Set([absoluteFile]));
23042
23097
  const replacements = plan.replacementsByFile.get(absoluteFile) ?? [];
23043
23098
  return {
23044
23099
  changed: replacements.length > 0,
@@ -23048,7 +23103,7 @@ function migrateRouteResponse(source, fileName) {
23048
23103
  };
23049
23104
  }
23050
23105
  function migrateRouteResponseProject(files, rootDir, sourceByPath) {
23051
- const absoluteFiles = files.map((file) => resolve17(file));
23106
+ const absoluteFiles = files.map((file) => resolve18(file));
23052
23107
  const program = createMigrationProgram(absoluteFiles, sourceByPath, rootDir);
23053
23108
  const sourceFiles = absoluteFiles.map((file) => program.getSourceFile(file)).filter((file) => file !== undefined);
23054
23109
  const plan = planRouteResponseMigration(sourceFiles, program.getTypeChecker(), rootDir, new Set(absoluteFiles));
@@ -23061,11 +23116,11 @@ function migrateRouteResponseProject(files, rootDir, sourceByPath) {
23061
23116
  changed: replacements.length > 0,
23062
23117
  content: applyReplacements(source, replacements),
23063
23118
  replacements: replacements.length,
23064
- issues: plan.issues.filter((issue) => resolve17(rootDir, issue.file) === file)
23119
+ issues: plan.issues.filter((issue) => resolve18(rootDir, issue.file) === file)
23065
23120
  });
23066
23121
  }
23067
23122
  for (const issue of plan.issues) {
23068
- const path = resolve17(rootDir, issue.file);
23123
+ const path = resolve18(rootDir, issue.file);
23069
23124
  if (!results.has(path) && sourceByPath.has(path)) {
23070
23125
  results.set(path, {
23071
23126
  changed: false,
@@ -23103,7 +23158,7 @@ async function writeAtomically(path, content) {
23103
23158
  }
23104
23159
  }
23105
23160
  async function migrateProject(options) {
23106
- const rootDir = resolve17(options.rootDir);
23161
+ const rootDir = resolve18(options.rootDir);
23107
23162
  let migrations = SUPACLOUD_MIGRATIONS;
23108
23163
  const preflightIssues = [];
23109
23164
  if (options.fromVersion !== undefined || options.toVersion !== undefined) {
@@ -23159,7 +23214,7 @@ async function migrateProject(options) {
23159
23214
  }
23160
23215
  };
23161
23216
  for (const filePath of files) {
23162
- sourceByPath.set(resolve17(filePath), await readFile9(filePath, "utf8"));
23217
+ sourceByPath.set(resolve18(filePath), await readFile9(filePath, "utf8"));
23163
23218
  }
23164
23219
  const originalSources = new Map(sourceByPath);
23165
23220
  const writtenFiles = new Set;
@@ -23168,7 +23223,7 @@ async function migrateProject(options) {
23168
23223
  if (projectResults)
23169
23224
  appendIssues(projectResults.issues);
23170
23225
  for (const filePath of files) {
23171
- const absoluteFile = resolve17(filePath);
23226
+ const absoluteFile = resolve18(filePath);
23172
23227
  const file = relative11(rootDir, absoluteFile) || absoluteFile;
23173
23228
  const before = sourceByPath.get(absoluteFile);
23174
23229
  if (before === undefined)
@@ -23230,11 +23285,11 @@ async function migrateProject(options) {
23230
23285
  // src/migration-assess.ts
23231
23286
  import { createHash as createHash10 } from "node:crypto";
23232
23287
  import { readFile as readFile11 } from "node:fs/promises";
23233
- import { join as join11, resolve as resolve19 } from "node:path";
23288
+ import { join as join11, resolve as resolve20 } from "node:path";
23234
23289
 
23235
23290
  // src/openapi-tools.ts
23236
23291
  import { mkdir as mkdir4, readFile as readFile10, rename as rename6, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
23237
- import { dirname as dirname10, resolve as resolve18 } from "node:path";
23292
+ import { dirname as dirname10, resolve as resolve19 } from "node:path";
23238
23293
  import { pathToFileURL as pathToFileURL2 } from "node:url";
23239
23294
 
23240
23295
  class OpenApiDocumentError extends Error {
@@ -23625,7 +23680,7 @@ function serializeOpenApiJson(document, space = 2) {
23625
23680
  }
23626
23681
  async function readOpenApiJson(path) {
23627
23682
  try {
23628
- const value = JSON.parse(await readFile10(resolve18(path), "utf8"));
23683
+ const value = JSON.parse(await readFile10(resolve19(path), "utf8"));
23629
23684
  return parseOpenApiDocument(value);
23630
23685
  } catch (error) {
23631
23686
  if (error instanceof OpenApiDocumentError)
@@ -23634,7 +23689,7 @@ async function readOpenApiJson(path) {
23634
23689
  }
23635
23690
  }
23636
23691
  async function writeOpenApiJson(document, outputPath, space = 2) {
23637
- const path = resolve18(outputPath);
23692
+ const path = resolve19(outputPath);
23638
23693
  const content = serializeOpenApiJson(document, space);
23639
23694
  await mkdir4(dirname10(path), { recursive: true });
23640
23695
  try {
@@ -23655,7 +23710,7 @@ async function writeOpenApiJson(document, outputPath, space = 2) {
23655
23710
  }
23656
23711
  async function loadGeneratedOpenApiDocument(modulePath) {
23657
23712
  try {
23658
- const moduleUrl = pathToFileURL2(resolve18(modulePath));
23713
+ const moduleUrl = pathToFileURL2(resolve19(modulePath));
23659
23714
  moduleUrl.searchParams.set("supacloud-openapi-export", "1");
23660
23715
  const loaded = await import(moduleUrl.href);
23661
23716
  if (!isRecord(loaded))
@@ -23758,11 +23813,11 @@ function overallStatus(findings) {
23758
23813
  return findings.reduce((current, finding) => STATUS_PRIORITY[finding.status] > STATUS_PRIORITY[current] ? finding.status : current, "compatible");
23759
23814
  }
23760
23815
  async function assessMigration(options) {
23761
- const projectDir = resolve19(options.projectDir);
23816
+ const projectDir = resolve20(options.projectDir);
23762
23817
  const compile = {
23763
23818
  ...options.compile,
23764
- rootDir: resolve19(options.compile.rootDir),
23765
- outDir: resolve19(options.compile.outDir)
23819
+ rootDir: resolve20(options.compile.rootDir),
23820
+ outDir: resolve20(options.compile.outDir)
23766
23821
  };
23767
23822
  const findings = [];
23768
23823
  const dependencyProblems = await checkMigrationDependencies(projectDir);
@@ -23842,8 +23897,8 @@ async function assessMigration(options) {
23842
23897
  }
23843
23898
  let openApi;
23844
23899
  if (options.baselineOpenApiPath && options.currentOpenApiPath) {
23845
- const baselinePath = resolve19(projectDir, options.baselineOpenApiPath);
23846
- const currentPath = resolve19(projectDir, options.currentOpenApiPath);
23900
+ const baselinePath = resolve20(projectDir, options.baselineOpenApiPath);
23901
+ const currentPath = resolve20(projectDir, options.currentOpenApiPath);
23847
23902
  try {
23848
23903
  const diff = diffOpenApiDocuments(await readOpenApiJson(baselinePath), await readOpenApiJson(currentPath));
23849
23904
  openApi = {
@@ -24272,7 +24327,7 @@ async function run() {
24272
24327
  throw new Error("Build context requires a manifest, target, subject, events, request ID and --json");
24273
24328
  }
24274
24329
  try {
24275
- const pack = await createDeliveryExecutionContextPack(contextManifest, contextTarget, query, await readExecutionMetadata(resolve23(executionEventsPath)), executionRequestId);
24330
+ const pack = await createDeliveryExecutionContextPack(contextManifest, contextTarget, query, await readExecutionMetadata(resolve24(executionEventsPath)), executionRequestId);
24276
24331
  console.log(JSON.stringify(pack, null, 2));
24277
24332
  } catch (error) {
24278
24333
  console.log(JSON.stringify({
@@ -24291,7 +24346,7 @@ async function run() {
24291
24346
  const currentPath = openApiDiffPaths[1];
24292
24347
  if (!basePath || !currentPath)
24293
24348
  throw new Error("openapi-diff requires two JSON file paths");
24294
- const result = diffOpenApiDocuments(await readOpenApiJson(resolve23(process.cwd(), basePath)), await readOpenApiJson(resolve23(process.cwd(), currentPath)));
24349
+ const result = diffOpenApiDocuments(await readOpenApiJson(resolve24(process.cwd(), basePath)), await readOpenApiJson(resolve24(process.cwd(), currentPath)));
24295
24350
  console.log(json ? JSON.stringify(result, null, 2) : formatOpenApiDiff(result));
24296
24351
  if (!result.ok)
24297
24352
  process.exitCode = 1;
@@ -24306,8 +24361,8 @@ async function run() {
24306
24361
  if (!modulePath || !outputPath)
24307
24362
  throw new Error("openapi-export requires an OpenAPI module and output path");
24308
24363
  const result = await exportGeneratedOpenApiJson({
24309
- modulePath: resolve23(process.cwd(), modulePath),
24310
- outputPath: resolve23(process.cwd(), outputPath),
24364
+ modulePath: resolve24(process.cwd(), modulePath),
24365
+ outputPath: resolve24(process.cwd(), outputPath),
24311
24366
  ...openApiExportSpace === undefined ? {} : { space: openApiExportSpace }
24312
24367
  });
24313
24368
  console.log(json ? JSON.stringify({ ok: true, ...result }, null, 2) : result.written ? `OpenAPI JSON written: ${result.path}` : `OpenAPI JSON matches: ${result.path}`);
@@ -24315,7 +24370,7 @@ async function run() {
24315
24370
  }
24316
24371
  if (command === "migrate") {
24317
24372
  const result = await migrateProject({
24318
- rootDir: rootDir ? resolve23(process.cwd(), rootDir) : process.cwd(),
24373
+ rootDir: rootDir ? resolve24(process.cwd(), rootDir) : process.cwd(),
24319
24374
  write: !dryRun,
24320
24375
  ...fromVersion === undefined ? {} : { fromVersion },
24321
24376
  ...toVersion === undefined ? {} : { toVersion }
@@ -24353,8 +24408,8 @@ async function run() {
24353
24408
  if (checkSchema && command !== "graphql-schema")
24354
24409
  throw new Error("--check is only supported by graphql-schema");
24355
24410
  const defaults = resolveSupacloudConfig(loadedConfig, process.cwd());
24356
- const resolvedRoot = rootDir ? resolve23(process.cwd(), rootDir) : defaults.rootDir;
24357
- const resolvedOut = outDir ? resolve23(process.cwd(), outDir) : defaults.outDir;
24411
+ const resolvedRoot = rootDir ? resolve24(process.cwd(), rootDir) : defaults.rootDir;
24412
+ const resolvedOut = outDir ? resolve24(process.cwd(), outDir) : defaults.outDir;
24358
24413
  const configured = compileOptionsFromConfig({
24359
24414
  ...loadedConfig,
24360
24415
  root: resolvedRoot,
@@ -24373,7 +24428,7 @@ async function run() {
24373
24428
  let delivery = loadedConfig.delivery;
24374
24429
  if (deliveryPath !== undefined) {
24375
24430
  try {
24376
- delivery = JSON.parse(await readFile14(resolve23(process.cwd(), deliveryPath), "utf8"));
24431
+ delivery = JSON.parse(await readFile14(resolve24(process.cwd(), deliveryPath), "utf8"));
24377
24432
  } catch {
24378
24433
  throw new DeliveryConfigurationError;
24379
24434
  }
@@ -24431,7 +24486,7 @@ ${item.suggestion ?? ""}`).join(`
24431
24486
  } else if (command === "fix") {
24432
24487
  if (!query)
24433
24488
  throw new Error("fix requires a JSON file containing one DiagnosticFix");
24434
- const input = JSON.parse(await readFile14(resolve23(process.cwd(), query), "utf8"));
24489
+ const input = JSON.parse(await readFile14(resolve24(process.cwd(), query), "utf8"));
24435
24490
  const envelope = input && typeof input === "object" && "fix" in input;
24436
24491
  if (envelope && (typeof input.expectedSourceHash !== "string" || !/^[a-f0-9]{64}$/.test(input.expectedSourceHash))) {
24437
24492
  throw new Error("Editor fix requires the source hash from its validated preview");
@@ -24572,7 +24627,7 @@ Source change detected; compiling...`);
24572
24627
  process.exitCode = 1;
24573
24628
  return;
24574
24629
  }
24575
- const file = resolve23(rootDir ? resolve23(process.cwd(), rootDir) : process.cwd(), bindingsFile ?? "supacloud.environments.json");
24630
+ const file = resolve24(rootDir ? resolve24(process.cwd(), rootDir) : process.cwd(), bindingsFile ?? "supacloud.environments.json");
24576
24631
  try {
24577
24632
  const document = await readEnvironmentBindingsFile(file);
24578
24633
  const graph = await analyzeProject(resolvedRoot);
@@ -24607,7 +24662,7 @@ Source change detected; compiling...`);
24607
24662
  try {
24608
24663
  const result = await checkProject(compileDefaults);
24609
24664
  if (executionEventsPath && executionRequestId) {
24610
- const pack = createExecutionContextPack({ ...result.graph, diagnostics: result.diagnostics }, query, await readExecutionMetadata(resolve23(process.cwd(), executionEventsPath)), executionRequestId);
24665
+ const pack = createExecutionContextPack({ ...result.graph, diagnostics: result.diagnostics }, query, await readExecutionMetadata(resolve24(process.cwd(), executionEventsPath)), executionRequestId);
24611
24666
  console.log(JSON.stringify(pack, null, 2));
24612
24667
  return;
24613
24668
  }