@supacloud/compiler 0.28.0 → 0.30.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/index.js CHANGED
@@ -1662,6 +1662,12 @@ class ModuleGenerator {
1662
1662
  }
1663
1663
  renderFactories() {
1664
1664
  const sections = [this.renderServicesFactory()];
1665
+ if (this.hasApplicationLifecycle("init")) {
1666
+ sections.push(this.renderApplicationLifecycle("init"));
1667
+ }
1668
+ if (this.hasApplicationLifecycle("destroy")) {
1669
+ sections.push(this.renderApplicationLifecycle("destroy"));
1670
+ }
1665
1671
  if (this.hasFactoryContent("request")) {
1666
1672
  sections.push(this.renderScopeFactory("request"));
1667
1673
  sections.push(this.renderScopeDestroyer("request"));
@@ -1678,6 +1684,12 @@ class ModuleGenerator {
1678
1684
  ` name: ${JSON.stringify(this.module.name)} as const,`,
1679
1685
  ` createServices: create${this.pascal}Services,`
1680
1686
  ];
1687
+ if (this.hasApplicationLifecycle("init")) {
1688
+ lines.push(` initializeServices: initialize${this.pascal}Services,`);
1689
+ }
1690
+ if (this.hasApplicationLifecycle("destroy")) {
1691
+ lines.push(` destroyServices: destroy${this.pascal}Services,`);
1692
+ }
1681
1693
  if (this.hasFactoryContent("request")) {
1682
1694
  lines.push(` createRequestScope: create${this.pascal}RequestScope,`);
1683
1695
  lines.push(` destroyRequestScope: destroy${this.pascal}RequestScope,`);
@@ -1700,6 +1712,40 @@ class ModuleGenerator {
1700
1712
  hasFactoryContent(kind) {
1701
1713
  return this.module.providers.some((p) => factoryOfScope(p.scope) === kind) || this.module.controllers.some((c) => factoryOfScope(c.scope) === kind);
1702
1714
  }
1715
+ hasApplicationLifecycle(kind) {
1716
+ return this.applicationLifecyclePlan(kind).length > 0;
1717
+ }
1718
+ applicationLifecyclePlan(kind) {
1719
+ const result = [];
1720
+ const multiIndices = new Map;
1721
+ for (const provider of orderProviders(this.module.providers.filter((p) => factoryOfScope(p.scope) === "services"))) {
1722
+ const index = provider.multi ? multiIndices.get(provider.token) ?? 0 : undefined;
1723
+ if (index !== undefined)
1724
+ multiIndices.set(provider.token, index + 1);
1725
+ const owned = provider.kind !== "existing";
1726
+ const selected = kind === "init" ? provider.hasOnInit : provider.hasOnDestroy;
1727
+ if (owned && selected)
1728
+ result.push({ key: camelName(provider.token), ...index === undefined ? {} : { index } });
1729
+ }
1730
+ for (const controller of this.module.controllers) {
1731
+ if (factoryOfScope(controller.scope) !== "services")
1732
+ continue;
1733
+ const selected = kind === "init" ? controller.hasOnInit : controller.hasOnDestroy;
1734
+ if (selected)
1735
+ result.push({ key: camelName(controller.className) });
1736
+ }
1737
+ return result;
1738
+ }
1739
+ renderApplicationLifecycle(kind) {
1740
+ const suffix = kind === "init" ? "initialize" : "destroy";
1741
+ const helper = kind === "init" ? "initializeServiceInstances" : "destroyServiceInstances";
1742
+ return [
1743
+ `async function ${suffix}${this.pascal}Services(services: Record<string, unknown>): Promise<void> {`,
1744
+ ` await ${helper}(services, ${JSON.stringify(this.applicationLifecyclePlan(kind))});`,
1745
+ `}`
1746
+ ].join(`
1747
+ `);
1748
+ }
1703
1749
  renderControllers() {
1704
1750
  if (this.module.controllers.length === 0)
1705
1751
  return "[]";
@@ -3418,6 +3464,10 @@ export interface CompiledModule {
3418
3464
  deps: Record<string, unknown>,
3419
3465
  imported: Record<string, Record<string, unknown>>,
3420
3466
  ): Record<string, unknown>;
3467
+ /** Initializes application-scoped instances owned by this module. */
3468
+ initializeServices?(services: Record<string, unknown>): Promise<void>;
3469
+ /** Destroys application-scoped instances owned by this module. */
3470
+ destroyServices?(services: Record<string, unknown>): Promise<void>;
3421
3471
  createRequestScope?(
3422
3472
  services: Record<string, unknown>,
3423
3473
  ctx: unknown,
@@ -3501,7 +3551,54 @@ function destroyScopeInstances(
3501
3551
  });
3502
3552
  scopeDestructions.set(scope, destruction);
3503
3553
  return destruction;
3504
- }`;
3554
+ }
3555
+
3556
+ type CompiledServiceLifecycleEntry = { key: string; index?: number };
3557
+
3558
+ async function initializeServiceInstances(
3559
+ services: Record<string, unknown>,
3560
+ plan: readonly CompiledServiceLifecycleEntry[],
3561
+ ): Promise<void> {
3562
+ const seen = new Set<unknown>();
3563
+ for (const entry of plan) {
3564
+ const value = services[entry.key];
3565
+ const instance = entry.index === undefined
3566
+ ? value
3567
+ : Array.isArray(value) ? value[entry.index] : undefined;
3568
+ if (seen.has(instance)) continue;
3569
+ seen.add(instance);
3570
+ if (!isRecord(instance) || !isFunction(instance.onInit)) continue;
3571
+ await instance.onInit();
3572
+ }
3573
+ }
3574
+
3575
+ async function destroyServiceInstances(
3576
+ services: Record<string, unknown>,
3577
+ plan: readonly CompiledServiceLifecycleEntry[],
3578
+ ): Promise<void> {
3579
+ const errors: unknown[] = [];
3580
+ const seen = new Set<unknown>();
3581
+ for (const entry of [...plan].reverse()) {
3582
+ const value = services[entry.key];
3583
+ const instance = entry.index === undefined
3584
+ ? value
3585
+ : Array.isArray(value) ? value[entry.index] : undefined;
3586
+ if (seen.has(instance)) continue;
3587
+ seen.add(instance);
3588
+ if (!isRecord(instance)) continue;
3589
+ const hook = isFunction(instance.onDestroy)
3590
+ ? instance.onDestroy
3591
+ : isFunction(instance.ngOnDestroy) ? instance.ngOnDestroy : undefined;
3592
+ if (!hook) continue;
3593
+ try {
3594
+ await hook.call(instance);
3595
+ } catch (error) {
3596
+ errors.push(error);
3597
+ }
3598
+ }
3599
+ if (errors.length > 0) throw new AggregateError(errors, "Application service destruction failed");
3600
+ }
3601
+ `;
3505
3602
  var init_generate = __esm(() => {
3506
3603
  init_contract_manifest();
3507
3604
  });
@@ -3723,8 +3820,8 @@ var init_graphql_options = __esm(() => {
3723
3820
  });
3724
3821
 
3725
3822
  // src/graphql-inputs.ts
3726
- import { resolve as resolve3 } from "node:path";
3727
- import * as ts7 from "@typescript/typescript6";
3823
+ import { resolve as resolve4 } from "node:path";
3824
+ import * as ts10 from "@typescript/typescript6";
3728
3825
  function graphqlInputPaths(options) {
3729
3826
  if (!options.graphql)
3730
3827
  return [];
@@ -3733,9 +3830,9 @@ function graphqlInputPaths(options) {
3733
3830
  } catch {
3734
3831
  return [];
3735
3832
  }
3736
- const root = resolve3(options.rootDir);
3737
- const schema = resolve3(root, options.graphql.schema);
3738
- const documents = ts7.sys.readDirectory(root, [".graphql", ".gql"], ["**/node_modules/**", "**/.git/**", resolve3(options.outDir)], options.graphql.documents ?? ["**/*.graphql", "**/*.gql"]).map((path) => resolve3(path)).filter((path) => path !== schema);
3833
+ const root = resolve4(options.rootDir);
3834
+ const schema = resolve4(root, options.graphql.schema);
3835
+ 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);
3739
3836
  return [schema, ...[...new Set(documents)].sort()];
3740
3837
  }
3741
3838
  var init_graphql_inputs = __esm(() => {
@@ -3743,10 +3840,10 @@ var init_graphql_inputs = __esm(() => {
3743
3840
  });
3744
3841
 
3745
3842
  // src/graphql-runtime.ts
3746
- import * as ts8 from "@typescript/typescript6";
3747
- import { resolve as resolve4 } from "node:path";
3843
+ import * as ts11 from "@typescript/typescript6";
3844
+ import { resolve as resolve5 } from "node:path";
3748
3845
  function renderGraphqlValidators(source, operationNames) {
3749
- const fileName = resolve4("/__supacloud_graphql__/contracts.ts");
3846
+ const fileName = resolve5("/__supacloud_graphql__/contracts.ts");
3750
3847
  const options = {
3751
3848
  strict: true,
3752
3849
  noUncheckedIndexedAccess: true,
@@ -3755,18 +3852,18 @@ function renderGraphqlValidators(source, operationNames) {
3755
3852
  noPropertyAccessFromIndexSignature: true,
3756
3853
  noFallthroughCasesInSwitch: true,
3757
3854
  skipLibCheck: false,
3758
- target: ts8.ScriptTarget.ES2022,
3855
+ target: ts11.ScriptTarget.ES2022,
3759
3856
  lib: ["lib.es2022.d.ts"],
3760
3857
  types: [],
3761
3858
  noEmit: true
3762
3859
  };
3763
- const host = ts8.createCompilerHost(options);
3860
+ const host = ts11.createCompilerHost(options);
3764
3861
  const getSourceFile = host.getSourceFile.bind(host);
3765
- host.getSourceFile = (path, languageVersion, onError, shouldCreateNewSourceFile) => resolve4(path) === fileName ? ts8.createSourceFile(path, source, languageVersion, true) : getSourceFile(path, languageVersion, onError, shouldCreateNewSourceFile);
3766
- const program = ts8.createProgram([fileName], options, host);
3767
- const diagnostics = ts8.getPreEmitDiagnostics(program);
3862
+ host.getSourceFile = (path, languageVersion, onError, shouldCreateNewSourceFile) => resolve5(path) === fileName ? ts11.createSourceFile(path, source, languageVersion, true) : getSourceFile(path, languageVersion, onError, shouldCreateNewSourceFile);
3863
+ const program = ts11.createProgram([fileName], options, host);
3864
+ const diagnostics = ts11.getPreEmitDiagnostics(program);
3768
3865
  if (diagnostics.length) {
3769
- throw new Error(`Generated GraphQL types cannot be validated: ${diagnostics.map((item) => ts8.flattenDiagnosticMessageText(item.messageText, `
3866
+ throw new Error(`Generated GraphQL types cannot be validated: ${diagnostics.map((item) => ts11.flattenDiagnosticMessageText(item.messageText, `
3770
3867
  `)).join("; ")}`);
3771
3868
  }
3772
3869
  const checker = program.getTypeChecker();
@@ -3796,25 +3893,25 @@ function renderGraphqlValidators(source, operationNames) {
3796
3893
  return name;
3797
3894
  }
3798
3895
  function expression(type) {
3799
- if (type.flags & ts8.TypeFlags.Any)
3896
+ if (type.flags & ts11.TypeFlags.Any)
3800
3897
  return unsupported(type);
3801
- if (type.flags & ts8.TypeFlags.Unknown)
3898
+ if (type.flags & ts11.TypeFlags.Unknown)
3802
3899
  return "true";
3803
- if (type.flags & ts8.TypeFlags.Never)
3900
+ if (type.flags & ts11.TypeFlags.Never)
3804
3901
  return "false";
3805
- if (type.flags & ts8.TypeFlags.Null)
3902
+ if (type.flags & ts11.TypeFlags.Null)
3806
3903
  return "value === null";
3807
- if (type.flags & ts8.TypeFlags.Undefined)
3904
+ if (type.flags & ts11.TypeFlags.Undefined)
3808
3905
  return "value === undefined";
3809
3906
  if (type.isStringLiteral() || type.isNumberLiteral())
3810
3907
  return `value === ${JSON.stringify(type.value)}`;
3811
- if (type.flags & ts8.TypeFlags.BooleanLiteral)
3908
+ if (type.flags & ts11.TypeFlags.BooleanLiteral)
3812
3909
  return `value === ${checker.typeToString(type)}`;
3813
- if (type.flags & ts8.TypeFlags.String)
3910
+ if (type.flags & ts11.TypeFlags.String)
3814
3911
  return 'typeof value === "string"';
3815
- if (type.flags & ts8.TypeFlags.Number)
3912
+ if (type.flags & ts11.TypeFlags.Number)
3816
3913
  return 'typeof value === "number" && Number.isFinite(value)';
3817
- if (type.flags & ts8.TypeFlags.Boolean)
3914
+ if (type.flags & ts11.TypeFlags.Boolean)
3818
3915
  return 'typeof value === "boolean"';
3819
3916
  if (type.isUnion())
3820
3917
  return type.types.map((part) => `${reference(part)}(value)`).join(" || ");
@@ -3823,16 +3920,16 @@ function renderGraphqlValidators(source, operationNames) {
3823
3920
  if (checker.isTupleType(type))
3824
3921
  return unsupported(type);
3825
3922
  if (checker.isArrayType(type)) {
3826
- const item = checker.getIndexTypeOfType(type, ts8.IndexKind.Number);
3923
+ const item = checker.getIndexTypeOfType(type, ts11.IndexKind.Number);
3827
3924
  if (!item)
3828
3925
  return unsupported(type);
3829
3926
  return `isGraphqlArray(value) && Array.from(value).every(${reference(item)})`;
3830
3927
  }
3831
- if (type.flags & ts8.TypeFlags.Object) {
3928
+ if (type.flags & ts11.TypeFlags.Object) {
3832
3929
  if (type.getCallSignatures().length || type.getConstructSignatures().length)
3833
3930
  return unsupported(type);
3834
3931
  const indexes = checker.getIndexInfosOfType(type);
3835
- if (indexes.some((index) => !(index.keyType.flags & ts8.TypeFlags.String)))
3932
+ if (indexes.some((index) => !(index.keyType.flags & ts11.TypeFlags.String)))
3836
3933
  return unsupported(type);
3837
3934
  const properties = checker.getPropertiesOfType(type).map((property) => {
3838
3935
  const declaration = property.valueDeclaration ?? property.declarations?.[0];
@@ -3841,7 +3938,7 @@ function renderGraphqlValidators(source, operationNames) {
3841
3938
  const check = reference(checker.getTypeOfSymbolAtLocation(property, declaration));
3842
3939
  const key = JSON.stringify(property.name);
3843
3940
  const present = `Object.prototype.hasOwnProperty.call(value, ${key})`;
3844
- return property.flags & ts8.SymbolFlags.Optional ? `(!${present} || ${check}(value[${key}]))` : `(${present} && ${check}(value[${key}]))`;
3941
+ return property.flags & ts11.SymbolFlags.Optional ? `(!${present} || ${check}(value[${key}]))` : `(${present} && ${check}(value[${key}]))`;
3845
3942
  });
3846
3943
  const indexedValues = indexes.map((index) => `Object.values(value).every(${reference(index.type)})`);
3847
3944
  return ["isGraphqlRecord(value)", ...properties, ...indexedValues].join(" && ");
@@ -14210,7 +14307,7 @@ var init_delivery_schema = __esm(() => {
14210
14307
  import { createHash as createHash7 } from "node:crypto";
14211
14308
  import { constants } from "node:fs";
14212
14309
  import { lstat, mkdir as mkdir2, open, readFile as readFile3, readdir, realpath, rename as rename2, rm, writeFile as writeFile2 } from "node:fs/promises";
14213
- import { dirname as dirname4, isAbsolute, join as join5, relative as relative5, resolve as resolve6, sep as sep5 } from "node:path";
14310
+ import { dirname as dirname4, isAbsolute, join as join5, relative as relative5, resolve as resolve7, sep as sep5 } from "node:path";
14214
14311
  function canonical2(value) {
14215
14312
  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);
14216
14313
  }
@@ -14273,7 +14370,7 @@ async function reserveOutput(project, requested) {
14273
14370
  if (!inside(project, requested))
14274
14371
  throw new Error("Delivery output must be inside the application project.");
14275
14372
  const base = await realpath(project);
14276
- const path = resolve6(base, relative5(project, requested));
14373
+ const path = resolve7(base, relative5(project, requested));
14277
14374
  if (relative5(base, path).split(sep5).some((part) => part === ".git" || part === "node_modules")) {
14278
14375
  throw new Error("Delivery output cannot use repository or dependency internals.");
14279
14376
  }
@@ -14576,6 +14673,12 @@ function createContextPack(graph, subject) {
14576
14673
  routeContracts: inspectRouteContracts({ ...graph, modules }),
14577
14674
  ...graphql ? { graphql } : {},
14578
14675
  diagnostics: (graph.diagnostics ?? []).filter((diagnostic) => diagnostic.file === undefined || files.includes(diagnostic.file)),
14676
+ conventions: {
14677
+ singleResult: "async-await",
14678
+ eventComposition: "rxjs",
14679
+ angularHost: "@supacloud/app/angular",
14680
+ cancellation: "explicit-owner-signal"
14681
+ },
14579
14682
  relatedModules: {
14580
14683
  imports: subjectModule.imports.filter((name) => selected.has(name)),
14581
14684
  importedBy: graph.modules.filter((module) => module.imports.includes(subjectModule.name)).map((module) => module.name).sort()
@@ -15334,9 +15437,9 @@ var init_delivery_files2 = __esm(() => {
15334
15437
 
15335
15438
  // node_modules/@supacloud/delivery/src/delivery-artifact.ts
15336
15439
  import { readdir as readdir2, realpath as realpath2 } from "node:fs/promises";
15337
- import { basename, dirname as dirname6, join as join8, resolve as resolve8 } from "node:path";
15440
+ import { basename, dirname as dirname6, join as join8, resolve as resolve9 } from "node:path";
15338
15441
  async function readDeliveryManifest(manifestPath) {
15339
- const selected = resolve8(manifestPath);
15442
+ const selected = resolve9(manifestPath);
15340
15443
  const root = await realpath2(dirname6(selected));
15341
15444
  const manifest = parseDeliveryBuildManifest(JSON.parse((await readBoundedOwned(root, join8(root, basename(selected)), JSON_LIMIT)).toString("utf8")));
15342
15445
  return { root, manifest };
@@ -15642,6 +15745,213 @@ var init_delivery_migration_archive2 = __esm(() => {
15642
15745
  init_src();
15643
15746
  });
15644
15747
 
15748
+ // src/fixes.ts
15749
+ import { createHash as createHash8, randomUUID } from "node:crypto";
15750
+ import { lstat as lstat2, readFile as readFile6, realpath as realpath4, rename as rename4, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
15751
+ import { dirname as dirname8, isAbsolute as isAbsolute3, relative as relative8, resolve as resolve12, sep as sep8 } from "node:path";
15752
+ import * as ts15 from "@typescript/typescript6";
15753
+ async function applyDiagnosticFix(fix, options = {}) {
15754
+ if (!fix || typeof fix.targetFile !== "string")
15755
+ throw new Error("Invalid DiagnosticFix");
15756
+ const root = await realpath4(options.rootDir ?? process.cwd());
15757
+ const file = resolve12(root, fix.targetFile);
15758
+ const stat = await lstat2(file);
15759
+ const resolved = await realpath4(file);
15760
+ const relativePath = relative8(root, resolved);
15761
+ if (stat.isSymbolicLink() || !stat.isFile() || isAbsolute3(relativePath) || relativePath === ".." || relativePath.startsWith(`..${sep8}`)) {
15762
+ throw new Error("Fix target must be a regular file inside rootDir");
15763
+ }
15764
+ const original = await readFile6(file, "utf8");
15765
+ const sourceHash = createHash8("sha256").update(original).digest("hex");
15766
+ if (options.expectedSourceHash !== undefined && options.expectedSourceHash !== sourceHash) {
15767
+ throw new Error("Fix source changed since preview; analyze the project again");
15768
+ }
15769
+ let source = parse5(file, original);
15770
+ let content;
15771
+ switch (fix.type) {
15772
+ case "set_command_mode": {
15773
+ if (fix.property !== "transaction" && fix.property !== "idempotency" || fix.value !== "required" && fix.value !== "none") {
15774
+ throw new Error("Command mode fix requires an explicit property and policy value");
15775
+ }
15776
+ const object = decoratorObject(findClass(source, fix.command), "Command");
15777
+ const current = property(object, fix.property);
15778
+ if (!current || current.initializer.getText(source) !== fix.expectedExpression) {
15779
+ throw new Error("Command mode changed since diagnosis; analyze the project again");
15780
+ }
15781
+ content = replaceProperty(source, object, fix.property, ts15.factory.createStringLiteral(fix.value));
15782
+ break;
15783
+ }
15784
+ case "add_module_import": {
15785
+ if (!fix.importPath || !fix.symbol)
15786
+ throw new Error("Module fix requires importPath and symbol");
15787
+ identifier2(fix.symbol);
15788
+ const withImport = importSymbol(source, fix.importPath, fix.symbol);
15789
+ source = parse5(file, withImport);
15790
+ const object = unique(moduleObjects(source).filter((candidate) => !fix.targetModule || stringProperty(candidate, "name") === fix.targetModule), "target module");
15791
+ const imports = property(object, "imports");
15792
+ if (imports && !ts15.isArrayLiteralExpression(imports.initializer)) {
15793
+ throw new Error("Module imports must be a static array");
15794
+ }
15795
+ const values = imports && ts15.isArrayLiteralExpression(imports.initializer) ? imports.initializer.elements : [];
15796
+ if (values.some(ts15.isSpreadElement))
15797
+ throw new Error("Module imports cannot contain spread elements");
15798
+ content = values.some((value) => ts15.isIdentifier(value) && value.text === fix.symbol) ? withImport : replaceProperty(source, object, "imports", ts15.factory.createArrayLiteralExpression([
15799
+ ...values,
15800
+ ts15.factory.createIdentifier(fix.symbol)
15801
+ ]));
15802
+ break;
15803
+ }
15804
+ case "add_command_permission": {
15805
+ const permission = options.permission ?? fix.permission;
15806
+ if (!permission?.trim()) {
15807
+ throw new Error("Permission fix requires an explicit permission; privileges are never inferred");
15808
+ }
15809
+ const command = findClass(source, fix.command);
15810
+ const object = decoratorObject(command, "Command");
15811
+ const current = property(object, "permission");
15812
+ if (current && (!ts15.isStringLiteral(current.initializer) || current.initializer.text !== permission)) {
15813
+ throw new Error("Command permission already exists with a different value");
15814
+ }
15815
+ content = current ? original : replaceProperty(source, object, "permission", ts15.factory.createStringLiteral(permission));
15816
+ break;
15817
+ }
15818
+ case "add_route_parameter_binding": {
15819
+ const controller = findClass(source, fix.controller);
15820
+ const method = unique(controller.members.filter((member) => ts15.isMethodDeclaration(member) && nameOf(member.name) === fix.route), "route handler");
15821
+ const parameter = unique(method.parameters.filter((candidate) => ts15.isIdentifier(candidate.name) && candidate.name.text === fix.parameter), "same-named route parameter");
15822
+ const binding = fix.binding === "param" ? "Param" : fix.binding === "query" ? "Query" : undefined;
15823
+ if (!binding)
15824
+ throw new Error("Invalid route binding");
15825
+ const decorators = ts15.getDecorators(parameter) ?? [];
15826
+ if (decorators.length > 0)
15827
+ throw new Error("Parameter already has a decorator");
15828
+ const framework = unique(source.statements.filter((statement) => ts15.isImportDeclaration(statement) && statement.importClause?.namedBindings && ts15.isNamedImports(statement.importClause.namedBindings) && statement.importClause.namedBindings.elements.some((element) => ["Controller", "Get", "Post", "Put", "Patch", "Delete", "Head", "Options"].includes(element.name.text))), "framework import");
15829
+ if (!ts15.isImportDeclaration(framework) || !ts15.isStringLiteral(framework.moduleSpecifier)) {
15830
+ throw new Error("Framework import must be static");
15831
+ }
15832
+ const edited = original.slice(0, parameter.getStart(source)) + `@${binding}(${JSON.stringify(fix.parameter)}) ` + original.slice(parameter.getStart(source));
15833
+ content = importSymbol(parse5(file, edited), framework.moduleSpecifier.text, binding);
15834
+ break;
15835
+ }
15836
+ default:
15837
+ throw new Error(`Diagnostic fix '${fix.type}' requires a manual semantic decision; no files changed`);
15838
+ }
15839
+ parse5(file, content);
15840
+ const result = { file, changed: content !== original, content, sourceHash };
15841
+ if (options.dryRun === false && result.changed) {
15842
+ const temporary = `${file}.supacloud-fix-${randomUUID()}`;
15843
+ try {
15844
+ await writeFile3(temporary, content, { encoding: "utf8", flag: "wx", mode: stat.mode });
15845
+ if (await readFile6(file, "utf8") !== original)
15846
+ throw new Error("Target changed while preparing the fix");
15847
+ await rename4(temporary, file);
15848
+ } finally {
15849
+ await unlink2(temporary).catch(() => {});
15850
+ }
15851
+ }
15852
+ return result;
15853
+ }
15854
+ function parse5(file, text) {
15855
+ const result = ts15.transpileModule(text, {
15856
+ fileName: file,
15857
+ reportDiagnostics: true,
15858
+ compilerOptions: { target: ts15.ScriptTarget.ESNext, experimentalDecorators: true }
15859
+ });
15860
+ if (result.diagnostics?.some((item) => item.category === ts15.DiagnosticCategory.Error)) {
15861
+ throw new Error("Cannot fix syntactically invalid TypeScript");
15862
+ }
15863
+ return ts15.createSourceFile(file, text, ts15.ScriptTarget.Latest, true, ts15.ScriptKind.TS);
15864
+ }
15865
+ function unique(items, description) {
15866
+ if (items.length !== 1)
15867
+ throw new Error(`Expected exactly one ${description}; found ${items.length}`);
15868
+ return items[0];
15869
+ }
15870
+ function identifier2(value) {
15871
+ if (!/^[A-Za-z_$][\w$]*$/.test(value))
15872
+ throw new Error(`Invalid identifier '${value}'`);
15873
+ }
15874
+ function nameOf(name) {
15875
+ if (!name)
15876
+ return "";
15877
+ return ts15.isIdentifier(name) || ts15.isStringLiteral(name) || ts15.isNumericLiteral(name) ? name.text : "";
15878
+ }
15879
+ function property(object, key) {
15880
+ if (object.properties.some((item) => !ts15.isPropertyAssignment(item) || ts15.isComputedPropertyName(item.name))) {
15881
+ throw new Error("Fix requires explicit static object properties");
15882
+ }
15883
+ const values = object.properties.filter((item) => ts15.isPropertyAssignment(item) && nameOf(item.name) === key);
15884
+ if (values.length > 1)
15885
+ throw new Error(`Duplicate '${key}' property`);
15886
+ return values[0];
15887
+ }
15888
+ function stringProperty(object, key) {
15889
+ const value = property(object, key)?.initializer;
15890
+ return value && ts15.isStringLiteral(value) ? value.text : undefined;
15891
+ }
15892
+ function replaceProperty(source, object, key, value) {
15893
+ const previous = property(object, key);
15894
+ const replacement = ts15.factory.createPropertyAssignment(key, value);
15895
+ const properties = object.properties.map((item) => item === previous ? replacement : item);
15896
+ if (!previous)
15897
+ properties.push(replacement);
15898
+ const updated = ts15.factory.updateObjectLiteralExpression(object, properties);
15899
+ return source.text.slice(0, object.getStart(source)) + ts15.createPrinter().printNode(ts15.EmitHint.Expression, updated, source) + source.text.slice(object.end);
15900
+ }
15901
+ function findClass(source, name) {
15902
+ return unique(source.statements.filter((statement) => ts15.isClassDeclaration(statement) && statement.name?.text === name), `class '${name}'`);
15903
+ }
15904
+ function decoratorObject(node, name) {
15905
+ const decorator = unique((ts15.getDecorators(node) ?? []).filter((item) => ts15.isCallExpression(item.expression) && item.expression.expression.getText() === name), `@${name} decorator`);
15906
+ const argument = ts15.isCallExpression(decorator.expression) ? decorator.expression.arguments[0] : undefined;
15907
+ if (!argument || !ts15.isObjectLiteralExpression(argument))
15908
+ throw new Error(`@${name} requires a static object`);
15909
+ return argument;
15910
+ }
15911
+ function moduleObjects(source) {
15912
+ const result = [];
15913
+ for (const statement of source.statements) {
15914
+ if (ts15.isClassDeclaration(statement) && (ts15.getDecorators(statement) ?? []).some((item) => ts15.isCallExpression(item.expression) && item.expression.expression.getText() === "Module")) {
15915
+ result.push(decoratorObject(statement, "Module"));
15916
+ }
15917
+ if (ts15.isVariableStatement(statement)) {
15918
+ for (const declaration of statement.declarationList.declarations) {
15919
+ const call = declaration.initializer;
15920
+ if (call && ts15.isCallExpression(call) && ["defineModule", "defineFeatureSlice"].includes(call.expression.getText()) && call.arguments[0] && ts15.isObjectLiteralExpression(call.arguments[0])) {
15921
+ result.push(call.arguments[0]);
15922
+ }
15923
+ }
15924
+ }
15925
+ }
15926
+ return result;
15927
+ }
15928
+ function importSymbol(source, path, symbol) {
15929
+ identifier2(symbol);
15930
+ const current = resolve12(source.fileName).replace(/\.(tsx?|mts|cts)$/, "");
15931
+ const target = resolve12(dirname8(source.fileName), path).replace(/\.(tsx?|mts|cts)$/, "");
15932
+ if (current === target)
15933
+ return source.text;
15934
+ const matches = source.statements.filter((item) => ts15.isImportDeclaration(item) && ts15.isStringLiteral(item.moduleSpecifier) && item.moduleSpecifier.text === path);
15935
+ if (matches.length > 1)
15936
+ throw new Error(`Ambiguous imports from '${path}'`);
15937
+ const match = matches[0];
15938
+ if (match && ts15.isImportDeclaration(match) && match.importClause?.namedBindings && ts15.isNamedImports(match.importClause.namedBindings) && !match.importClause.isTypeOnly) {
15939
+ if (match.importClause.namedBindings.elements.some((item) => item.name.text === symbol))
15940
+ return source.text;
15941
+ const bindings = match.importClause.namedBindings;
15942
+ const updated = ts15.factory.updateNamedImports(bindings, [
15943
+ ...bindings.elements,
15944
+ ts15.factory.createImportSpecifier(false, undefined, ts15.factory.createIdentifier(symbol))
15945
+ ]);
15946
+ return source.text.slice(0, bindings.getStart(source)) + ts15.createPrinter().printNode(ts15.EmitHint.Unspecified, updated, source) + source.text.slice(bindings.end);
15947
+ }
15948
+ if (match)
15949
+ throw new Error(`Import from '${path}' is not a named value import`);
15950
+ return `import { ${symbol} } from ${JSON.stringify(path)};
15951
+ ${source.text}`;
15952
+ }
15953
+ var init_fixes = () => {};
15954
+
15645
15955
  // src/execution-context.ts
15646
15956
  import { open as open2 } from "node:fs/promises";
15647
15957
  import { constants as constants2 } from "node:fs";
@@ -16095,8 +16405,8 @@ var init_release_evidence = __esm(() => {
16095
16405
 
16096
16406
  // src/graphql-schema.ts
16097
16407
  import { mkdir as mkdir5, readFile as readFile12 } from "node:fs/promises";
16098
- import { createHash as createHash10 } from "node:crypto";
16099
- import { dirname as dirname11, resolve as resolve19 } from "node:path";
16408
+ import { createHash as createHash11 } from "node:crypto";
16409
+ import { dirname as dirname11, resolve as resolve20 } from "node:path";
16100
16410
  async function pullGraphqlSchema(options) {
16101
16411
  assertGraphqlOptions({ schema: options.output });
16102
16412
  const endpoint = new URL(options.url);
@@ -16136,7 +16446,7 @@ async function pullGraphqlSchema(options) {
16136
16446
  throw new Error("GraphQL schema export failed. Verify caller grants and enable introspection only in the intended development environment.");
16137
16447
  }
16138
16448
  const schema = lexicographicSortSchema(buildClientSchema(data));
16139
- const path = resolve19(options.output);
16449
+ const path = resolve20(options.output);
16140
16450
  const content = path.endsWith(".json") ? JSON.stringify(introspectionFromSchema(schema), null, 2) + `
16141
16451
  ` : `# GENERATED BY supacloud-compiler graphql-schema. DO NOT EDIT.
16142
16452
  # Database First: change database declarations, apply migrations, then re-export for the intended role.
@@ -16150,7 +16460,7 @@ async function pullGraphqlSchema(options) {
16150
16460
  throw error;
16151
16461
  }
16152
16462
  const upToDate = previous === content;
16153
- const schemaHash = createHash10("sha256").update(content).digest("hex");
16463
+ const schemaHash = createHash11("sha256").update(content).digest("hex");
16154
16464
  if (options.check)
16155
16465
  return { path, schemaHash, upToDate, written: false };
16156
16466
  await mkdir5(dirname11(path), { recursive: true });
@@ -16163,12 +16473,12 @@ var init_graphql_schema = __esm(() => {
16163
16473
  });
16164
16474
 
16165
16475
  // src/database-contracts.ts
16166
- import { createHash as createHash11 } from "node:crypto";
16476
+ import { createHash as createHash12 } from "node:crypto";
16167
16477
  import { mkdir as mkdir6, readFile as readFile13 } from "node:fs/promises";
16168
- import { dirname as dirname12, relative as relative12, resolve as resolve20 } from "node:path";
16169
- import * as ts14 from "@typescript/typescript6";
16478
+ import { dirname as dirname12, relative as relative12, resolve as resolve21 } from "node:path";
16479
+ import * as ts17 from "@typescript/typescript6";
16170
16480
  function hash3(value) {
16171
- return createHash11("sha256").update(value).digest("hex");
16481
+ return createHash12("sha256").update(value).digest("hex");
16172
16482
  }
16173
16483
  function importPath(out, path) {
16174
16484
  const value = relative12(out, path).replaceAll("\\", "/").replace(/\.(?:d\.)?[cm]?ts$/, "");
@@ -16193,33 +16503,33 @@ function parseDatabaseContractsOptions(value, directory) {
16193
16503
  throw new TypeError("migrations must be an ordered list of SQL files");
16194
16504
  }
16195
16505
  return {
16196
- rootDir: resolve20(directory, field("rootDir")),
16197
- outDir: resolve20(directory, field("outDir")),
16198
- postgrestTypes: resolve20(directory, field("postgrestTypes")),
16199
- drizzleSchema: resolve20(directory, field("drizzleSchema")),
16506
+ rootDir: resolve21(directory, field("rootDir")),
16507
+ outDir: resolve21(directory, field("outDir")),
16508
+ postgrestTypes: resolve21(directory, field("postgrestTypes")),
16509
+ drizzleSchema: resolve21(directory, field("drizzleSchema")),
16200
16510
  role: field("role"),
16201
- graphql: { ...graphql, schema: resolve20(directory, graphql.schema) },
16202
- migrations: migrations.map((file) => resolve20(directory, file))
16511
+ graphql: { ...graphql, schema: resolve21(directory, graphql.schema) },
16512
+ migrations: migrations.map((file) => resolve21(directory, file))
16203
16513
  };
16204
16514
  }
16205
16515
  async function generateDatabaseContracts(options, check = false) {
16206
- const rootDir = resolve20(options.rootDir), outDir = resolve20(options.outDir);
16207
- const postgrestTypes = resolve20(rootDir, options.postgrestTypes), drizzleSchema = resolve20(rootDir, options.drizzleSchema);
16516
+ const rootDir = resolve21(options.rootDir), outDir = resolve21(options.outDir);
16517
+ const postgrestTypes = resolve21(rootDir, options.postgrestTypes), drizzleSchema = resolve21(rootDir, options.drizzleSchema);
16208
16518
  const snapshot = await readFile13(postgrestTypes, "utf8");
16209
- const syntax = ts14.createSourceFile(postgrestTypes, snapshot, ts14.ScriptTarget.Latest, true);
16210
- const database = syntax.statements.find((node) => (ts14.isTypeAliasDeclaration(node) || ts14.isInterfaceDeclaration(node)) && node.name.text === "Database" && node.modifiers?.some((modifier) => modifier.kind === ts14.SyntaxKind.ExportKeyword));
16519
+ const syntax = ts17.createSourceFile(postgrestTypes, snapshot, ts17.ScriptTarget.Latest, true);
16520
+ 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));
16211
16521
  if (!database)
16212
16522
  throw new Error("PostgREST snapshot must export Database from the official type generator");
16213
- const program = ts14.createProgram([postgrestTypes], {
16523
+ const program = ts17.createProgram([postgrestTypes], {
16214
16524
  strict: true,
16215
16525
  noEmit: true,
16216
16526
  skipLibCheck: true,
16217
16527
  types: [],
16218
- target: ts14.ScriptTarget.ES2022,
16219
- module: ts14.ModuleKind.ESNext,
16220
- moduleResolution: ts14.ModuleResolutionKind.Bundler
16528
+ target: ts17.ScriptTarget.ES2022,
16529
+ module: ts17.ModuleKind.ESNext,
16530
+ moduleResolution: ts17.ModuleResolutionKind.Bundler
16221
16531
  });
16222
- if (ts14.getPreEmitDiagnostics(program).length)
16532
+ if (ts17.getPreEmitDiagnostics(program).length)
16223
16533
  throw new Error("PostgREST snapshot has TypeScript errors");
16224
16534
  const artifacts = await renderGraphql({
16225
16535
  rootDir,
@@ -16232,16 +16542,16 @@ async function generateDatabaseContracts(options, check = false) {
16232
16542
  }
16233
16543
  const inputs = {};
16234
16544
  const addInput = async (path) => {
16235
- const absolute = resolve20(rootDir, path);
16545
+ const absolute = resolve21(rootDir, path);
16236
16546
  inputs[relative12(rootDir, absolute).replaceAll("\\", "/")] = hash3(await readFile13(absolute, "utf8"));
16237
16547
  };
16238
16548
  await addInput(postgrestTypes);
16239
16549
  await addInput(drizzleSchema);
16240
- const drizzleProgram = ts14.createProgram([drizzleSchema], {
16550
+ const drizzleProgram = ts17.createProgram([drizzleSchema], {
16241
16551
  noEmit: true,
16242
- moduleResolution: ts14.ModuleResolutionKind.Bundler,
16243
- module: ts14.ModuleKind.ESNext,
16244
- target: ts14.ScriptTarget.ES2022,
16552
+ moduleResolution: ts17.ModuleResolutionKind.Bundler,
16553
+ module: ts17.ModuleKind.ESNext,
16554
+ target: ts17.ScriptTarget.ES2022,
16245
16555
  types: [],
16246
16556
  skipLibCheck: true
16247
16557
  });
@@ -16249,8 +16559,8 @@ async function generateDatabaseContracts(options, check = false) {
16249
16559
  if (!source.isDeclarationFile && !source.fileName.includes("/node_modules/"))
16250
16560
  await addInput(source.fileName);
16251
16561
  }
16252
- await addInput(resolve20(rootDir, options.graphql.schema));
16253
- if (new Set(options.migrations.map((path) => resolve20(rootDir, path))).size !== options.migrations.length) {
16562
+ await addInput(resolve21(rootDir, options.graphql.schema));
16563
+ if (new Set(options.migrations.map((path) => resolve21(rootDir, path))).size !== options.migrations.length) {
16254
16564
  throw new Error("Duplicate migration in database contracts configuration");
16255
16565
  }
16256
16566
  for (const path of options.migrations)
@@ -16271,14 +16581,14 @@ async function generateDatabaseContracts(options, check = false) {
16271
16581
  version: 1,
16272
16582
  role: options.role,
16273
16583
  inputs: Object.fromEntries(Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b))),
16274
- migrationOrder: options.migrations.map((path) => relative12(rootDir, resolve20(rootDir, path)).replaceAll("\\", "/")),
16584
+ migrationOrder: options.migrations.map((path) => relative12(rootDir, resolve21(rootDir, path)).replaceAll("\\", "/")),
16275
16585
  outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file, hash3(text)]))
16276
16586
  };
16277
16587
  files["database.manifest.json"] = JSON.stringify(manifest, null, 2) + `
16278
16588
  `;
16279
16589
  const mismatches = [];
16280
16590
  for (const [file, content] of Object.entries(files)) {
16281
- const path = resolve20(outDir, file);
16591
+ const path = resolve21(outDir, file);
16282
16592
  let current;
16283
16593
  try {
16284
16594
  current = await readFile13(path, "utf8");
@@ -16292,12 +16602,12 @@ async function generateDatabaseContracts(options, check = false) {
16292
16602
  if (!check) {
16293
16603
  await mkdir6(outDir, { recursive: true });
16294
16604
  for (const [file, content] of Object.entries(files))
16295
- await writeFileIfChanged(resolve20(outDir, file), content);
16605
+ await writeFileIfChanged(resolve21(outDir, file), content);
16296
16606
  }
16297
16607
  return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest };
16298
16608
  }
16299
16609
  async function runDatabaseContractsFile(path, check = false) {
16300
- const absolute = resolve20(path);
16610
+ const absolute = resolve21(path);
16301
16611
  const value = JSON.parse(await readFile13(absolute, "utf8"));
16302
16612
  return generateDatabaseContracts(parseDatabaseContractsOptions(value, dirname12(absolute)), check);
16303
16613
  }
@@ -16310,7 +16620,7 @@ var init_database_contracts = __esm(() => {
16310
16620
  // src/analyze.ts
16311
16621
  import { createHash as createHash3 } from "node:crypto";
16312
16622
  import { relative as relative2, resolve as resolvePath, sep as sep2 } from "node:path";
16313
- import * as ts4 from "@typescript/typescript6";
16623
+ import * as ts7 from "@typescript/typescript6";
16314
16624
 
16315
16625
  // src/program.ts
16316
16626
  import { createHash as createHash2 } from "node:crypto";
@@ -16646,12 +16956,258 @@ function readProjectConfig(rootDir) {
16646
16956
  init_validate();
16647
16957
 
16648
16958
  // src/static-di.ts
16959
+ import * as ts6 from "@typescript/typescript6";
16960
+
16961
+ // src/reactive-analysis.ts
16962
+ import * as ts4 from "@typescript/typescript6";
16963
+
16964
+ // src/api-source.ts
16649
16965
  import * as ts3 from "@typescript/typescript6";
16966
+ import { resolve as resolve2 } from "node:path";
16967
+ function bindApiSource(source) {
16968
+ const file = resolve2(source.fileName);
16969
+ const bound = ts3.createSourceFile(file, source.text, ts3.ScriptTarget.Latest, true);
16970
+ const options = { noLib: true, noResolve: true, target: ts3.ScriptTarget.ES2022 };
16971
+ const host = {
16972
+ getSourceFile: (name) => resolve2(name) === file ? bound : undefined,
16973
+ getDefaultLibFileName: () => "",
16974
+ writeFile: () => {},
16975
+ getCurrentDirectory: () => process.cwd(),
16976
+ getDirectories: () => [],
16977
+ fileExists: (name) => resolve2(name) === file,
16978
+ readFile: (name) => resolve2(name) === file ? source.text : undefined,
16979
+ getCanonicalFileName: (name) => name,
16980
+ useCaseSensitiveFileNames: () => true,
16981
+ getNewLine: () => `
16982
+ `
16983
+ };
16984
+ const program = ts3.createProgram([file], options, host);
16985
+ return { source: bound, checker: program.getTypeChecker() };
16986
+ }
16987
+ function importedFrom(node) {
16988
+ let current = node;
16989
+ while (current && !ts3.isImportDeclaration(current))
16990
+ current = current.parent;
16991
+ return current && ts3.isImportDeclaration(current) && ts3.isStringLiteral(current.moduleSpecifier) ? current.moduleSpecifier.text : undefined;
16992
+ }
16993
+ function apiOrigin(expression, checker, seen = new Set) {
16994
+ if (seen.has(expression))
16995
+ return;
16996
+ seen.add(expression);
16997
+ if (ts3.isParenthesizedExpression(expression) || ts3.isAsExpression(expression) || ts3.isSatisfiesExpression(expression) || ts3.isTypeAssertionExpression(expression)) {
16998
+ return apiOrigin(expression.expression, checker, seen);
16999
+ }
17000
+ if (ts3.isPropertyAccessExpression(expression) || ts3.isElementAccessExpression(expression)) {
17001
+ const name = ts3.isPropertyAccessExpression(expression) ? expression.name.text : ts3.isStringLiteral(expression.argumentExpression) ? expression.argumentExpression.text : undefined;
17002
+ const namespace = apiOrigin(expression.expression, checker, seen);
17003
+ return namespace?.name === "*" && name ? { module: namespace.module, name } : undefined;
17004
+ }
17005
+ if (!ts3.isIdentifier(expression))
17006
+ return;
17007
+ const symbol = checker.getSymbolAtLocation(expression);
17008
+ for (const declaration of symbol?.declarations ?? []) {
17009
+ if (ts3.isImportSpecifier(declaration) && !declaration.isTypeOnly && !declaration.parent.parent.isTypeOnly) {
17010
+ const module = importedFrom(declaration);
17011
+ if (module)
17012
+ return { module, name: (declaration.propertyName ?? declaration.name).text };
17013
+ }
17014
+ if (ts3.isNamespaceImport(declaration) && !declaration.parent.isTypeOnly) {
17015
+ const module = importedFrom(declaration);
17016
+ if (module)
17017
+ return { module, name: "*" };
17018
+ }
17019
+ if (ts3.isVariableDeclaration(declaration) && declaration.initializer && ts3.isVariableDeclarationList(declaration.parent) && declaration.parent.flags & ts3.NodeFlags.Const) {
17020
+ return apiOrigin(declaration.initializer, checker, seen);
17021
+ }
17022
+ }
17023
+ return;
17024
+ }
17025
+
17026
+ // src/reactive-analysis.ts
17027
+ var angularState = new Set(["@angular/core", "@supacloud/app/angular"]);
17028
+ var signalBridges = new Set(["@angular/core/rxjs-interop", "@supacloud/app/angular", "@supacloud/app/rxjs"]);
17029
+ function scanReactiveSource(input, file) {
17030
+ if (!input.statements.some((node) => ts4.isImportDeclaration(node) && ts4.isStringLiteral(node.moduleSpecifier) && (angularState.has(node.moduleSpecifier.text) || signalBridges.has(node.moduleSpecifier.text))))
17031
+ return [];
17032
+ const { source, checker } = bindApiSource(input);
17033
+ const diagnostics = [];
17034
+ const reported = new Set;
17035
+ const visit = (node, reactive) => {
17036
+ if (ts4.isCallExpression(node)) {
17037
+ const origin = apiOrigin(node.expression, checker);
17038
+ if (reactive && origin && signalBridges.has(origin.module) && ["toSignal", "toScopedSignal", "rxResource"].includes(origin.name) && !reported.has(node.pos)) {
17039
+ reported.add(node.pos);
17040
+ const start = source.getLineAndCharacterOfPosition(node.getStart(source));
17041
+ const end = source.getLineAndCharacterOfPosition(node.end);
17042
+ diagnostics.push({
17043
+ severity: "error",
17044
+ code: "reactive-subscription-in-computation",
17045
+ file,
17046
+ line: start.line + 1,
17047
+ column: start.character,
17048
+ endLine: end.line + 1,
17049
+ endColumn: end.character,
17050
+ message: `${origin.name} creates a subscription inside a reactive computation.`,
17051
+ suggestion: "Create the subscription once in its explicit owner scope, then derive state with computed. Hoisting requires ownership review; no automatic edit is safe.",
17052
+ docsUrl: "https://supacloud.dev/errors/reactive-subscription-in-computation"
17053
+ });
17054
+ }
17055
+ if (origin && angularState.has(origin.module) && ["computed", "effect", "untracked"].includes(origin.name)) {
17056
+ const callback = node.arguments[0];
17057
+ if (callback && (ts4.isArrowFunction(callback) || ts4.isFunctionExpression(callback))) {
17058
+ visit(callback.body, origin.name === "untracked" ? false : true);
17059
+ for (const argument of node.arguments.slice(1))
17060
+ visit(argument, reactive);
17061
+ return;
17062
+ }
17063
+ }
17064
+ let expression = node.expression;
17065
+ while (ts4.isParenthesizedExpression(expression))
17066
+ expression = expression.expression;
17067
+ if (ts4.isArrowFunction(expression) || ts4.isFunctionExpression(expression))
17068
+ visit(expression.body, reactive);
17069
+ }
17070
+ if (ts4.isFunctionLike(node)) {
17071
+ if (!reactive)
17072
+ ts4.forEachChild(node, (child) => visit(child, false));
17073
+ return;
17074
+ }
17075
+ ts4.forEachChild(node, (child) => visit(child, reactive));
17076
+ };
17077
+ visit(source, false);
17078
+ return diagnostics;
17079
+ }
17080
+
17081
+ // src/http-provider-migration.ts
17082
+ import * as ts5 from "@typescript/typescript6";
17083
+ function providerArgument(node, checker) {
17084
+ let current = node;
17085
+ while (ts5.isParenthesizedExpression(current.parent))
17086
+ current = current.parent;
17087
+ if (!ts5.isCallExpression(current.parent) || current.parent.expression !== current)
17088
+ return false;
17089
+ current = current.parent;
17090
+ while (ts5.isParenthesizedExpression(current.parent))
17091
+ current = current.parent;
17092
+ const parent = current.parent;
17093
+ if (!ts5.isCallExpression(parent) || !parent.arguments.some((argument) => argument === current))
17094
+ return false;
17095
+ const owner = apiOrigin(parent.expression, checker);
17096
+ return owner?.name === "provideHttpClient" && ["@supacloud/app", "@supacloud/app/http"].includes(owner.module);
17097
+ }
17098
+ function migrateHttpProviderImports(source, fileName) {
17099
+ const bound = bindApiSource(ts5.createSourceFile(fileName, source, ts5.ScriptTarget.Latest, true));
17100
+ const { source: sf, checker } = bound;
17101
+ const edits = [];
17102
+ const issues = [];
17103
+ const printer = ts5.createPrinter({ newLine: source.includes(`\r
17104
+ `) ? ts5.NewLineKind.CarriageReturnLineFeed : ts5.NewLineKind.LineFeed });
17105
+ const newline = source.includes(`\r
17106
+ `) ? `\r
17107
+ ` : `
17108
+ `;
17109
+ for (const statement of sf.statements) {
17110
+ if (!ts5.isImportDeclaration(statement) || !ts5.isStringLiteral(statement.moduleSpecifier) || statement.moduleSpecifier.text !== "@supacloud/app" || !statement.importClause || statement.importClause.isTypeOnly)
17111
+ continue;
17112
+ const named = statement.importClause.namedBindings;
17113
+ if (!named || !ts5.isNamedImports(named))
17114
+ continue;
17115
+ const specifier = named.elements.find((item) => !item.isTypeOnly && (item.propertyName ?? item.name).text === "withInterceptors");
17116
+ if (!specifier)
17117
+ continue;
17118
+ const symbol = checker.getSymbolAtLocation(specifier.name);
17119
+ if (!symbol)
17120
+ continue;
17121
+ const uses = [];
17122
+ const visit = (node) => {
17123
+ if (ts5.isImportDeclaration(node))
17124
+ return;
17125
+ if (ts5.isIdentifier(node) && checker.getSymbolAtLocation(node) === symbol)
17126
+ uses.push(node);
17127
+ ts5.forEachChild(node, visit);
17128
+ };
17129
+ visit(sf);
17130
+ if (!uses.some((node) => providerArgument(node, checker)))
17131
+ continue;
17132
+ if (!uses.every((node) => providerArgument(node, checker)) || statement.attributes) {
17133
+ issues.push({
17134
+ code: "http-provider-migration-ambiguous",
17135
+ file: fileName,
17136
+ line: sf.getLineAndCharacterOfPosition(specifier.getStart(sf)).line + 1,
17137
+ message: "withInterceptors also has non-provider uses; split the bindings manually before migration."
17138
+ });
17139
+ continue;
17140
+ }
17141
+ const remaining = named.elements.filter((item) => item !== specifier);
17142
+ if (remaining.length === 0 && !statement.importClause.name) {
17143
+ edits.push({ start: statement.moduleSpecifier.getStart(sf), end: statement.moduleSpecifier.end, text: '"@supacloud/app/http"' });
17144
+ } else {
17145
+ const clause = ts5.factory.updateImportClause(statement.importClause, false, statement.importClause.name, remaining.length ? ts5.factory.updateNamedImports(named, remaining) : undefined);
17146
+ const updated = ts5.factory.updateImportDeclaration(statement, statement.modifiers, clause, statement.moduleSpecifier, statement.attributes);
17147
+ const text = printer.printNode(ts5.EmitHint.Unspecified, updated, sf).trimStart() + newline + `import { ${specifier.getText(sf)} } from "@supacloud/app/http";`;
17148
+ const withoutLeading = text.replace(/^(?:\/\/[^\n]*\n|\/\*[\s\S]*?\*\/\s*)+/, "");
17149
+ edits.push({ start: statement.getStart(sf), end: statement.end, text: withoutLeading });
17150
+ }
17151
+ }
17152
+ const checkNamespace = (node) => {
17153
+ if ((ts5.isPropertyAccessExpression(node) || ts5.isElementAccessExpression(node)) && providerArgument(node, checker)) {
17154
+ const origin = apiOrigin(node, checker);
17155
+ if (origin?.module === "@supacloud/app" && origin.name === "withInterceptors")
17156
+ issues.push({
17157
+ code: "http-provider-migration-namespace",
17158
+ file: fileName,
17159
+ line: sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1,
17160
+ message: "Use a dedicated named import from @supacloud/app/http; namespace rewrites require manual review."
17161
+ });
17162
+ }
17163
+ ts5.forEachChild(node, checkNamespace);
17164
+ };
17165
+ checkNamespace(sf);
17166
+ if (issues.length)
17167
+ return { changed: false, content: source, replacements: 0, issues };
17168
+ let content = source;
17169
+ for (const edit of edits.sort((a, b) => b.start - a.start))
17170
+ content = content.slice(0, edit.start) + edit.text + content.slice(edit.end);
17171
+ return { changed: edits.length > 0, content, replacements: edits.length, issues: [] };
17172
+ }
17173
+ function scanHttpProviderImports(source, file) {
17174
+ if (!source.text.includes("@supacloud/app"))
17175
+ return [];
17176
+ const { source: sf, checker } = bindApiSource(source);
17177
+ const diagnostics = [];
17178
+ const visit = (node) => {
17179
+ if (ts5.isCallExpression(node)) {
17180
+ const origin = apiOrigin(node.expression, checker);
17181
+ if (origin?.module === "@supacloud/app" && origin.name === "withInterceptors" && providerArgument(node.expression, checker)) {
17182
+ const start = sf.getLineAndCharacterOfPosition(node.getStart(sf));
17183
+ const end = sf.getLineAndCharacterOfPosition(node.end);
17184
+ diagnostics.push({
17185
+ severity: "error",
17186
+ code: "http-provider-import-mismatch",
17187
+ file,
17188
+ line: start.line + 1,
17189
+ column: start.character,
17190
+ endLine: end.line + 1,
17191
+ endColumn: end.character,
17192
+ message: "The root withInterceptors returns an interceptor array, not a provideHttpClient feature.",
17193
+ suggestion: "Import withInterceptors from @supacloud/app/http. Preview the http-provider-entrypoint source migration; mixed/namespace uses require manual review.",
17194
+ docsUrl: "https://supacloud.dev/errors/http-provider-import-mismatch"
17195
+ });
17196
+ }
17197
+ }
17198
+ ts5.forEachChild(node, visit);
17199
+ };
17200
+ visit(sf);
17201
+ return diagnostics;
17202
+ }
17203
+
17204
+ // src/static-di.ts
16650
17205
  var runtimeApis = new Set([
16651
17206
  "inject",
16652
17207
  "createEnvironmentInjector",
16653
17208
  "runInInjectionContext",
16654
17209
  "EnvironmentInjector",
17210
+ "Injector",
16655
17211
  "bootstrapBun",
16656
17212
  "runInScope",
16657
17213
  "runInRequestContext",
@@ -16661,25 +17217,33 @@ var runtimeApis = new Set([
16661
17217
  function scanRuntimeDi(source, file) {
16662
17218
  const diagnostics = [];
16663
17219
  const namespaces = new Set;
16664
- const report = (node) => diagnostics.push({
16665
- severity: "error",
16666
- code: "runtime-injection-disallowed",
16667
- errorCode: "SC2012",
16668
- docsUrl: "https://supacloud.dev/errors/SC2012",
16669
- file,
16670
- line: source.getLineAndCharacterOfPosition(node.getStart()).line + 1,
16671
- message: "Compiled applications cannot import runtime DI. Use explicit constructors and generated scope factories."
16672
- });
17220
+ const report = (node) => {
17221
+ const start = source.getLineAndCharacterOfPosition(node.getStart());
17222
+ const end = source.getLineAndCharacterOfPosition(node.end);
17223
+ diagnostics.push({
17224
+ severity: "error",
17225
+ code: "runtime-injection-disallowed",
17226
+ errorCode: "SC2012",
17227
+ docsUrl: "https://supacloud.dev/errors/SC2012",
17228
+ file,
17229
+ line: start.line + 1,
17230
+ column: start.character,
17231
+ endLine: end.line + 1,
17232
+ endColumn: end.character,
17233
+ message: "Compiled applications cannot import runtime DI. Use explicit constructors and generated scope factories.",
17234
+ suggestion: "Use constructor dependencies and generated request/job factories. Keep Angular runtime services outside the compiled application source root."
17235
+ });
17236
+ };
16673
17237
  for (const statement of source.statements) {
16674
- if (!(ts3.isImportDeclaration(statement) || ts3.isExportDeclaration(statement)) || !statement.moduleSpecifier || !ts3.isStringLiteral(statement.moduleSpecifier) || !/^@supacloud\/app(?:\/|$)/.test(statement.moduleSpecifier.text))
17238
+ if (!(ts6.isImportDeclaration(statement) || ts6.isExportDeclaration(statement)) || !statement.moduleSpecifier || !ts6.isStringLiteral(statement.moduleSpecifier) || !(/^@supacloud\/app(?:\/|$)/.test(statement.moduleSpecifier.text) || statement.moduleSpecifier.text === "@angular/core"))
16675
17239
  continue;
16676
- if (ts3.isImportDeclaration(statement)) {
17240
+ if (ts6.isImportDeclaration(statement)) {
16677
17241
  if (statement.importClause?.isTypeOnly)
16678
17242
  continue;
16679
17243
  const binding = statement.importClause?.namedBindings;
16680
- if (binding && ts3.isNamespaceImport(binding))
17244
+ if (binding && ts6.isNamespaceImport(binding))
16681
17245
  namespaces.add(binding.name.text);
16682
- if (binding && ts3.isNamedImports(binding))
17246
+ if (binding && ts6.isNamedImports(binding))
16683
17247
  for (const item of binding.elements) {
16684
17248
  if (!item.isTypeOnly && runtimeApis.has((item.propertyName ?? item.name).text))
16685
17249
  report(item);
@@ -16687,24 +17251,29 @@ function scanRuntimeDi(source, file) {
16687
17251
  } else if (!statement.isTypeOnly) {
16688
17252
  if (!statement.exportClause)
16689
17253
  report(statement);
16690
- else if (ts3.isNamedExports(statement.exportClause))
17254
+ else if (ts6.isNamedExports(statement.exportClause))
16691
17255
  for (const item of statement.exportClause.elements) {
16692
17256
  if (!item.isTypeOnly && runtimeApis.has((item.propertyName ?? item.name).text))
16693
17257
  report(item);
16694
17258
  }
16695
17259
  }
16696
17260
  }
16697
- const visit = (node) => {
16698
- if (ts3.isPropertyAccessExpression(node) && ts3.isIdentifier(node.expression) && namespaces.has(node.expression.text) && runtimeApis.has(node.name.text))
16699
- report(node);
16700
- if (ts3.isElementAccessExpression(node) && ts3.isIdentifier(node.expression) && namespaces.has(node.expression.text) && (!ts3.isStringLiteral(node.argumentExpression) || runtimeApis.has(node.argumentExpression.text)))
16701
- report(node);
16702
- if (ts3.isVariableDeclaration(node) && node.initializer && ts3.isIdentifier(node.initializer) && namespaces.has(node.initializer.text))
16703
- report(node);
16704
- ts3.forEachChild(node, visit);
16705
- };
16706
- visit(source);
16707
- return diagnostics;
17261
+ if (namespaces.size > 0) {
17262
+ const bound = bindApiSource(source);
17263
+ const protectedNamespace = (expression) => {
17264
+ const origin = apiOrigin(expression, bound.checker);
17265
+ return origin?.name === "*" && (origin.module === "@angular/core" || /^@supacloud\/app(?:\/|$)/.test(origin.module));
17266
+ };
17267
+ const visit = (node) => {
17268
+ if (ts6.isPropertyAccessExpression(node) && protectedNamespace(node.expression) && runtimeApis.has(node.name.text))
17269
+ report(node);
17270
+ if (ts6.isElementAccessExpression(node) && protectedNamespace(node.expression) && (!ts6.isStringLiteral(node.argumentExpression) || runtimeApis.has(node.argumentExpression.text)))
17271
+ report(node);
17272
+ ts6.forEachChild(node, visit);
17273
+ };
17274
+ visit(bound.source);
17275
+ }
17276
+ return [...diagnostics, ...scanReactiveSource(source, file), ...scanHttpProviderImports(source, file)];
16708
17277
  }
16709
17278
 
16710
17279
  // src/analyze.ts
@@ -16755,36 +17324,39 @@ function lineOf(node) {
16755
17324
  return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
16756
17325
  }
16757
17326
  function variableName(decl) {
16758
- return ts4.isIdentifier(decl.name) ? decl.name.text : nodeText(decl.name);
17327
+ return ts7.isIdentifier(decl.name) ? decl.name.text : nodeText(decl.name);
16759
17328
  }
16760
17329
  function propertyName(name) {
16761
- if (ts4.isIdentifier(name) || ts4.isPrivateIdentifier(name))
17330
+ if (ts7.isIdentifier(name) || ts7.isPrivateIdentifier(name))
16762
17331
  return name.text;
16763
- if (ts4.isStringLiteral(name) || ts4.isNumericLiteral(name))
17332
+ if (ts7.isStringLiteral(name) || ts7.isNumericLiteral(name))
16764
17333
  return name.text;
16765
17334
  return nodeText(name);
16766
17335
  }
16767
17336
  function parameterName(param) {
16768
- return ts4.isIdentifier(param.name) ? param.name.text : nodeText(param.name);
17337
+ return ts7.isIdentifier(param.name) ? param.name.text : nodeText(param.name);
16769
17338
  }
16770
17339
  function decoratorsOf(node) {
16771
- return ts4.canHaveDecorators(node) ? ts4.getDecorators(node) ?? [] : [];
17340
+ return ts7.canHaveDecorators(node) ? ts7.getDecorators(node) ?? [] : [];
16772
17341
  }
16773
17342
  function decoratorArguments(dec) {
16774
- return ts4.isCallExpression(dec.expression) ? dec.expression.arguments : [];
17343
+ return ts7.isCallExpression(dec.expression) ? dec.expression.arguments : [];
16775
17344
  }
16776
17345
  function hasMethod(cls, name) {
16777
- return cls.members.some((member) => (ts4.isMethodDeclaration(member) || ts4.isGetAccessorDeclaration(member) || ts4.isSetAccessorDeclaration(member)) && member.name !== undefined && propertyName(member.name) === name);
17346
+ return cls.members.some((member) => (ts7.isMethodDeclaration(member) || ts7.isGetAccessorDeclaration(member) || ts7.isSetAccessorDeclaration(member)) && member.name !== undefined && propertyName(member.name) === name);
16778
17347
  }
16779
17348
  function hasDestroyHook(cls) {
16780
17349
  return hasMethod(cls, "onDestroy") || hasMethod(cls, "ngOnDestroy");
16781
17350
  }
17351
+ function hasInitHook(cls) {
17352
+ return hasMethod(cls, "onInit");
17353
+ }
16782
17354
  function descendantsOfKind(root, predicate) {
16783
17355
  const result = [];
16784
17356
  const visit = (node) => {
16785
17357
  if (predicate(node))
16786
17358
  result.push(node);
16787
- ts4.forEachChild(node, visit);
17359
+ ts7.forEachChild(node, visit);
16788
17360
  };
16789
17361
  visit(root);
16790
17362
  return result;
@@ -16793,7 +17365,7 @@ async function analyzeProject(rootDir, include, cache, changedPaths) {
16793
17365
  const session = cache?.programSession ?? createIncrementalProgramSession(rootDir);
16794
17366
  if (cache)
16795
17367
  cache.programSession = session;
16796
- const rootNames = ts4.sys.readDirectory(rootDir, [".ts", ".tsx"], ["node_modules", "dist"], include ?? DEFAULT_INCLUDE);
17368
+ const rootNames = ts7.sys.readDirectory(rootDir, [".ts", ".tsx"], ["node_modules", "dist"], include ?? DEFAULT_INCLUDE);
16797
17369
  const update = session.update(rootNames, changedPaths);
16798
17370
  const program = update.program;
16799
17371
  const checker = program.getTypeChecker();
@@ -16829,7 +17401,7 @@ async function analyzeProject(rootDir, include, cache, changedPaths) {
16829
17401
  for (const sf of sourceFiles) {
16830
17402
  const traits = nativeTraitFiles.get(sf.fileName);
16831
17403
  if (!cache || traits?.has("module")) {
16832
- for (const cls of sf.statements.filter(ts4.isClassDeclaration)) {
17404
+ for (const cls of sf.statements.filter(ts7.isClassDeclaration)) {
16833
17405
  const moduleDec = findDecorator(cls, "Module");
16834
17406
  if (!moduleDec)
16835
17407
  continue;
@@ -16846,14 +17418,14 @@ async function analyzeProject(rootDir, include, cache, changedPaths) {
16846
17418
  }
16847
17419
  }
16848
17420
  if (!cache || traits?.has("defineModule") || traits?.has("defineFeatureSlice")) {
16849
- for (const call of descendantsOfKind(sf, ts4.isCallExpression)) {
17421
+ for (const call of descendantsOfKind(sf, ts7.isCallExpression)) {
16850
17422
  if (!["defineModule", "defineFeatureSlice"].includes(nodeText(call.expression)))
16851
17423
  continue;
16852
17424
  const parent = call.parent;
16853
- if (!parent || !ts4.isVariableDeclaration(parent))
17425
+ if (!parent || !ts7.isVariableDeclaration(parent))
16854
17426
  continue;
16855
17427
  const arg = call.arguments[0];
16856
- if (!arg || !ts4.isObjectLiteralExpression(arg))
17428
+ if (!arg || !ts7.isObjectLiteralExpression(arg))
16857
17429
  continue;
16858
17430
  candidates.push({
16859
17431
  node: parent,
@@ -16989,6 +17561,7 @@ async function analyzeProject(rootDir, include, cache, changedPaths) {
16989
17561
  ...functionalInjects.length > 0 ? { functionalInjects } : {},
16990
17562
  providedIn: "root",
16991
17563
  ...hasDestroyHook(classInfo.decl) ? { hasOnDestroy: true } : {},
17564
+ ...hasInitHook(classInfo.decl) ? { hasOnInit: true } : {},
16992
17565
  exported: true,
16993
17566
  file,
16994
17567
  line,
@@ -17000,7 +17573,7 @@ async function analyzeProject(rootDir, include, cache, changedPaths) {
17000
17573
  const controllerDec = findDecorator(classInfo.decl, "Controller");
17001
17574
  if (controllerDec) {
17002
17575
  const arg = decoratorArguments(controllerDec)[0];
17003
- const isStandalone = arg && ts4.isObjectLiteralExpression(arg) && booleanProp(arg, "standalone");
17576
+ const isStandalone = arg && ts7.isObjectLiteralExpression(arg) && booleanProp(arg, "standalone");
17004
17577
  if (isStandalone) {
17005
17578
  const ctrl = parseController(classInfo.decl, ctx);
17006
17579
  if (ctrl)
@@ -17160,16 +17733,16 @@ function collectModuleSourceClosure(module, ctx) {
17160
17733
  ownedFiles.add(relativeFile);
17161
17734
  for (const statement of sourceFile.statements) {
17162
17735
  let moduleName;
17163
- if (ts4.isImportDeclaration(statement) && ts4.isStringLiteral(statement.moduleSpecifier)) {
17736
+ if (ts7.isImportDeclaration(statement) && ts7.isStringLiteral(statement.moduleSpecifier)) {
17164
17737
  moduleName = statement.moduleSpecifier.text;
17165
- } else if (ts4.isExportDeclaration(statement) && statement.moduleSpecifier && ts4.isStringLiteral(statement.moduleSpecifier)) {
17738
+ } else if (ts7.isExportDeclaration(statement) && statement.moduleSpecifier && ts7.isStringLiteral(statement.moduleSpecifier)) {
17166
17739
  moduleName = statement.moduleSpecifier.text;
17167
- } else if (ts4.isImportEqualsDeclaration(statement) && ts4.isExternalModuleReference(statement.moduleReference) && ts4.isStringLiteral(statement.moduleReference.expression)) {
17740
+ } else if (ts7.isImportEqualsDeclaration(statement) && ts7.isExternalModuleReference(statement.moduleReference) && ts7.isStringLiteral(statement.moduleReference.expression)) {
17168
17741
  moduleName = statement.moduleReference.expression.text;
17169
17742
  }
17170
17743
  if (!moduleName || moduleName.startsWith("node:"))
17171
17744
  continue;
17172
- const resolved = ts4.resolveModuleName(moduleName, sourceFile.fileName, ctx.program.getCompilerOptions(), ts4.sys).resolvedModule?.resolvedFileName;
17745
+ const resolved = ts7.resolveModuleName(moduleName, sourceFile.fileName, ctx.program.getCompilerOptions(), ts7.sys).resolvedModule?.resolvedFileName;
17173
17746
  if (resolved && isProjectSourcePath(resolved, ctx.rootDir) && !enqueued.has(resolved)) {
17174
17747
  enqueued.add(resolved);
17175
17748
  queue.push(resolved);
@@ -17191,7 +17764,7 @@ function isProjectSourceFile(sourceFile, rootDir) {
17191
17764
  return isProjectSourcePath(sourceFile.fileName, rootDir) && /\.(tsx?|mts|cts)$/.test(sourceFile.fileName);
17192
17765
  }
17193
17766
  function indexFile(sf, ctx) {
17194
- for (const cls of sf.statements.filter(ts4.isClassDeclaration)) {
17767
+ for (const cls of sf.statements.filter(ts7.isClassDeclaration)) {
17195
17768
  const name = cls.name?.text;
17196
17769
  if (name && !ctx.classesByName.has(name)) {
17197
17770
  ctx.classesByName.set(name, { name, decl: cls, file: sf.fileName });
@@ -17199,9 +17772,9 @@ function indexFile(sf, ctx) {
17199
17772
  if (name)
17200
17773
  indexInfraResource(cls, name, sf, ctx);
17201
17774
  }
17202
- for (const statement of sf.statements.filter(ts4.isVariableStatement)) {
17775
+ for (const statement of sf.statements.filter(ts7.isVariableStatement)) {
17203
17776
  for (const decl of statement.declarationList.declarations) {
17204
- if (ts4.isIdentifier(decl.name) && !ctx.variablesByName.has(decl.name.text)) {
17777
+ if (ts7.isIdentifier(decl.name) && !ctx.variablesByName.has(decl.name.text)) {
17205
17778
  ctx.variablesByName.set(decl.name.text, decl);
17206
17779
  }
17207
17780
  const info = parseTokenVariable(decl, sf.fileName);
@@ -17213,16 +17786,16 @@ function indexFile(sf, ctx) {
17213
17786
  }
17214
17787
  function parseTokenVariable(decl, file) {
17215
17788
  const init = decl.initializer;
17216
- if (!init || !ts4.isNewExpression(init))
17789
+ if (!init || !ts7.isNewExpression(init))
17217
17790
  return;
17218
17791
  if (nodeText(init.expression) !== "InjectionToken")
17219
17792
  return;
17220
17793
  const [nameArg, optionsArg] = init.arguments ?? [];
17221
17794
  const info = { name: variableName(decl), file, line: lineOf(decl) };
17222
- if (nameArg && ts4.isStringLiteral(nameArg)) {
17795
+ if (nameArg && ts7.isStringLiteral(nameArg)) {
17223
17796
  info.stringName = nameArg.text;
17224
17797
  }
17225
- if (optionsArg && ts4.isObjectLiteralExpression(optionsArg)) {
17798
+ if (optionsArg && ts7.isObjectLiteralExpression(optionsArg)) {
17226
17799
  const scope = stringLiteralProp(optionsArg, "scope");
17227
17800
  if (scope && isScope(scope)) {
17228
17801
  info.scope = scope;
@@ -17242,23 +17815,23 @@ function parseModule(candidate, nameByNode, ctx) {
17242
17815
  const { options, className, file, line } = candidate;
17243
17816
  const name = nameByNode.get(candidate.node) ?? className;
17244
17817
  const featureSpec = parseFeatureSpec(getProp(options, "spec"), ctx);
17245
- const tags = arrayProp(options, "tags").map((el) => ts4.isStringLiteral(el) ? el.text : nodeText(el).replace(/['"]/g, "")).filter(Boolean);
17818
+ const tags = arrayProp(options, "tags").map((el) => ts7.isStringLiteral(el) ? el.text : nodeText(el).replace(/['"]/g, "")).filter(Boolean);
17246
17819
  const aspects = parseAspectRefs(getProp(options, "aspects"), ctx, `module ${name}`);
17247
17820
  const moduleResourceNames = parseModuleInfraResources(infraResourceProp(options, "resources", ctx), ctx, `module ${name}`, sourcePath(ctx.rootDir, file), line);
17248
17821
  const imports = arrayProp(options, "imports").map((el) => {
17249
17822
  const unwrapped = unwrapForwardRef(el);
17250
- const decl = ts4.isIdentifier(unwrapped) ? resolveDeclaration(unwrapped, ctx)[0] : undefined;
17823
+ const decl = ts7.isIdentifier(unwrapped) ? resolveDeclaration(unwrapped, ctx)[0] : undefined;
17251
17824
  if (decl) {
17252
17825
  const known = nameByNode.get(decl);
17253
17826
  if (known)
17254
17827
  return known;
17255
- if (ts4.isClassDeclaration(decl)) {
17828
+ if (ts7.isClassDeclaration(decl)) {
17256
17829
  const dec = findDecorator(decl, "Module");
17257
17830
  const decOptions = dec && decoratorObjectArg(dec);
17258
17831
  const decName = decOptions && stringLiteralProp(decOptions, "name");
17259
17832
  return decName ?? decl.name?.text ?? nodeText(el);
17260
17833
  }
17261
- if (ts4.isVariableDeclaration(decl))
17834
+ if (ts7.isVariableDeclaration(decl))
17262
17835
  return variableName(decl);
17263
17836
  }
17264
17837
  return nodeText(el);
@@ -17272,7 +17845,7 @@ function parseModule(candidate, nameByNode, ctx) {
17272
17845
  providers.push(...parsedProviders);
17273
17846
  continue;
17274
17847
  }
17275
- if (ts4.isCallExpression(el)) {
17848
+ if (ts7.isCallExpression(el)) {
17276
17849
  const helper = nodeText(el.expression).split(".").pop() ?? nodeText(el.expression);
17277
17850
  warn(ctx, "unsupported-provider-helper", `无法静态展开 provider helper '${helper}';请改用显式 Provider 或实现编译器支持的 helper`, sourcePath(ctx.rootDir, el.getSourceFile().fileName), lineOf(el));
17278
17851
  continue;
@@ -17282,10 +17855,10 @@ function parseModule(candidate, nameByNode, ctx) {
17282
17855
  providers.push(provider);
17283
17856
  }
17284
17857
  for (const el of arrayProp(options, "jobs")) {
17285
- if (!ts4.isIdentifier(el))
17858
+ if (!ts7.isIdentifier(el))
17286
17859
  continue;
17287
17860
  const decl = resolveDeclaration(el, ctx)[0];
17288
- if (!decl || !ts4.isClassDeclaration(decl))
17861
+ if (!decl || !ts7.isClassDeclaration(decl))
17289
17862
  continue;
17290
17863
  const className = decl.name?.text ?? el.text;
17291
17864
  const registeredProvider = providers.find((provider) => provider.token === className || provider.useClass === className);
@@ -17307,6 +17880,7 @@ function parseModule(candidate, nameByNode, ctx) {
17307
17880
  ...deps.hostDeps.length > 0 ? { hostDeps: deps.hostDeps } : {},
17308
17881
  ...deps.functionalInjects.length > 0 ? { functionalInjects: deps.functionalInjects } : {},
17309
17882
  ...hasDestroyHook(decl) ? { hasOnDestroy: true } : {},
17883
+ ...hasInitHook(decl) ? { hasOnInit: true } : {},
17310
17884
  exported: exportsSet.has(className),
17311
17885
  file: sourcePath(ctx.rootDir, decl.getSourceFile().fileName),
17312
17886
  line: lineOf(decl),
@@ -17322,18 +17896,18 @@ function parseModule(candidate, nameByNode, ctx) {
17322
17896
  const handlerClasses = [];
17323
17897
  const seenHandlers = new Set;
17324
17898
  const collectHandler = (expr) => {
17325
- if (!ts4.isIdentifier(expr))
17899
+ if (!ts7.isIdentifier(expr))
17326
17900
  return;
17327
17901
  const decl = resolveDeclaration(expr, ctx)[0];
17328
- if (decl && ts4.isClassDeclaration(decl) && !seenHandlers.has(decl.name?.text ?? "")) {
17902
+ if (decl && ts7.isClassDeclaration(decl) && !seenHandlers.has(decl.name?.text ?? "")) {
17329
17903
  seenHandlers.add(decl.name?.text ?? "");
17330
17904
  handlerClasses.push(decl);
17331
17905
  }
17332
17906
  };
17333
17907
  for (const el of arrayProp(options, "providers")) {
17334
- if (ts4.isIdentifier(el))
17908
+ if (ts7.isIdentifier(el))
17335
17909
  collectHandler(el);
17336
- if (ts4.isObjectLiteralExpression(el)) {
17910
+ if (ts7.isObjectLiteralExpression(el)) {
17337
17911
  const useClass = getProp(el, "useClass");
17338
17912
  if (useClass)
17339
17913
  collectHandler(useClass);
@@ -17442,17 +18016,17 @@ function parseFeatureSpec(input, ctx, seen = new Set) {
17442
18016
  if (seen.has(input))
17443
18017
  return;
17444
18018
  seen.add(input);
17445
- if (ts4.isIdentifier(input)) {
17446
- const local = input.getSourceFile().statements.flatMap((statement) => ts4.isVariableStatement(statement) ? [...statement.declarationList.declarations] : []);
18019
+ if (ts7.isIdentifier(input)) {
18020
+ const local = input.getSourceFile().statements.flatMap((statement) => ts7.isVariableStatement(statement) ? [...statement.declarationList.declarations] : []);
17447
18021
  const resolved = resolveDeclaration(input, ctx)[0];
17448
- const decl = (resolved && ts4.isVariableDeclaration(resolved) ? resolved : undefined) ?? ctx.variablesByName.get(input.text) ?? local.find((candidate) => ts4.isIdentifier(candidate.name) && candidate.name.text === input.text) ?? descendantsOfKind(input.getSourceFile(), ts4.isVariableDeclaration).find((candidate) => ts4.isIdentifier(candidate.name) && candidate.name.text === input.text);
17449
- if (decl && ts4.isVariableDeclaration(decl))
18022
+ const decl = (resolved && ts7.isVariableDeclaration(resolved) ? resolved : undefined) ?? ctx.variablesByName.get(input.text) ?? local.find((candidate) => ts7.isIdentifier(candidate.name) && candidate.name.text === input.text) ?? descendantsOfKind(input.getSourceFile(), ts7.isVariableDeclaration).find((candidate) => ts7.isIdentifier(candidate.name) && candidate.name.text === input.text);
18023
+ if (decl && ts7.isVariableDeclaration(decl))
17450
18024
  return parseFeatureSpec(decl.initializer, ctx, seen);
17451
18025
  }
17452
- if (ts4.isCallExpression(input) && nodeText(input.expression) === "defineFeatureSpec") {
18026
+ if (ts7.isCallExpression(input) && nodeText(input.expression) === "defineFeatureSpec") {
17453
18027
  return parseFeatureSpec(input.arguments[0], ctx, seen);
17454
18028
  }
17455
- if (ts4.isAsExpression(input) || ts4.isSatisfiesExpression(input) || ts4.isParenthesizedExpression(input)) {
18029
+ if (ts7.isAsExpression(input) || ts7.isSatisfiesExpression(input) || ts7.isParenthesizedExpression(input)) {
17456
18030
  return parseFeatureSpec(input.expression, ctx, seen);
17457
18031
  }
17458
18032
  const invalid = () => {
@@ -17465,28 +18039,28 @@ function parseFeatureSpec(input, ctx, seen = new Set) {
17465
18039
  });
17466
18040
  return;
17467
18041
  };
17468
- if (!ts4.isObjectLiteralExpression(input))
18042
+ if (!ts7.isObjectLiteralExpression(input))
17469
18043
  return invalid();
17470
18044
  const name = stringLiteralProp(input, "name");
17471
18045
  const statesExpr = getProp(input, "states");
17472
18046
  const transitionObject = getProp(input, "transitions");
17473
- if (!name || !statesExpr || !ts4.isArrayLiteralExpression(statesExpr) || statesExpr.elements.some((state) => !ts4.isStringLiteral(state)) || !transitionObject || !ts4.isObjectLiteralExpression(transitionObject) || input.properties.some((property) => !ts4.isPropertyAssignment(property))) {
18047
+ if (!name || !statesExpr || !ts7.isArrayLiteralExpression(statesExpr) || statesExpr.elements.some((state) => !ts7.isStringLiteral(state)) || !transitionObject || !ts7.isObjectLiteralExpression(transitionObject) || input.properties.some((property) => !ts7.isPropertyAssignment(property))) {
17474
18048
  return invalid();
17475
18049
  }
17476
18050
  const states = [];
17477
18051
  for (const state of statesExpr.elements) {
17478
- if (!ts4.isStringLiteral(state))
18052
+ if (!ts7.isStringLiteral(state))
17479
18053
  return invalid();
17480
18054
  states.push(state.text);
17481
18055
  }
17482
18056
  const transitions = [];
17483
18057
  for (const property of transitionObject.properties) {
17484
- if (!ts4.isPropertyAssignment(property) || ts4.isComputedPropertyName(property.name) || !ts4.isObjectLiteralExpression(property.initializer))
18058
+ if (!ts7.isPropertyAssignment(property) || ts7.isComputedPropertyName(property.name) || !ts7.isObjectLiteralExpression(property.initializer))
17485
18059
  return invalid();
17486
18060
  const options = property.initializer;
17487
18061
  const from = stringLiteralProp(options, "from");
17488
18062
  const to = stringLiteralProp(options, "to");
17489
- if (!from || !to || options.properties.some((prop) => !ts4.isPropertyAssignment(prop)) || ["permission", "command", "route", "audit"].some((key) => getProp(options, key) && !stringLiteralProp(options, key)) || ["transaction", "idempotency"].some((key) => getProp(options, key) && !commandModeProp(options, key))) {
18063
+ if (!from || !to || options.properties.some((prop) => !ts7.isPropertyAssignment(prop)) || ["permission", "command", "route", "audit"].some((key) => getProp(options, key) && !stringLiteralProp(options, key)) || ["transaction", "idempotency"].some((key) => getProp(options, key) && !commandModeProp(options, key))) {
17490
18064
  return invalid();
17491
18065
  }
17492
18066
  const permission = stringLiteralProp(options, "permission");
@@ -17513,21 +18087,21 @@ function resolveStaticObjectLiteral(input, ctx, seen = new Set) {
17513
18087
  if (!input || seen.has(input))
17514
18088
  return;
17515
18089
  seen.add(input);
17516
- if (ts4.isAsExpression(input) || ts4.isSatisfiesExpression(input) || ts4.isParenthesizedExpression(input)) {
18090
+ if (ts7.isAsExpression(input) || ts7.isSatisfiesExpression(input) || ts7.isParenthesizedExpression(input)) {
17517
18091
  return resolveStaticObjectLiteral(input.expression, ctx, seen);
17518
18092
  }
17519
- if (ts4.isIdentifier(input)) {
17520
- const declaration = resolveDeclaration(input, ctx).find(ts4.isVariableDeclaration);
18093
+ if (ts7.isIdentifier(input)) {
18094
+ const declaration = resolveDeclaration(input, ctx).find(ts7.isVariableDeclaration);
17521
18095
  return declaration?.initializer ? resolveStaticObjectLiteral(declaration.initializer, ctx, seen) : undefined;
17522
18096
  }
17523
- if (ts4.isCallExpression(input)) {
18097
+ if (ts7.isCallExpression(input)) {
17524
18098
  const expressionName = nodeText(input.expression);
17525
18099
  if (expressionName === "defineRouteContract" || expressionName.endsWith(".defineRouteContract")) {
17526
18100
  return resolveStaticObjectLiteral(input.arguments[0], ctx, seen);
17527
18101
  }
17528
18102
  return;
17529
18103
  }
17530
- return ts4.isObjectLiteralExpression(input) ? input : undefined;
18104
+ return ts7.isObjectLiteralExpression(input) ? input : undefined;
17531
18105
  }
17532
18106
  function routePolicyProperty(object, name, ctx, seen = new Set) {
17533
18107
  if (seen.has(object))
@@ -17535,15 +18109,15 @@ function routePolicyProperty(object, name, ctx, seen = new Set) {
17535
18109
  const ancestry = new Set(seen).add(object);
17536
18110
  let result = { unresolved: false };
17537
18111
  for (const property of object.properties) {
17538
- if (ts4.isSpreadAssignment(property)) {
18112
+ if (ts7.isSpreadAssignment(property)) {
17539
18113
  const spread = resolveStaticObjectLiteral(property.expression, ctx);
17540
18114
  const nested = spread ? routePolicyProperty(spread, name, ctx, ancestry) : { unresolved: true };
17541
18115
  if (nested.unresolved || nested.value !== undefined)
17542
18116
  result = nested;
17543
- } else if (ts4.isComputedPropertyName(property.name)) {
18117
+ } else if (ts7.isComputedPropertyName(property.name)) {
17544
18118
  result = { unresolved: true };
17545
18119
  } else if (propertyName(property.name) === name) {
17546
- result = ts4.isPropertyAssignment(property) ? { value: property.initializer, unresolved: false } : { unresolved: true };
18120
+ result = ts7.isPropertyAssignment(property) ? { value: property.initializer, unresolved: false } : { unresolved: true };
17547
18121
  }
17548
18122
  }
17549
18123
  return result;
@@ -17581,9 +18155,9 @@ function parseProvider(el, exportsSet, ctx) {
17581
18155
  const file = sourcePath(ctx.rootDir, el.getSourceFile().fileName);
17582
18156
  const line = lineOf(el);
17583
18157
  const unwrappedEl = unwrapForwardRef(el);
17584
- if (ts4.isIdentifier(unwrappedEl)) {
18158
+ if (ts7.isIdentifier(unwrappedEl)) {
17585
18159
  const decl = resolveDeclaration(unwrappedEl, ctx)[0];
17586
- const cls = decl && ts4.isClassDeclaration(decl) ? decl : undefined;
18160
+ const cls = decl && ts7.isClassDeclaration(decl) ? decl : undefined;
17587
18161
  const className = cls?.name?.text ?? unwrappedEl.text;
17588
18162
  const { deps, optionalDeps, selfDeps, skipSelfDeps, hostDeps, functionalInjects, missing } = cls ? classDeps(cls, ctx) : { deps: [], optionalDeps: [], selfDeps: [], skipSelfDeps: [], hostDeps: [], functionalInjects: [], missing: false };
17589
18163
  const injectable = cls ? parseInjectableOptions(cls, ctx) : undefined;
@@ -17604,13 +18178,14 @@ function parseProvider(el, exportsSet, ctx) {
17604
18178
  ...functionalInjects.length > 0 ? { functionalInjects } : {},
17605
18179
  ...injectable?.providedIn ? { providedIn: injectable.providedIn } : {},
17606
18180
  ...cls && hasDestroyHook(cls) ? { hasOnDestroy: true } : {},
18181
+ ...cls && hasInitHook(cls) ? { hasOnInit: true } : {},
17607
18182
  exported: exportsSet.has(className),
17608
18183
  file,
17609
18184
  line,
17610
18185
  ...cls ? { importPath: modulePath(ctx.rootDir, cls.getSourceFile().fileName) } : {}
17611
18186
  };
17612
18187
  }
17613
- if (!ts4.isObjectLiteralExpression(el))
18188
+ if (!ts7.isObjectLiteralExpression(el))
17614
18189
  return;
17615
18190
  const provideExpr = getProp(el, "provide");
17616
18191
  if (!provideExpr)
@@ -17625,8 +18200,8 @@ function parseProvider(el, exportsSet, ctx) {
17625
18200
  const useExistingExpr = getProp(el, "useExisting");
17626
18201
  if (useClassExpr) {
17627
18202
  const unwrappedClass = unwrapForwardRef(useClassExpr);
17628
- const decl = ts4.isIdentifier(unwrappedClass) ? resolveDeclaration(unwrappedClass, ctx)[0] : undefined;
17629
- const cls = decl && ts4.isClassDeclaration(decl) ? decl : undefined;
18203
+ const decl = ts7.isIdentifier(unwrappedClass) ? resolveDeclaration(unwrappedClass, ctx)[0] : undefined;
18204
+ const cls = decl && ts7.isClassDeclaration(decl) ? decl : undefined;
17630
18205
  const useClass = cls?.name?.text ?? nodeText(unwrappedClass);
17631
18206
  let deps = explicitDeps;
17632
18207
  let optionalDeps = [];
@@ -17674,6 +18249,7 @@ function parseProvider(el, exportsSet, ctx) {
17674
18249
  ...multi === undefined ? {} : { multi },
17675
18250
  ...injectable?.providedIn ? { providedIn: injectable.providedIn } : {},
17676
18251
  ...cls && hasMethod(cls, "onDestroy") ? { hasOnDestroy: true } : {},
18252
+ ...cls && hasInitHook(cls) ? { hasOnInit: true } : {},
17677
18253
  exported: exportsSet.has(token),
17678
18254
  file,
17679
18255
  line,
@@ -17682,7 +18258,7 @@ function parseProvider(el, exportsSet, ctx) {
17682
18258
  }
17683
18259
  if (useValueExpr) {
17684
18260
  validateProviderCompatibility(provideExpr, useValueExpr, "value", token, ctx, file, line);
17685
- const importPath = ts4.isIdentifier(useValueExpr) ? importPathOf(useValueExpr, ctx) : undefined;
18261
+ const importPath = ts7.isIdentifier(useValueExpr) ? importPathOf(useValueExpr, ctx) : undefined;
17686
18262
  return {
17687
18263
  token,
17688
18264
  tokenKind,
@@ -17698,12 +18274,12 @@ function parseProvider(el, exportsSet, ctx) {
17698
18274
  };
17699
18275
  }
17700
18276
  if (useFactoryExpr) {
17701
- const factoryName = ts4.isIdentifier(useFactoryExpr) ? (() => {
18277
+ const factoryName = ts7.isIdentifier(useFactoryExpr) ? (() => {
17702
18278
  const decl = resolveDeclaration(useFactoryExpr, ctx)[0];
17703
- return decl && (ts4.isFunctionDeclaration(decl) || ts4.isVariableDeclaration(decl)) ? (ts4.isFunctionDeclaration(decl) ? decl.name?.text : variableName(decl)) ?? useFactoryExpr.text : useFactoryExpr.text;
18279
+ return decl && (ts7.isFunctionDeclaration(decl) || ts7.isVariableDeclaration(decl)) ? (ts7.isFunctionDeclaration(decl) ? decl.name?.text : variableName(decl)) ?? useFactoryExpr.text : useFactoryExpr.text;
17704
18280
  })() : nodeText(useFactoryExpr);
17705
18281
  validateProviderCompatibility(provideExpr, useFactoryExpr, "factory", token, ctx, file, line);
17706
- const importPath = ts4.isIdentifier(useFactoryExpr) ? importPathOf(useFactoryExpr, ctx) : undefined;
18282
+ const importPath = ts7.isIdentifier(useFactoryExpr) ? importPathOf(useFactoryExpr, ctx) : undefined;
17707
18283
  return {
17708
18284
  token,
17709
18285
  tokenKind,
@@ -17739,20 +18315,20 @@ function parseProvider(el, exportsSet, ctx) {
17739
18315
  function expandProviderExpressions(expressions, ctx, seen = new Set) {
17740
18316
  const result = [];
17741
18317
  for (const expression of expressions) {
17742
- if (ts4.isSpreadElement(expression)) {
18318
+ if (ts7.isSpreadElement(expression)) {
17743
18319
  result.push(...expandProviderExpressions([expression.expression], ctx, seen));
17744
18320
  continue;
17745
18321
  }
17746
- if (ts4.isIdentifier(expression)) {
18322
+ if (ts7.isIdentifier(expression)) {
17747
18323
  const declaration = resolveDeclaration(expression, ctx)[0];
17748
- if (declaration && ts4.isVariableDeclaration(declaration) && declaration.initializer) {
18324
+ if (declaration && ts7.isVariableDeclaration(declaration) && declaration.initializer) {
17749
18325
  const key = `${declaration.getSourceFile().fileName}:${declaration.pos}`;
17750
18326
  if (seen.has(key))
17751
18327
  continue;
17752
18328
  const initializer = declaration.initializer;
17753
- if (ts4.isCallExpression(initializer) && isProviderHelper(initializer, "makeEnvironmentProviders")) {
18329
+ if (ts7.isCallExpression(initializer) && isProviderHelper(initializer, "makeEnvironmentProviders")) {
17754
18330
  const nested = initializer.arguments[0];
17755
- if (nested && ts4.isArrayLiteralExpression(nested)) {
18331
+ if (nested && ts7.isArrayLiteralExpression(nested)) {
17756
18332
  seen.add(key);
17757
18333
  result.push(...expandProviderExpressions([...nested.elements], ctx, seen));
17758
18334
  seen.delete(key);
@@ -17761,9 +18337,9 @@ function expandProviderExpressions(expressions, ctx, seen = new Set) {
17761
18337
  }
17762
18338
  }
17763
18339
  }
17764
- if (ts4.isCallExpression(expression) && isProviderHelper(expression, "makeEnvironmentProviders")) {
18340
+ if (ts7.isCallExpression(expression) && isProviderHelper(expression, "makeEnvironmentProviders")) {
17765
18341
  const nested = expression.arguments[0];
17766
- if (nested && ts4.isArrayLiteralExpression(nested)) {
18342
+ if (nested && ts7.isArrayLiteralExpression(nested)) {
17767
18343
  result.push(...expandProviderExpressions([...nested.elements], ctx, seen));
17768
18344
  continue;
17769
18345
  }
@@ -17776,7 +18352,7 @@ function isProviderHelper(expression, name) {
17776
18352
  return nodeText(expression.expression).split(".").pop() === name;
17777
18353
  }
17778
18354
  function parseFunctionalProvider(expression, exportsSet, ctx) {
17779
- if (!ts4.isCallExpression(expression))
18355
+ if (!ts7.isCallExpression(expression))
17780
18356
  return;
17781
18357
  const helper = nodeText(expression.expression).split(".").pop();
17782
18358
  const args = expression.arguments;
@@ -17789,7 +18365,7 @@ function parseFunctionalProvider(expression, exportsSet, ctx) {
17789
18365
  return [];
17790
18366
  const { name: token, kind: tokenKind } = tokenNameOf(tokenExpr, ctx);
17791
18367
  validateProviderCompatibility(tokenExpr, valueExpr, "value", token, ctx, file, line);
17792
- const importPath = ts4.isIdentifier(valueExpr) ? importPathOf(valueExpr, ctx) : undefined;
18368
+ const importPath = ts7.isIdentifier(valueExpr) ? importPathOf(valueExpr, ctx) : undefined;
17793
18369
  return [{
17794
18370
  token,
17795
18371
  tokenKind,
@@ -17808,7 +18384,7 @@ function parseFunctionalProvider(expression, exportsSet, ctx) {
17808
18384
  if (!initializer)
17809
18385
  return [];
17810
18386
  const token = helper === "provideAppInitializer" ? "APP_INITIALIZER" : "ENVIRONMENT_INITIALIZER";
17811
- const importPath = ts4.isIdentifier(initializer) ? importPathOf(initializer, ctx) : undefined;
18387
+ const importPath = ts7.isIdentifier(initializer) ? importPathOf(initializer, ctx) : undefined;
17812
18388
  return [{
17813
18389
  token,
17814
18390
  tokenKind: "injection-token",
@@ -17827,7 +18403,7 @@ function parseFunctionalProvider(expression, exportsSet, ctx) {
17827
18403
  const providers = [];
17828
18404
  const routes = args[0];
17829
18405
  if (routes) {
17830
- const importPath = ts4.isIdentifier(routes) ? importPathOf(routes, ctx) : undefined;
18406
+ const importPath = ts7.isIdentifier(routes) ? importPathOf(routes, ctx) : undefined;
17831
18407
  providers.push({
17832
18408
  token: "ROUTE_CONFIG",
17833
18409
  tokenKind: "injection-token",
@@ -17842,7 +18418,7 @@ function parseFunctionalProvider(expression, exportsSet, ctx) {
17842
18418
  });
17843
18419
  }
17844
18420
  for (const feature of args.slice(1)) {
17845
- if (!ts4.isCallExpression(feature))
18421
+ if (!ts7.isCallExpression(feature))
17846
18422
  continue;
17847
18423
  const featureName = nodeText(feature.expression).split(".").pop();
17848
18424
  if (featureName === "withRouterConfig" && feature.arguments[0]) {
@@ -17859,8 +18435,8 @@ function parseFunctionalProvider(expression, exportsSet, ctx) {
17859
18435
  });
17860
18436
  } else if (featureName === "withTitleStrategy" && feature.arguments[0]) {
17861
18437
  const strategy = feature.arguments[0];
17862
- const isClass = ts4.isIdentifier(strategy) && Boolean(resolveDeclaration(strategy, ctx).find((declaration) => ts4.isClassDeclaration(declaration)));
17863
- const importPath = ts4.isIdentifier(strategy) ? importPathOf(strategy, ctx) : undefined;
18438
+ const isClass = ts7.isIdentifier(strategy) && Boolean(resolveDeclaration(strategy, ctx).find((declaration) => ts7.isClassDeclaration(declaration)));
18439
+ const importPath = ts7.isIdentifier(strategy) ? importPathOf(strategy, ctx) : undefined;
17864
18440
  providers.push({
17865
18441
  token: "TITLE_STRATEGY",
17866
18442
  tokenKind: "injection-token",
@@ -17892,14 +18468,14 @@ function parseFunctionalProvider(expression, exportsSet, ctx) {
17892
18468
  importModule: "@supacloud/app"
17893
18469
  }];
17894
18470
  for (const feature of args) {
17895
- if (!ts4.isCallExpression(feature))
18471
+ if (!ts7.isCallExpression(feature))
17896
18472
  continue;
17897
18473
  const featureName = nodeText(feature.expression).split(".").pop();
17898
18474
  if (featureName === "withInterceptors") {
17899
18475
  for (const interceptorArg of feature.arguments) {
17900
- const values = ts4.isArrayLiteralExpression(interceptorArg) ? [...interceptorArg.elements] : [interceptorArg];
18476
+ const values = ts7.isArrayLiteralExpression(interceptorArg) ? [...interceptorArg.elements] : [interceptorArg];
17901
18477
  for (const value of values) {
17902
- const importPath = ts4.isIdentifier(value) ? importPathOf(value, ctx) : undefined;
18478
+ const importPath = ts7.isIdentifier(value) ? importPathOf(value, ctx) : undefined;
17903
18479
  providers.push({
17904
18480
  token: "HTTP_INTERCEPTORS",
17905
18481
  tokenKind: "injection-token",
@@ -17946,9 +18522,9 @@ function providerTokenValueType(expr, ctx) {
17946
18522
  const typeArguments = typeArgumentsOf(type, ctx);
17947
18523
  if (typeArguments.length > 0)
17948
18524
  return typeArguments[0];
17949
- if (ts4.isIdentifier(expr)) {
18525
+ if (ts7.isIdentifier(expr)) {
17950
18526
  const declaration = resolveDeclaration(expr, ctx)[0];
17951
- if (declaration && ts4.isClassDeclaration(declaration)) {
18527
+ if (declaration && ts7.isClassDeclaration(declaration)) {
17952
18528
  return declaredClassType(declaration, ctx);
17953
18529
  }
17954
18530
  }
@@ -17956,9 +18532,9 @@ function providerTokenValueType(expr, ctx) {
17956
18532
  }
17957
18533
  function providerImplementationType(expr, kind, ctx) {
17958
18534
  if (kind === "class" || kind === "existing") {
17959
- if (ts4.isIdentifier(expr)) {
18535
+ if (ts7.isIdentifier(expr)) {
17960
18536
  const declaration = resolveDeclaration(expr, ctx)[0];
17961
- if (declaration && ts4.isClassDeclaration(declaration)) {
18537
+ if (declaration && ts7.isClassDeclaration(declaration)) {
17962
18538
  return declaredClassType(declaration, ctx);
17963
18539
  }
17964
18540
  }
@@ -17968,7 +18544,7 @@ function providerImplementationType(expr, kind, ctx) {
17968
18544
  }
17969
18545
  if (kind === "factory") {
17970
18546
  const type = ctx.checker.getTypeAtLocation(expr);
17971
- const signature = ctx.checker.getSignaturesOfType(type, ts4.SignatureKind.Call)[0];
18547
+ const signature = ctx.checker.getSignaturesOfType(type, ts7.SignatureKind.Call)[0];
17972
18548
  return signature?.getReturnType();
17973
18549
  }
17974
18550
  return ctx.checker.getTypeAtLocation(expr);
@@ -17987,16 +18563,16 @@ function isTypeReference(type) {
17987
18563
  return "target" in type;
17988
18564
  }
17989
18565
  function isUnknownOrAny(type) {
17990
- return (type.flags & (ts4.TypeFlags.Any | ts4.TypeFlags.Unknown)) !== 0;
18566
+ return (type.flags & (ts7.TypeFlags.Any | ts7.TypeFlags.Unknown)) !== 0;
17991
18567
  }
17992
18568
  function parseController(input, ctx) {
17993
18569
  let decl;
17994
- if (ts4.isClassDeclaration(input)) {
18570
+ if (ts7.isClassDeclaration(input)) {
17995
18571
  decl = input;
17996
18572
  } else {
17997
18573
  const unwrapped = unwrapForwardRef(input);
17998
- const resolved = ts4.isIdentifier(unwrapped) ? resolveDeclaration(unwrapped, ctx)[0] : undefined;
17999
- if (resolved && ts4.isClassDeclaration(resolved)) {
18574
+ const resolved = ts7.isIdentifier(unwrapped) ? resolveDeclaration(unwrapped, ctx)[0] : undefined;
18575
+ if (resolved && ts7.isClassDeclaration(resolved)) {
18000
18576
  decl = resolved;
18001
18577
  }
18002
18578
  }
@@ -18009,9 +18585,9 @@ function parseController(input, ctx) {
18009
18585
  let standalone;
18010
18586
  const pathArg = decoratorArguments(controllerDec)[0];
18011
18587
  if (pathArg) {
18012
- if (ts4.isStringLiteral(pathArg)) {
18588
+ if (ts7.isStringLiteral(pathArg)) {
18013
18589
  path = pathArg.text;
18014
- } else if (ts4.isObjectLiteralExpression(pathArg)) {
18590
+ } else if (ts7.isObjectLiteralExpression(pathArg)) {
18015
18591
  const p = stringLiteralProp(pathArg, "path");
18016
18592
  if (p)
18017
18593
  path = p;
@@ -18034,7 +18610,7 @@ function parseController(input, ctx) {
18034
18610
  }
18035
18611
  }
18036
18612
  }
18037
- for (const method of decl.members.filter(ts4.isMethodDeclaration)) {
18613
+ for (const method of decl.members.filter(ts7.isMethodDeclaration)) {
18038
18614
  for (const dec of decoratorsOf(method)) {
18039
18615
  const name = decoratorName2(dec);
18040
18616
  const httpMethod = name ? ROUTE_DECORATORS[name] : undefined;
@@ -18042,7 +18618,7 @@ function parseController(input, ctx) {
18042
18618
  continue;
18043
18619
  const args = decoratorArguments(dec);
18044
18620
  const pathArg = args[0];
18045
- const routePath = pathArg && ts4.isStringLiteral(pathArg) ? pathArg.text : "/";
18621
+ const routePath = pathArg && ts7.isStringLiteral(pathArg) ? pathArg.text : "/";
18046
18622
  const route = {
18047
18623
  method: httpMethod,
18048
18624
  path: routePath,
@@ -18116,12 +18692,12 @@ function parseController(input, ctx) {
18116
18692
  } else if (dName === "Headers") {
18117
18693
  hasBindingDecorator = true;
18118
18694
  const argument = dArgs[0];
18119
- const bindingName = argument !== undefined && ts4.isStringLiteral(argument) ? argument.text : undefined;
18695
+ const bindingName = argument !== undefined && ts7.isStringLiteral(argument) ? argument.text : undefined;
18120
18696
  paramNode = { name: pName, kind: "headers", ...bindingName === undefined ? {} : { bindingName } };
18121
18697
  } else if (dName === "Cookie") {
18122
18698
  hasBindingDecorator = true;
18123
18699
  const argument = dArgs[0];
18124
- const bindingName = argument !== undefined && ts4.isStringLiteral(argument) ? argument.text : undefined;
18700
+ const bindingName = argument !== undefined && ts7.isStringLiteral(argument) ? argument.text : undefined;
18125
18701
  paramNode = { name: pName, kind: "cookie", ...bindingName === undefined ? {} : { bindingName } };
18126
18702
  }
18127
18703
  }
@@ -18183,20 +18759,20 @@ function parseController(input, ctx) {
18183
18759
  }
18184
18760
  } else if (dName === "Title") {
18185
18761
  const tArg = mArgs[0];
18186
- if (tArg && ts4.isStringLiteral(tArg)) {
18762
+ if (tArg && ts7.isStringLiteral(tArg)) {
18187
18763
  route.title = tArg.text;
18188
18764
  }
18189
18765
  } else if (dName === "Data") {
18190
18766
  const dArg = mArgs[0];
18191
- if (dArg && ts4.isObjectLiteralExpression(dArg)) {
18767
+ if (dArg && ts7.isObjectLiteralExpression(dArg)) {
18192
18768
  route.data = { ...route.data, ...parseObjectLiteralValues(dArg) };
18193
18769
  }
18194
18770
  } else if (dName === "Resolve") {
18195
18771
  const rArg = mArgs[0];
18196
- if (rArg && ts4.isObjectLiteralExpression(rArg)) {
18772
+ if (rArg && ts7.isObjectLiteralExpression(rArg)) {
18197
18773
  const resolvers = route.resolvers ?? {};
18198
18774
  for (const prop of rArg.properties) {
18199
- if (ts4.isPropertyAssignment(prop)) {
18775
+ if (ts7.isPropertyAssignment(prop)) {
18200
18776
  const rName = propertyName(prop.name);
18201
18777
  const init = prop.initializer;
18202
18778
  if (init)
@@ -18224,7 +18800,7 @@ function parseController(input, ctx) {
18224
18800
  }
18225
18801
  const parse = parsePolicy.value;
18226
18802
  if (parse) {
18227
- if (ts4.isStringLiteral(parse) && parse.text === "none")
18803
+ if (ts7.isStringLiteral(parse) && parse.text === "none")
18228
18804
  route.parse = "none";
18229
18805
  else
18230
18806
  ctx.diagnostics.push({
@@ -18236,7 +18812,7 @@ function parseController(input, ctx) {
18236
18812
  }
18237
18813
  const allowDeleteBody = deletePolicy.value;
18238
18814
  if (allowDeleteBody) {
18239
- if (allowDeleteBody.kind === ts4.SyntaxKind.TrueKeyword)
18815
+ if (allowDeleteBody.kind === ts7.SyntaxKind.TrueKeyword)
18240
18816
  route.allowDeleteBody = true;
18241
18817
  else
18242
18818
  ctx.diagnostics.push({
@@ -18261,7 +18837,7 @@ function parseController(input, ctx) {
18261
18837
  });
18262
18838
  }
18263
18839
  const contract = getProp(optionsObject, "contract");
18264
- if (contract && ts4.isObjectLiteralExpression(contract)) {
18840
+ if (contract && ts7.isObjectLiteralExpression(contract)) {
18265
18841
  route.contract = {};
18266
18842
  for (const field of ["body", "response", "evidence"]) {
18267
18843
  const value = stringLiteralProp(contract, field);
@@ -18279,7 +18855,7 @@ function parseController(input, ctx) {
18279
18855
  }
18280
18856
  for (const field of ["body", "params", "query", "headers", "cookie", "response"]) {
18281
18857
  const schemaExpr = getProp(optionsObject, field);
18282
- if (schemaExpr && ts4.isIdentifier(schemaExpr)) {
18858
+ if (schemaExpr && ts7.isIdentifier(schemaExpr)) {
18283
18859
  route[field] = nodeText(schemaExpr);
18284
18860
  const importPath = importPathOf(schemaExpr, ctx);
18285
18861
  if (importPath)
@@ -18294,7 +18870,7 @@ function parseController(input, ctx) {
18294
18870
  const responses = {};
18295
18871
  const selectors = new Map;
18296
18872
  for (const property of responsesObject.properties) {
18297
- if (!ts4.isPropertyAssignment(property) || ts4.isComputedPropertyName(property.name))
18873
+ if (!ts7.isPropertyAssignment(property) || ts7.isComputedPropertyName(property.name))
18298
18874
  continue;
18299
18875
  const status = propertyName(property.name);
18300
18876
  if (!isRouteResponseSelector(status)) {
@@ -18326,7 +18902,7 @@ function parseController(input, ctx) {
18326
18902
  }
18327
18903
  selectors.set(canonical, status);
18328
18904
  const schemaExpr = property.initializer;
18329
- if (!ts4.isIdentifier(schemaExpr)) {
18905
+ if (!ts7.isIdentifier(schemaExpr)) {
18330
18906
  ctx.diagnostics.push({
18331
18907
  severity: "error",
18332
18908
  code: "invalid-route-response-map",
@@ -18348,18 +18924,18 @@ function parseController(input, ctx) {
18348
18924
  route.responses = responses;
18349
18925
  }
18350
18926
  const commandExpr = getProp(optionsObject, "command");
18351
- if (commandExpr && ts4.isIdentifier(commandExpr)) {
18927
+ if (commandExpr && ts7.isIdentifier(commandExpr)) {
18352
18928
  const commandDecl = resolveDeclaration(commandExpr, ctx)[0];
18353
- route.command = commandDecl && ts4.isClassDeclaration(commandDecl) ? commandDecl.name?.text ?? commandExpr.text : commandExpr.text;
18929
+ route.command = commandDecl && ts7.isClassDeclaration(commandDecl) ? commandDecl.name?.text ?? commandExpr.text : commandExpr.text;
18354
18930
  }
18355
18931
  const guardsExpr = getProp(optionsObject, "guards");
18356
- if (guardsExpr && ts4.isArrayLiteralExpression(guardsExpr)) {
18932
+ if (guardsExpr && ts7.isArrayLiteralExpression(guardsExpr)) {
18357
18933
  for (const el of guardsExpr.elements) {
18358
18934
  routeGuards.push(tokenText(el, ctx));
18359
18935
  }
18360
18936
  }
18361
18937
  const canMatchExpr = getProp(optionsObject, "canMatch");
18362
- if (canMatchExpr && ts4.isArrayLiteralExpression(canMatchExpr)) {
18938
+ if (canMatchExpr && ts7.isArrayLiteralExpression(canMatchExpr)) {
18363
18939
  const canMatchList = [];
18364
18940
  for (const el of canMatchExpr.elements) {
18365
18941
  canMatchList.push(tokenText(el, ctx));
@@ -18369,16 +18945,16 @@ function parseController(input, ctx) {
18369
18945
  }
18370
18946
  }
18371
18947
  const canDeactivateExpr = getProp(optionsObject, "canDeactivate");
18372
- if (canDeactivateExpr && ts4.isArrayLiteralExpression(canDeactivateExpr)) {
18948
+ if (canDeactivateExpr && ts7.isArrayLiteralExpression(canDeactivateExpr)) {
18373
18949
  for (const el of canDeactivateExpr.elements) {
18374
18950
  routeCanDeactivate.push(tokenText(el, ctx));
18375
18951
  }
18376
18952
  }
18377
18953
  const resolversExpr = getProp(optionsObject, "resolvers");
18378
- if (resolversExpr && ts4.isObjectLiteralExpression(resolversExpr)) {
18954
+ if (resolversExpr && ts7.isObjectLiteralExpression(resolversExpr)) {
18379
18955
  const resolvers = {};
18380
18956
  for (const prop of resolversExpr.properties) {
18381
- if (ts4.isPropertyAssignment(prop)) {
18957
+ if (ts7.isPropertyAssignment(prop)) {
18382
18958
  const rName = propertyName(prop.name);
18383
18959
  const init = prop.initializer;
18384
18960
  if (init)
@@ -18390,22 +18966,22 @@ function parseController(input, ctx) {
18390
18966
  }
18391
18967
  }
18392
18968
  const redirectToExpr = getProp(optionsObject, "redirectTo");
18393
- if (redirectToExpr && ts4.isStringLiteral(redirectToExpr)) {
18969
+ if (redirectToExpr && ts7.isStringLiteral(redirectToExpr)) {
18394
18970
  route.redirectTo = redirectToExpr.text;
18395
18971
  }
18396
18972
  const pathMatchExpr = getProp(optionsObject, "pathMatch");
18397
- if (pathMatchExpr && ts4.isStringLiteral(pathMatchExpr)) {
18973
+ if (pathMatchExpr && ts7.isStringLiteral(pathMatchExpr)) {
18398
18974
  const val = pathMatchExpr.text;
18399
18975
  if (val === "full" || val === "prefix") {
18400
18976
  route.pathMatch = val;
18401
18977
  }
18402
18978
  }
18403
18979
  const titleExpr = getProp(optionsObject, "title");
18404
- if (titleExpr && ts4.isStringLiteral(titleExpr)) {
18980
+ if (titleExpr && ts7.isStringLiteral(titleExpr)) {
18405
18981
  route.title = titleExpr.text;
18406
18982
  }
18407
18983
  const dataExpr = getProp(optionsObject, "data");
18408
- if (dataExpr && ts4.isObjectLiteralExpression(dataExpr)) {
18984
+ if (dataExpr && ts7.isObjectLiteralExpression(dataExpr)) {
18409
18985
  route.data = { ...route.data, ...parseObjectLiteralValues(dataExpr) };
18410
18986
  }
18411
18987
  const aspects = parseAspectRefs(getProp(optionsObject, "aspects"), ctx, `route ${httpMethod} ${routePath}`);
@@ -18427,6 +19003,7 @@ function parseController(input, ctx) {
18427
19003
  scope: injectable?.scope ?? "request",
18428
19004
  deps,
18429
19005
  ...hasDestroyHook(decl) ? { hasOnDestroy: true } : {},
19006
+ ...hasInitHook(decl) ? { hasOnInit: true } : {},
18430
19007
  ...optionalDeps.length > 0 ? { optionalDeps } : {},
18431
19008
  ...selfDeps.length > 0 ? { selfDeps } : {},
18432
19009
  ...skipSelfDeps.length > 0 ? { skipSelfDeps } : {},
@@ -18460,7 +19037,7 @@ function parseJobOptions(meta, owner, ctx) {
18460
19037
  const expression = getProp(meta, field);
18461
19038
  if (!expression)
18462
19039
  continue;
18463
- if (!ts4.isIdentifier(expression)) {
19040
+ if (!ts7.isIdentifier(expression)) {
18464
19041
  jobOptionError(ctx, "invalid-job-schema", `${owner} 的 ${field} schema 必须是可静态解析的标识符引用,不能使用内联调用或动态表达式`, expression, "SC4019", `将 schema 提取为命名导出,例如 ${field}: ${field === "input" ? "JobInput" : "JobOutput"}。`);
18465
19042
  continue;
18466
19043
  }
@@ -18484,7 +19061,7 @@ function parseJobEnum(meta, field, allowed, owner, ctx, code, errorCode) {
18484
19061
  const expression = getProp(meta, field);
18485
19062
  if (!expression)
18486
19063
  return;
18487
- if (!ts4.isStringLiteral(expression) || !allowed.includes(expression.text)) {
19064
+ if (!ts7.isStringLiteral(expression) || !allowed.includes(expression.text)) {
18488
19065
  jobOptionError(ctx, code, `${owner} 的 ${field} 必须是 ${allowed.map((value) => JSON.stringify(value)).join(" 或 ")} 字符串字面量`, expression, errorCode);
18489
19066
  return;
18490
19067
  }
@@ -18494,7 +19071,7 @@ function parseJobInteger(meta, field, min, max, owner, ctx, code, errorCode) {
18494
19071
  const expression = getProp(meta, field);
18495
19072
  if (!expression)
18496
19073
  return;
18497
- const value = ts4.isNumericLiteral(expression) ? Number(expression.text) : Number.NaN;
19074
+ const value = ts7.isNumericLiteral(expression) ? Number(expression.text) : Number.NaN;
18498
19075
  if (!Number.isSafeInteger(value) || value < min || value > max) {
18499
19076
  jobOptionError(ctx, code, `${owner} 的 ${field} 必须是 ${min} 到 ${max} 之间的安全整数`, expression, errorCode);
18500
19077
  return;
@@ -18530,7 +19107,7 @@ function isOpaqueSchema(identifier, declaration, ctx) {
18530
19107
  const property = type.getProperty(kind.value === "Union" ? "anyOf" : "allOf");
18531
19108
  if (!property)
18532
19109
  return true;
18533
- const members = ctx.checker.getIndexTypeOfType(ctx.checker.getTypeOfSymbolAtLocation(property, identifier), ts4.IndexKind.Number);
19110
+ const members = ctx.checker.getIndexTypeOfType(ctx.checker.getTypeOfSymbolAtLocation(property, identifier), ts7.IndexKind.Number);
18534
19111
  if (!members)
18535
19112
  return true;
18536
19113
  const branches = members.isUnion() ? members.types : [members];
@@ -18542,8 +19119,8 @@ function isOpaqueSchema(identifier, declaration, ctx) {
18542
19119
  }
18543
19120
  if (opaque(ctx.checker.getTypeAtLocation(identifier), new Set))
18544
19121
  return true;
18545
- const initializer = declaration && ts4.isVariableDeclaration(declaration) ? declaration.initializer : undefined;
18546
- return Boolean(initializer && ts4.isCallExpression(initializer) && ts4.isPropertyAccessExpression(initializer.expression) && ["Unknown", "Any"].includes(initializer.expression.name.text));
19122
+ const initializer = declaration && ts7.isVariableDeclaration(declaration) ? declaration.initializer : undefined;
19123
+ return Boolean(initializer && ts7.isCallExpression(initializer) && ts7.isPropertyAccessExpression(initializer.expression) && ["Unknown", "Any"].includes(initializer.expression.name.text));
18547
19124
  }
18548
19125
  function checkedRpc(meta, ctx) {
18549
19126
  const expression = getProp(meta, "rpc");
@@ -18564,7 +19141,7 @@ function checkedRpc(meta, ctx) {
18564
19141
  }
18565
19142
  function classDeps(cls, ctx) {
18566
19143
  const injectable = parseInjectableOptions(cls, ctx);
18567
- const ctor = cls.members.find(ts4.isConstructorDeclaration);
19144
+ const ctor = cls.members.find(ts7.isConstructorDeclaration);
18568
19145
  const deps = injectable?.deps ? [...injectable.deps] : [];
18569
19146
  const optionalDeps = [];
18570
19147
  const selfDeps = [];
@@ -18598,23 +19175,23 @@ function classDeps(cls, ctx) {
18598
19175
  }
18599
19176
  });
18600
19177
  }
18601
- for (const prop of cls.members.filter(ts4.isPropertyDeclaration)) {
19178
+ for (const prop of cls.members.filter(ts7.isPropertyDeclaration)) {
18602
19179
  const init = prop.initializer;
18603
- if (init && ts4.isCallExpression(init)) {
19180
+ if (init && ts7.isCallExpression(init)) {
18604
19181
  const callName = nodeText(init.expression).split(".").pop();
18605
19182
  if (callName === "inject") {
18606
19183
  const [tokenArg, optionsArg] = init.arguments;
18607
19184
  if (tokenArg) {
18608
19185
  const tokenName = tokenText(tokenArg, ctx);
18609
19186
  const unwrappedToken = unwrapForwardRef(tokenArg);
18610
- const known = ts4.isStringLiteral(unwrappedToken) || ts4.isIdentifier(unwrappedToken) && (ctx.tokensByName.has(tokenName) || ctx.classesByName.has(tokenName));
19187
+ const known = ts7.isStringLiteral(unwrappedToken) || ts7.isIdentifier(unwrappedToken) && (ctx.tokensByName.has(tokenName) || ctx.classesByName.has(tokenName));
18611
19188
  if (!known) {
18612
19189
  missing = true;
18613
19190
  continue;
18614
19191
  }
18615
19192
  if (!deps.includes(tokenName))
18616
19193
  deps.push(tokenName);
18617
- const options = optionsArg && ts4.isObjectLiteralExpression(optionsArg) ? {
19194
+ const options = optionsArg && ts7.isObjectLiteralExpression(optionsArg) ? {
18618
19195
  optional: booleanProp(optionsArg, "optional") ?? false,
18619
19196
  self: booleanProp(optionsArg, "self") ?? false,
18620
19197
  skipSelf: booleanProp(optionsArg, "skipSelf") ?? false,
@@ -18629,9 +19206,9 @@ function classDeps(cls, ctx) {
18629
19206
  if (options.host && !hostDeps.includes(tokenName))
18630
19207
  hostDeps.push(tokenName);
18631
19208
  if (!functionalInjects.some((entry) => entry.token === tokenName)) {
18632
- const declaration = ts4.isIdentifier(unwrappedToken) ? resolveDeclaration(unwrappedToken, ctx)[0] : undefined;
19209
+ const declaration = ts7.isIdentifier(unwrappedToken) ? resolveDeclaration(unwrappedToken, ctx)[0] : undefined;
18633
19210
  const localFile = declaration && isProjectSourcePath(declaration.getSourceFile().fileName, ctx.rootDir) ? declaration.getSourceFile().fileName : undefined;
18634
- const importModule = declaration && !localFile && ts4.isIdentifier(unwrappedToken) ? importModuleOf(unwrappedToken, ctx) : undefined;
19211
+ const importModule = declaration && !localFile && ts7.isIdentifier(unwrappedToken) ? importModuleOf(unwrappedToken, ctx) : undefined;
18635
19212
  functionalInjects.push({
18636
19213
  token: tokenName,
18637
19214
  expression: nodeText(unwrappedToken),
@@ -18675,7 +19252,7 @@ function parseInjectableOptions(cls, ctx) {
18675
19252
  }
18676
19253
  function parseInjectParams(cls, ctx) {
18677
19254
  const result = new Map;
18678
- const ctor = cls.members.find(ts4.isConstructorDeclaration);
19255
+ const ctor = cls.members.find(ts7.isConstructorDeclaration);
18679
19256
  if (!ctor)
18680
19257
  return result;
18681
19258
  ctor.parameters.forEach((param, index) => {
@@ -18691,7 +19268,7 @@ function parseInjectParams(cls, ctx) {
18691
19268
  }
18692
19269
  function parseOptionalParams(cls) {
18693
19270
  const result = new Set;
18694
- const ctor = cls.members.find(ts4.isConstructorDeclaration);
19271
+ const ctor = cls.members.find(ts7.isConstructorDeclaration);
18695
19272
  if (!ctor)
18696
19273
  return result;
18697
19274
  ctor.parameters.forEach((param, index) => {
@@ -18706,7 +19283,7 @@ function parseOptionalParams(cls) {
18706
19283
  }
18707
19284
  function parseModifierParams(cls, modifierName) {
18708
19285
  const result = new Set;
18709
- const ctor = cls.members.find(ts4.isConstructorDeclaration);
19286
+ const ctor = cls.members.find(ts7.isConstructorDeclaration);
18710
19287
  if (!ctor)
18711
19288
  return result;
18712
19289
  ctor.parameters.forEach((param, index) => {
@@ -18718,13 +19295,13 @@ function parseModifierParams(cls, modifierName) {
18718
19295
  return result;
18719
19296
  }
18720
19297
  function unwrapForwardRef(expr) {
18721
- if (ts4.isCallExpression(expr)) {
19298
+ if (ts7.isCallExpression(expr)) {
18722
19299
  const exprText = nodeText(expr.expression);
18723
19300
  if (exprText === "forwardRef" || exprText.endsWith(".forwardRef")) {
18724
19301
  const arg = expr.arguments[0];
18725
- if (arg && (ts4.isArrowFunction(arg) || ts4.isFunctionExpression(arg))) {
19302
+ if (arg && (ts7.isArrowFunction(arg) || ts7.isFunctionExpression(arg))) {
18726
19303
  const body = arg.body;
18727
- if (body && ts4.isExpression(body)) {
19304
+ if (body && ts7.isExpression(body)) {
18728
19305
  return unwrapForwardRef(body);
18729
19306
  }
18730
19307
  }
@@ -18734,13 +19311,13 @@ function unwrapForwardRef(expr) {
18734
19311
  }
18735
19312
  function tokenText(expr, ctx) {
18736
19313
  const unwrapped = unwrapForwardRef(expr);
18737
- if (ts4.isStringLiteral(unwrapped))
19314
+ if (ts7.isStringLiteral(unwrapped))
18738
19315
  return unwrapped.text;
18739
- if (ts4.isIdentifier(unwrapped)) {
19316
+ if (ts7.isIdentifier(unwrapped)) {
18740
19317
  const decl = resolveDeclaration(unwrapped, ctx)[0];
18741
- if (decl && ts4.isClassDeclaration(decl))
19318
+ if (decl && ts7.isClassDeclaration(decl))
18742
19319
  return decl.name?.text ?? unwrapped.text;
18743
- if (decl && ts4.isVariableDeclaration(decl))
19320
+ if (decl && ts7.isVariableDeclaration(decl))
18744
19321
  return variableName(decl);
18745
19322
  }
18746
19323
  return nodeText(unwrapped);
@@ -18760,12 +19337,12 @@ function resolveScope(input, ctx) {
18760
19337
  }
18761
19338
  function tokenNameOf(expr, ctx) {
18762
19339
  const unwrapped = unwrapForwardRef(expr);
18763
- if (ts4.isIdentifier(unwrapped)) {
19340
+ if (ts7.isIdentifier(unwrapped)) {
18764
19341
  const decl = resolveDeclaration(unwrapped, ctx)[0];
18765
- if (decl && ts4.isClassDeclaration(decl)) {
19342
+ if (decl && ts7.isClassDeclaration(decl)) {
18766
19343
  return { name: decl.name?.text ?? nodeText(expr), kind: "class" };
18767
19344
  }
18768
- if (decl && ts4.isVariableDeclaration(decl)) {
19345
+ if (decl && ts7.isVariableDeclaration(decl)) {
18769
19346
  const name = variableName(decl);
18770
19347
  return { name, kind: ctx.tokensByName.has(name) ? "injection-token" : "class" };
18771
19348
  }
@@ -18781,10 +19358,10 @@ function resolveDeclaration(id, ctx) {
18781
19358
  return [];
18782
19359
  let declarations = symbol.declarations ?? [];
18783
19360
  for (let guard = 0;guard < 4; guard += 1) {
18784
- const isAlias = declarations.some((d) => ts4.isImportSpecifier(d) || ts4.isImportClause(d) || ts4.isNamespaceImport(d));
19361
+ const isAlias = declarations.some((d) => ts7.isImportSpecifier(d) || ts7.isImportClause(d) || ts7.isNamespaceImport(d));
18785
19362
  if (!isAlias)
18786
19363
  break;
18787
- if (!(symbol.flags & ts4.SymbolFlags.Alias))
19364
+ if (!(symbol.flags & ts7.SymbolFlags.Alias))
18788
19365
  break;
18789
19366
  const aliased = ctx.checker.getAliasedSymbol(symbol);
18790
19367
  symbol = aliased;
@@ -18804,9 +19381,9 @@ function importModuleOf(id, ctx) {
18804
19381
  for (const declaration of declarations) {
18805
19382
  let current = declaration;
18806
19383
  while (current) {
18807
- if (ts4.isImportDeclaration(current)) {
19384
+ if (ts7.isImportDeclaration(current)) {
18808
19385
  const moduleSpecifier = current.moduleSpecifier;
18809
- return ts4.isStringLiteral(moduleSpecifier) ? moduleSpecifier.text : undefined;
19386
+ return ts7.isStringLiteral(moduleSpecifier) ? moduleSpecifier.text : undefined;
18810
19387
  }
18811
19388
  current = current.parent;
18812
19389
  }
@@ -18818,27 +19395,27 @@ function findDecorator(cls, name) {
18818
19395
  }
18819
19396
  function decoratorName2(dec) {
18820
19397
  const expr = dec.expression;
18821
- if (ts4.isCallExpression(expr)) {
19398
+ if (ts7.isCallExpression(expr)) {
18822
19399
  return nodeText(expr.expression).split(".").pop();
18823
19400
  }
18824
- if (ts4.isIdentifier(expr))
19401
+ if (ts7.isIdentifier(expr))
18825
19402
  return expr.text;
18826
19403
  return;
18827
19404
  }
18828
19405
  function decoratorObjectArg(dec) {
18829
19406
  const expr = dec.expression;
18830
- if (!ts4.isCallExpression(expr))
19407
+ if (!ts7.isCallExpression(expr))
18831
19408
  return;
18832
19409
  const arg = expr.arguments[0];
18833
- return arg && ts4.isObjectLiteralExpression(arg) ? arg : undefined;
19410
+ return arg && ts7.isObjectLiteralExpression(arg) ? arg : undefined;
18834
19411
  }
18835
19412
  function getProp(obj, name) {
18836
- const prop = obj.properties.find((item) => (ts4.isPropertyAssignment(item) || ts4.isShorthandPropertyAssignment(item)) && propertyName(item.name) === name);
19413
+ const prop = obj.properties.find((item) => (ts7.isPropertyAssignment(item) || ts7.isShorthandPropertyAssignment(item)) && propertyName(item.name) === name);
18837
19414
  if (!prop)
18838
19415
  return;
18839
- if (ts4.isPropertyAssignment(prop))
19416
+ if (ts7.isPropertyAssignment(prop))
18840
19417
  return prop.initializer;
18841
- if (ts4.isShorthandPropertyAssignment(prop))
19418
+ if (ts7.isShorthandPropertyAssignment(prop))
18842
19419
  return prop.name;
18843
19420
  return;
18844
19421
  }
@@ -18846,10 +19423,10 @@ function toCompilerDiagnostic(diagnostic, rootDir) {
18846
19423
  const file = diagnostic.file;
18847
19424
  const position = file && diagnostic.start !== undefined ? file.getLineAndCharacterOfPosition(diagnostic.start) : undefined;
18848
19425
  return {
18849
- severity: diagnostic.category === ts4.DiagnosticCategory.Error ? "error" : "warn",
19426
+ severity: diagnostic.category === ts7.DiagnosticCategory.Error ? "error" : "warn",
18850
19427
  code: `typescript-${diagnostic.code}`,
18851
19428
  errorCode: `TS${diagnostic.code}`,
18852
- message: ts4.flattenDiagnosticMessageText(diagnostic.messageText, `
19429
+ message: ts7.flattenDiagnosticMessageText(diagnostic.messageText, `
18853
19430
  `),
18854
19431
  ...file ? { file: sourcePath(rootDir, file.fileName) } : {},
18855
19432
  ...position ? { line: position.line + 1 } : {}
@@ -18857,16 +19434,16 @@ function toCompilerDiagnostic(diagnostic, rootDir) {
18857
19434
  }
18858
19435
  function stringLiteralProp(obj, name) {
18859
19436
  const expr = getProp(obj, name);
18860
- return expr && ts4.isStringLiteral(expr) ? expr.text : undefined;
19437
+ return expr && ts7.isStringLiteral(expr) ? expr.text : undefined;
18861
19438
  }
18862
19439
  function arrayProp(obj, name) {
18863
19440
  const expr = getProp(obj, name);
18864
- return expr && ts4.isArrayLiteralExpression(expr) ? [...expr.elements] : [];
19441
+ return expr && ts7.isArrayLiteralExpression(expr) ? [...expr.elements] : [];
18865
19442
  }
18866
19443
  function parseAspectRefs(expression, ctx, owner) {
18867
19444
  if (!expression)
18868
19445
  return [];
18869
- if (!ts4.isArrayLiteralExpression(expression)) {
19446
+ if (!ts7.isArrayLiteralExpression(expression)) {
18870
19447
  ctx.diagnostics.push({
18871
19448
  severity: "error",
18872
19449
  code: "dynamic-aspect-reference",
@@ -18881,7 +19458,7 @@ function parseAspectRefs(expression, ctx, owner) {
18881
19458
  }
18882
19459
  const refs = [];
18883
19460
  for (const element of expression.elements) {
18884
- if (ts4.isSpreadElement(element) || !ts4.isIdentifier(element)) {
19461
+ if (ts7.isSpreadElement(element) || !ts7.isIdentifier(element)) {
18885
19462
  ctx.diagnostics.push({
18886
19463
  severity: "error",
18887
19464
  code: "dynamic-aspect-reference",
@@ -18894,7 +19471,7 @@ function parseAspectRefs(expression, ctx, owner) {
18894
19471
  });
18895
19472
  continue;
18896
19473
  }
18897
- const declaration = resolveDeclaration(element, ctx).find((candidate) => ts4.isFunctionDeclaration(candidate) || ts4.isVariableDeclaration(candidate) && candidate.initializer !== undefined && (ts4.isArrowFunction(candidate.initializer) || ts4.isFunctionExpression(candidate.initializer)));
19474
+ const declaration = resolveDeclaration(element, ctx).find((candidate) => ts7.isFunctionDeclaration(candidate) || ts7.isVariableDeclaration(candidate) && candidate.initializer !== undefined && (ts7.isArrowFunction(candidate.initializer) || ts7.isFunctionExpression(candidate.initializer)));
18898
19475
  if (!declaration) {
18899
19476
  ctx.diagnostics.push({
18900
19477
  severity: "error",
@@ -18908,7 +19485,7 @@ function parseAspectRefs(expression, ctx, owner) {
18908
19485
  });
18909
19486
  continue;
18910
19487
  }
18911
- const name = ts4.isFunctionDeclaration(declaration) ? declaration.name?.text : ts4.isVariableDeclaration(declaration) ? variableName(declaration) : undefined;
19488
+ const name = ts7.isFunctionDeclaration(declaration) ? declaration.name?.text : ts7.isVariableDeclaration(declaration) ? variableName(declaration) : undefined;
18912
19489
  if (!name)
18913
19490
  continue;
18914
19491
  const declaredFile = declaration.getSourceFile().fileName;
@@ -18928,9 +19505,9 @@ function booleanProp(obj, name) {
18928
19505
  const expr = getProp(obj, name);
18929
19506
  if (!expr)
18930
19507
  return;
18931
- if (expr.kind === ts4.SyntaxKind.TrueKeyword)
19508
+ if (expr.kind === ts7.SyntaxKind.TrueKeyword)
18932
19509
  return true;
18933
- if (expr.kind === ts4.SyntaxKind.FalseKeyword)
19510
+ if (expr.kind === ts7.SyntaxKind.FalseKeyword)
18934
19511
  return false;
18935
19512
  return;
18936
19513
  }
@@ -18944,15 +19521,15 @@ function parseBindingOptions(args, defaultName) {
18944
19521
  let defaultValue;
18945
19522
  const first = args[0];
18946
19523
  const second = args[1];
18947
- if (first && ts4.isStringLiteral(first)) {
19524
+ if (first && ts7.isStringLiteral(first)) {
18948
19525
  name = first.text;
18949
- } else if (first && ts4.isObjectLiteralExpression(first)) {
19526
+ } else if (first && ts7.isObjectLiteralExpression(first)) {
18950
19527
  const nameProp = getProp(first, "name");
18951
- if (nameProp && ts4.isStringLiteral(nameProp)) {
19528
+ if (nameProp && ts7.isStringLiteral(nameProp)) {
18952
19529
  name = nameProp.text;
18953
19530
  }
18954
19531
  const trProp = getProp(first, "transform");
18955
- if (trProp && ts4.isStringLiteral(trProp)) {
19532
+ if (trProp && ts7.isStringLiteral(trProp)) {
18956
19533
  const val = trProp.text;
18957
19534
  if (val === "number" || val === "boolean" || val === "string") {
18958
19535
  transform = val;
@@ -18963,9 +19540,9 @@ function parseBindingOptions(args, defaultName) {
18963
19540
  defaultValue = parseLiteralValue(defProp);
18964
19541
  }
18965
19542
  }
18966
- if (second && ts4.isObjectLiteralExpression(second)) {
19543
+ if (second && ts7.isObjectLiteralExpression(second)) {
18967
19544
  const trProp = getProp(second, "transform");
18968
- if (trProp && ts4.isStringLiteral(trProp)) {
19545
+ if (trProp && ts7.isStringLiteral(trProp)) {
18969
19546
  const val = trProp.text;
18970
19547
  if (val === "number" || val === "boolean" || val === "string") {
18971
19548
  transform = val;
@@ -18979,18 +19556,18 @@ function parseBindingOptions(args, defaultName) {
18979
19556
  return { name, ...transform ? { transform } : {}, default: defaultValue };
18980
19557
  }
18981
19558
  function parseLiteralValue(node) {
18982
- if (ts4.isStringLiteral(node))
19559
+ if (ts7.isStringLiteral(node))
18983
19560
  return node.text;
18984
- if (ts4.isNumericLiteral(node))
19561
+ if (ts7.isNumericLiteral(node))
18985
19562
  return Number(node.text);
18986
- if (node.kind === ts4.SyntaxKind.TrueKeyword)
19563
+ if (node.kind === ts7.SyntaxKind.TrueKeyword)
18987
19564
  return true;
18988
- if (node.kind === ts4.SyntaxKind.FalseKeyword)
19565
+ if (node.kind === ts7.SyntaxKind.FalseKeyword)
18989
19566
  return false;
18990
- if (ts4.isArrayLiteralExpression(node)) {
19567
+ if (ts7.isArrayLiteralExpression(node)) {
18991
19568
  return node.elements.map(parseLiteralValue);
18992
19569
  }
18993
- if (ts4.isObjectLiteralExpression(node)) {
19570
+ if (ts7.isObjectLiteralExpression(node)) {
18994
19571
  return parseObjectLiteralValues(node);
18995
19572
  }
18996
19573
  return;
@@ -18998,7 +19575,7 @@ function parseLiteralValue(node) {
18998
19575
  function parseObjectLiteralValues(obj) {
18999
19576
  const result = {};
19000
19577
  for (const prop of obj.properties) {
19001
- if (ts4.isPropertyAssignment(prop)) {
19578
+ if (ts7.isPropertyAssignment(prop)) {
19002
19579
  const name = propertyName(prop.name);
19003
19580
  const init = prop.initializer;
19004
19581
  if (init) {
@@ -19015,7 +19592,7 @@ function sourcePath(rootDir, absFile) {
19015
19592
  return relative2(rootDir, absFile).split(sep2).join("/");
19016
19593
  }
19017
19594
  function unwrapInfraResourceExpression(value) {
19018
- while (ts4.isParenthesizedExpression(value) || ts4.isAsExpression(value) || ts4.isTypeAssertionExpression(value) || ts4.isSatisfiesExpression(value) || ts4.isNonNullExpression(value)) {
19595
+ while (ts7.isParenthesizedExpression(value) || ts7.isAsExpression(value) || ts7.isTypeAssertionExpression(value) || ts7.isSatisfiesExpression(value) || ts7.isNonNullExpression(value)) {
19019
19596
  value = value.expression;
19020
19597
  }
19021
19598
  return value;
@@ -19025,7 +19602,7 @@ function infraResourceProp(obj, name, ctx) {
19025
19602
  if (members.length === 0)
19026
19603
  return;
19027
19604
  const member = members[0];
19028
- if (members.length !== 1 || !ts4.isPropertyAssignment(member) || ts4.isComputedPropertyName(member.name) || obj.properties.some(ts4.isSpreadAssignment)) {
19605
+ if (members.length !== 1 || !ts7.isPropertyAssignment(member) || ts7.isComputedPropertyName(member.name) || obj.properties.some(ts7.isSpreadAssignment)) {
19029
19606
  pushResourceError(ctx, "unknown-resource", `${name} 必须是唯一、显式的静态属性,且不能被对象展开覆盖`, sourcePath(ctx.rootDir, obj.getSourceFile().fileName), lineOf(member), `使用 ${name}: [...],不要使用简写属性、计算属性或对象展开。`);
19030
19607
  return;
19031
19608
  }
@@ -19038,7 +19615,7 @@ function indexInfraResource(cls, className, sf, ctx) {
19038
19615
  const file = sourcePath(ctx.rootDir, sf.fileName);
19039
19616
  const line = lineOf(cls);
19040
19617
  const options = decoratorObjectArg(decorator);
19041
- if (!options || options.properties.some((property) => !ts4.isPropertyAssignment(property) || ts4.isComputedPropertyName(property.name)) || new Set(options.properties.map((property) => property.name && propertyName(property.name))).size !== options.properties.length) {
19618
+ if (!options || options.properties.some((property) => !ts7.isPropertyAssignment(property) || ts7.isComputedPropertyName(property.name)) || new Set(options.properties.map((property) => property.name && propertyName(property.name))).size !== options.properties.length) {
19042
19619
  pushResourceError(ctx, "invalid-resource-kind", "@InfraResource 需要静态的 { name, kind } 对象参数", file, line, '使用 @InfraResource({ name: "orders-db", kind: "database" }),不要使用对象展开或重复属性。');
19043
19620
  return;
19044
19621
  }
@@ -19069,14 +19646,14 @@ function indexInfraResource(cls, className, sf, ctx) {
19069
19646
  }
19070
19647
  function resolveInfraResourceRef(el, ctx, owner, file, line) {
19071
19648
  const unwrapped = unwrapInfraResourceExpression(unwrapForwardRef(unwrapInfraResourceExpression(el)));
19072
- const identifier = ts4.isIdentifier(unwrapped) ? unwrapped : ts4.isPropertyAccessExpression(unwrapped) && ts4.isIdentifier(unwrapped.name) ? unwrapped.name : undefined;
19649
+ const identifier = ts7.isIdentifier(unwrapped) ? unwrapped : ts7.isPropertyAccessExpression(unwrapped) && ts7.isIdentifier(unwrapped.name) ? unwrapped.name : undefined;
19073
19650
  let symbol = identifier ? ctx.checker.getSymbolAtLocation(identifier) : undefined;
19074
19651
  const visited = new Set;
19075
- while (symbol && symbol.flags & ts4.SymbolFlags.Alias && !visited.has(symbol)) {
19652
+ while (symbol && symbol.flags & ts7.SymbolFlags.Alias && !visited.has(symbol)) {
19076
19653
  visited.add(symbol);
19077
19654
  symbol = ctx.checker.getAliasedSymbol(symbol);
19078
19655
  }
19079
- const declaration = symbol?.declarations?.find(ts4.isClassDeclaration);
19656
+ const declaration = symbol?.declarations?.find(ts7.isClassDeclaration);
19080
19657
  const resource = declaration ? ctx.infraResources.get(declaration) : undefined;
19081
19658
  if (!resource) {
19082
19659
  pushResourceError(ctx, "unknown-resource", `${owner} 引用的资源 '${nodeText(el)}' 未声明为 @InfraResource`, file, line, "引用实际声明了 @InfraResource({ name, kind }) 的类,不能依赖其他文件的同名类。");
@@ -19089,7 +19666,7 @@ function parseModuleInfraResources(value, ctx, owner, file, line) {
19089
19666
  if (!value)
19090
19667
  return names;
19091
19668
  const array = unwrapInfraResourceExpression(value);
19092
- if (!ts4.isArrayLiteralExpression(array)) {
19669
+ if (!ts7.isArrayLiteralExpression(array)) {
19093
19670
  pushResourceError(ctx, "unknown-resource", `${owner} 的 resources 必须是静态数组`, file, line, "使用 resources: [ResourceClass];省略该属性表示不声明资源。");
19094
19671
  return names;
19095
19672
  }
@@ -19104,14 +19681,14 @@ function parseInfraResourceUseRefs(value, ctx, owner, file, line) {
19104
19681
  if (!value)
19105
19682
  return [];
19106
19683
  const array = unwrapInfraResourceExpression(value);
19107
- if (!ts4.isArrayLiteralExpression(array)) {
19684
+ if (!ts7.isArrayLiteralExpression(array)) {
19108
19685
  pushResourceError(ctx, "unknown-resource", `${owner} 的 uses 必须是静态数组`, file, line, '使用 uses: [{ resource: ResourceClass, operations: ["read"] }]。');
19109
19686
  return [];
19110
19687
  }
19111
19688
  const uses = new Map;
19112
19689
  for (const element of array.elements) {
19113
19690
  const entry = unwrapInfraResourceExpression(element);
19114
- if (!ts4.isObjectLiteralExpression(entry) || entry.properties.some((property) => !ts4.isPropertyAssignment(property) || ts4.isComputedPropertyName(property.name) || !["resource", "operations"].includes(propertyName(property.name))) || new Set(entry.properties.map((property) => property.name && propertyName(property.name))).size !== entry.properties.length) {
19691
+ if (!ts7.isObjectLiteralExpression(entry) || entry.properties.some((property) => !ts7.isPropertyAssignment(property) || ts7.isComputedPropertyName(property.name) || !["resource", "operations"].includes(propertyName(property.name))) || new Set(entry.properties.map((property) => property.name && propertyName(property.name))).size !== entry.properties.length) {
19115
19692
  pushResourceError(ctx, "unknown-resource", `${owner} 的 uses 项必须是显式的 { resource, operations } 对象`, file, lineOf(element), "使用显式属性,不要使用对象/数组展开、简写、计算属性或重复属性。");
19116
19693
  continue;
19117
19694
  }
@@ -19129,14 +19706,14 @@ function parseInfraResourceUseRefs(value, ctx, owner, file, line) {
19129
19706
  operations.add("read");
19130
19707
  } else {
19131
19708
  const operationArray = unwrapInfraResourceExpression(operationsEl);
19132
- if (!ts4.isArrayLiteralExpression(operationArray) || operationArray.elements.length === 0) {
19709
+ if (!ts7.isArrayLiteralExpression(operationArray) || operationArray.elements.length === 0) {
19133
19710
  pushResourceError(ctx, "invalid-resource-operation", `${owner} 对资源 '${resource}' 的 operations 必须是非空静态数组`, file, lineOf(operationsEl), "仅省略 operations 时默认 read;显式填写时必须包含有效操作。");
19134
19711
  continue;
19135
19712
  }
19136
19713
  let invalid = false;
19137
19714
  for (const operationEl of operationArray.elements) {
19138
19715
  const operation = unwrapInfraResourceExpression(operationEl);
19139
- if (!ts4.isStringLiteral(operation) || !isInfraResourceOperation(operation.text)) {
19716
+ if (!ts7.isStringLiteral(operation) || !isInfraResourceOperation(operation.text)) {
19140
19717
  pushResourceError(ctx, "invalid-resource-operation", `${owner} 对资源 '${resource}' 声明了无效操作 '${nodeText(operationEl)}'`, file, lineOf(operationEl), `operations 只能包含字符串字面量 ${INFRA_RESOURCE_OPERATIONS.join(" | ")}。`);
19141
19718
  invalid = true;
19142
19719
  continue;
@@ -19183,11 +19760,11 @@ import { join as join4 } from "node:path";
19183
19760
 
19184
19761
  // src/type-safety.ts
19185
19762
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
19186
- import { dirname as dirname3, join as join3, relative as relative3, resolve as resolve2, sep as sep3 } from "node:path";
19187
- import * as ts6 from "@typescript/typescript6";
19763
+ import { dirname as dirname3, join as join3, relative as relative3, resolve as resolve3, sep as sep3 } from "node:path";
19764
+ import * as ts9 from "@typescript/typescript6";
19188
19765
 
19189
19766
  // src/sql-safety.ts
19190
- import * as ts5 from "@typescript/typescript6";
19767
+ import * as ts8 from "@typescript/typescript6";
19191
19768
  var SQL_SAFETY_DIAGNOSTIC_CODES = {
19192
19769
  "sql-result-assertion": { errorCode: "SC6007", docsUrl: "https://supacloud.dev/errors/SC6007" },
19193
19770
  "sql-raw-dynamic": { errorCode: "SC6008", docsUrl: "https://supacloud.dev/errors/SC6008" }
@@ -19195,10 +19772,10 @@ var SQL_SAFETY_DIAGNOSTIC_CODES = {
19195
19772
  function scanDrizzleSql(sourceFile, checker, file, strict) {
19196
19773
  const diagnostics = [];
19197
19774
  const importedSql = (expression) => {
19198
- const symbol = checker.getSymbolAtLocation(ts5.isPropertyAccessExpression(expression) ? expression.name : expression);
19775
+ const symbol = checker.getSymbolAtLocation(ts8.isPropertyAccessExpression(expression) ? expression.name : expression);
19199
19776
  if (!symbol)
19200
19777
  return false;
19201
- const target = symbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
19778
+ const target = symbol.flags & ts8.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
19202
19779
  return target.name === "sql" && (target.declarations ?? []).some((declaration) => /(?:^|\/)node_modules\/drizzle-orm\//.test(declaration.getSourceFile().fileName.replaceAll("\\", "/")));
19203
19780
  };
19204
19781
  const report = (code, node, message) => {
@@ -19212,16 +19789,16 @@ function scanDrizzleSql(sourceFile, checker, file, strict) {
19212
19789
  });
19213
19790
  };
19214
19791
  const visit = (node) => {
19215
- if (ts5.isTaggedTemplateExpression(node) && importedSql(node.tag) && node.typeArguments?.some((type) => type.kind !== ts5.SyntaxKind.UnknownKeyword)) {
19792
+ if (ts8.isTaggedTemplateExpression(node) && importedSql(node.tag) && node.typeArguments?.some((type) => type.kind !== ts8.SyntaxKind.UnknownKeyword)) {
19216
19793
  report("sql-result-assertion", node, "Drizzle sql<T> asserts a result type without checking SQL or decoding rows. Use sql<unknown> and a schema decoder at the result boundary.");
19217
19794
  }
19218
- if (ts5.isCallExpression(node) && ts5.isPropertyAccessExpression(node.expression) && node.expression.name.text === "raw" && importedSql(node.expression.expression)) {
19795
+ if (ts8.isCallExpression(node) && ts8.isPropertyAccessExpression(node.expression) && node.expression.name.text === "raw" && importedSql(node.expression.expression)) {
19219
19796
  const argument = node.arguments[0];
19220
- if (!argument || !ts5.isStringLiteral(argument) && !ts5.isNoSubstitutionTemplateLiteral(argument)) {
19797
+ if (!argument || !ts8.isStringLiteral(argument) && !ts8.isNoSubstitutionTemplateLiteral(argument)) {
19221
19798
  report("sql-raw-dynamic", node, "Dynamic sql.raw bypasses parameter binding. Interpolate values with sql templates; keep reviewed static DDL in migrations.");
19222
19799
  }
19223
19800
  }
19224
- ts5.forEachChild(node, visit);
19801
+ ts8.forEachChild(node, visit);
19225
19802
  };
19226
19803
  visit(sourceFile);
19227
19804
  return diagnostics;
@@ -19253,7 +19830,7 @@ function scanGeneratedArtifacts(artifacts, strict = true) {
19253
19830
  for (const [file, content] of Object.entries(artifacts)) {
19254
19831
  if (content === undefined)
19255
19832
  continue;
19256
- const sourceFile = ts6.createSourceFile(file, content, ts6.ScriptTarget.Latest, true, ts6.ScriptKind.TS);
19833
+ const sourceFile = ts9.createSourceFile(file, content, ts9.ScriptTarget.Latest, true, ts9.ScriptKind.TS);
19257
19834
  for (const node of descendantsOfKind2(sourceFile, isAnyKeyword)) {
19258
19835
  diagnostics.push(makeDiagnostic("generated-any", `生成产物 ${file} 包含 any;严格生成模式要求使用 unknown、具体接口或泛型约束。`, sourceFile, node, strict));
19259
19836
  }
@@ -19261,31 +19838,31 @@ function scanGeneratedArtifacts(artifacts, strict = true) {
19261
19838
  return diagnostics;
19262
19839
  }
19263
19840
  function scanProductionSource(options) {
19264
- const rootDir = resolve2(options.rootDir);
19265
- const configPath = ts6.findConfigFile(rootDir, ts6.sys.fileExists) ?? join3(rootDir, "tsconfig.json");
19841
+ const rootDir = resolve3(options.rootDir);
19842
+ const configPath = ts9.findConfigFile(rootDir, ts9.sys.fileExists) ?? join3(rootDir, "tsconfig.json");
19266
19843
  const projectConfig = existsSync2(configPath) ? readProjectConfig2(configPath) : {
19267
19844
  options: {
19268
19845
  strict: true,
19269
19846
  skipLibCheck: true,
19270
- target: ts6.ScriptTarget.ES2022,
19271
- module: ts6.ModuleKind.ESNext,
19272
- moduleResolution: ts6.ModuleResolutionKind.Bundler
19847
+ target: ts9.ScriptTarget.ES2022,
19848
+ module: ts9.ModuleKind.ESNext,
19849
+ moduleResolution: ts9.ModuleResolutionKind.Bundler
19273
19850
  },
19274
19851
  errors: []
19275
19852
  };
19276
19853
  const include = options.include ?? ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"];
19277
- const rootNames = ts6.sys.readDirectory(rootDir, [".ts", ".tsx", ".mts", ".cts"], ["node_modules", "dist"], include).filter((file) => isProductionSourcePath(rootDir, file, [...DEFAULT_EXCLUDES, ...options.exclude ?? []]));
19854
+ const rootNames = ts9.sys.readDirectory(rootDir, [".ts", ".tsx", ".mts", ".cts"], ["node_modules", "dist"], include).filter((file) => isProductionSourcePath(rootDir, file, [...DEFAULT_EXCLUDES, ...options.exclude ?? []]));
19278
19855
  const compilerOptions = { ...projectConfig.options, noEmit: true };
19279
- const host = ts6.createCompilerHost(compilerOptions);
19856
+ const host = ts9.createCompilerHost(compilerOptions);
19280
19857
  host.getCurrentDirectory = () => dirname3(configPath);
19281
- const program = ts6.createProgram(rootNames, compilerOptions, host);
19858
+ const program = ts9.createProgram(rootNames, compilerOptions, host);
19282
19859
  const outDir = options.outDir ? normalizeRelative(rootDir, options.outDir) : undefined;
19283
19860
  const excludes = [...DEFAULT_EXCLUDES, ...options.exclude ?? []];
19284
19861
  const sourceFiles = program.getSourceFiles().filter((sourceFile) => isProductionSource(rootDir, sourceFile, excludes, outDir));
19285
19862
  const diagnostics = [...projectConfig.errors, ...program.getOptionsDiagnostics()].map((diagnostic) => ({
19286
19863
  severity: "error",
19287
19864
  code: "source-config",
19288
- message: ts6.flattenDiagnosticMessageText(diagnostic.messageText, `
19865
+ message: ts9.flattenDiagnosticMessageText(diagnostic.messageText, `
19289
19866
  `),
19290
19867
  file: diagnostic.file ? normalizeRelative(rootDir, diagnostic.file.fileName) : normalizeRelative(rootDir, configPath),
19291
19868
  ...diagnostic.file && diagnostic.start !== undefined ? { line: diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start).line + 1 } : {},
@@ -19302,7 +19879,7 @@ function scanProductionSource(options) {
19302
19879
  diagnostics.push({
19303
19880
  severity: "error",
19304
19881
  code: "source-typescript",
19305
- message: ts6.flattenDiagnosticMessageText(diagnostic.messageText, `
19882
+ message: ts9.flattenDiagnosticMessageText(diagnostic.messageText, `
19306
19883
  `),
19307
19884
  ...diagnostic.file ? { file: normalizeRelative(rootDir, diagnostic.file.fileName) } : {},
19308
19885
  ...diagnostic.file && diagnostic.start !== undefined ? { line: diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start).line + 1 } : {},
@@ -19312,9 +19889,9 @@ function scanProductionSource(options) {
19312
19889
  for (const sourceFile of sourceFiles) {
19313
19890
  scanSourceFile(sourceFile, checker, rootDir, diagnostics, options.strict ?? false);
19314
19891
  diagnostics.push(...scanDrizzleSql(sourceFile, checker, normalizeRelative(rootDir, sourceFile.fileName), options.strict ?? false));
19315
- const scanner = ts6.createScanner(ts6.ScriptTarget.Latest, false, sourceFile.languageVariant, sourceFile.text);
19316
- for (let kind = scanner.scan();kind !== ts6.SyntaxKind.EndOfFileToken; kind = scanner.scan()) {
19317
- if ((kind === ts6.SyntaxKind.SingleLineCommentTrivia || kind === ts6.SyntaxKind.MultiLineCommentTrivia) && /@ts-(?:ignore|nocheck|expect-error)\b/.test(scanner.getTokenText())) {
19892
+ const scanner = ts9.createScanner(ts9.ScriptTarget.Latest, false, sourceFile.languageVariant, sourceFile.text);
19893
+ for (let kind = scanner.scan();kind !== ts9.SyntaxKind.EndOfFileToken; kind = scanner.scan()) {
19894
+ if ((kind === ts9.SyntaxKind.SingleLineCommentTrivia || kind === ts9.SyntaxKind.MultiLineCommentTrivia) && /@ts-(?:ignore|nocheck|expect-error)\b/.test(scanner.getTokenText())) {
19318
19895
  diagnostics.push({
19319
19896
  severity: "error",
19320
19897
  code: "source-type-suppression",
@@ -19334,22 +19911,22 @@ function scanSourceFile(sourceFile, checker, rootDir, diagnostics, strict) {
19334
19911
  diagnostics.push(makeDiagnostic("source-any", "生产源码使用了显式 any;请改用 unknown、具体接口或泛型约束。", sourceFile, node, strict, rootDir));
19335
19912
  }
19336
19913
  for (const node of descendants(sourceFile)) {
19337
- if (ts6.isAsExpression(node)) {
19338
- if (ts6.isAsExpression(node.parent) || ts6.isTypeAssertionExpression(node.parent))
19914
+ if (ts9.isAsExpression(node)) {
19915
+ if (ts9.isAsExpression(node.parent) || ts9.isTypeAssertionExpression(node.parent))
19339
19916
  continue;
19340
19917
  const assertedType = node.type.getText(sourceFile);
19341
19918
  if (assertedType === "const")
19342
19919
  continue;
19343
19920
  diagnostics.push(makeDiagnostic("source-type-assertion", `生产源码包含类型断言 ${node.getText(sourceFile)};请优先使用类型守卫、satisfies 或显式边界解析。`, sourceFile, node, strict, rootDir));
19344
- } else if (ts6.isTypeAssertionExpression(node)) {
19345
- if (ts6.isAsExpression(node.parent) || ts6.isTypeAssertionExpression(node.parent))
19921
+ } else if (ts9.isTypeAssertionExpression(node)) {
19922
+ if (ts9.isAsExpression(node.parent) || ts9.isTypeAssertionExpression(node.parent))
19346
19923
  continue;
19347
19924
  diagnostics.push(makeDiagnostic("source-type-assertion", `生产源码包含类型断言 ${node.getText(sourceFile)};请优先使用类型守卫、satisfies 或显式边界解析。`, sourceFile, node, strict, rootDir));
19348
- } else if (ts6.isNonNullExpression(node)) {
19925
+ } else if (ts9.isNonNullExpression(node)) {
19349
19926
  diagnostics.push(makeDiagnostic("source-non-null-assertion", `生产源码包含非空断言 ${node.getText(sourceFile)};请显式处理 null/undefined。`, sourceFile, node, strict, rootDir));
19350
19927
  }
19351
19928
  }
19352
- for (const declaration of descendantsOfKind2(sourceFile, ts6.isVariableDeclaration)) {
19929
+ for (const declaration of descendantsOfKind2(sourceFile, ts9.isVariableDeclaration)) {
19353
19930
  const initializer = declaration.initializer;
19354
19931
  if (!initializer || declaration.type)
19355
19932
  continue;
@@ -19365,11 +19942,11 @@ function scanSourceFile(sourceFile, checker, rootDir, diagnostics, strict) {
19365
19942
  if (isLetDeclaration(declaration) && isLiteralSyntax(initializer) && !isLiteralType(declarationType)) {
19366
19943
  diagnostics.push(makeDiagnostic("source-implicit-widening", `变量 ${declaration.name.getText(sourceFile)} 的字面量类型从 ${checker.typeToString(initializerType, initializer)} 隐式宽化为 ${checker.typeToString(declarationType, declaration)};请补充类型或使用 const。`, sourceFile, declaration, strict, rootDir));
19367
19944
  }
19368
- if (ts6.isObjectLiteralExpression(initializer) && isConstDeclaration(declaration) && initializer.getText(sourceFile).length > 0 && initializer.properties.some((property) => ts6.isPropertyAssignment(property) && property.initializer !== undefined && !ts6.isAsExpression(property.initializer) && isLiteralExpression(property.initializer))) {
19945
+ if (ts9.isObjectLiteralExpression(initializer) && isConstDeclaration(declaration) && initializer.getText(sourceFile).length > 0 && initializer.properties.some((property) => ts9.isPropertyAssignment(property) && property.initializer !== undefined && !ts9.isAsExpression(property.initializer) && isLiteralExpression(property.initializer))) {
19369
19946
  diagnostics.push(makeDiagnostic("source-implicit-widening", `常量对象 ${declaration.name.getText(sourceFile)} 的字面量属性会隐式宽化;请补充对象类型或使用 as const。`, sourceFile, declaration, strict, rootDir));
19370
19947
  }
19371
19948
  }
19372
- for (const parameter of descendantsOfKind2(sourceFile, ts6.isParameter)) {
19949
+ for (const parameter of descendantsOfKind2(sourceFile, ts9.isParameter)) {
19373
19950
  if (parameter.type)
19374
19951
  continue;
19375
19952
  for (const name of bindingNames(parameter.name)) {
@@ -19380,10 +19957,10 @@ function scanSourceFile(sourceFile, checker, rootDir, diagnostics, strict) {
19380
19957
  }
19381
19958
  }
19382
19959
  function readProjectConfig2(configPath) {
19383
- const config = ts6.readConfigFile(configPath, (file) => readFileSync2(file, "utf8"));
19960
+ const config = ts9.readConfigFile(configPath, (file) => readFileSync2(file, "utf8"));
19384
19961
  if (config.error)
19385
19962
  return { options: {}, errors: [config.error] };
19386
- const parsed = ts6.parseJsonConfigFileContent(config.config, ts6.sys, dirname3(configPath));
19963
+ const parsed = ts9.parseJsonConfigFileContent(config.config, ts9.sys, dirname3(configPath));
19387
19964
  return { options: parsed.options, errors: parsed.errors };
19388
19965
  }
19389
19966
  function isProductionSource(rootDir, sourceFile, excludes, outDir) {
@@ -19403,42 +19980,42 @@ function globMatches(value, pattern) {
19403
19980
  return new RegExp(`^${escaped}$`).test(value);
19404
19981
  }
19405
19982
  function bindingNames(name) {
19406
- if (ts6.isIdentifier(name))
19983
+ if (ts9.isIdentifier(name))
19407
19984
  return [name];
19408
- return name.elements.flatMap((element) => ts6.isBindingElement(element) ? bindingNames(element.name) : []);
19985
+ return name.elements.flatMap((element) => ts9.isBindingElement(element) ? bindingNames(element.name) : []);
19409
19986
  }
19410
19987
  function isLiteralExpression(node) {
19411
19988
  if (!node)
19412
19989
  return false;
19413
19990
  return [
19414
- ts6.SyntaxKind.StringLiteral,
19415
- ts6.SyntaxKind.NumericLiteral,
19416
- ts6.SyntaxKind.TrueKeyword,
19417
- ts6.SyntaxKind.FalseKeyword
19991
+ ts9.SyntaxKind.StringLiteral,
19992
+ ts9.SyntaxKind.NumericLiteral,
19993
+ ts9.SyntaxKind.TrueKeyword,
19994
+ ts9.SyntaxKind.FalseKeyword
19418
19995
  ].includes(node.kind);
19419
19996
  }
19420
19997
  function isLiteralSyntax(node) {
19421
- return ts6.isStringLiteral(node) || ts6.isNumericLiteral(node) || node.kind === ts6.SyntaxKind.TrueKeyword || node.kind === ts6.SyntaxKind.FalseKeyword;
19998
+ return ts9.isStringLiteral(node) || ts9.isNumericLiteral(node) || node.kind === ts9.SyntaxKind.TrueKeyword || node.kind === ts9.SyntaxKind.FalseKeyword;
19422
19999
  }
19423
20000
  function isLiteralType(type) {
19424
- return (type.flags & (ts6.TypeFlags.StringLiteral | ts6.TypeFlags.NumberLiteral | ts6.TypeFlags.BooleanLiteral | ts6.TypeFlags.BigIntLiteral)) !== 0;
20001
+ return (type.flags & (ts9.TypeFlags.StringLiteral | ts9.TypeFlags.NumberLiteral | ts9.TypeFlags.BooleanLiteral | ts9.TypeFlags.BigIntLiteral)) !== 0;
19425
20002
  }
19426
20003
  function isAnyType(type) {
19427
- return (type.flags & ts6.TypeFlags.Any) !== 0;
20004
+ return (type.flags & ts9.TypeFlags.Any) !== 0;
19428
20005
  }
19429
20006
  function isLetDeclaration(declaration) {
19430
- return ts6.isVariableDeclarationList(declaration.parent) && (declaration.parent.flags & ts6.NodeFlags.Let) !== 0;
20007
+ return ts9.isVariableDeclarationList(declaration.parent) && (declaration.parent.flags & ts9.NodeFlags.Let) !== 0;
19431
20008
  }
19432
20009
  function isConstDeclaration(declaration) {
19433
- return ts6.isVariableDeclarationList(declaration.parent) && (declaration.parent.flags & ts6.NodeFlags.Const) !== 0;
20010
+ return ts9.isVariableDeclarationList(declaration.parent) && (declaration.parent.flags & ts9.NodeFlags.Const) !== 0;
19434
20011
  }
19435
20012
  function descendants(root) {
19436
20013
  const result = [];
19437
20014
  const visit = (node) => {
19438
20015
  result.push(node);
19439
- ts6.forEachChild(node, visit);
20016
+ ts9.forEachChild(node, visit);
19440
20017
  };
19441
- ts6.forEachChild(root, visit);
20018
+ ts9.forEachChild(root, visit);
19442
20019
  return result;
19443
20020
  }
19444
20021
  function descendantsOfKind2(root, predicate) {
@@ -19446,9 +20023,9 @@ function descendantsOfKind2(root, predicate) {
19446
20023
  const visit = (node) => {
19447
20024
  if (predicate(node))
19448
20025
  result.push(node);
19449
- ts6.forEachChild(node, visit);
20026
+ ts9.forEachChild(node, visit);
19450
20027
  };
19451
- ts6.forEachChild(root, visit);
20028
+ ts9.forEachChild(root, visit);
19452
20029
  return result;
19453
20030
  }
19454
20031
  function makeDiagnostic(code, message, fileOrSourceFile, node, strict, rootDir) {
@@ -19469,7 +20046,7 @@ function normalizeRelative(rootDir, filePath) {
19469
20046
  return relative3(rootDir, filePath).split(sep3).join("/").replace(/^\.\//, "");
19470
20047
  }
19471
20048
  function isAnyKeyword(node) {
19472
- return node.kind === ts6.SyntaxKind.AnyKeyword;
20049
+ return node.kind === ts9.SyntaxKind.AnyKeyword;
19473
20050
  }
19474
20051
 
19475
20052
  // src/compile.ts
@@ -19870,8 +20447,8 @@ function formatDeliveryPlan(result) {
19870
20447
  // src/delivery-build.ts
19871
20448
  import { mkdir as mkdir3, mkdtemp, readFile as readFile5, realpath as realpath3, rename as rename3, rm as rm2 } from "node:fs/promises";
19872
20449
  import { readFileSync as readFileSync3 } from "node:fs";
19873
- import { dirname as dirname7, join as join9, relative as relative7, resolve as resolve10, sep as sep7 } from "node:path";
19874
- import * as ts11 from "@typescript/typescript6";
20450
+ import { dirname as dirname7, join as join9, relative as relative7, resolve as resolve11, sep as sep7 } from "node:path";
20451
+ import * as ts14 from "@typescript/typescript6";
19875
20452
 
19876
20453
  // src/delivery-build-schema.ts
19877
20454
  init_delivery_build_schema();
@@ -19912,23 +20489,23 @@ function renderDeliveryTarget(graph, target, options) {
19912
20489
  init_delivery_files2();
19913
20490
  import { isBuiltin } from "node:module";
19914
20491
  import { readFile as readFile4 } from "node:fs/promises";
19915
- import { join as join7, resolve as resolve7 } from "node:path";
19916
- import * as ts10 from "@typescript/typescript6";
20492
+ import { join as join7, resolve as resolve8 } from "node:path";
20493
+ import * as ts13 from "@typescript/typescript6";
19917
20494
 
19918
20495
  // src/delivery-imports.ts
19919
- import * as ts9 from "@typescript/typescript6";
20496
+ import * as ts12 from "@typescript/typescript6";
19920
20497
  function staticDeliveryImports(path, contents) {
19921
20498
  if (!/\.[cm]?[jt]sx?$/.test(path))
19922
20499
  return contents;
19923
- const source = ts9.createSourceFile(path, new TextDecoder().decode(contents), ts9.ScriptTarget.Latest, true);
20500
+ const source = ts12.createSourceFile(path, new TextDecoder().decode(contents), ts12.ScriptTarget.Latest, true);
19924
20501
  const computed = [];
19925
20502
  function scan(node) {
19926
- if (ts9.isCallExpression(node) && (node.expression.kind === ts9.SyntaxKind.ImportKeyword || ts9.isIdentifier(node.expression) && node.expression.text === "require")) {
20503
+ if (ts12.isCallExpression(node) && (node.expression.kind === ts12.SyntaxKind.ImportKeyword || ts12.isIdentifier(node.expression) && node.expression.text === "require")) {
19927
20504
  const argument = node.arguments[0];
19928
- if (!argument || !ts9.isStringLiteral(argument) && !ts9.isNoSubstitutionTemplateLiteral(argument))
20505
+ if (!argument || !ts12.isStringLiteral(argument) && !ts12.isNoSubstitutionTemplateLiteral(argument))
19929
20506
  computed.push(node);
19930
20507
  }
19931
- ts9.forEachChild(node, scan);
20508
+ ts12.forEachChild(node, scan);
19932
20509
  }
19933
20510
  scan(source);
19934
20511
  if (computed.length === 0)
@@ -19936,36 +20513,36 @@ function staticDeliveryImports(path, contents) {
19936
20513
  const reject = () => {
19937
20514
  throw new Error("Computed module loading is not supported in independent delivery bundles.");
19938
20515
  };
19939
- if (!ts9.isExternalModule(source))
20516
+ if (!ts12.isExternalModule(source))
19940
20517
  return reject();
19941
- const host = ts9.createCompilerHost({ noLib: true, noResolve: true, allowJs: true });
20518
+ const host = ts12.createCompilerHost({ noLib: true, noResolve: true, allowJs: true });
19942
20519
  host.getSourceFile = (name) => name === path ? source : undefined;
19943
- const checker = ts9.createProgram([path], { noLib: true, noResolve: true, allowJs: true }, host).getTypeChecker();
20520
+ const checker = ts12.createProgram([path], { noLib: true, noResolve: true, allowJs: true }, host).getTypeChecker();
19944
20521
  const replacements = new Map;
19945
20522
  const removed = new Set;
19946
20523
  for (const call of computed) {
19947
20524
  let visit = function(node) {
19948
- const referenced = ts9.isIdentifier(node) ? ts9.isShorthandPropertyAssignment(node.parent) ? checker.getShorthandAssignmentValueSymbol(node.parent) : ts9.isExportSpecifier(node.parent) ? checker.getExportSpecifierLocalTargetSymbol(node.parent) : checker.getSymbolAtLocation(node) : undefined;
19949
- if (ts9.isIdentifier(node) && node !== declarationName && referenced === symbol) {
20525
+ const referenced = ts12.isIdentifier(node) ? ts12.isShorthandPropertyAssignment(node.parent) ? checker.getShorthandAssignmentValueSymbol(node.parent) : ts12.isExportSpecifier(node.parent) ? checker.getExportSpecifierLocalTargetSymbol(node.parent) : checker.getSymbolAtLocation(node) : undefined;
20526
+ if (ts12.isIdentifier(node) && node !== declarationName && referenced === symbol) {
19950
20527
  const use = node.parent;
19951
- if (!ts9.isCallExpression(use) || use.expression !== node || use.arguments.length !== 1 || use.questionDotToken || use.typeArguments?.length)
20528
+ if (!ts12.isCallExpression(use) || use.expression !== node || use.arguments.length !== 1 || use.questionDotToken || use.typeArguments?.length)
19952
20529
  return reject();
19953
20530
  const value = use.arguments[0];
19954
- if (!value || !ts9.isStringLiteral(value) && !ts9.isNoSubstitutionTemplateLiteral(value))
20531
+ if (!value || !ts12.isStringLiteral(value) && !ts12.isNoSubstitutionTemplateLiteral(value))
19955
20532
  return reject();
19956
20533
  references++;
19957
- replacements.set(use, ts9.factory.createCallExpression(call.expression, undefined, [value]));
20534
+ replacements.set(use, ts12.factory.createCallExpression(call.expression, undefined, [value]));
19958
20535
  }
19959
- ts9.forEachChild(node, visit);
20536
+ ts12.forEachChild(node, visit);
19960
20537
  };
19961
20538
  const statement = call.parent;
19962
20539
  const block = statement.parent;
19963
20540
  const declaration = block.parent;
19964
- if (call.expression.kind !== ts9.SyntaxKind.ImportKeyword || call.arguments.length !== 1 || !ts9.isReturnStatement(statement) || !ts9.isBlock(block) || block.statements.length !== 1 || !ts9.isFunctionDeclaration(declaration) || declaration.parent !== source || !declaration.name || declaration.modifiers?.length || declaration.asteriskToken || declaration.typeParameters?.length || declaration.parameters.length !== 1)
20541
+ if (call.expression.kind !== ts12.SyntaxKind.ImportKeyword || call.arguments.length !== 1 || !ts12.isReturnStatement(statement) || !ts12.isBlock(block) || block.statements.length !== 1 || !ts12.isFunctionDeclaration(declaration) || declaration.parent !== source || !declaration.name || declaration.modifiers?.length || declaration.asteriskToken || declaration.typeParameters?.length || declaration.parameters.length !== 1)
19965
20542
  return reject();
19966
20543
  const parameter = declaration.parameters[0];
19967
20544
  const argument = call.arguments[0];
19968
- if (!parameter || !ts9.isIdentifier(parameter.name) || parameter.initializer || parameter.dotDotDotToken || !argument || !ts9.isIdentifier(argument) || checker.getSymbolAtLocation(argument) !== checker.getSymbolAtLocation(parameter.name))
20545
+ if (!parameter || !ts12.isIdentifier(parameter.name) || parameter.initializer || parameter.dotDotDotToken || !argument || !ts12.isIdentifier(argument) || checker.getSymbolAtLocation(argument) !== checker.getSymbolAtLocation(parameter.name))
19969
20546
  return reject();
19970
20547
  const symbol = checker.getSymbolAtLocation(declaration.name);
19971
20548
  if (!symbol || symbol.declarations?.length !== 1)
@@ -19977,22 +20554,22 @@ function staticDeliveryImports(path, contents) {
19977
20554
  return reject();
19978
20555
  removed.add(declaration);
19979
20556
  }
19980
- const transformed = ts9.transform(source, [(context) => {
20557
+ const transformed = ts12.transform(source, [(context) => {
19981
20558
  const visit = (node) => {
19982
- if (ts9.isFunctionDeclaration(node) && removed.has(node))
20559
+ if (ts12.isFunctionDeclaration(node) && removed.has(node))
19983
20560
  return;
19984
- const replacement = ts9.isCallExpression(node) ? replacements.get(node) : undefined;
20561
+ const replacement = ts12.isCallExpression(node) ? replacements.get(node) : undefined;
19985
20562
  if (replacement)
19986
20563
  return replacement;
19987
- return ts9.visitEachChild(node, visit, context);
20564
+ return ts12.visitEachChild(node, visit, context);
19988
20565
  };
19989
- return (node) => ts9.visitNode(node, visit, ts9.isSourceFile) ?? node;
20566
+ return (node) => ts12.visitNode(node, visit, ts12.isSourceFile) ?? node;
19990
20567
  }]);
19991
20568
  try {
19992
20569
  const transformedSource = transformed.transformed[0];
19993
20570
  if (!transformedSource)
19994
20571
  return reject();
19995
- return new TextEncoder().encode(ts9.createPrinter().printFile(transformedSource));
20572
+ return new TextEncoder().encode(ts12.createPrinter().printFile(transformedSource));
19996
20573
  } finally {
19997
20574
  transformed.dispose();
19998
20575
  }
@@ -20089,7 +20666,7 @@ async function bundleDeliveryTarget(name, code, project, generatedDirectory, opt
20089
20666
  async function bundleDeliveryTargetInProcess(name, code, project, generatedDirectory, options) {
20090
20667
  const inputs = new Map;
20091
20668
  const workingDirectory = process.cwd();
20092
- const entry = resolve7(generatedDirectory, `delivery-${name}.ts`);
20669
+ const entry = resolve8(generatedDirectory, `delivery-${name}.ts`);
20093
20670
  const entryPattern = new RegExp(`^${entry.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`);
20094
20671
  const result = await Bun.build({
20095
20672
  entrypoints: [entry],
@@ -20112,7 +20689,7 @@ async function bundleDeliveryTargetInProcess(name, code, project, generatedDirec
20112
20689
  if (args.path === entry)
20113
20690
  return { contents: code, loader: "ts" };
20114
20691
  const bytes = await readFile4(args.path);
20115
- inputs.set(resolve7(args.path), digest(bytes));
20692
+ inputs.set(resolve8(args.path), digest(bytes));
20116
20693
  return { contents: staticDeliveryImports(args.path, bytes), loader: args.loader };
20117
20694
  });
20118
20695
  }
@@ -20122,7 +20699,7 @@ async function bundleDeliveryTargetInProcess(name, code, project, generatedDirec
20122
20699
  throw new Error("Independent bundle failed or has no dependency metadata.");
20123
20700
  const runtimeImports = new Set;
20124
20701
  for (const [path, metadata] of Object.entries(result.metafile.inputs)) {
20125
- if (resolve7(workingDirectory, path) !== entry && !inputs.has(resolve7(workingDirectory, path))) {
20702
+ if (resolve8(workingDirectory, path) !== entry && !inputs.has(resolve8(workingDirectory, path))) {
20126
20703
  throw new Error("Bundler reported an input that was not captured by the delivery snapshot.");
20127
20704
  }
20128
20705
  for (const imported of metadata.imports) {
@@ -20140,16 +20717,16 @@ async function bundleDeliveryTargetInProcess(name, code, project, generatedDirec
20140
20717
  const bytes = new Uint8Array(await output.arrayBuffer());
20141
20718
  if (/\.[cm]?js$/.test(path)) {
20142
20719
  let check = function(node) {
20143
- const specifier = ts10.isImportDeclaration(node) || ts10.isExportDeclaration(node) ? node.moduleSpecifier : ts10.isCallExpression(node) && (node.expression.kind === ts10.SyntaxKind.ImportKeyword || ts10.isIdentifier(node.expression) && /^(?:__)?require$/.test(node.expression.text) || ts10.isPropertyAccessExpression(node.expression) && node.expression.name.text === "require" && ts10.isMetaProperty(node.expression.expression) && node.expression.expression.keywordToken === ts10.SyntaxKind.ImportKeyword) ? node.arguments[0] : undefined;
20144
- if (specifier && ts10.isStringLiteralLike(specifier)) {
20720
+ const specifier = ts13.isImportDeclaration(node) || ts13.isExportDeclaration(node) ? node.moduleSpecifier : ts13.isCallExpression(node) && (node.expression.kind === ts13.SyntaxKind.ImportKeyword || ts13.isIdentifier(node.expression) && /^(?:__)?require$/.test(node.expression.text) || ts13.isPropertyAccessExpression(node.expression) && node.expression.name.text === "require" && ts13.isMetaProperty(node.expression.expression) && node.expression.expression.keywordToken === ts13.SyntaxKind.ImportKeyword) ? node.arguments[0] : undefined;
20721
+ if (specifier && ts13.isStringLiteralLike(specifier)) {
20145
20722
  if (!isBuiltin(specifier.text) && specifier.text !== "bun" && !specifier.text.startsWith("bun:")) {
20146
20723
  throw new Error("Independent bundles cannot retain external package imports.");
20147
20724
  }
20148
20725
  runtimeImports.add(specifier.text);
20149
20726
  }
20150
- ts10.forEachChild(node, check);
20727
+ ts13.forEachChild(node, check);
20151
20728
  };
20152
- const source = ts10.createSourceFile(path, new TextDecoder().decode(bytes), ts10.ScriptTarget.Latest, true);
20729
+ const source = ts13.createSourceFile(path, new TextDecoder().decode(bytes), ts13.ScriptTarget.Latest, true);
20153
20730
  check(source);
20154
20731
  }
20155
20732
  files.set(`bundle/${path}`, bytes);
@@ -20439,14 +21016,14 @@ interface DeliveryWorkerHost {
20439
21016
 
20440
21017
  // src/delivery-migrations.ts
20441
21018
  init_delivery_files2();
20442
- import { resolve as resolve9 } from "node:path";
21019
+ import { resolve as resolve10 } from "node:path";
20443
21020
  async function prepareDeliveryMigrations(project, generatedRoot, declarations = []) {
20444
21021
  const entries = [];
20445
21022
  const files = new Map;
20446
21023
  const inputs = new Map;
20447
21024
  let totalBytes = 0;
20448
21025
  for (const declaration of [...declarations].sort((a, b) => BigInt(a.version) < BigInt(b.version) ? -1 : BigInt(a.version) > BigInt(b.version) ? 1 : 0)) {
20449
- const source = resolve9(project, declaration.source);
21026
+ const source = resolve10(project, declaration.source);
20450
21027
  if (!inside(project, source) || inside(generatedRoot, source))
20451
21028
  throw new Error("Invalid migration source.");
20452
21029
  const bytes = await readBoundedOwned(project, source, 1048576);
@@ -20497,7 +21074,7 @@ async function buildDeliveryProject(options, delivery) {
20497
21074
  const settings = parseDeliveryOptions(delivery);
20498
21075
  if (typeof Bun === "undefined")
20499
21076
  throw new Error("Independent delivery builds require Bun.");
20500
- const configPath = ts11.findConfigFile(resolve10(options.rootDir), ts11.sys.fileExists);
21077
+ const configPath = ts14.findConfigFile(resolve11(options.rootDir), ts14.sys.fileExists);
20501
21078
  if (!configPath)
20502
21079
  throw new Error("Independent delivery builds require a project tsconfig.json.");
20503
21080
  const lexicalProject = dirname7(configPath);
@@ -20505,19 +21082,19 @@ async function buildDeliveryProject(options, delivery) {
20505
21082
  const sourceRoot = await realpath3(options.rootDir);
20506
21083
  if (!inside(project, sourceRoot))
20507
21084
  throw new Error("Application sources must be inside the project.");
20508
- const requested = resolve10(options.outDir, "delivery");
21085
+ const requested = resolve11(options.outDir, "delivery");
20509
21086
  if (!inside(lexicalProject, requested))
20510
21087
  throw new Error("Output must be inside the application project.");
20511
- const buildRoot = resolve10(project, relative7(lexicalProject, requested));
20512
- const generatedRoot = resolve10(project, relative7(lexicalProject, options.outDir));
21088
+ const buildRoot = resolve11(project, relative7(lexicalProject, requested));
21089
+ const generatedRoot = resolve11(project, relative7(lexicalProject, options.outDir));
20513
21090
  if (inside(generatedRoot, sourceRoot))
20514
21091
  throw new Error("Output must not contain the application source root.");
20515
21092
  const configInputs = new Map;
20516
- const parsedConfig = ts11.getParsedCommandLineOfConfigFile(await realpath3(configPath), {}, {
20517
- ...ts11.sys,
21093
+ const parsedConfig = ts14.getParsedCommandLineOfConfigFile(await realpath3(configPath), {}, {
21094
+ ...ts14.sys,
20518
21095
  readFile(path) {
20519
21096
  const contents = readFileSync3(path, "utf8");
20520
- configInputs.set(resolve10(path), digest(contents));
21097
+ configInputs.set(resolve11(path), digest(contents));
20521
21098
  return contents;
20522
21099
  },
20523
21100
  onUnRecoverableConfigFileDiagnostic() {
@@ -20555,7 +21132,7 @@ async function buildDeliveryProject(options, delivery) {
20555
21132
  if (!target || (kind === "worker" ? target.kind !== "jobs" : target.kind === "jobs")) {
20556
21133
  throw new Error("Delivery host kind does not match its target.");
20557
21134
  }
20558
- const path = resolve10(sourceRoot, app.source);
21135
+ const path = resolve11(sourceRoot, app.source);
20559
21136
  if (inside(generatedRoot, path) || !/\.[cm]?ts$/.test(path))
20560
21137
  throw new Error("Hosts require application TypeScript source.");
20561
21138
  hosts.set(app.target, { path, kind, hash: digest(await readOwned(sourceRoot, path)) });
@@ -20634,7 +21211,7 @@ async function buildDeliveryProject(options, delivery) {
20634
21211
  for (const [name, contents] of Object.entries(generated))
20635
21212
  await writeArtifact(stage, `generated/${name}`, contents);
20636
21213
  {
20637
- const program = ts11.createProgram({
21214
+ const program = ts14.createProgram({
20638
21215
  rootNames: [
20639
21216
  ...parsedConfig.fileNames.filter((path) => !inside(generatedRoot, path)),
20640
21217
  ...Object.keys(generated).map((name) => join9(stage, "generated", name))
@@ -20642,12 +21219,12 @@ async function buildDeliveryProject(options, delivery) {
20642
21219
  options: { ...parsedConfig.options, rootDir: project },
20643
21220
  ...parsedConfig.projectReferences ? { projectReferences: parsedConfig.projectReferences } : {}
20644
21221
  });
20645
- const diagnostics = ts11.getPreEmitDiagnostics(program);
20646
- if (diagnostics.some((item) => item.category === ts11.DiagnosticCategory.Error)) {
20647
- return failed(diagnostics.filter((item) => item.category === ts11.DiagnosticCategory.Error).map((item) => ({
21222
+ const diagnostics = ts14.getPreEmitDiagnostics(program);
21223
+ if (diagnostics.some((item) => item.category === ts14.DiagnosticCategory.Error)) {
21224
+ return failed(diagnostics.filter((item) => item.category === ts14.DiagnosticCategory.Error).map((item) => ({
20648
21225
  severity: "error",
20649
21226
  code: "delivery-generated-type-error",
20650
- message: ts11.flattenDiagnosticMessageText(item.messageText, `
21227
+ message: ts14.flattenDiagnosticMessageText(item.messageText, `
20651
21228
  `),
20652
21229
  ...item.file ? { file: item.file.fileName } : {}
20653
21230
  })));
@@ -20682,7 +21259,7 @@ async function buildDeliveryProject(options, delivery) {
20682
21259
  }));
20683
21260
  const assetInputs = {};
20684
21261
  for (const asset of assets.filter((asset) => asset.target === target.name)) {
20685
- const path = resolve10(sourceRoot, asset.source);
21262
+ const path = resolve11(sourceRoot, asset.source);
20686
21263
  const bytes = await readOwned(sourceRoot, path);
20687
21264
  const hash = digest(bytes);
20688
21265
  const previousHash = snapshots.get(path);
@@ -20793,210 +21370,7 @@ async function buildDeliveryProject(options, delivery) {
20793
21370
  // src/index.ts
20794
21371
  init_delivery_migration_archive2();
20795
21372
  init_feature();
20796
-
20797
- // src/fixes.ts
20798
- import { randomUUID } from "node:crypto";
20799
- import { lstat as lstat2, readFile as readFile6, realpath as realpath4, rename as rename4, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
20800
- import { dirname as dirname8, isAbsolute as isAbsolute3, relative as relative8, resolve as resolve11, sep as sep8 } from "node:path";
20801
- import * as ts12 from "@typescript/typescript6";
20802
- async function applyDiagnosticFix(fix, options = {}) {
20803
- if (!fix || typeof fix.targetFile !== "string")
20804
- throw new Error("Invalid DiagnosticFix");
20805
- const root = await realpath4(options.rootDir ?? process.cwd());
20806
- const file = resolve11(root, fix.targetFile);
20807
- const stat = await lstat2(file);
20808
- const resolved = await realpath4(file);
20809
- const relativePath = relative8(root, resolved);
20810
- if (stat.isSymbolicLink() || !stat.isFile() || isAbsolute3(relativePath) || relativePath === ".." || relativePath.startsWith(`..${sep8}`)) {
20811
- throw new Error("Fix target must be a regular file inside rootDir");
20812
- }
20813
- const original = await readFile6(file, "utf8");
20814
- let source = parse5(file, original);
20815
- let content;
20816
- switch (fix.type) {
20817
- case "set_command_mode": {
20818
- if (fix.property !== "transaction" && fix.property !== "idempotency" || fix.value !== "required" && fix.value !== "none") {
20819
- throw new Error("Command mode fix requires an explicit property and policy value");
20820
- }
20821
- const object = decoratorObject(findClass(source, fix.command), "Command");
20822
- const current = property(object, fix.property);
20823
- if (!current || current.initializer.getText(source) !== fix.expectedExpression) {
20824
- throw new Error("Command mode changed since diagnosis; analyze the project again");
20825
- }
20826
- content = replaceProperty(source, object, fix.property, ts12.factory.createStringLiteral(fix.value));
20827
- break;
20828
- }
20829
- case "add_module_import": {
20830
- if (!fix.importPath || !fix.symbol)
20831
- throw new Error("Module fix requires importPath and symbol");
20832
- identifier2(fix.symbol);
20833
- const withImport = importSymbol(source, fix.importPath, fix.symbol);
20834
- source = parse5(file, withImport);
20835
- const object = unique(moduleObjects(source).filter((candidate) => !fix.targetModule || stringProperty(candidate, "name") === fix.targetModule), "target module");
20836
- const imports = property(object, "imports");
20837
- if (imports && !ts12.isArrayLiteralExpression(imports.initializer)) {
20838
- throw new Error("Module imports must be a static array");
20839
- }
20840
- const values = imports && ts12.isArrayLiteralExpression(imports.initializer) ? imports.initializer.elements : [];
20841
- if (values.some(ts12.isSpreadElement))
20842
- throw new Error("Module imports cannot contain spread elements");
20843
- content = values.some((value) => ts12.isIdentifier(value) && value.text === fix.symbol) ? withImport : replaceProperty(source, object, "imports", ts12.factory.createArrayLiteralExpression([
20844
- ...values,
20845
- ts12.factory.createIdentifier(fix.symbol)
20846
- ]));
20847
- break;
20848
- }
20849
- case "add_command_permission": {
20850
- const permission = options.permission ?? fix.permission;
20851
- if (!permission?.trim()) {
20852
- throw new Error("Permission fix requires an explicit permission; privileges are never inferred");
20853
- }
20854
- const command = findClass(source, fix.command);
20855
- const object = decoratorObject(command, "Command");
20856
- const current = property(object, "permission");
20857
- if (current && (!ts12.isStringLiteral(current.initializer) || current.initializer.text !== permission)) {
20858
- throw new Error("Command permission already exists with a different value");
20859
- }
20860
- content = current ? original : replaceProperty(source, object, "permission", ts12.factory.createStringLiteral(permission));
20861
- break;
20862
- }
20863
- case "add_route_parameter_binding": {
20864
- const controller = findClass(source, fix.controller);
20865
- const method = unique(controller.members.filter((member) => ts12.isMethodDeclaration(member) && nameOf(member.name) === fix.route), "route handler");
20866
- const parameter = unique(method.parameters.filter((candidate) => ts12.isIdentifier(candidate.name) && candidate.name.text === fix.parameter), "same-named route parameter");
20867
- const binding = fix.binding === "param" ? "Param" : fix.binding === "query" ? "Query" : undefined;
20868
- if (!binding)
20869
- throw new Error("Invalid route binding");
20870
- const decorators = ts12.getDecorators(parameter) ?? [];
20871
- if (decorators.length > 0)
20872
- throw new Error("Parameter already has a decorator");
20873
- const framework = unique(source.statements.filter((statement) => ts12.isImportDeclaration(statement) && statement.importClause?.namedBindings && ts12.isNamedImports(statement.importClause.namedBindings) && statement.importClause.namedBindings.elements.some((element) => ["Controller", "Get", "Post", "Put", "Patch", "Delete", "Head", "Options"].includes(element.name.text))), "framework import");
20874
- if (!ts12.isImportDeclaration(framework) || !ts12.isStringLiteral(framework.moduleSpecifier)) {
20875
- throw new Error("Framework import must be static");
20876
- }
20877
- const edited = original.slice(0, parameter.getStart(source)) + `@${binding}(${JSON.stringify(fix.parameter)}) ` + original.slice(parameter.getStart(source));
20878
- content = importSymbol(parse5(file, edited), framework.moduleSpecifier.text, binding);
20879
- break;
20880
- }
20881
- default:
20882
- throw new Error(`Diagnostic fix '${fix.type}' requires a manual semantic decision; no files changed`);
20883
- }
20884
- parse5(file, content);
20885
- const result = { file, changed: content !== original, content };
20886
- if (options.dryRun === false && result.changed) {
20887
- const temporary = `${file}.supacloud-fix-${randomUUID()}`;
20888
- try {
20889
- await writeFile3(temporary, content, { encoding: "utf8", flag: "wx", mode: stat.mode });
20890
- if (await readFile6(file, "utf8") !== original)
20891
- throw new Error("Target changed while preparing the fix");
20892
- await rename4(temporary, file);
20893
- } finally {
20894
- await unlink2(temporary).catch(() => {});
20895
- }
20896
- }
20897
- return result;
20898
- }
20899
- function parse5(file, text) {
20900
- const result = ts12.transpileModule(text, {
20901
- fileName: file,
20902
- reportDiagnostics: true,
20903
- compilerOptions: { target: ts12.ScriptTarget.ESNext, experimentalDecorators: true }
20904
- });
20905
- if (result.diagnostics?.some((item) => item.category === ts12.DiagnosticCategory.Error)) {
20906
- throw new Error("Cannot fix syntactically invalid TypeScript");
20907
- }
20908
- return ts12.createSourceFile(file, text, ts12.ScriptTarget.Latest, true, ts12.ScriptKind.TS);
20909
- }
20910
- function unique(items, description) {
20911
- if (items.length !== 1)
20912
- throw new Error(`Expected exactly one ${description}; found ${items.length}`);
20913
- return items[0];
20914
- }
20915
- function identifier2(value) {
20916
- if (!/^[A-Za-z_$][\w$]*$/.test(value))
20917
- throw new Error(`Invalid identifier '${value}'`);
20918
- }
20919
- function nameOf(name) {
20920
- if (!name)
20921
- return "";
20922
- return ts12.isIdentifier(name) || ts12.isStringLiteral(name) || ts12.isNumericLiteral(name) ? name.text : "";
20923
- }
20924
- function property(object, key) {
20925
- if (object.properties.some((item) => !ts12.isPropertyAssignment(item) || ts12.isComputedPropertyName(item.name))) {
20926
- throw new Error("Fix requires explicit static object properties");
20927
- }
20928
- const values = object.properties.filter((item) => ts12.isPropertyAssignment(item) && nameOf(item.name) === key);
20929
- if (values.length > 1)
20930
- throw new Error(`Duplicate '${key}' property`);
20931
- return values[0];
20932
- }
20933
- function stringProperty(object, key) {
20934
- const value = property(object, key)?.initializer;
20935
- return value && ts12.isStringLiteral(value) ? value.text : undefined;
20936
- }
20937
- function replaceProperty(source, object, key, value) {
20938
- const previous = property(object, key);
20939
- const replacement = ts12.factory.createPropertyAssignment(key, value);
20940
- const properties = object.properties.map((item) => item === previous ? replacement : item);
20941
- if (!previous)
20942
- properties.push(replacement);
20943
- const updated = ts12.factory.updateObjectLiteralExpression(object, properties);
20944
- return source.text.slice(0, object.getStart(source)) + ts12.createPrinter().printNode(ts12.EmitHint.Expression, updated, source) + source.text.slice(object.end);
20945
- }
20946
- function findClass(source, name) {
20947
- return unique(source.statements.filter((statement) => ts12.isClassDeclaration(statement) && statement.name?.text === name), `class '${name}'`);
20948
- }
20949
- function decoratorObject(node, name) {
20950
- const decorator = unique((ts12.getDecorators(node) ?? []).filter((item) => ts12.isCallExpression(item.expression) && item.expression.expression.getText() === name), `@${name} decorator`);
20951
- const argument = ts12.isCallExpression(decorator.expression) ? decorator.expression.arguments[0] : undefined;
20952
- if (!argument || !ts12.isObjectLiteralExpression(argument))
20953
- throw new Error(`@${name} requires a static object`);
20954
- return argument;
20955
- }
20956
- function moduleObjects(source) {
20957
- const result = [];
20958
- for (const statement of source.statements) {
20959
- if (ts12.isClassDeclaration(statement) && (ts12.getDecorators(statement) ?? []).some((item) => ts12.isCallExpression(item.expression) && item.expression.expression.getText() === "Module")) {
20960
- result.push(decoratorObject(statement, "Module"));
20961
- }
20962
- if (ts12.isVariableStatement(statement)) {
20963
- for (const declaration of statement.declarationList.declarations) {
20964
- const call = declaration.initializer;
20965
- if (call && ts12.isCallExpression(call) && ["defineModule", "defineFeatureSlice"].includes(call.expression.getText()) && call.arguments[0] && ts12.isObjectLiteralExpression(call.arguments[0])) {
20966
- result.push(call.arguments[0]);
20967
- }
20968
- }
20969
- }
20970
- }
20971
- return result;
20972
- }
20973
- function importSymbol(source, path, symbol) {
20974
- identifier2(symbol);
20975
- const current = resolve11(source.fileName).replace(/\.(tsx?|mts|cts)$/, "");
20976
- const target = resolve11(dirname8(source.fileName), path).replace(/\.(tsx?|mts|cts)$/, "");
20977
- if (current === target)
20978
- return source.text;
20979
- const matches = source.statements.filter((item) => ts12.isImportDeclaration(item) && ts12.isStringLiteral(item.moduleSpecifier) && item.moduleSpecifier.text === path);
20980
- if (matches.length > 1)
20981
- throw new Error(`Ambiguous imports from '${path}'`);
20982
- const match = matches[0];
20983
- if (match && ts12.isImportDeclaration(match) && match.importClause?.namedBindings && ts12.isNamedImports(match.importClause.namedBindings) && !match.importClause.isTypeOnly) {
20984
- if (match.importClause.namedBindings.elements.some((item) => item.name.text === symbol))
20985
- return source.text;
20986
- const bindings = match.importClause.namedBindings;
20987
- const updated = ts12.factory.updateNamedImports(bindings, [
20988
- ...bindings.elements,
20989
- ts12.factory.createImportSpecifier(false, undefined, ts12.factory.createIdentifier(symbol))
20990
- ]);
20991
- return source.text.slice(0, bindings.getStart(source)) + ts12.createPrinter().printNode(ts12.EmitHint.Unspecified, updated, source) + source.text.slice(bindings.end);
20992
- }
20993
- if (match)
20994
- throw new Error(`Import from '${path}' is not a named value import`);
20995
- return `import { ${symbol} } from ${JSON.stringify(path)};
20996
- ${source.text}`;
20997
- }
20998
-
20999
- // src/index.ts
21373
+ init_fixes();
21000
21374
  init_execution_context();
21001
21375
  init_delivery_context();
21002
21376
  init_application_development2();
@@ -21220,12 +21594,12 @@ init_release_evidence();
21220
21594
 
21221
21595
  // src/watch.ts
21222
21596
  import { existsSync as existsSync4, watch } from "node:fs";
21223
- import { dirname as dirname9, relative as relative10, resolve as resolve13, sep as sep10 } from "node:path";
21597
+ import { dirname as dirname9, relative as relative10, resolve as resolve14, sep as sep10 } from "node:path";
21224
21598
 
21225
21599
  // src/incremental.ts
21226
- import { createHash as createHash8 } from "node:crypto";
21600
+ import { createHash as createHash9 } from "node:crypto";
21227
21601
  import { access as access3, readdir as readdir3, readFile as readFile7 } from "node:fs/promises";
21228
- import { isAbsolute as isAbsolute4, relative as relative9, resolve as resolve12, sep as sep9 } from "node:path";
21602
+ import { isAbsolute as isAbsolute4, relative as relative9, resolve as resolve13, sep as sep9 } from "node:path";
21229
21603
  init_graphql_inputs();
21230
21604
  function createDependencyGraphCache() {
21231
21605
  return {
@@ -21306,11 +21680,11 @@ async function readSourceBytes(path) {
21306
21680
  return readFile7(path);
21307
21681
  }
21308
21682
  async function updateSnapshot(previous, options, changedPaths) {
21309
- const rootDir = resolve12(options.rootDir);
21310
- const outDir = resolve12(options.outDir);
21683
+ const rootDir = resolve13(options.rootDir);
21684
+ const outDir = resolve13(options.outDir);
21311
21685
  const files = { ...previous.files };
21312
21686
  await Promise.all(changedPaths.map(async (changedPath) => {
21313
- const absolutePath = isAbsolute4(changedPath) ? resolve12(changedPath) : resolve12(rootDir, changedPath);
21687
+ const absolutePath = isAbsolute4(changedPath) ? resolve13(changedPath) : resolve13(rootDir, changedPath);
21314
21688
  const relativeChangedPath = relative9(rootDir, absolutePath);
21315
21689
  if (relativeChangedPath === ".." || relativeChangedPath.startsWith(`..${sep9}`))
21316
21690
  return;
@@ -21320,7 +21694,7 @@ async function updateSnapshot(previous, options, changedPaths) {
21320
21694
  try {
21321
21695
  await access3(absolutePath);
21322
21696
  const content = await readSourceBytes(absolutePath);
21323
- files[relativePath] = createHash8("sha256").update(content).digest("hex");
21697
+ files[relativePath] = createHash9("sha256").update(content).digest("hex");
21324
21698
  } catch {
21325
21699
  delete files[relativePath];
21326
21700
  }
@@ -21328,14 +21702,14 @@ async function updateSnapshot(previous, options, changedPaths) {
21328
21702
  return { files, optionsKey: optionsKeyOf(options) };
21329
21703
  }
21330
21704
  async function createSnapshot(options) {
21331
- const rootDir = resolve12(options.rootDir);
21332
- const outDir = resolve12(options.outDir);
21705
+ const rootDir = resolve13(options.rootDir);
21706
+ const outDir = resolve13(options.outDir);
21333
21707
  const paths = await listSourceFiles(rootDir, outDir);
21334
21708
  const files = {};
21335
21709
  const entries = await Promise.all(paths.map(async (path) => {
21336
21710
  const content = await readSourceBytes(path);
21337
21711
  const key = relative9(rootDir, path).split(sep9).join("/");
21338
- return [key, createHash8("sha256").update(content).digest("hex")];
21712
+ return [key, createHash9("sha256").update(content).digest("hex")];
21339
21713
  }));
21340
21714
  for (const [key, hash] of entries)
21341
21715
  files[key] = hash;
@@ -21343,7 +21717,7 @@ async function createSnapshot(options) {
21343
21717
  const key = relative9(rootDir, path).split(sep9).join("/");
21344
21718
  try {
21345
21719
  const content = await readSourceBytes(path);
21346
- files[key] = createHash8("sha256").update(content).digest("hex");
21720
+ files[key] = createHash9("sha256").update(content).digest("hex");
21347
21721
  } catch {
21348
21722
  files[key] = "missing";
21349
21723
  }
@@ -21352,8 +21726,8 @@ async function createSnapshot(options) {
21352
21726
  }
21353
21727
  function optionsKeyOf(options) {
21354
21728
  return JSON.stringify({
21355
- rootDir: resolve12(options.rootDir),
21356
- outDir: resolve12(options.outDir),
21729
+ rootDir: resolve13(options.rootDir),
21730
+ outDir: resolve13(options.outDir),
21357
21731
  include: options.include,
21358
21732
  strict: options.strict,
21359
21733
  writeOnError: options.writeOnError,
@@ -21377,7 +21751,7 @@ async function listSourceFiles(rootDir, outDir) {
21377
21751
  const result = [];
21378
21752
  const visit = async (directory) => {
21379
21753
  for (const entry of await readdir3(directory, { withFileTypes: true })) {
21380
- const path = resolve12(directory, entry.name);
21754
+ const path = resolve13(directory, entry.name);
21381
21755
  if (entry.isDirectory()) {
21382
21756
  if (entry.name === "node_modules" || entry.name === ".git" || path === outDir)
21383
21757
  continue;
@@ -21512,8 +21886,8 @@ function isCompilerConfigurationPath(rootDir, changedPath) {
21512
21886
  ].includes(relativePath) || /^tsconfig\.[^/]+\.json$/.test(relativePath);
21513
21887
  }
21514
21888
  function watchProject(options) {
21515
- const rootDir = resolve13(options.rootDir);
21516
- const outDir = resolve13(options.outDir);
21889
+ const rootDir = resolve14(options.rootDir);
21890
+ const outDir = resolve14(options.outDir);
21517
21891
  const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
21518
21892
  let timer;
21519
21893
  let closed = false;
@@ -21523,7 +21897,7 @@ function watchProject(options) {
21523
21897
  const pendingPaths = new Set;
21524
21898
  let watcher;
21525
21899
  let schemaWatcher;
21526
- const schemaPath = options.graphql ? resolve13(rootDir, options.graphql.schema) : undefined;
21900
+ const schemaPath = options.graphql ? resolve14(rootDir, options.graphql.schema) : undefined;
21527
21901
  const incremental = createIncrementalCompiler();
21528
21902
  let initialEvent;
21529
21903
  let resolveReady = () => {
@@ -21633,7 +22007,7 @@ function watchProject(options) {
21633
22007
  watcher = watch(rootDir, { recursive: true }, (_eventType, filename) => {
21634
22008
  if (!filename)
21635
22009
  return schedule();
21636
- const changedPath = resolve13(rootDir, filename.toString());
22010
+ const changedPath = resolve14(rootDir, filename.toString());
21637
22011
  const relativePath = relative10(outDir, changedPath);
21638
22012
  if (!relativePath.startsWith("..") && relativePath !== "")
21639
22013
  return;
@@ -21646,7 +22020,7 @@ function watchProject(options) {
21646
22020
  while (!existsSync4(directory) && dirname9(directory) !== directory)
21647
22021
  directory = dirname9(directory);
21648
22022
  schemaWatcher = watch(directory, { recursive: true }, (_eventType, filename) => {
21649
- if (!filename || resolve13(directory, filename.toString()) === schemaPath)
22023
+ if (!filename || resolve14(directory, filename.toString()) === schemaPath)
21650
22024
  schedule(schemaPath);
21651
22025
  });
21652
22026
  }
@@ -21669,13 +22043,13 @@ function watchProject(options) {
21669
22043
  }
21670
22044
  // src/migrations.ts
21671
22045
  import { rename as rename5, readFile as readFile9, writeFile as writeFile4, rm as rm3 } from "node:fs/promises";
21672
- import { relative as relative11, resolve as resolve15 } from "node:path";
21673
- import * as ts13 from "@typescript/typescript6";
22046
+ import { relative as relative11, resolve as resolve16 } from "node:path";
22047
+ import * as ts16 from "@typescript/typescript6";
21674
22048
 
21675
22049
  // src/migration-policy.ts
21676
22050
  import { readFile as readFile8 } from "node:fs/promises";
21677
22051
  import { readFileSync as readFileSync4 } from "node:fs";
21678
- import { resolve as resolve14 } from "node:path";
22052
+ import { resolve as resolve15 } from "node:path";
21679
22053
  var cachedCompilerVersion;
21680
22054
  function compilerVersion() {
21681
22055
  if (cachedCompilerVersion !== undefined)
@@ -21689,9 +22063,9 @@ function compilerVersion() {
21689
22063
  }
21690
22064
  function migrationDependencies() {
21691
22065
  return {
21692
- "@supacloud/app": "0.19.0",
22066
+ "@supacloud/app": "0.21.0",
21693
22067
  "@supacloud/compiler": compilerVersion(),
21694
- "@supacloud/elysia": "0.21.0",
22068
+ "@supacloud/elysia": "0.23.0",
21695
22069
  elysia: "2.0.0-beta.19",
21696
22070
  typescript: "7.0.2"
21697
22071
  };
@@ -21700,7 +22074,7 @@ async function checkMigrationDependencies(rootDir) {
21700
22074
  const problems = [];
21701
22075
  for (const [name, expected] of Object.entries(migrationDependencies())) {
21702
22076
  try {
21703
- const manifest = JSON.parse(await readFile8(resolve14(rootDir, "node_modules", name, "package.json"), "utf8"));
22077
+ const manifest = JSON.parse(await readFile8(resolve15(rootDir, "node_modules", name, "package.json"), "utf8"));
21704
22078
  if (!manifest || typeof manifest !== "object" || !("name" in manifest) || manifest.name !== name || !("version" in manifest) || manifest.version !== expected) {
21705
22079
  problems.push(`${name}: requires tested installed version ${expected}`);
21706
22080
  }
@@ -21714,29 +22088,29 @@ async function checkMigrationDependencies(rootDir) {
21714
22088
  // src/migrations.ts
21715
22089
  var ROUTE_DECORATORS2 = new Set(["Get", "Post", "Put", "Patch", "Delete", "Head", "Options"]);
21716
22090
  var MIGRATION_COMPILER_OPTIONS = {
21717
- target: ts13.ScriptTarget.ES2022,
21718
- module: ts13.ModuleKind.ESNext,
21719
- moduleResolution: ts13.ModuleResolutionKind.Bundler,
22091
+ target: ts16.ScriptTarget.ES2022,
22092
+ module: ts16.ModuleKind.ESNext,
22093
+ moduleResolution: ts16.ModuleResolutionKind.Bundler,
21720
22094
  noEmit: true,
21721
22095
  skipLibCheck: true
21722
22096
  };
21723
22097
  function migrationCompilerOptions(rootDir) {
21724
22098
  if (!rootDir)
21725
22099
  return MIGRATION_COMPILER_OPTIONS;
21726
- const configPath = ts13.findConfigFile(rootDir, ts13.sys.fileExists);
22100
+ const configPath = ts16.findConfigFile(rootDir, ts16.sys.fileExists);
21727
22101
  if (!configPath)
21728
22102
  return MIGRATION_COMPILER_OPTIONS;
21729
22103
  const configHost = {
21730
- ...ts13.sys,
22104
+ ...ts16.sys,
21731
22105
  onUnRecoverableConfigFileDiagnostic: (_diagnostic) => {}
21732
22106
  };
21733
- const parsed = ts13.getParsedCommandLineOfConfigFile(configPath, {}, configHost);
22107
+ const parsed = ts16.getParsedCommandLineOfConfigFile(configPath, {}, configHost);
21734
22108
  if (!parsed || parsed.errors.length > 0)
21735
22109
  return MIGRATION_COMPILER_OPTIONS;
21736
22110
  return { ...parsed.options, noEmit: true, skipLibCheck: true };
21737
22111
  }
21738
22112
  function propertyName2(property) {
21739
- if (ts13.isIdentifier(property) || ts13.isStringLiteral(property) || ts13.isNumericLiteral(property))
22113
+ if (ts16.isIdentifier(property) || ts16.isStringLiteral(property) || ts16.isNumericLiteral(property))
21740
22114
  return property.text;
21741
22115
  return;
21742
22116
  }
@@ -21746,7 +22120,7 @@ function lineOf2(sourceFile, node) {
21746
22120
  function resolveSymbol(symbol, checker) {
21747
22121
  if (!symbol)
21748
22122
  return;
21749
- for (let guard = 0;guard < 4 && (symbol.flags & ts13.SymbolFlags.Alias) !== 0; guard += 1) {
22123
+ for (let guard = 0;guard < 4 && (symbol.flags & ts16.SymbolFlags.Alias) !== 0; guard += 1) {
21750
22124
  const aliased = checker.getAliasedSymbol(symbol);
21751
22125
  if (aliased === symbol)
21752
22126
  break;
@@ -21755,12 +22129,12 @@ function resolveSymbol(symbol, checker) {
21755
22129
  return symbol;
21756
22130
  }
21757
22131
  function symbolForExpression(expression, checker) {
21758
- const location = ts13.isIdentifier(expression) ? expression : ts13.isPropertyAccessExpression(expression) ? expression.name : ts13.isElementAccessExpression(expression) && expression.argumentExpression && ts13.isStringLiteral(expression.argumentExpression) ? expression : undefined;
22132
+ const location = ts16.isIdentifier(expression) ? expression : ts16.isPropertyAccessExpression(expression) ? expression.name : ts16.isElementAccessExpression(expression) && expression.argumentExpression && ts16.isStringLiteral(expression.argumentExpression) ? expression : undefined;
21759
22133
  return location ? resolveSymbol(checker.getSymbolAtLocation(location), checker) : undefined;
21760
22134
  }
21761
22135
  function unwrapExpression(expression) {
21762
22136
  let current = expression;
21763
- while (ts13.isAsExpression(current) || ts13.isSatisfiesExpression(current) || ts13.isParenthesizedExpression(current) || ts13.isTypeAssertionExpression(current)) {
22137
+ while (ts16.isAsExpression(current) || ts16.isSatisfiesExpression(current) || ts16.isParenthesizedExpression(current) || ts16.isTypeAssertionExpression(current)) {
21764
22138
  current = current.expression;
21765
22139
  }
21766
22140
  return current;
@@ -21775,7 +22149,7 @@ function isRouteDecoratorCall(node, checker) {
21775
22149
  if (node.arguments.length < 2)
21776
22150
  return false;
21777
22151
  const name = node.expression.getText(node.getSourceFile());
21778
- if (ts13.isIdentifier(node.expression) && ROUTE_DECORATORS2.has(node.expression.text))
22152
+ if (ts16.isIdentifier(node.expression) && ROUTE_DECORATORS2.has(node.expression.text))
21779
22153
  return true;
21780
22154
  if (ROUTE_DECORATORS2.has(name))
21781
22155
  return true;
@@ -21789,14 +22163,14 @@ function resolveStaticObjectLiteral2(input, checker, seen = new Set) {
21789
22163
  if (seen.has(expression))
21790
22164
  return;
21791
22165
  seen.add(expression);
21792
- if (ts13.isObjectLiteralExpression(expression))
22166
+ if (ts16.isObjectLiteralExpression(expression))
21793
22167
  return expression;
21794
- if (ts13.isCallExpression(expression) && isDefineRouteContractCall(expression, checker)) {
22168
+ if (ts16.isCallExpression(expression) && isDefineRouteContractCall(expression, checker)) {
21795
22169
  return resolveStaticObjectLiteral2(expression.arguments[0], checker, seen);
21796
22170
  }
21797
22171
  const symbol = symbolForExpression(expression, checker);
21798
22172
  for (const declaration of symbol?.declarations ?? []) {
21799
- if (ts13.isVariableDeclaration(declaration) && declaration.initializer) {
22173
+ if (ts16.isVariableDeclaration(declaration) && declaration.initializer) {
21800
22174
  const resolved = resolveStaticObjectLiteral2(declaration.initializer, checker, seen);
21801
22175
  if (resolved)
21802
22176
  return resolved;
@@ -21810,25 +22184,25 @@ function displayFile(rootDir, fileName) {
21810
22184
  }
21811
22185
  function createMigrationProgram(fileNames, sourceOverrides, rootDir) {
21812
22186
  const compilerOptions = migrationCompilerOptions(rootDir);
21813
- const host = ts13.createCompilerHost(compilerOptions);
22187
+ const host = ts16.createCompilerHost(compilerOptions);
21814
22188
  const getSourceFile = host.getSourceFile.bind(host);
21815
22189
  const fileExists = host.fileExists.bind(host);
21816
22190
  const readFile = host.readFile.bind(host);
21817
22191
  const currentDirectory = host.getCurrentDirectory.bind(host);
21818
- host.fileExists = (fileName) => sourceOverrides.has(resolve15(fileName)) || fileExists(fileName);
21819
- host.readFile = (fileName) => sourceOverrides.get(resolve15(fileName)) ?? readFile(fileName);
22192
+ host.fileExists = (fileName) => sourceOverrides.has(resolve16(fileName)) || fileExists(fileName);
22193
+ host.readFile = (fileName) => sourceOverrides.get(resolve16(fileName)) ?? readFile(fileName);
21820
22194
  host.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
21821
- const source = sourceOverrides.get(resolve15(fileName));
21822
- return source === undefined ? getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) : ts13.createSourceFile(fileName, source, languageVersion, true);
22195
+ const source = sourceOverrides.get(resolve16(fileName));
22196
+ return source === undefined ? getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) : ts16.createSourceFile(fileName, source, languageVersion, true);
21823
22197
  };
21824
22198
  host.getCurrentDirectory = () => rootDir ?? currentDirectory();
21825
- return ts13.createProgram(fileNames, compilerOptions, host);
22199
+ return ts16.createProgram(fileNames, compilerOptions, host);
21826
22200
  }
21827
22201
  function routeResponseProperties(object) {
21828
- const responseProperties = object.properties.filter((property) => ts13.isPropertyAssignment(property) && propertyName2(property.name) === "response");
22202
+ const responseProperties = object.properties.filter((property) => ts16.isPropertyAssignment(property) && propertyName2(property.name) === "response");
21829
22203
  return {
21830
22204
  response: responseProperties[0],
21831
- hasResponses: object.properties.some((property) => (ts13.isPropertyAssignment(property) || ts13.isShorthandPropertyAssignment(property)) && propertyName2(property.name) === "responses"),
22205
+ hasResponses: object.properties.some((property) => (ts16.isPropertyAssignment(property) || ts16.isShorthandPropertyAssignment(property)) && propertyName2(property.name) === "responses"),
21832
22206
  duplicateResponse: responseProperties.length > 1
21833
22207
  };
21834
22208
  }
@@ -21844,15 +22218,15 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
21844
22218
  issues.push(issue);
21845
22219
  };
21846
22220
  for (const sourceFile of sourceFiles) {
21847
- const sourcePath = resolve15(sourceFile.fileName);
22221
+ const sourcePath = resolve16(sourceFile.fileName);
21848
22222
  if (!includedFiles.has(sourcePath))
21849
22223
  continue;
21850
22224
  const visit = (node) => {
21851
- if (ts13.isCallExpression(node) && isRouteDecoratorCall(node, checker)) {
22225
+ if (ts16.isCallExpression(node) && isRouteDecoratorCall(node, checker)) {
21852
22226
  const options = node.arguments[1];
21853
22227
  const object = options && resolveStaticObjectLiteral2(options, checker);
21854
22228
  if (object) {
21855
- const objectPath = resolve15(object.getSourceFile().fileName);
22229
+ const objectPath = resolve16(object.getSourceFile().fileName);
21856
22230
  const properties = routeResponseProperties(object);
21857
22231
  if (properties.response) {
21858
22232
  if (!includedFiles.has(objectPath)) {
@@ -21868,7 +22242,7 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
21868
22242
  }
21869
22243
  }
21870
22244
  }
21871
- ts13.forEachChild(node, visit);
22245
+ ts16.forEachChild(node, visit);
21872
22246
  };
21873
22247
  visit(sourceFile);
21874
22248
  }
@@ -21895,13 +22269,13 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
21895
22269
  line: lineOf2(sourceFile, response)
21896
22270
  });
21897
22271
  } else {
21898
- const replacements = replacementsByFile.get(resolve15(sourceFile.fileName)) ?? [];
22272
+ const replacements = replacementsByFile.get(resolve16(sourceFile.fileName)) ?? [];
21899
22273
  replacements.push({
21900
22274
  start: response.getStart(sourceFile),
21901
22275
  end: response.getEnd(),
21902
22276
  text: `responses: { 200: ${response.initializer.getText(sourceFile)} }`
21903
22277
  });
21904
- replacementsByFile.set(resolve15(sourceFile.fileName), replacements);
22278
+ replacementsByFile.set(resolve16(sourceFile.fileName), replacements);
21905
22279
  }
21906
22280
  }
21907
22281
  return { replacementsByFile, issues };
@@ -21914,7 +22288,7 @@ function applyReplacements(source, replacements) {
21914
22288
  return content;
21915
22289
  }
21916
22290
  function migrateRouteResponse(source, fileName) {
21917
- const absoluteFile = resolve15(fileName);
22291
+ const absoluteFile = resolve16(fileName);
21918
22292
  const sourceOverrides = new Map([[absoluteFile, source]]);
21919
22293
  const program = createMigrationProgram([absoluteFile], sourceOverrides);
21920
22294
  const sourceFile = program.getSourceFile(absoluteFile);
@@ -21930,7 +22304,7 @@ function migrateRouteResponse(source, fileName) {
21930
22304
  }]
21931
22305
  };
21932
22306
  }
21933
- const plan = planRouteResponseMigration([sourceFile], program.getTypeChecker(), resolve15("."), new Set([absoluteFile]));
22307
+ const plan = planRouteResponseMigration([sourceFile], program.getTypeChecker(), resolve16("."), new Set([absoluteFile]));
21934
22308
  const replacements = plan.replacementsByFile.get(absoluteFile) ?? [];
21935
22309
  return {
21936
22310
  changed: replacements.length > 0,
@@ -21940,7 +22314,7 @@ function migrateRouteResponse(source, fileName) {
21940
22314
  };
21941
22315
  }
21942
22316
  function migrateRouteResponseProject(files, rootDir, sourceByPath) {
21943
- const absoluteFiles = files.map((file) => resolve15(file));
22317
+ const absoluteFiles = files.map((file) => resolve16(file));
21944
22318
  const program = createMigrationProgram(absoluteFiles, sourceByPath, rootDir);
21945
22319
  const sourceFiles = absoluteFiles.map((file) => program.getSourceFile(file)).filter((file) => file !== undefined);
21946
22320
  const plan = planRouteResponseMigration(sourceFiles, program.getTypeChecker(), rootDir, new Set(absoluteFiles));
@@ -21953,11 +22327,11 @@ function migrateRouteResponseProject(files, rootDir, sourceByPath) {
21953
22327
  changed: replacements.length > 0,
21954
22328
  content: applyReplacements(source, replacements),
21955
22329
  replacements: replacements.length,
21956
- issues: plan.issues.filter((issue) => resolve15(rootDir, issue.file) === file)
22330
+ issues: plan.issues.filter((issue) => resolve16(rootDir, issue.file) === file)
21957
22331
  });
21958
22332
  }
21959
22333
  for (const issue of plan.issues) {
21960
- const path = resolve15(rootDir, issue.file);
22334
+ const path = resolve16(rootDir, issue.file);
21961
22335
  if (!results.has(path) && sourceByPath.has(path)) {
21962
22336
  results.set(path, {
21963
22337
  changed: false,
@@ -21976,6 +22350,13 @@ var SUPACLOUD_MIGRATIONS = [
21976
22350
  to: "0.12.0",
21977
22351
  description: "Replace deprecated route response schemas with explicit HTTP status maps.",
21978
22352
  apply: migrateRouteResponse
22353
+ },
22354
+ {
22355
+ id: "http-provider-entrypoint",
22356
+ from: "0.12.0",
22357
+ to: "0.13.0",
22358
+ description: "Move provider-only withInterceptors imports to the shared HTTP feature entry; reject ambiguous uses.",
22359
+ apply: migrateHttpProviderImports
21979
22360
  }
21980
22361
  ];
21981
22362
  async function writeAtomically(path, content) {
@@ -21988,7 +22369,7 @@ async function writeAtomically(path, content) {
21988
22369
  }
21989
22370
  }
21990
22371
  async function migrateProject(options) {
21991
- const rootDir = resolve15(options.rootDir);
22372
+ const rootDir = resolve16(options.rootDir);
21992
22373
  let migrations = SUPACLOUD_MIGRATIONS;
21993
22374
  const preflightIssues = [];
21994
22375
  if (options.fromVersion !== undefined || options.toVersion !== undefined) {
@@ -22028,7 +22409,7 @@ async function migrateProject(options) {
22028
22409
  }
22029
22410
  }
22030
22411
  const include = options.include ?? ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"];
22031
- const files = ts13.sys.readDirectory(rootDir, [".ts", ".tsx", ".mts", ".cts"], ["node_modules", "dist", "generated"], include).sort();
22412
+ const files = ts16.sys.readDirectory(rootDir, [".ts", ".tsx", ".mts", ".cts"], ["node_modules", "dist", "generated"], include).sort();
22032
22413
  const results = [];
22033
22414
  const issues = [];
22034
22415
  const pendingWrites = new Map;
@@ -22044,7 +22425,7 @@ async function migrateProject(options) {
22044
22425
  }
22045
22426
  };
22046
22427
  for (const filePath of files) {
22047
- sourceByPath.set(resolve15(filePath), await readFile9(filePath, "utf8"));
22428
+ sourceByPath.set(resolve16(filePath), await readFile9(filePath, "utf8"));
22048
22429
  }
22049
22430
  const originalSources = new Map(sourceByPath);
22050
22431
  const writtenFiles = new Set;
@@ -22053,7 +22434,7 @@ async function migrateProject(options) {
22053
22434
  if (projectResults)
22054
22435
  appendIssues(projectResults.issues);
22055
22436
  for (const filePath of files) {
22056
- const absoluteFile = resolve15(filePath);
22437
+ const absoluteFile = resolve16(filePath);
22057
22438
  const file = relative11(rootDir, absoluteFile) || absoluteFile;
22058
22439
  const before = sourceByPath.get(absoluteFile);
22059
22440
  if (before === undefined)
@@ -22112,13 +22493,13 @@ async function migrateProject(options) {
22112
22493
  };
22113
22494
  }
22114
22495
  // src/migration-assess.ts
22115
- import { createHash as createHash9 } from "node:crypto";
22496
+ import { createHash as createHash10 } from "node:crypto";
22116
22497
  import { readFile as readFile11 } from "node:fs/promises";
22117
- import { join as join10, resolve as resolve17 } from "node:path";
22498
+ import { join as join10, resolve as resolve18 } from "node:path";
22118
22499
 
22119
22500
  // src/openapi-tools.ts
22120
22501
  import { mkdir as mkdir4, readFile as readFile10, rename as rename6, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
22121
- import { dirname as dirname10, resolve as resolve16 } from "node:path";
22502
+ import { dirname as dirname10, resolve as resolve17 } from "node:path";
22122
22503
  import { pathToFileURL } from "node:url";
22123
22504
 
22124
22505
  class OpenApiDocumentError extends Error {
@@ -22509,7 +22890,7 @@ function serializeOpenApiJson(document, space = 2) {
22509
22890
  }
22510
22891
  async function readOpenApiJson(path) {
22511
22892
  try {
22512
- const value = JSON.parse(await readFile10(resolve16(path), "utf8"));
22893
+ const value = JSON.parse(await readFile10(resolve17(path), "utf8"));
22513
22894
  return parseOpenApiDocument(value);
22514
22895
  } catch (error) {
22515
22896
  if (error instanceof OpenApiDocumentError)
@@ -22518,7 +22899,7 @@ async function readOpenApiJson(path) {
22518
22899
  }
22519
22900
  }
22520
22901
  async function writeOpenApiJson(document, outputPath, space = 2) {
22521
- const path = resolve16(outputPath);
22902
+ const path = resolve17(outputPath);
22522
22903
  const content = serializeOpenApiJson(document, space);
22523
22904
  await mkdir4(dirname10(path), { recursive: true });
22524
22905
  try {
@@ -22539,7 +22920,7 @@ async function writeOpenApiJson(document, outputPath, space = 2) {
22539
22920
  }
22540
22921
  async function loadGeneratedOpenApiDocument(modulePath) {
22541
22922
  try {
22542
- const moduleUrl = pathToFileURL(resolve16(modulePath));
22923
+ const moduleUrl = pathToFileURL(resolve17(modulePath));
22543
22924
  moduleUrl.searchParams.set("supacloud-openapi-export", "1");
22544
22925
  const loaded = await import(moduleUrl.href);
22545
22926
  if (!isRecord(loaded))
@@ -22636,17 +23017,17 @@ function arrayLength(value) {
22636
23017
  return Array.isArray(value) ? value.length : undefined;
22637
23018
  }
22638
23019
  async function sha256(path) {
22639
- return createHash9("sha256").update(await readFile11(path)).digest("hex");
23020
+ return createHash10("sha256").update(await readFile11(path)).digest("hex");
22640
23021
  }
22641
23022
  function overallStatus(findings) {
22642
23023
  return findings.reduce((current, finding) => STATUS_PRIORITY[finding.status] > STATUS_PRIORITY[current] ? finding.status : current, "compatible");
22643
23024
  }
22644
23025
  async function assessMigration(options) {
22645
- const projectDir = resolve17(options.projectDir);
23026
+ const projectDir = resolve18(options.projectDir);
22646
23027
  const compile = {
22647
23028
  ...options.compile,
22648
- rootDir: resolve17(options.compile.rootDir),
22649
- outDir: resolve17(options.compile.outDir)
23029
+ rootDir: resolve18(options.compile.rootDir),
23030
+ outDir: resolve18(options.compile.outDir)
22650
23031
  };
22651
23032
  const findings = [];
22652
23033
  const dependencyProblems = await checkMigrationDependencies(projectDir);
@@ -22726,8 +23107,8 @@ async function assessMigration(options) {
22726
23107
  }
22727
23108
  let openApi;
22728
23109
  if (options.baselineOpenApiPath && options.currentOpenApiPath) {
22729
- const baselinePath = resolve17(projectDir, options.baselineOpenApiPath);
22730
- const currentPath = resolve17(projectDir, options.currentOpenApiPath);
23110
+ const baselinePath = resolve18(projectDir, options.baselineOpenApiPath);
23111
+ const currentPath = resolve18(projectDir, options.currentOpenApiPath);
22731
23112
  try {
22732
23113
  const diff = diffOpenApiDocuments(await readOpenApiJson(baselinePath), await readOpenApiJson(currentPath));
22733
23114
  openApi = {
@@ -22816,7 +23197,7 @@ init_validate();
22816
23197
  // src/config.ts
22817
23198
  init_graphql_options();
22818
23199
  import { existsSync as existsSync5 } from "node:fs";
22819
- import { join as join11, resolve as resolve18 } from "node:path";
23200
+ import { join as join11, resolve as resolve19 } from "node:path";
22820
23201
  import { pathToFileURL as pathToFileURL2 } from "node:url";
22821
23202
  var DEFAULT_SUPACLOUD_CONFIG = {
22822
23203
  graphql: false,
@@ -22909,8 +23290,8 @@ function validateGovernanceConfig(config) {
22909
23290
  function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
22910
23291
  const resolved = defineSupacloudConfig(config);
22911
23292
  return {
22912
- rootDir: resolve18(cwd, resolved.root ?? DEFAULT_SUPACLOUD_CONFIG.root),
22913
- outDir: resolve18(cwd, resolved.outDir ?? DEFAULT_SUPACLOUD_CONFIG.outDir),
23293
+ rootDir: resolve19(cwd, resolved.root ?? DEFAULT_SUPACLOUD_CONFIG.root),
23294
+ outDir: resolve19(cwd, resolved.outDir ?? DEFAULT_SUPACLOUD_CONFIG.outDir),
22914
23295
  include: resolved.include ?? [...DEFAULT_SUPACLOUD_CONFIG.include],
22915
23296
  strict: resolved.strict ?? DEFAULT_SUPACLOUD_CONFIG.strict,
22916
23297
  requireRouteContracts: resolved.requireRouteContracts ?? DEFAULT_SUPACLOUD_CONFIG.requireRouteContracts,
@@ -22928,7 +23309,7 @@ function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
22928
23309
  treeShakeUnusedProviders: resolved.treeShakeUnusedProviders ?? DEFAULT_SUPACLOUD_CONFIG.treeShakeUnusedProviders,
22929
23310
  graphql: resolved.graphql ? {
22930
23311
  ...resolved.graphql,
22931
- schema: resolve18(cwd, resolved.graphql.schema)
23312
+ schema: resolve19(cwd, resolved.graphql.schema)
22932
23313
  } : undefined
22933
23314
  };
22934
23315
  }