@luckystack/devkit 0.10.2 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/AGENTS.md +9 -0
  2. package/CHANGELOG.md +9 -0
  3. package/README.md +2 -37
  4. package/dist/cli/validateDeploy.d.ts +2 -0
  5. package/dist/functionRegistry.d.ts +72 -0
  6. package/dist/hotReload.d.ts +1 -0
  7. package/dist/importDependencyGraph.d.ts +2 -0
  8. package/dist/index.d.ts +15 -280
  9. package/dist/index.js +551 -424
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal/mapUtils.d.ts +2 -0
  12. package/dist/loader.d.ts +11 -0
  13. package/dist/prismaClientCheck.d.ts +19 -0
  14. package/dist/routeConventions.d.ts +20 -0
  15. package/dist/routeNamingValidation.d.ts +46 -0
  16. package/dist/routingRules.d.ts +62 -0
  17. package/dist/runtimeTypeResolver.d.ts +15 -0
  18. package/dist/supervisor.d.ts +25 -0
  19. package/dist/templateInjector.d.ts +60 -0
  20. package/dist/templateRegistry.d.ts +78 -0
  21. package/dist/typeMap/apiMeta.d.ts +42 -0
  22. package/dist/typeMap/discovery.d.ts +3 -0
  23. package/dist/typeMap/emitterArtifacts.d.ts +94 -0
  24. package/dist/typeMap/extractionDiagnostics.d.ts +16 -0
  25. package/dist/typeMap/extractors.d.ts +18 -0
  26. package/dist/typeMap/functionsMeta.d.ts +5 -0
  27. package/dist/typeMap/routeMeta.d.ts +6 -0
  28. package/dist/typeMap/tsApi.d.ts +12 -0
  29. package/dist/typeMap/tsProgram.d.ts +41 -0
  30. package/dist/typeMap/typeContext.d.ts +21 -0
  31. package/dist/typeMap/zodEmitter.d.ts +8 -0
  32. package/dist/typeMapGenerator.d.ts +5 -0
  33. package/dist/validateDeploy.d.ts +25 -0
  34. package/docs/cli.md +3 -243
  35. package/docs/hot-reload.md +4 -362
  36. package/docs/loader-pipeline.md +3 -322
  37. package/docs/runtime-type-resolver.md +3 -256
  38. package/docs/supervisor.md +3 -290
  39. package/docs/template-customization.md +2 -133
  40. package/docs/ts-program-cache.md +4 -197
  41. package/docs/type-map-generation.md +5 -418
  42. package/package.json +5 -5
  43. package/CLAUDE.md +0 -135
package/dist/index.js CHANGED
@@ -567,34 +567,98 @@ var extractSyncVersion = (filePath) => {
567
567
  };
568
568
 
569
569
  // src/typeMap/apiMeta.ts
570
- import * as ts from "typescript";
571
- import fs3 from "fs";
570
+ import fs4 from "fs";
571
+ import {
572
+ getJSDocTags,
573
+ SyntaxKind
574
+ } from "typescript-7-api/ast";
575
+ import {
576
+ isArrayLiteralExpression,
577
+ isAsExpression,
578
+ isIdentifier,
579
+ isNumericLiteral,
580
+ isObjectLiteralExpression,
581
+ isParenthesizedExpression,
582
+ isPropertyAssignment,
583
+ isSatisfiesExpression,
584
+ isStringLiteral,
585
+ isVariableStatement
586
+ } from "typescript-7-api/ast/is";
572
587
  import { inferHttpMethod, tryCatchSync } from "@luckystack/core";
588
+
589
+ // src/typeMap/tsApi.ts
590
+ import fs3 from "fs";
591
+ import path4 from "path";
592
+ import { API } from "typescript-7-api/sync";
593
+ import { ROOT_DIR as ROOT_DIR3 } from "@luckystack/core";
594
+ var api = null;
595
+ var serverSnapshot = null;
596
+ var serverProject = null;
597
+ var getTsApi = () => {
598
+ api ??= new API({ cwd: ROOT_DIR3 });
599
+ return api;
600
+ };
601
+ var openTsconfigProject = (tsconfigPath) => {
602
+ const tsApi = getTsApi();
603
+ const { fileNames, options } = tsApi.parseConfigFile(tsconfigPath);
604
+ const snapshot = tsApi.createSnapshot({ createPrograms: [{ rootFiles: fileNames, compilerOptions: options }] });
605
+ const [program] = snapshot.operation.createdPrograms;
606
+ return { project: program.getProject(), snapshot };
607
+ };
608
+ var getServerProgram = () => {
609
+ if (serverProject) return serverProject;
610
+ const tsconfigPath = path4.join(ROOT_DIR3, "tsconfig.server.json");
611
+ if (!fs3.existsSync(tsconfigPath)) throw new Error("[TypeProgram] tsconfig.server.json not found");
612
+ const { project, snapshot } = openTsconfigProject(tsconfigPath);
613
+ serverSnapshot = snapshot;
614
+ serverProject = project;
615
+ return project;
616
+ };
617
+ var invalidateProgramCache = () => {
618
+ serverSnapshot?.dispose();
619
+ serverSnapshot = null;
620
+ serverProject = null;
621
+ };
622
+ var disposeTsApi = () => {
623
+ invalidateProgramCache();
624
+ api?.close();
625
+ api = null;
626
+ };
627
+ var parseSourceText = (fileName, text, scriptKind) => {
628
+ const retained = getTsApi().createSourceFile(fileName, text, scriptKind === void 0 ? void 0 : { scriptKind });
629
+ retained.dispose();
630
+ return retained.sourceFile;
631
+ };
632
+ var transpileSourceText = (fileName, text) => {
633
+ return getTsApi().transpileModule(text, { fileName, reportDiagnostics: true });
634
+ };
635
+
636
+ // src/typeMap/apiMeta.ts
573
637
  var findExportedConst = (sourceFile, name) => {
574
638
  for (const statement of sourceFile.statements) {
575
- if (!ts.isVariableStatement(statement)) continue;
576
- const hasExport = statement.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
639
+ if (!isVariableStatement(statement)) continue;
640
+ const hasExport = statement.modifiers?.some((m) => m.kind === SyntaxKind.ExportKeyword);
577
641
  if (!hasExport) continue;
578
642
  for (const decl of statement.declarationList.declarations) {
579
- if (ts.isIdentifier(decl.name) && decl.name.text === name) return decl;
643
+ if (isIdentifier(decl.name) && decl.name.text === name) return decl;
580
644
  }
581
645
  }
582
646
  return null;
583
647
  };
584
648
  var unwrapExpression = (node) => {
585
649
  let current = node;
586
- while (ts.isAsExpression(current) || ts.isSatisfiesExpression(current) || ts.isParenthesizedExpression(current)) {
650
+ while (isAsExpression(current) || isSatisfiesExpression(current) || isParenthesizedExpression(current)) {
587
651
  current = current.expression;
588
652
  }
589
653
  return current;
590
654
  };
591
655
  var extractHttpMethod = (filePath, apiName) => {
592
656
  const [error, method] = tryCatchSync(() => {
593
- const content = fs3.readFileSync(filePath, "utf8");
594
- const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
657
+ const content = fs4.readFileSync(filePath, "utf8");
658
+ const sourceFile = parseSourceText(filePath, content);
595
659
  const decl = findExportedConst(sourceFile, "httpMethod");
596
660
  const initializer = decl?.initializer ? unwrapExpression(decl.initializer) : void 0;
597
- if (initializer && ts.isStringLiteral(initializer)) {
661
+ if (initializer && isStringLiteral(initializer)) {
598
662
  const candidate = initializer.text.toUpperCase();
599
663
  if (["GET", "POST", "PUT", "DELETE"].includes(candidate)) return candidate;
600
664
  }
@@ -607,13 +671,13 @@ var extractHttpMethod = (filePath, apiName) => {
607
671
  };
608
672
  var extractRateLimit = (filePath) => {
609
673
  const [error, rateLimit] = tryCatchSync(() => {
610
- const content = fs3.readFileSync(filePath, "utf8");
611
- const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
674
+ const content = fs4.readFileSync(filePath, "utf8");
675
+ const sourceFile = parseSourceText(filePath, content);
612
676
  const decl = findExportedConst(sourceFile, "rateLimit");
613
677
  if (decl?.initializer) {
614
678
  const initializer = unwrapExpression(decl.initializer);
615
- if (initializer.kind === ts.SyntaxKind.FalseKeyword) return false;
616
- if (ts.isNumericLiteral(initializer)) return Number(initializer.text);
679
+ if (initializer.kind === SyntaxKind.FalseKeyword) return false;
680
+ if (isNumericLiteral(initializer)) return Number(initializer.text);
617
681
  }
618
682
  return void 0;
619
683
  });
@@ -624,16 +688,16 @@ var extractRateLimit = (filePath) => {
624
688
  };
625
689
  var readPrimitive = (rawNode) => {
626
690
  const node = unwrapExpression(rawNode);
627
- if (ts.isStringLiteral(node)) return node.text;
628
- if (ts.isNumericLiteral(node)) return Number(node.text);
629
- if (node.kind === ts.SyntaxKind.TrueKeyword) return true;
630
- if (node.kind === ts.SyntaxKind.FalseKeyword) return false;
691
+ if (isStringLiteral(node)) return node.text;
692
+ if (isNumericLiteral(node)) return Number(node.text);
693
+ if (node.kind === SyntaxKind.TrueKeyword) return true;
694
+ if (node.kind === SyntaxKind.FalseKeyword) return false;
631
695
  return void 0;
632
696
  };
633
697
  var parseAdditionalItem = (objectLiteral) => {
634
698
  const item = {};
635
699
  for (const prop of objectLiteral.properties) {
636
- if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) continue;
700
+ if (!isPropertyAssignment(prop) || !isIdentifier(prop.name)) continue;
637
701
  const value = readPrimitive(prop.initializer);
638
702
  if (value !== void 0) item[prop.name.text] = value;
639
703
  }
@@ -653,8 +717,8 @@ var commentToString = (commentValue) => {
653
717
  };
654
718
  var extractDocsMeta = (filePath) => {
655
719
  const [error, docsMeta] = tryCatchSync(() => {
656
- const content = fs3.readFileSync(filePath, "utf8");
657
- const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
720
+ const content = fs4.readFileSync(filePath, "utf8");
721
+ const sourceFile = parseSourceText(filePath, content);
658
722
  const result = {};
659
723
  const consumeTag = (tag) => {
660
724
  if (tag.tagName.text !== "docs") return;
@@ -673,7 +737,7 @@ var extractDocsMeta = (filePath) => {
673
737
  }
674
738
  };
675
739
  for (const statement of sourceFile.statements) {
676
- for (const tag of ts.getJSDocTags(statement)) {
740
+ for (const tag of getJSDocTags(statement)) {
677
741
  consumeTag(tag);
678
742
  }
679
743
  }
@@ -690,25 +754,25 @@ var extractDocsMeta = (filePath) => {
690
754
  };
691
755
  var extractAuth = (filePath) => {
692
756
  const [, auth] = tryCatchSync(() => {
693
- const content = fs3.readFileSync(filePath, "utf8");
694
- const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
757
+ const content = fs4.readFileSync(filePath, "utf8");
758
+ const sourceFile = parseSourceText(filePath, content);
695
759
  const decl = findExportedConst(sourceFile, "auth");
696
760
  const authInitializer = decl?.initializer ? unwrapExpression(decl.initializer) : void 0;
697
- if (!authInitializer || !ts.isObjectLiteralExpression(authInitializer)) return { login: false, hasAdditional: false };
761
+ if (!authInitializer || !isObjectLiteralExpression(authInitializer)) return { login: false, hasAdditional: false };
698
762
  let login = false;
699
763
  let additional;
700
764
  let hasAdditional = false;
701
765
  for (const prop of authInitializer.properties) {
702
- if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) continue;
766
+ if (!isPropertyAssignment(prop) || !isIdentifier(prop.name)) continue;
703
767
  const propInit = unwrapExpression(prop.initializer);
704
768
  if (prop.name.text === "login") {
705
- login = propInit.kind === ts.SyntaxKind.TrueKeyword;
769
+ login = propInit.kind === SyntaxKind.TrueKeyword;
706
770
  }
707
- if (prop.name.text === "additional" && ts.isArrayLiteralExpression(propInit)) {
771
+ if (prop.name.text === "additional" && isArrayLiteralExpression(propInit)) {
708
772
  hasAdditional = propInit.elements.length > 0;
709
773
  additional = [];
710
774
  for (const element of propInit.elements) {
711
- if (!ts.isObjectLiteralExpression(element)) continue;
775
+ if (!isObjectLiteralExpression(element)) continue;
712
776
  const item = parseAdditionalItem(element);
713
777
  if (item) additional.push(item);
714
778
  }
@@ -720,46 +784,78 @@ var extractAuth = (filePath) => {
720
784
  };
721
785
 
722
786
  // src/typeMap/emitterArtifacts.ts
723
- import fs4 from "fs";
724
- import path4 from "path";
725
- import * as ts3 from "typescript";
787
+ import fs5 from "fs";
788
+ import path5 from "path";
789
+ import {
790
+ ScriptKind
791
+ } from "typescript-7-api/ast";
792
+ import {
793
+ isClassDeclaration,
794
+ isEnumDeclaration,
795
+ isFunctionDeclaration,
796
+ isIdentifier as isIdentifier3,
797
+ isImportDeclaration,
798
+ isInferTypeNode,
799
+ isInterfaceDeclaration,
800
+ isMappedTypeNode,
801
+ isNamedImports,
802
+ isNamespaceImport,
803
+ isQualifiedName,
804
+ isTypeAliasDeclaration as isTypeAliasDeclaration2,
805
+ isTypeReferenceNode as isTypeReferenceNode2
806
+ } from "typescript-7-api/ast/is";
726
807
  import { getGeneratedApiDocsPath, getGeneratedApiSchemasPath, getGeneratedSocketTypesPath } from "@luckystack/core";
727
808
 
728
809
  // src/typeMap/zodEmitter.ts
729
- import * as ts2 from "typescript";
810
+ import { SyntaxKind as SyntaxKind2 } from "typescript-7-api/ast";
811
+ import {
812
+ isArrayTypeNode,
813
+ isIdentifier as isIdentifier2,
814
+ isIndexSignatureDeclaration,
815
+ isIntersectionTypeNode,
816
+ isLiteralTypeNode,
817
+ isNumericLiteral as isNumericLiteral2,
818
+ isParenthesizedTypeNode,
819
+ isPropertySignatureDeclaration,
820
+ isStringLiteral as isStringLiteral2,
821
+ isTypeAliasDeclaration,
822
+ isTypeLiteralNode,
823
+ isTypeReferenceNode,
824
+ isUnionTypeNode
825
+ } from "typescript-7-api/ast/is";
730
826
  var wrapOptional = (inner) => `${inner}.optional()`;
731
827
  var anyFallback = (reason) => `z.any() /* ${reason} */`;
732
828
  var convertTypeNode = (node) => {
733
- if (node.kind === ts2.SyntaxKind.StringKeyword) return "z.string()";
734
- if (node.kind === ts2.SyntaxKind.NumberKeyword) return "z.number()";
735
- if (node.kind === ts2.SyntaxKind.BooleanKeyword) return "z.boolean()";
736
- if (node.kind === ts2.SyntaxKind.NullKeyword) return "z.null()";
737
- if (node.kind === ts2.SyntaxKind.UndefinedKeyword) return "z.undefined()";
738
- if (node.kind === ts2.SyntaxKind.AnyKeyword) return "z.any()";
739
- if (node.kind === ts2.SyntaxKind.UnknownKeyword) return "z.unknown()";
740
- if (node.kind === ts2.SyntaxKind.NeverKeyword) return "z.never()";
741
- if (ts2.isLiteralTypeNode(node)) {
829
+ if (node.kind === SyntaxKind2.StringKeyword) return "z.string()";
830
+ if (node.kind === SyntaxKind2.NumberKeyword) return "z.number()";
831
+ if (node.kind === SyntaxKind2.BooleanKeyword) return "z.boolean()";
832
+ if (node.kind === SyntaxKind2.NullKeyword) return "z.null()";
833
+ if (node.kind === SyntaxKind2.UndefinedKeyword) return "z.undefined()";
834
+ if (node.kind === SyntaxKind2.AnyKeyword) return "z.any()";
835
+ if (node.kind === SyntaxKind2.UnknownKeyword) return "z.unknown()";
836
+ if (node.kind === SyntaxKind2.NeverKeyword) return "z.never()";
837
+ if (isLiteralTypeNode(node)) {
742
838
  const literal = node.literal;
743
- if (ts2.isStringLiteral(literal)) return `z.literal(${JSON.stringify(literal.text)})`;
744
- if (ts2.isNumericLiteral(literal)) return `z.literal(${literal.text})`;
745
- if (literal.kind === ts2.SyntaxKind.TrueKeyword) return "z.literal(true)";
746
- if (literal.kind === ts2.SyntaxKind.FalseKeyword) return "z.literal(false)";
747
- if (literal.kind === ts2.SyntaxKind.NullKeyword) return "z.null()";
839
+ if (isStringLiteral2(literal)) return `z.literal(${JSON.stringify(literal.text)})`;
840
+ if (isNumericLiteral2(literal)) return `z.literal(${literal.text})`;
841
+ if (literal.kind === SyntaxKind2.TrueKeyword) return "z.literal(true)";
842
+ if (literal.kind === SyntaxKind2.FalseKeyword) return "z.literal(false)";
843
+ if (literal.kind === SyntaxKind2.NullKeyword) return "z.null()";
748
844
  return anyFallback("unknown literal");
749
845
  }
750
- if (ts2.isArrayTypeNode(node)) {
846
+ if (isArrayTypeNode(node)) {
751
847
  return `z.array(${convertTypeNode(node.elementType)})`;
752
848
  }
753
- if (ts2.isUnionTypeNode(node)) {
849
+ if (isUnionTypeNode(node)) {
754
850
  const members = node.types;
755
- const hasUndefined = members.some((m) => m.kind === ts2.SyntaxKind.UndefinedKeyword);
756
- const nonUndef = members.filter((m) => m.kind !== ts2.SyntaxKind.UndefinedKeyword);
851
+ const hasUndefined = members.some((m) => m.kind === SyntaxKind2.UndefinedKeyword);
852
+ const nonUndef = members.filter((m) => m.kind !== SyntaxKind2.UndefinedKeyword);
757
853
  if (nonUndef.length === 0) return "z.undefined()";
758
854
  const firstNonUndef = nonUndef[0];
759
855
  const innerSchema = nonUndef.length === 1 && firstNonUndef ? convertTypeNode(firstNonUndef) : `z.union([${nonUndef.map((m) => convertTypeNode(m)).join(", ")}])`;
760
856
  return hasUndefined ? wrapOptional(innerSchema) : innerSchema;
761
857
  }
762
- if (ts2.isTypeReferenceNode(node)) {
858
+ if (isTypeReferenceNode(node)) {
763
859
  const name = node.typeName.getText();
764
860
  const args = node.typeArguments ?? [];
765
861
  switch (name) {
@@ -787,10 +883,10 @@ var convertTypeNode = (node) => {
787
883
  }
788
884
  }
789
885
  }
790
- if (ts2.isTypeLiteralNode(node)) {
791
- const indexSignatures = node.members.filter((m) => ts2.isIndexSignatureDeclaration(m));
792
- const propertySignatures = node.members.filter((m) => ts2.isPropertySignature(m));
793
- if (indexSignatures.length === 1 && propertySignatures.length === 0 && indexSignatures[0]?.type.kind === ts2.SyntaxKind.NeverKeyword) {
886
+ if (isTypeLiteralNode(node)) {
887
+ const indexSignatures = node.members.filter((m) => isIndexSignatureDeclaration(m));
888
+ const propertySignatures = node.members.filter((m) => isPropertySignatureDeclaration(m));
889
+ if (indexSignatures.length === 1 && propertySignatures.length === 0 && indexSignatures[0]?.type.kind === SyntaxKind2.NeverKeyword) {
794
890
  return "z.object({}).strict()";
795
891
  }
796
892
  if (indexSignatures.length > 0 && propertySignatures.length === 0) {
@@ -802,21 +898,21 @@ var convertTypeNode = (node) => {
802
898
  }
803
899
  }
804
900
  const entries = propertySignatures.map((prop) => {
805
- if (!ts2.isIdentifier(prop.name)) return null;
901
+ if (!isIdentifier2(prop.name)) return null;
806
902
  if (!prop.type) return null;
807
903
  const name = prop.name.text;
808
904
  let schema = convertTypeNode(prop.type);
809
- if (prop.questionToken && !schema.endsWith(".optional()")) {
905
+ if (prop.postfixToken?.kind === SyntaxKind2.QuestionToken && !schema.endsWith(".optional()")) {
810
906
  schema = wrapOptional(schema);
811
907
  }
812
908
  return `${JSON.stringify(name)}: ${schema}`;
813
909
  }).filter((entry) => entry !== null);
814
910
  return `z.object({ ${entries.join(", ")} }).strict()`;
815
911
  }
816
- if (ts2.isParenthesizedTypeNode(node)) {
912
+ if (isParenthesizedTypeNode(node)) {
817
913
  return convertTypeNode(node.type);
818
914
  }
819
- if (ts2.isIntersectionTypeNode(node)) {
915
+ if (isIntersectionTypeNode(node)) {
820
916
  return anyFallback("intersection not yet supported");
821
917
  }
822
918
  return anyFallback(`unsupported TypeNode kind=${String(node.kind)}`);
@@ -825,9 +921,9 @@ var typeTextToZodSource = (typeText) => {
825
921
  const trimmed = typeText.trim();
826
922
  if (!trimmed) return null;
827
923
  const synthetic = `type __X = ${trimmed};`;
828
- const source = ts2.createSourceFile("__zod.ts", synthetic, ts2.ScriptTarget.Latest, true);
924
+ const source = parseSourceText("__zod.ts", synthetic);
829
925
  const statement = source.statements[0];
830
- if (!statement || !ts2.isTypeAliasDeclaration(statement)) return null;
926
+ if (!statement || !isTypeAliasDeclaration(statement)) return null;
831
927
  return convertTypeNode(statement.type);
832
928
  };
833
929
 
@@ -956,13 +1052,13 @@ var splitVersionedKey = (value) => {
956
1052
  return { name: name ?? "", version: version ?? "v1" };
957
1053
  };
958
1054
  var writeFileIfChanged = (filePath, content) => {
959
- if (fs4.existsSync(filePath)) {
960
- const currentContent = fs4.readFileSync(filePath, "utf8");
1055
+ if (fs5.existsSync(filePath)) {
1056
+ const currentContent = fs5.readFileSync(filePath, "utf8");
961
1057
  if (currentContent === content) {
962
1058
  return false;
963
1059
  }
964
1060
  }
965
- fs4.writeFileSync(filePath, content, "utf8");
1061
+ fs5.writeFileSync(filePath, content, "utf8");
966
1062
  return true;
967
1063
  };
968
1064
  var indentStr = (str, indentText) => {
@@ -1001,7 +1097,7 @@ var stripSymbolKeyedMembers = (text) => {
1001
1097
  return result;
1002
1098
  };
1003
1099
  var validateGeneratedTypeIdentifiers = (content) => {
1004
- const sourceFile = ts3.createSourceFile("apiTypes.generated.ts", content, ts3.ScriptTarget.Latest, true, ts3.ScriptKind.TS);
1100
+ const sourceFile = parseSourceText("apiTypes.generated.ts", content, ScriptKind.TS);
1005
1101
  const knownSymbols = /* @__PURE__ */ new Set();
1006
1102
  const referencedSymbols = /* @__PURE__ */ new Set();
1007
1103
  const builtIns = /* @__PURE__ */ new Set([
@@ -1058,38 +1154,38 @@ var validateGeneratedTypeIdentifiers = (content) => {
1058
1154
  }
1059
1155
  };
1060
1156
  const collectKnownSymbols = (node) => {
1061
- if (ts3.isInferTypeNode(node)) {
1157
+ if (isInferTypeNode(node)) {
1062
1158
  knownSymbols.add(node.typeParameter.name.text);
1063
1159
  }
1064
- if (ts3.isMappedTypeNode(node)) {
1160
+ if (isMappedTypeNode(node)) {
1065
1161
  knownSymbols.add(node.typeParameter.name.text);
1066
1162
  }
1067
- if (ts3.isImportDeclaration(node)) {
1163
+ if (isImportDeclaration(node)) {
1068
1164
  const importClause = node.importClause;
1069
1165
  if (importClause?.name) knownSymbols.add(importClause.name.text);
1070
- if (importClause?.namedBindings && ts3.isNamedImports(importClause.namedBindings)) {
1166
+ if (importClause?.namedBindings && isNamedImports(importClause.namedBindings)) {
1071
1167
  for (const importElement of importClause.namedBindings.elements) {
1072
1168
  knownSymbols.add((importElement.propertyName ?? importElement.name).text);
1073
1169
  }
1074
1170
  }
1075
- if (importClause?.namedBindings && ts3.isNamespaceImport(importClause.namedBindings)) {
1171
+ if (importClause?.namedBindings && isNamespaceImport(importClause.namedBindings)) {
1076
1172
  knownSymbols.add(importClause.namedBindings.name.text);
1077
1173
  }
1078
1174
  }
1079
- if (ts3.isInterfaceDeclaration(node) || ts3.isTypeAliasDeclaration(node) || ts3.isClassDeclaration(node) || ts3.isEnumDeclaration(node) || ts3.isFunctionDeclaration(node)) {
1175
+ if (isInterfaceDeclaration(node) || isTypeAliasDeclaration2(node) || isClassDeclaration(node) || isEnumDeclaration(node) || isFunctionDeclaration(node)) {
1080
1176
  addDeclaredName(node.name);
1081
1177
  collectTypeParams(node);
1082
1178
  }
1083
- if (ts3.isTypeReferenceNode(node)) {
1179
+ if (isTypeReferenceNode2(node)) {
1084
1180
  const typeName = node.typeName;
1085
- if (ts3.isIdentifier(typeName)) {
1181
+ if (isIdentifier3(typeName)) {
1086
1182
  referencedSymbols.add(typeName.text);
1087
1183
  }
1088
- if (ts3.isQualifiedName(typeName) && ts3.isIdentifier(typeName.left)) {
1184
+ if (isQualifiedName(typeName) && isIdentifier3(typeName.left)) {
1089
1185
  referencedSymbols.add(typeName.left.text);
1090
1186
  }
1091
1187
  }
1092
- ts3.forEachChild(node, collectKnownSymbols);
1188
+ node.forEachChild(collectKnownSymbols);
1093
1189
  };
1094
1190
  collectKnownSymbols(sourceFile);
1095
1191
  const unknown = [...referencedSymbols].filter((name) => !knownSymbols.has(name) && !builtIns.has(name)).toSorted();
@@ -1522,9 +1618,9 @@ var writeTypeMapArtifacts = ({
1522
1618
  }
1523
1619
  }
1524
1620
  const docsPath = getGeneratedApiDocsPath();
1525
- const docsDir = path4.dirname(docsPath);
1526
- if (!fs4.existsSync(docsDir)) {
1527
- fs4.mkdirSync(docsDir, { recursive: true });
1621
+ const docsDir = path5.dirname(docsPath);
1622
+ if (!fs5.existsSync(docsDir)) {
1623
+ fs5.mkdirSync(docsDir, { recursive: true });
1528
1624
  }
1529
1625
  const docsContent = JSON.stringify(docsData, null, 2);
1530
1626
  const hasUpdatedDocs = writeFileIfChanged(docsPath, docsContent);
@@ -1532,7 +1628,7 @@ var writeTypeMapArtifacts = ({
1532
1628
  console.log("[TypeMapGenerator] Generated apiDocs.generated.json");
1533
1629
  }
1534
1630
  if (diagnosticsData !== void 0) {
1535
- const diagnosticsPath = path4.join(path4.dirname(docsPath), "apiTypeDiagnostics.generated.json");
1631
+ const diagnosticsPath = path5.join(path5.dirname(docsPath), "apiTypeDiagnostics.generated.json");
1536
1632
  const diagnosticsContent = JSON.stringify(diagnosticsData, null, 2);
1537
1633
  const hasUpdatedDiagnostics = writeFileIfChanged(diagnosticsPath, diagnosticsContent);
1538
1634
  if (hasUpdatedDiagnostics) {
@@ -1548,30 +1644,46 @@ var writeTypeMapArtifacts = ({
1548
1644
  };
1549
1645
 
1550
1646
  // src/typeMap/extractors.ts
1551
- import * as ts5 from "typescript";
1552
- import path6 from "path";
1647
+ import path7 from "path";
1648
+ import { SymbolFlags as SymbolFlags2 } from "typescript-7-api/sync";
1649
+ import {
1650
+ ScriptKind as ScriptKind2
1651
+ } from "typescript-7-api/ast";
1652
+ import {
1653
+ isArrowFunction,
1654
+ isCallExpression,
1655
+ isFunctionDeclaration as isFunctionDeclaration2,
1656
+ isFunctionExpression,
1657
+ isIdentifier as isIdentifier5,
1658
+ isInterfaceDeclaration as isInterfaceDeclaration2,
1659
+ isObjectLiteralExpression as isObjectLiteralExpression2,
1660
+ isPropertySignatureDeclaration as isPropertySignatureDeclaration2,
1661
+ isReturnStatement,
1662
+ isTypeReferenceNode as isTypeReferenceNode3,
1663
+ isVariableStatement as isVariableStatement2
1664
+ } from "typescript-7-api/ast/is";
1553
1665
 
1554
1666
  // src/typeMap/tsProgram.ts
1555
- import * as ts4 from "typescript";
1556
- import path5 from "path";
1557
- import { ROOT_DIR as ROOT_DIR3, getGeneratedSocketTypesPath as getGeneratedSocketTypesPath2 } from "@luckystack/core";
1558
- var cachedProgram = null;
1559
- var getServerProgram = () => {
1560
- if (cachedProgram) return cachedProgram;
1561
- const tsconfigPath = ts4.findConfigFile(ROOT_DIR3, ts4.sys.fileExists.bind(ts4.sys), "tsconfig.server.json");
1562
- if (!tsconfigPath) throw new Error("[TypeProgram] tsconfig.server.json not found");
1563
- const { config } = ts4.readConfigFile(tsconfigPath, ts4.sys.readFile.bind(ts4.sys));
1564
- const { options, fileNames } = ts4.parseJsonConfigFileContent(
1565
- config,
1566
- ts4.sys,
1567
- path5.dirname(tsconfigPath)
1568
- );
1569
- cachedProgram = ts4.createProgram(fileNames, options);
1570
- return cachedProgram;
1571
- };
1572
- var invalidateProgramCache = () => {
1573
- cachedProgram = null;
1574
- };
1667
+ import path6 from "path";
1668
+ import {
1669
+ ObjectFlags,
1670
+ SymbolFlags,
1671
+ TypeFlags
1672
+ } from "typescript-7-api/sync";
1673
+ import { SyntaxKind as SyntaxKind3 } from "typescript-7-api/ast";
1674
+ import {
1675
+ isAsExpression as isAsExpression2,
1676
+ isIdentifier as isIdentifier4,
1677
+ isNoSubstitutionTemplateLiteral,
1678
+ isNumericLiteral as isNumericLiteral3,
1679
+ isParenthesizedExpression as isParenthesizedExpression2,
1680
+ isPrefixUnaryExpression,
1681
+ isPropertyAssignment as isPropertyAssignment2,
1682
+ isShorthandPropertyAssignment,
1683
+ isStringLiteral as isStringLiteral3,
1684
+ isTypeAssertion
1685
+ } from "typescript-7-api/ast/is";
1686
+ import { getGeneratedSocketTypesPath as getGeneratedSocketTypesPath2 } from "@luckystack/core";
1575
1687
  var DEPTH_LIMIT = 14;
1576
1688
  var JSON_TYPE_NAMES = /* @__PURE__ */ new Set([
1577
1689
  "Json",
@@ -1621,35 +1733,35 @@ var UnsupportedWireTypeError = class extends Error {
1621
1733
  }
1622
1734
  };
1623
1735
  var isJsonLikeType = (type, checker) => {
1624
- const symbolName = type.symbol?.name ?? "";
1625
- const aliasName = type.aliasSymbol?.name ?? "";
1736
+ const symbolName = type.getSymbol()?.name ?? "";
1737
+ const aliasName = type.getAliasSymbol()?.name ?? "";
1626
1738
  if (JSON_TYPE_NAMES.has(symbolName) || JSON_TYPE_NAMES.has(aliasName)) return true;
1627
1739
  const rendered = checker.typeToString(type).trim();
1628
1740
  return /^(?:Prisma\.)?(?:Input)?Json(?:Value|Object|Array)$/.test(rendered);
1629
1741
  };
1630
1742
  var getLiteralTypeFromExpression = (expression, checker, depth) => {
1631
- if (ts4.isParenthesizedExpression(expression)) {
1743
+ if (isParenthesizedExpression2(expression)) {
1632
1744
  return getLiteralTypeFromExpression(expression.expression, checker, depth);
1633
1745
  }
1634
- if (ts4.isAsExpression(expression) || ts4.isTypeAssertionExpression(expression)) {
1746
+ if (isAsExpression2(expression) || isTypeAssertion(expression)) {
1635
1747
  return getLiteralTypeFromExpression(expression.expression, checker, depth);
1636
1748
  }
1637
- if (expression.kind === ts4.SyntaxKind.TrueKeyword) return "true";
1638
- if (expression.kind === ts4.SyntaxKind.FalseKeyword) return "false";
1639
- if (expression.kind === ts4.SyntaxKind.NullKeyword) return "null";
1640
- if (ts4.isStringLiteral(expression) || ts4.isNoSubstitutionTemplateLiteral(expression)) {
1749
+ if (expression.kind === SyntaxKind3.TrueKeyword) return "true";
1750
+ if (expression.kind === SyntaxKind3.FalseKeyword) return "false";
1751
+ if (expression.kind === SyntaxKind3.NullKeyword) return "null";
1752
+ if (isStringLiteral3(expression) || isNoSubstitutionTemplateLiteral(expression)) {
1641
1753
  return `'${expression.text.replaceAll("\\", "\\\\").replaceAll("'", String.raw`\'`)}'`;
1642
1754
  }
1643
- if (ts4.isNumericLiteral(expression)) {
1755
+ if (isNumericLiteral3(expression)) {
1644
1756
  return expression.text;
1645
1757
  }
1646
- if (ts4.isPrefixUnaryExpression(expression) && expression.operator === ts4.SyntaxKind.MinusToken && ts4.isNumericLiteral(expression.operand)) {
1758
+ if (isPrefixUnaryExpression(expression) && expression.operator === SyntaxKind3.MinusToken && isNumericLiteral3(expression.operand)) {
1647
1759
  return `-${expression.operand.text}`;
1648
1760
  }
1649
- if (ts4.isIdentifier(expression)) {
1761
+ if (isIdentifier4(expression)) {
1650
1762
  const identifierType = checker.getTypeAtLocation(expression);
1651
- const isLiteralType = (identifierType.flags & (ts4.TypeFlags.StringLiteral | ts4.TypeFlags.NumberLiteral | ts4.TypeFlags.BooleanLiteral | ts4.TypeFlags.Null | ts4.TypeFlags.Undefined)) !== 0;
1652
- if (isLiteralType || identifierType.isUnion()) {
1763
+ const isLiteralType = (identifierType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.BooleanLiteral | TypeFlags.Null | TypeFlags.Undefined)) !== 0;
1764
+ if (isLiteralType || identifierType.isUnionType()) {
1653
1765
  const expanded = expandTypeDetailed(identifierType, checker, depth).text;
1654
1766
  if (expanded.includes("'") || /\btrue\b|\bfalse\b|\bnull\b|\bundefined\b/.test(expanded)) {
1655
1767
  return expanded;
@@ -1659,13 +1771,15 @@ var getLiteralTypeFromExpression = (expression, checker, depth) => {
1659
1771
  return null;
1660
1772
  };
1661
1773
  var getLiteralTypeFromPropertySymbol = (symbol, checker, depth) => {
1662
- const declarations = symbol.declarations ?? [];
1663
- for (const declaration of declarations) {
1664
- if (ts4.isPropertyAssignment(declaration)) {
1774
+ for (const handle of symbol.declarations) {
1775
+ if (handle.kind !== SyntaxKind3.PropertyAssignment && handle.kind !== SyntaxKind3.ShorthandPropertyAssignment) continue;
1776
+ const declaration = handle.resolve();
1777
+ if (!declaration) continue;
1778
+ if (isPropertyAssignment2(declaration)) {
1665
1779
  const literal = getLiteralTypeFromExpression(declaration.initializer, checker, depth);
1666
1780
  if (literal) return literal;
1667
1781
  }
1668
- if (ts4.isShorthandPropertyAssignment(declaration)) {
1782
+ if (isShorthandPropertyAssignment(declaration) && isIdentifier4(declaration.name)) {
1669
1783
  const literal = getLiteralTypeFromExpression(declaration.name, checker, depth);
1670
1784
  if (literal) return literal;
1671
1785
  }
@@ -1673,10 +1787,10 @@ var getLiteralTypeFromPropertySymbol = (symbol, checker, depth) => {
1673
1787
  return null;
1674
1788
  };
1675
1789
  var normalizeImportPath = (targetFilePath) => {
1676
- const fromDir = path5.dirname(getGeneratedSocketTypesPath2());
1790
+ const fromDir = path6.dirname(getGeneratedSocketTypesPath2());
1677
1791
  const from = fromDir.replaceAll("\\", "/");
1678
1792
  const to = targetFilePath.replaceAll("\\", "/");
1679
- const normalized = path5.posix.relative(from, to).replaceAll("\\", "/");
1793
+ const normalized = path6.posix.relative(from, to).replaceAll("\\", "/");
1680
1794
  const withoutExtension = normalized.replace(/(\.d)?\.(ts|tsx|js|jsx)$/i, "");
1681
1795
  if (withoutExtension.startsWith(".")) return withoutExtension;
1682
1796
  return `./${withoutExtension}`;
@@ -1692,17 +1806,20 @@ var mergeUnresolvedSymbols = (left, right) => {
1692
1806
  }
1693
1807
  return merged;
1694
1808
  };
1809
+ var isNodeModulesPath = (filePath) => filePath.includes("/node_modules/") || filePath.includes("\\node_modules\\");
1810
+ var getDeclarationFileName = (symbol) => {
1811
+ const handle = symbol.declarations[0];
1812
+ if (!handle || isNodeModulesPath(handle.path)) return void 0;
1813
+ const fileName = handle.resolve()?.getSourceFile().fileName;
1814
+ return fileName && !isNodeModulesPath(fileName) ? fileName : void 0;
1815
+ };
1695
1816
  var collectTypeSymbolFallback = (type) => {
1696
- const symbol = type.aliasSymbol ?? type.getSymbol();
1817
+ const symbol = type.getAliasSymbol() ?? type.getSymbol();
1697
1818
  if (!symbol) return [];
1698
- const name = symbol.getName();
1819
+ const name = symbol.name;
1699
1820
  if (!name || name.startsWith("__")) return [];
1700
- const declaration = symbol.declarations?.[0];
1701
- if (!declaration) return [{ name }];
1702
- const sourceFile = declaration.getSourceFile().fileName;
1703
- if (!sourceFile || sourceFile.includes("/node_modules/") || sourceFile.includes("\\node_modules\\")) {
1704
- return [{ name }];
1705
- }
1821
+ const sourceFile = getDeclarationFileName(symbol);
1822
+ if (!sourceFile) return [{ name }];
1706
1823
  return [{
1707
1824
  name,
1708
1825
  sourceFile,
@@ -1713,16 +1830,14 @@ var WIRE_PROJECTED_TYPES = /* @__PURE__ */ new Map([["Date", "string"]]);
1713
1830
  var resolveToJsonReturnType = (type, checker) => {
1714
1831
  const toJson = type.getProperty("toJSON");
1715
1832
  if (!toJson) return null;
1716
- const declaration = toJson.valueDeclaration ?? toJson.declarations?.[0];
1717
- if (!declaration) return null;
1718
- const signature = checker.getTypeOfSymbolAtLocation(toJson, declaration).getCallSignatures()[0];
1833
+ if (!toJson.valueDeclaration && toJson.declarations.length === 0) return null;
1834
+ const signature = checker.getNonMissingTypeOfSymbol(toJson).getCallSignatures()[0];
1719
1835
  return signature ? signature.getReturnType() : null;
1720
1836
  };
1721
1837
  var isFunctionValueType = (type) => type.getCallSignatures().length > 0;
1722
1838
  var typeNameOf = (type, checker) => {
1723
- const objectType = type;
1724
- if (type.flags & ts4.TypeFlags.Object && objectType.objectFlags & ts4.ObjectFlags.Reference) {
1725
- const targetName = objectType.target.getSymbol()?.name;
1839
+ if (type.isTypeReference()) {
1840
+ const targetName = type.getTarget().getSymbol()?.name;
1726
1841
  if (targetName) return targetName;
1727
1842
  }
1728
1843
  return type.getSymbol()?.name ?? checker.typeToString(type);
@@ -1732,13 +1847,13 @@ var assertSupportedWireType = (type, checker) => {
1732
1847
  if (TRANSPORT_DEPENDENT_BINARY_TYPES.has(typeName)) {
1733
1848
  throw new UnsupportedWireTypeError(typeName);
1734
1849
  }
1735
- if ((type.flags & (ts4.TypeFlags.BigInt | ts4.TypeFlags.BigIntLiteral)) !== 0) {
1850
+ if ((type.flags & (TypeFlags.BigInt | TypeFlags.BigIntLiteral)) !== 0) {
1736
1851
  throw new UnsupportedWireTypeError("bigint");
1737
1852
  }
1738
1853
  };
1739
- var isJsonOmittedValueType = (type) => (type.flags & (ts4.TypeFlags.Undefined | ts4.TypeFlags.Void | ts4.TypeFlags.ESSymbol | ts4.TypeFlags.UniqueESSymbol)) !== 0 || isFunctionValueType(type);
1854
+ var isJsonOmittedValueType = (type) => (type.flags & (TypeFlags.Undefined | TypeFlags.Void | TypeFlags.ESSymbol | TypeFlags.UniqueESSymbol)) !== 0 || isFunctionValueType(type);
1740
1855
  var resolveWireConstituents = (type, checker) => {
1741
- const queue = type.isUnion() ? [...type.types] : [type];
1856
+ const queue = type.isUnionType() ? [...type.getTypes()] : [type];
1742
1857
  const serializable = [];
1743
1858
  let omitted = false;
1744
1859
  let changed = false;
@@ -1750,9 +1865,9 @@ var resolveWireConstituents = (type, checker) => {
1750
1865
  continue;
1751
1866
  }
1752
1867
  const jsonType = resolveToJsonReturnType(candidate, checker);
1753
- const effective = jsonType && jsonType !== candidate ? jsonType : candidate;
1868
+ const effective = jsonType && jsonType.id !== candidate.id ? jsonType : candidate;
1754
1869
  if (effective !== candidate) changed = true;
1755
- const effectiveTypes = effective.isUnion() ? effective.types : [effective];
1870
+ const effectiveTypes = effective.isUnionType() ? effective.getTypes() : [effective];
1756
1871
  for (const effectiveType of effectiveTypes) {
1757
1872
  assertSupportedWireType(effectiveType, checker);
1758
1873
  if (isJsonOmittedValueType(effectiveType)) {
@@ -1768,15 +1883,13 @@ var resolveWireConstituents = (type, checker) => {
1768
1883
  var expandTypeDetailed = (type, checker, depth = 0, state, options) => {
1769
1884
  const expandState = state ?? { stackTypeIds: /* @__PURE__ */ new Set(), wireProjection: options?.wireProjection ?? false };
1770
1885
  const typeId = type.id;
1771
- if (typeId !== void 0) {
1772
- if (expandState.stackTypeIds.has(typeId)) {
1773
- return {
1774
- text: checker.typeToString(type),
1775
- unresolvedSymbols: collectTypeSymbolFallback(type)
1776
- };
1777
- }
1778
- expandState.stackTypeIds.add(typeId);
1886
+ if (expandState.stackTypeIds.has(typeId)) {
1887
+ return {
1888
+ text: checker.typeToString(type),
1889
+ unresolvedSymbols: collectTypeSymbolFallback(type)
1890
+ };
1779
1891
  }
1892
+ expandState.stackTypeIds.add(typeId);
1780
1893
  try {
1781
1894
  if (expandState.wireProjection) {
1782
1895
  assertSupportedWireType(type, checker);
@@ -1791,14 +1904,14 @@ var expandTypeDetailed = (type, checker, depth = 0, state, options) => {
1791
1904
  };
1792
1905
  }
1793
1906
  if (isJsonLikeType(type, checker)) return { text: "JsonValue", unresolvedSymbols: [] };
1794
- if (type.isStringLiteral()) return { text: `'${type.value.replaceAll("\\", "\\\\").replaceAll("'", String.raw`\'`)}'`, unresolvedSymbols: [] };
1795
- if (type.isNumberLiteral()) return { text: String(type.value), unresolvedSymbols: [] };
1796
- if (type.flags & (ts4.TypeFlags.String | ts4.TypeFlags.Number | ts4.TypeFlags.Boolean | ts4.TypeFlags.BooleanLiteral | ts4.TypeFlags.Undefined | ts4.TypeFlags.Null | ts4.TypeFlags.Any | ts4.TypeFlags.Unknown | ts4.TypeFlags.Never | ts4.TypeFlags.Void)) {
1907
+ if (type.isStringLiteralType()) return { text: `'${type.value.replaceAll("\\", "\\\\").replaceAll("'", String.raw`\'`)}'`, unresolvedSymbols: [] };
1908
+ if (type.isNumberLiteralType()) return { text: String(type.value), unresolvedSymbols: [] };
1909
+ if (type.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.Boolean | TypeFlags.BooleanLiteral | TypeFlags.Undefined | TypeFlags.Null | TypeFlags.Any | TypeFlags.Unknown | TypeFlags.Never | TypeFlags.Void)) {
1797
1910
  return { text: checker.typeToString(type), unresolvedSymbols: [] };
1798
1911
  }
1799
- if (type.isUnion()) {
1912
+ if (type.isUnionType()) {
1800
1913
  let unresolvedSymbols = [];
1801
- const expandedTypes = type.types.map((innerType) => {
1914
+ const expandedTypes = type.getTypes().map((innerType) => {
1802
1915
  const expanded = expandTypeDetailed(innerType, checker, depth + 1, expandState);
1803
1916
  unresolvedSymbols = mergeUnresolvedSymbols(unresolvedSymbols, expanded.unresolvedSymbols);
1804
1917
  return expanded.text;
@@ -1806,20 +1919,19 @@ var expandTypeDetailed = (type, checker, depth = 0, state, options) => {
1806
1919
  const uniqueTypes = [...new Set(expandedTypes)];
1807
1920
  return { text: uniqueTypes.join(" | "), unresolvedSymbols };
1808
1921
  }
1809
- if (type.isIntersection()) {
1922
+ if (type.isIntersectionType()) {
1810
1923
  let unresolvedSymbols = [];
1811
- const expandedTypes = type.types.map((innerType) => {
1924
+ const expandedTypes = type.getTypes().map((innerType) => {
1812
1925
  const expanded = expandTypeDetailed(innerType, checker, depth + 1, expandState);
1813
1926
  unresolvedSymbols = mergeUnresolvedSymbols(unresolvedSymbols, expanded.unresolvedSymbols);
1814
1927
  return expanded.text;
1815
1928
  });
1816
1929
  return { text: expandedTypes.join(" & "), unresolvedSymbols };
1817
1930
  }
1818
- if (type.flags & ts4.TypeFlags.Object) {
1819
- const objectType = type;
1820
- const tupleTarget = objectType.objectFlags & ts4.ObjectFlags.Reference ? objectType.target : objectType;
1821
- if (tupleTarget.objectFlags & ts4.ObjectFlags.Tuple) {
1822
- const typeArgs = checker.getTypeArguments(objectType);
1931
+ if (type.isObjectType()) {
1932
+ const tupleTarget = type.isTypeReference() ? type.getTarget() : type;
1933
+ if (tupleTarget.objectFlags & ObjectFlags.Tuple) {
1934
+ const typeArgs = type.isTypeReference() ? checker.getTypeArguments(type) : [];
1823
1935
  let unresolvedSymbols = [];
1824
1936
  const tupleTypes = typeArgs.map((innerType) => {
1825
1937
  const wire = expandState.wireProjection ? resolveWireConstituents(innerType, checker) : { serializable: [innerType], omitted: false };
@@ -1836,15 +1948,14 @@ var expandTypeDetailed = (type, checker, depth = 0, state, options) => {
1836
1948
  }
1837
1949
  if (expandState.wireProjection) {
1838
1950
  const jsonType = resolveToJsonReturnType(type, checker);
1839
- if (jsonType && jsonType !== type) {
1951
+ if (jsonType && jsonType.id !== type.id) {
1840
1952
  return expandTypeDetailed(jsonType, checker, depth + 1, expandState);
1841
1953
  }
1842
1954
  }
1843
- if (objectType.objectFlags & ts4.ObjectFlags.Reference) {
1844
- const refType = objectType;
1845
- const targetName = refType.target.symbol?.name ?? "";
1955
+ if (type.isTypeReference()) {
1956
+ const targetName = type.getTarget().getSymbol()?.name ?? "";
1846
1957
  if (targetName === "Array" || targetName === "ReadonlyArray") {
1847
- const typeArgs = checker.getTypeArguments(refType);
1958
+ const typeArgs = checker.getTypeArguments(type);
1848
1959
  const firstArg = typeArgs[0];
1849
1960
  if (firstArg) {
1850
1961
  const wire = expandState.wireProjection ? resolveWireConstituents(firstArg, checker) : { serializable: [firstArg], omitted: false };
@@ -1866,7 +1977,7 @@ var expandTypeDetailed = (type, checker, depth = 0, state, options) => {
1866
1977
  return { text: projected ?? checker.typeToString(type), unresolvedSymbols: [] };
1867
1978
  }
1868
1979
  }
1869
- const symbolName = type.symbol?.name || (type.aliasSymbol?.name ?? "");
1980
+ const symbolName = (type.getSymbol()?.name ?? "") || (type.getAliasSymbol()?.name ?? "");
1870
1981
  if (SKIP_EXPANSION.has(symbolName)) {
1871
1982
  const projected = expandState.wireProjection ? WIRE_PROJECTED_TYPES.get(symbolName) : void 0;
1872
1983
  return { text: projected ?? checker.typeToString(type), unresolvedSymbols: [] };
@@ -1877,12 +1988,12 @@ var expandTypeDetailed = (type, checker, depth = 0, state, options) => {
1877
1988
  const fields = [];
1878
1989
  let unresolvedSymbols = [];
1879
1990
  for (const prop of props) {
1880
- if (prop.getName().startsWith("__@")) continue;
1991
+ if (prop.name.startsWith("__@")) continue;
1881
1992
  const propType = checker.getTypeOfSymbol(prop);
1882
1993
  const wire = expandState.wireProjection ? resolveWireConstituents(propType, checker) : { serializable: [propType], omitted: false };
1883
1994
  if (wire.serializable.length === 0) continue;
1884
1995
  const literalType = getLiteralTypeFromPropertySymbol(prop, checker, depth + 1);
1885
- const isOptional = (prop.flags & ts4.SymbolFlags.Optional) !== 0 || wire.omitted;
1996
+ const isOptional = (prop.flags & SymbolFlags.Optional) !== 0 || wire.omitted;
1886
1997
  if (literalType && !wire.omitted) {
1887
1998
  fields.push(`${prop.name}${isOptional ? "?" : ""}: ${literalType}`);
1888
1999
  continue;
@@ -1897,7 +2008,7 @@ var expandTypeDetailed = (type, checker, depth = 0, state, options) => {
1897
2008
  }
1898
2009
  for (const indexInfo of indexInfos) {
1899
2010
  const keyType = expandTypeDetailed(indexInfo.keyType, checker, depth + 1, expandState);
1900
- const wire = expandState.wireProjection ? resolveWireConstituents(indexInfo.type, checker) : { serializable: [indexInfo.type], omitted: false };
2011
+ const wire = expandState.wireProjection ? resolveWireConstituents(indexInfo.valueType, checker) : { serializable: [indexInfo.valueType], omitted: false };
1901
2012
  if (wire.serializable.length === 0) continue;
1902
2013
  const valueTexts = [];
1903
2014
  for (const serializableType of wire.serializable) {
@@ -1925,9 +2036,7 @@ ${outerIndent}}`,
1925
2036
  unresolvedSymbols: collectTypeSymbolFallback(type)
1926
2037
  };
1927
2038
  } finally {
1928
- if (typeId !== void 0) {
1929
- expandState.stackTypeIds.delete(typeId);
1930
- }
2039
+ expandState.stackTypeIds.delete(typeId);
1931
2040
  }
1932
2041
  };
1933
2042
  var expandType = (type, checker, depth = 0) => {
@@ -1969,10 +2078,10 @@ var KNOWN_GLOBAL_TYPE_NAMES = /* @__PURE__ */ new Set([
1969
2078
  "JsonPrimitive"
1970
2079
  ]);
1971
2080
  var normalizeImportPath2 = (targetFilePath) => {
1972
- const fromDir = path6.dirname(getGeneratedSocketTypesPath3());
2081
+ const fromDir = path7.dirname(getGeneratedSocketTypesPath3());
1973
2082
  const from = fromDir.replaceAll("\\", "/");
1974
2083
  const to = targetFilePath.replaceAll("\\", "/");
1975
- const normalized = path6.posix.relative(from, to).replaceAll("\\", "/");
2084
+ const normalized = path7.posix.relative(from, to).replaceAll("\\", "/");
1976
2085
  const withoutExtension = normalized.replace(/(\.d)?\.(ts|tsx|js|jsx)$/i, "");
1977
2086
  if (withoutExtension.startsWith(".")) return withoutExtension;
1978
2087
  return `./${withoutExtension}`;
@@ -1992,22 +2101,19 @@ var collectFallbackSymbolsFromTypeText = (typeText, scopeNode, checker) => {
1992
2101
  const names = new Set((typeText.match(TYPE_NAME_PATTERN) ?? []).filter((name) => !KNOWN_GLOBAL_TYPE_NAMES.has(name)));
1993
2102
  const symbolsInScope = checker.getSymbolsInScope(
1994
2103
  scopeNode,
1995
- ts5.SymbolFlags.TypeAlias | ts5.SymbolFlags.Interface | ts5.SymbolFlags.Class | ts5.SymbolFlags.Enum | ts5.SymbolFlags.Alias
2104
+ SymbolFlags2.TypeAlias | SymbolFlags2.Interface | SymbolFlags2.Class | SymbolFlags2.Enum | SymbolFlags2.Alias
1996
2105
  );
1997
2106
  const unresolvedSymbols = [];
1998
2107
  for (const name of names) {
1999
2108
  const localSymbol = symbolsInScope.find((symbol) => symbol.name === name);
2000
2109
  if (!localSymbol) continue;
2001
- const targetSymbol = (localSymbol.flags & ts5.SymbolFlags.Alias) === 0 ? localSymbol : checker.getAliasedSymbol(localSymbol);
2002
- const declaration = targetSymbol.declarations?.[0];
2003
- if (!declaration) {
2110
+ const targetSymbol = (localSymbol.flags & SymbolFlags2.Alias) === 0 ? localSymbol : checker.getAliasedSymbol(localSymbol);
2111
+ if (targetSymbol.declarations.length === 0) {
2004
2112
  unresolvedSymbols.push({ name });
2005
2113
  continue;
2006
2114
  }
2007
- const sourceFile = declaration.getSourceFile().fileName;
2008
- if (!sourceFile || sourceFile.includes("/node_modules/") || sourceFile.includes("\\node_modules\\")) {
2009
- continue;
2010
- }
2115
+ const sourceFile = getDeclarationFileName(targetSymbol);
2116
+ if (!sourceFile) continue;
2011
2117
  unresolvedSymbols.push({
2012
2118
  name,
2013
2119
  sourceFile,
@@ -2018,13 +2124,13 @@ var collectFallbackSymbolsFromTypeText = (typeText, scopeNode, checker) => {
2018
2124
  };
2019
2125
  var findInterface = (sourceFile, name) => {
2020
2126
  for (const stmt of sourceFile.statements) {
2021
- if (ts5.isInterfaceDeclaration(stmt) && stmt.name.text === name) return stmt;
2127
+ if (isInterfaceDeclaration2(stmt) && stmt.name.text === name) return stmt;
2022
2128
  }
2023
2129
  return null;
2024
2130
  };
2025
2131
  var getInterfacePropertyType = (iface, propertyName, checker) => {
2026
2132
  for (const member of iface.members) {
2027
- if (ts5.isPropertySignature(member) && ts5.isIdentifier(member.name) && member.name.text === propertyName && member.type) {
2133
+ if (isPropertySignatureDeclaration2(member) && isIdentifier5(member.name) && member.name.text === propertyName && member.type) {
2028
2134
  return checker.getTypeFromTypeNode(member.type);
2029
2135
  }
2030
2136
  }
@@ -2032,14 +2138,14 @@ var getInterfacePropertyType = (iface, propertyName, checker) => {
2032
2138
  };
2033
2139
  var findMainFunction = (sourceFile) => {
2034
2140
  for (const stmt of sourceFile.statements) {
2035
- if (ts5.isVariableStatement(stmt)) {
2141
+ if (isVariableStatement2(stmt)) {
2036
2142
  for (const decl of stmt.declarationList.declarations) {
2037
- if (ts5.isIdentifier(decl.name) && decl.name.text === "main" && decl.initializer && (ts5.isArrowFunction(decl.initializer) || ts5.isFunctionExpression(decl.initializer))) {
2143
+ if (isIdentifier5(decl.name) && decl.name.text === "main" && decl.initializer && (isArrowFunction(decl.initializer) || isFunctionExpression(decl.initializer))) {
2038
2144
  return decl.initializer;
2039
2145
  }
2040
2146
  }
2041
2147
  }
2042
- if (ts5.isFunctionDeclaration(stmt) && stmt.name?.text === "main") {
2148
+ if (isFunctionDeclaration2(stmt) && stmt.name?.text === "main") {
2043
2149
  return stmt;
2044
2150
  }
2045
2151
  }
@@ -2049,7 +2155,7 @@ var collectReturnObjectTypeDetails = (funcNode, checker) => {
2049
2155
  const types = [];
2050
2156
  let unresolvedSymbols = [];
2051
2157
  const visit = (node) => {
2052
- if (ts5.isReturnStatement(node) && node.expression && ts5.isObjectLiteralExpression(node.expression)) {
2158
+ if (isReturnStatement(node) && node.expression && isObjectLiteralExpression2(node.expression)) {
2053
2159
  const type = checker.getTypeAtLocation(node.expression);
2054
2160
  const expanded = expandTypeDetailed(type, checker, 0, void 0, { wireProjection: true });
2055
2161
  types.push(expanded.text);
@@ -2059,11 +2165,11 @@ var collectReturnObjectTypeDetails = (funcNode, checker) => {
2059
2165
  collectFallbackSymbolsFromTypeText(expanded.text, node.expression, checker)
2060
2166
  );
2061
2167
  }
2062
- if (!ts5.isArrowFunction(node) && !ts5.isFunctionExpression(node) && !ts5.isFunctionDeclaration(node)) {
2063
- ts5.forEachChild(node, visit);
2168
+ if (!isArrowFunction(node) && !isFunctionExpression(node) && !isFunctionDeclaration2(node)) {
2169
+ node.forEachChild(visit);
2064
2170
  }
2065
2171
  };
2066
- ts5.forEachChild(funcNode, visit);
2172
+ funcNode.forEachChild(visit);
2067
2173
  return { text: unionTypes(types), unresolvedSymbols };
2068
2174
  };
2069
2175
  var STREAM_EMIT_NAMES = /* @__PURE__ */ new Set(["stream", "broadcastStream", "streamTo"]);
@@ -2071,7 +2177,7 @@ var collectStreamCallPayloadTypeDetails = (funcNode, checker) => {
2071
2177
  const types = [];
2072
2178
  let unresolvedSymbols = [];
2073
2179
  const visit = (node) => {
2074
- if (ts5.isCallExpression(node) && ts5.isIdentifier(node.expression) && STREAM_EMIT_NAMES.has(node.expression.text)) {
2180
+ if (isCallExpression(node) && isIdentifier5(node.expression) && STREAM_EMIT_NAMES.has(node.expression.text)) {
2075
2181
  const callName = node.expression.text;
2076
2182
  const payloadIndex = callName === "streamTo" ? 1 : 0;
2077
2183
  const payloadArg = node.arguments[payloadIndex];
@@ -2089,11 +2195,11 @@ var collectStreamCallPayloadTypeDetails = (funcNode, checker) => {
2089
2195
  );
2090
2196
  }
2091
2197
  }
2092
- if (!ts5.isArrowFunction(node) && !ts5.isFunctionExpression(node) && !ts5.isFunctionDeclaration(node)) {
2093
- ts5.forEachChild(node, visit);
2198
+ if (!isArrowFunction(node) && !isFunctionExpression(node) && !isFunctionDeclaration2(node)) {
2199
+ node.forEachChild(visit);
2094
2200
  }
2095
2201
  };
2096
- ts5.forEachChild(funcNode, visit);
2202
+ funcNode.forEachChild(visit);
2097
2203
  return { text: unionTypes(types), unresolvedSymbols };
2098
2204
  };
2099
2205
  var unionTypes = (types) => {
@@ -2107,15 +2213,13 @@ var UnsupportedTransportInputError = class extends Error {
2107
2213
  }
2108
2214
  };
2109
2215
  var assertTransportInputIsWireSafe = (typeText, filePath) => {
2110
- const sourceFile = ts5.createSourceFile(
2216
+ const sourceFile = parseSourceText(
2111
2217
  "__luckystack_input_check.ts",
2112
2218
  `type __LuckyStackInput = ${typeText};`,
2113
- ts5.ScriptTarget.Latest,
2114
- true,
2115
- ts5.ScriptKind.TS
2219
+ ScriptKind2.TS
2116
2220
  );
2117
2221
  const containsDate = (node) => {
2118
- if (ts5.isTypeReferenceNode(node) && ts5.isIdentifier(node.typeName) && node.typeName.text === "Date") {
2222
+ if (isTypeReferenceNode3(node) && isIdentifier5(node.typeName) && node.typeName.text === "Date") {
2119
2223
  return true;
2120
2224
  }
2121
2225
  return node.getChildren(sourceFile).some((child) => containsDate(child));
@@ -2129,13 +2233,12 @@ var getInputTypeDetailsFromFile = (filePath) => {
2129
2233
  const DEFAULT = "{ }";
2130
2234
  recordExtractionOutcome({ filePath, kind: "api", field: "input", error: null });
2131
2235
  try {
2132
- const program = getServerProgram();
2236
+ const { program, checker } = getServerProgram();
2133
2237
  const sourceFile = program.getSourceFile(filePath);
2134
2238
  if (!sourceFile) {
2135
2239
  console.warn(`[TypeMapGenerator] getSourceFile miss for ${filePath} \u2014 input types will default to { }`);
2136
2240
  return { text: DEFAULT, unresolvedSymbols: [] };
2137
2241
  }
2138
- const checker = program.getTypeChecker();
2139
2242
  const iface = findInterface(sourceFile, "ApiParams");
2140
2243
  if (!iface) return { text: DEFAULT, unresolvedSymbols: [] };
2141
2244
  const dataType = getInterfacePropertyType(iface, "data", checker);
@@ -2161,9 +2264,9 @@ var extractDeclaredStreamTypeFromApiParams = (sourceFile, checker) => {
2161
2264
  let result = null;
2162
2265
  const visit = (node) => {
2163
2266
  if (result) return;
2164
- if (ts5.isInterfaceDeclaration(node) && node.name.text.endsWith("Params")) {
2267
+ if (isInterfaceDeclaration2(node) && node.name.text.endsWith("Params")) {
2165
2268
  for (const member of node.members) {
2166
- if (ts5.isPropertySignature(member) && ts5.isIdentifier(member.name) && member.name.text === "stream" && member.type && ts5.isTypeReferenceNode(member.type) && ts5.isIdentifier(member.type.typeName) && STREAM_EMITTER_TYPE_NAMES.has(member.type.typeName.text)) {
2269
+ if (isPropertySignatureDeclaration2(member) && isIdentifier5(member.name) && member.name.text === "stream" && member.type && isTypeReferenceNode3(member.type) && isIdentifier5(member.type.typeName) && STREAM_EMITTER_TYPE_NAMES.has(member.type.typeName.text)) {
2167
2270
  const typeArg = member.type.typeArguments?.[0];
2168
2271
  if (typeArg) {
2169
2272
  const argType = checker.getNonNullableType(checker.getTypeFromTypeNode(typeArg));
@@ -2176,7 +2279,7 @@ var extractDeclaredStreamTypeFromApiParams = (sourceFile, checker) => {
2176
2279
  }
2177
2280
  }
2178
2281
  }
2179
- ts5.forEachChild(node, visit);
2282
+ node.forEachChild(visit);
2180
2283
  };
2181
2284
  visit(sourceFile);
2182
2285
  return result;
@@ -2185,10 +2288,9 @@ var getApiStreamPayloadTypeDetailsFromFile = (filePath) => {
2185
2288
  const DEFAULT = "never";
2186
2289
  recordExtractionOutcome({ filePath, kind: "api", field: "stream", error: null });
2187
2290
  try {
2188
- const program = getServerProgram();
2291
+ const { program, checker } = getServerProgram();
2189
2292
  const sourceFile = program.getSourceFile(filePath);
2190
2293
  if (!sourceFile) return { text: DEFAULT, unresolvedSymbols: [] };
2191
- const checker = program.getTypeChecker();
2192
2294
  const mainFn = findMainFunction(sourceFile);
2193
2295
  if (!mainFn) return { text: DEFAULT, unresolvedSymbols: [] };
2194
2296
  const details = collectStreamCallPayloadTypeDetails(mainFn, checker);
@@ -2207,10 +2309,9 @@ var getOutputTypeDetailsFromFile = (filePath) => {
2207
2309
  const DEFAULT = "{ status: string }";
2208
2310
  recordExtractionOutcome({ filePath, kind: "api", field: "output", error: null });
2209
2311
  try {
2210
- const program = getServerProgram();
2312
+ const { program, checker } = getServerProgram();
2211
2313
  const sourceFile = program.getSourceFile(filePath);
2212
2314
  if (!sourceFile) return { text: DEFAULT, unresolvedSymbols: [] };
2213
- const checker = program.getTypeChecker();
2214
2315
  const mainFn = findMainFunction(sourceFile);
2215
2316
  if (!mainFn) return { text: DEFAULT, unresolvedSymbols: [] };
2216
2317
  const details = collectReturnObjectTypeDetails(mainFn, checker);
@@ -2229,10 +2330,9 @@ var getSyncClientDataTypeDetailsFromFile = (filePath) => {
2229
2330
  const DEFAULT = "{ }";
2230
2331
  recordExtractionOutcome({ filePath, kind: "sync", field: "clientInput", error: null });
2231
2332
  try {
2232
- const program = getServerProgram();
2333
+ const { program, checker } = getServerProgram();
2233
2334
  const sourceFile = program.getSourceFile(filePath);
2234
2335
  if (!sourceFile) return { text: DEFAULT, unresolvedSymbols: [] };
2235
- const checker = program.getTypeChecker();
2236
2336
  const iface = findInterface(sourceFile, "SyncParams");
2237
2337
  if (!iface) return { text: DEFAULT, unresolvedSymbols: [] };
2238
2338
  const dataType = getInterfacePropertyType(iface, "clientInput", checker) ?? getInterfacePropertyType(iface, "clientData", checker);
@@ -2251,10 +2351,9 @@ var getSyncServerStreamPayloadTypeDetailsFromFile = (filePath) => {
2251
2351
  const DEFAULT = "never";
2252
2352
  recordExtractionOutcome({ filePath, kind: "sync", field: "serverStream", error: null });
2253
2353
  try {
2254
- const program = getServerProgram();
2354
+ const { program, checker } = getServerProgram();
2255
2355
  const sourceFile = program.getSourceFile(filePath);
2256
2356
  if (!sourceFile) return { text: DEFAULT, unresolvedSymbols: [] };
2257
- const checker = program.getTypeChecker();
2258
2357
  const mainFn = findMainFunction(sourceFile);
2259
2358
  if (!mainFn) return { text: DEFAULT, unresolvedSymbols: [] };
2260
2359
  const details = collectStreamCallPayloadTypeDetails(mainFn, checker);
@@ -2270,10 +2369,9 @@ var getSyncServerOutputTypeDetailsFromFile = (filePath) => {
2270
2369
  const DEFAULT = "{ status: string }";
2271
2370
  recordExtractionOutcome({ filePath, kind: "sync", field: "serverOutput", error: null });
2272
2371
  try {
2273
- const program = getServerProgram();
2372
+ const { program, checker } = getServerProgram();
2274
2373
  const sourceFile = program.getSourceFile(filePath);
2275
2374
  if (!sourceFile) return { text: DEFAULT, unresolvedSymbols: [] };
2276
- const checker = program.getTypeChecker();
2277
2375
  const mainFn = findMainFunction(sourceFile);
2278
2376
  if (!mainFn) return { text: DEFAULT, unresolvedSymbols: [] };
2279
2377
  const details = collectReturnObjectTypeDetails(mainFn, checker);
@@ -2289,10 +2387,9 @@ var getSyncClientStreamPayloadTypeDetailsFromFile = (filePath) => {
2289
2387
  const DEFAULT = "never";
2290
2388
  recordExtractionOutcome({ filePath, kind: "sync", field: "clientStream", error: null });
2291
2389
  try {
2292
- const program = getServerProgram();
2390
+ const { program, checker } = getServerProgram();
2293
2391
  const sourceFile = program.getSourceFile(filePath);
2294
2392
  if (!sourceFile) return { text: DEFAULT, unresolvedSymbols: [] };
2295
- const checker = program.getTypeChecker();
2296
2393
  const mainFn = findMainFunction(sourceFile);
2297
2394
  if (!mainFn) return { text: DEFAULT, unresolvedSymbols: [] };
2298
2395
  const details = collectStreamCallPayloadTypeDetails(mainFn, checker);
@@ -2308,10 +2405,9 @@ var getSyncClientOutputTypeDetailsFromFile = (filePath) => {
2308
2405
  const DEFAULT = "{ }";
2309
2406
  recordExtractionOutcome({ filePath, kind: "sync", field: "clientOutput", error: null });
2310
2407
  try {
2311
- const program = getServerProgram();
2408
+ const { program, checker } = getServerProgram();
2312
2409
  const sourceFile = program.getSourceFile(filePath);
2313
2410
  if (!sourceFile) return { text: DEFAULT, unresolvedSymbols: [] };
2314
- const checker = program.getTypeChecker();
2315
2411
  const mainFn = findMainFunction(sourceFile);
2316
2412
  if (!mainFn) return { text: DEFAULT, unresolvedSymbols: [] };
2317
2413
  const details = collectReturnObjectTypeDetails(mainFn, checker);
@@ -2325,19 +2421,48 @@ var getSyncClientOutputTypeDetailsFromFile = (filePath) => {
2325
2421
  };
2326
2422
 
2327
2423
  // src/typeMap/functionsMeta.ts
2328
- import * as ts7 from "typescript";
2329
- import fs6 from "fs";
2330
- import path9 from "path";
2424
+ import fs7 from "fs";
2425
+ import path10 from "path";
2426
+ import {
2427
+ createScanner,
2428
+ LanguageVariant,
2429
+ SyntaxKind as SyntaxKind5
2430
+ } from "typescript-7-api/ast";
2431
+ import {
2432
+ isArrowFunction as isArrowFunction2,
2433
+ isClassDeclaration as isClassDeclaration3,
2434
+ isEnumDeclaration as isEnumDeclaration3,
2435
+ isExportAssignment,
2436
+ isExportDeclaration,
2437
+ isFunctionDeclaration as isFunctionDeclaration3,
2438
+ isFunctionExpression as isFunctionExpression2,
2439
+ isIdentifier as isIdentifier6,
2440
+ isInterfaceDeclaration as isInterfaceDeclaration4,
2441
+ isNamedExports,
2442
+ isStringLiteral as isStringLiteral5,
2443
+ isTypeAliasDeclaration as isTypeAliasDeclaration4,
2444
+ isVariableStatement as isVariableStatement3
2445
+ } from "typescript-7-api/ast/is";
2331
2446
 
2332
2447
  // src/typeMap/typeContext.ts
2333
- import * as ts6 from "typescript";
2334
- import path7 from "path";
2448
+ import path8 from "path";
2449
+ import { SyntaxKind as SyntaxKind4 } from "typescript-7-api/ast";
2450
+ import {
2451
+ isClassDeclaration as isClassDeclaration2,
2452
+ isEnumDeclaration as isEnumDeclaration2,
2453
+ isImportDeclaration as isImportDeclaration2,
2454
+ isInterfaceDeclaration as isInterfaceDeclaration3,
2455
+ isNamedImports as isNamedImports2,
2456
+ isNamespaceImport as isNamespaceImport2,
2457
+ isStringLiteral as isStringLiteral4,
2458
+ isTypeAliasDeclaration as isTypeAliasDeclaration3
2459
+ } from "typescript-7-api/ast/is";
2335
2460
  import { getGeneratedSocketTypesPath as getGeneratedSocketTypesPath4 } from "@luckystack/core";
2336
2461
  var toGeneratedImportPath = (source, filePath) => {
2337
2462
  if (!source.startsWith(".")) return source;
2338
- const outputDir = path7.dirname(getGeneratedSocketTypesPath4());
2339
- const absoluteSource = path7.resolve(path7.dirname(filePath), source);
2340
- let relPath = path7.relative(outputDir, absoluteSource).replaceAll("\\", "/");
2463
+ const outputDir = path8.dirname(getGeneratedSocketTypesPath4());
2464
+ const absoluteSource = path8.resolve(path8.dirname(filePath), source);
2465
+ let relPath = path8.relative(outputDir, absoluteSource).replaceAll("\\", "/");
2341
2466
  relPath = relPath.replace(/\.tsx?$/, "");
2342
2467
  if (!relPath.startsWith(".")) relPath = `./${relPath}`;
2343
2468
  return relPath;
@@ -2345,23 +2470,18 @@ var toGeneratedImportPath = (source, filePath) => {
2345
2470
  var parseFileTypeContext = (content) => {
2346
2471
  const availableExports = /* @__PURE__ */ new Set();
2347
2472
  const fileImports = /* @__PURE__ */ new Map();
2348
- const sourceFile = ts6.createSourceFile(
2349
- "__temp__.ts",
2350
- content,
2351
- ts6.ScriptTarget.Latest,
2352
- true
2353
- );
2473
+ const sourceFile = parseSourceText("__temp__.ts", content);
2354
2474
  for (const statement of sourceFile.statements) {
2355
- if (ts6.isInterfaceDeclaration(statement) || ts6.isTypeAliasDeclaration(statement) || ts6.isClassDeclaration(statement) || ts6.isEnumDeclaration(statement)) {
2356
- const hasExport = statement.modifiers?.some((m) => m.kind === ts6.SyntaxKind.ExportKeyword);
2475
+ if (isInterfaceDeclaration3(statement) || isTypeAliasDeclaration3(statement) || isClassDeclaration2(statement) || isEnumDeclaration2(statement)) {
2476
+ const hasExport = statement.modifiers?.some((m) => m.kind === SyntaxKind4.ExportKeyword);
2357
2477
  if (hasExport && statement.name) {
2358
2478
  availableExports.add(statement.name.text);
2359
2479
  }
2360
2480
  continue;
2361
2481
  }
2362
- if (!ts6.isImportDeclaration(statement)) continue;
2482
+ if (!isImportDeclaration2(statement)) continue;
2363
2483
  const moduleSpecifier = statement.moduleSpecifier;
2364
- if (!ts6.isStringLiteral(moduleSpecifier)) continue;
2484
+ if (!isStringLiteral4(moduleSpecifier)) continue;
2365
2485
  const source = moduleSpecifier.text;
2366
2486
  const importClause = statement.importClause;
2367
2487
  if (!importClause) continue;
@@ -2370,11 +2490,11 @@ var parseFileTypeContext = (content) => {
2370
2490
  }
2371
2491
  const namedBindings = importClause.namedBindings;
2372
2492
  if (!namedBindings) continue;
2373
- if (ts6.isNamespaceImport(namedBindings)) {
2493
+ if (isNamespaceImport2(namedBindings)) {
2374
2494
  fileImports.set(namedBindings.name.text, { source, isDefault: true });
2375
2495
  continue;
2376
2496
  }
2377
- if (ts6.isNamedImports(namedBindings)) {
2497
+ if (isNamedImports2(namedBindings)) {
2378
2498
  for (const specifier of namedBindings.elements) {
2379
2499
  const localName = specifier.name.text;
2380
2500
  const originalName = specifier.propertyName?.text ?? localName;
@@ -2424,11 +2544,11 @@ var sanitizeTypeAndCollectImports = ({
2424
2544
  import { getGeneratedSocketTypesPath as getGeneratedSocketTypesPath5, ROOT_DIR as ROOT_DIR5 } from "@luckystack/core";
2425
2545
 
2426
2546
  // src/functionRegistry.ts
2427
- import fs5 from "fs";
2428
- import path8 from "path";
2547
+ import fs6 from "fs";
2548
+ import path9 from "path";
2429
2549
  import { ROOT_DIR as ROOT_DIR4, getServerFunctionDirs, isTestFile as isTestFile2, isTestDirectory as isTestDirectory2 } from "@luckystack/core";
2430
2550
  var normalizePath2 = (value) => value.replaceAll("\\", "/");
2431
- var toWorkspaceRelative = (absolutePath) => normalizePath2(path8.relative(ROOT_DIR4, absolutePath));
2551
+ var toWorkspaceRelative = (absolutePath) => normalizePath2(path9.relative(ROOT_DIR4, absolutePath));
2432
2552
  var formatFunctionKeyPath = (keyPath) => keyPath.join(".");
2433
2553
  var functionModuleFileName = (keyPath) => {
2434
2554
  const fileName = keyPath.at(-1);
@@ -2440,12 +2560,12 @@ var functionModuleFileName = (keyPath) => {
2440
2560
  var formatFunctionKeyConflict = (keyPath, firstSourcePath, secondSourcePath) => `[function-injection] Conflict at \`functions.${formatFunctionKeyPath(keyPath)}\`: defined in both \`${firstSourcePath}\` and \`${secondSourcePath}\`. Delete one \u2014 \`shared/\` is the canonical location for framework re-exports.`;
2441
2561
  var formatFunctionNamespaceConflict = (moduleKeyPath, moduleSourcePath, nestedKeyPath, nestedSourcePath) => `[function-injection] Conflict at \`functions.${formatFunctionKeyPath(moduleKeyPath)}\`: \`${moduleSourcePath}\` defines it as a module, but \`${nestedSourcePath}\` nests \`functions.${formatFunctionKeyPath(nestedKeyPath)}\` underneath it. Rename one \u2014 a key cannot be both a module and a namespace.`;
2442
2562
  var walkFunctionRoot = (dir, rootDir, basePath, collected) => {
2443
- const entries = fs5.readdirSync(dir).toSorted();
2563
+ const entries = fs6.readdirSync(dir).toSorted();
2444
2564
  for (const entry of entries) {
2445
2565
  if (entry === "node_modules") continue;
2446
- const fullPath = path8.join(dir, entry);
2566
+ const fullPath = path9.join(dir, entry);
2447
2567
  if (getRoutingRules().ignore(toWorkspaceRelative(fullPath))) continue;
2448
- if (fs5.statSync(fullPath).isDirectory()) {
2568
+ if (fs6.statSync(fullPath).isDirectory()) {
2449
2569
  if (isTestDirectory2(entry)) continue;
2450
2570
  walkFunctionRoot(fullPath, rootDir, [...basePath, entry], collected);
2451
2571
  continue;
@@ -2488,7 +2608,7 @@ var collectFunctionModules = (options = {}) => {
2488
2608
  onConflict(message);
2489
2609
  };
2490
2610
  for (const root of functionRoots) {
2491
- if (!fs5.existsSync(root)) continue;
2611
+ if (!fs6.existsSync(root)) continue;
2492
2612
  const fromThisRoot = [];
2493
2613
  walkFunctionRoot(root, root, [], fromThisRoot);
2494
2614
  for (const module of fromThisRoot) {
@@ -2562,17 +2682,16 @@ var stripDefaultValues = (params) => {
2562
2682
  return params.replaceAll(/\s*=(?!>)[^,)]+/g, "");
2563
2683
  };
2564
2684
  var stripLineComments = (value) => {
2565
- const scanner = ts7.createScanner(
2566
- ts7.ScriptTarget.Latest,
2685
+ const scanner = createScanner(
2567
2686
  /* skipTrivia */
2568
2687
  false,
2569
- ts7.LanguageVariant.Standard,
2688
+ LanguageVariant.Standard,
2570
2689
  value
2571
2690
  );
2572
2691
  let result = "";
2573
2692
  let token = scanner.scan();
2574
- while (token !== ts7.SyntaxKind.EndOfFileToken) {
2575
- result += token === ts7.SyntaxKind.SingleLineCommentTrivia ? " " : scanner.getTokenText();
2693
+ while (token !== SyntaxKind5.EndOfFile) {
2694
+ result += token === SyntaxKind5.SingleLineCommentTrivia ? " " : scanner.getTokenText();
2576
2695
  token = scanner.scan();
2577
2696
  }
2578
2697
  return result;
@@ -2585,9 +2704,9 @@ var simplifyInferredType = (value) => {
2585
2704
  if (/\bRedis\b/.test(value)) return "Redis";
2586
2705
  return value;
2587
2706
  };
2588
- var getGeneratedFileDir = () => path9.dirname(getGeneratedSocketTypesPath5());
2707
+ var getGeneratedFileDir = () => path10.dirname(getGeneratedSocketTypesPath5());
2589
2708
  var sourceModuleSpecifier = (sourceFilePath) => {
2590
- const relative = path9.relative(getGeneratedFileDir(), sourceFilePath).replaceAll("\\", "/").replace(/\.tsx?$/i, "");
2709
+ const relative = path10.relative(getGeneratedFileDir(), sourceFilePath).replaceAll("\\", "/").replace(/\.tsx?$/i, "");
2591
2710
  return relative.startsWith(".") ? relative : `./${relative}`;
2592
2711
  };
2593
2712
  var portableInferredValueType = (inferred, sourceFilePath, exportName) => {
@@ -2598,16 +2717,16 @@ var relativizeModuleSpecifier = (specifier, sourceFilePath) => {
2598
2717
  if (!specifier.startsWith("./") && !specifier.startsWith("../")) {
2599
2718
  return specifier;
2600
2719
  }
2601
- const absolute = path9.resolve(path9.dirname(sourceFilePath), specifier);
2602
- const rel = path9.relative(getGeneratedFileDir(), absolute);
2603
- const normalized = rel.split(path9.sep).join("/");
2720
+ const absolute = path10.resolve(path10.dirname(sourceFilePath), specifier);
2721
+ const rel = path10.relative(getGeneratedFileDir(), absolute);
2722
+ const normalized = rel.split(path10.sep).join("/");
2604
2723
  return normalized.startsWith(".") ? normalized : `./${normalized}`;
2605
2724
  };
2606
2725
  var findProgramVariableDeclaration = (sourceFile, exportName) => {
2607
2726
  for (const statement of sourceFile.statements) {
2608
- if (!ts7.isVariableStatement(statement)) continue;
2727
+ if (!isVariableStatement3(statement)) continue;
2609
2728
  for (const declaration of statement.declarationList.declarations) {
2610
- if (ts7.isIdentifier(declaration.name) && declaration.name.text === exportName) {
2729
+ if (isIdentifier6(declaration.name) && declaration.name.text === exportName) {
2611
2730
  return declaration;
2612
2731
  }
2613
2732
  }
@@ -2616,10 +2735,10 @@ var findProgramVariableDeclaration = (sourceFile, exportName) => {
2616
2735
  };
2617
2736
  var findProgramTypeDeclaration = (sourceFile, typeName) => {
2618
2737
  for (const statement of sourceFile.statements) {
2619
- if (ts7.isInterfaceDeclaration(statement) && statement.name.text === typeName) return statement;
2620
- if (ts7.isTypeAliasDeclaration(statement) && statement.name.text === typeName) return statement;
2621
- if (ts7.isClassDeclaration(statement) && statement.name?.text === typeName) return statement;
2622
- if (ts7.isEnumDeclaration(statement) && statement.name.text === typeName) return statement;
2738
+ if (isInterfaceDeclaration4(statement) && statement.name.text === typeName) return statement;
2739
+ if (isTypeAliasDeclaration4(statement) && statement.name.text === typeName) return statement;
2740
+ if (isClassDeclaration3(statement) && statement.name?.text === typeName) return statement;
2741
+ if (isEnumDeclaration3(statement) && statement.name.text === typeName) return statement;
2623
2742
  }
2624
2743
  return null;
2625
2744
  };
@@ -2636,7 +2755,7 @@ var resolveLocalExportedTypes = ({
2636
2755
  if (!hasReference) continue;
2637
2756
  const declaration = findProgramTypeDeclaration(programSource, exportName);
2638
2757
  if (!declaration) continue;
2639
- const declarationNode = ts7.isClassDeclaration(declaration) ? declaration.name ?? declaration : ts7.isTypeAliasDeclaration(declaration) ? declaration.type : declaration;
2758
+ const declarationNode = isClassDeclaration3(declaration) ? declaration.name ?? declaration : isTypeAliasDeclaration4(declaration) ? declaration.type : declaration;
2640
2759
  const declarationType = checker.getTypeAtLocation(declarationNode);
2641
2760
  const expanded = normalizeInlineType(expandType(declarationType, checker));
2642
2761
  resolved = resolved.replaceAll(new RegExp(String.raw`\b${exportName}\b`, "g"), expanded);
@@ -2645,9 +2764,9 @@ var resolveLocalExportedTypes = ({
2645
2764
  };
2646
2765
  var findSourceVariableDeclaration = (sourceFile, exportName) => {
2647
2766
  for (const statement of sourceFile.statements) {
2648
- if (!ts7.isVariableStatement(statement)) continue;
2767
+ if (!isVariableStatement3(statement)) continue;
2649
2768
  for (const declaration of statement.declarationList.declarations) {
2650
- if (ts7.isIdentifier(declaration.name) && declaration.name.text === exportName) {
2769
+ if (isIdentifier6(declaration.name) && declaration.name.text === exportName) {
2651
2770
  return declaration;
2652
2771
  }
2653
2772
  }
@@ -2665,8 +2784,8 @@ var inferValueTypeForExport = ({
2665
2784
  checker,
2666
2785
  programSource
2667
2786
  }) => {
2668
- const resolvedChecker = checker ?? getServerProgram().getTypeChecker();
2669
- const resolvedSource = programSource ?? getServerProgram().getSourceFile(filePath);
2787
+ const resolvedChecker = checker ?? getServerProgram().checker;
2788
+ const resolvedSource = programSource ?? getServerProgram().program.getSourceFile(filePath);
2670
2789
  if (declaration.type) {
2671
2790
  const rawType = normalizeInlineType(rawContent.slice(declaration.type.pos, declaration.type.end).trim());
2672
2791
  const localResolvedType = resolvedSource ? resolveLocalExportedTypes({
@@ -2715,7 +2834,7 @@ var extractSignatureFromNode = (node, rawContent, filePath, availableExports, fi
2715
2834
  knownGenerics.add(typeParam.name.text);
2716
2835
  }
2717
2836
  }
2718
- const isAsync = node.modifiers?.some((m) => m.kind === ts7.SyntaxKind.AsyncKeyword) ?? false;
2837
+ const isAsync = node.modifiers?.some((m) => m.kind === SyntaxKind5.AsyncKeyword) ?? false;
2719
2838
  const genericsClause = node.typeParameters ? `<${normalizeInlineType(rawContent.slice(node.typeParameters.pos, node.typeParameters.end))}>` : "";
2720
2839
  const rawParams = node.parameters.map((p) => normalizeInlineType(rawContent.slice(p.pos, p.end).trim())).join(", ");
2721
2840
  const cleanParams = normalizeInlineType(stripDefaultValues(`(${rawParams})`));
@@ -2758,38 +2877,38 @@ var extractSignatureFromNode = (node, rawContent, filePath, availableExports, fi
2758
2877
  };
2759
2878
  var findSignatureForExport = (name, sourceFile, rawContent, filePath, availableExports, fileImports, collectors, checker, programSource) => {
2760
2879
  for (const statement of sourceFile.statements) {
2761
- if (ts7.isVariableStatement(statement)) {
2880
+ if (isVariableStatement3(statement)) {
2762
2881
  for (const decl of statement.declarationList.declarations) {
2763
- if (!ts7.isIdentifier(decl.name) || decl.name.text !== name || !decl.initializer) continue;
2764
- if (ts7.isArrowFunction(decl.initializer) || ts7.isFunctionExpression(decl.initializer)) {
2882
+ if (!isIdentifier6(decl.name) || decl.name.text !== name || !decl.initializer) continue;
2883
+ if (isArrowFunction2(decl.initializer) || isFunctionExpression2(decl.initializer)) {
2765
2884
  return extractSignatureFromNode(decl.initializer, rawContent, filePath, availableExports, fileImports, collectors, checker, programSource);
2766
2885
  }
2767
2886
  }
2768
2887
  }
2769
- if (ts7.isFunctionDeclaration(statement) && statement.name?.text === name) {
2888
+ if (isFunctionDeclaration3(statement) && statement.name?.text === name) {
2770
2889
  return extractSignatureFromNode(statement, rawContent, filePath, availableExports, fileImports, collectors, checker, programSource);
2771
2890
  }
2772
2891
  }
2773
2892
  return "any";
2774
2893
  };
2894
+ var hasExportModifier = (statement) => (isVariableStatement3(statement) || isFunctionDeclaration3(statement)) && (statement.modifiers?.some((m) => m.kind === SyntaxKind5.ExportKeyword) ?? false);
2775
2895
  var parseFunctionFile = (fullPath, collectors) => {
2776
2896
  try {
2777
- const rawContent = fs6.readFileSync(fullPath, "utf8");
2778
- const sourceFile = ts7.createSourceFile(fullPath, rawContent, ts7.ScriptTarget.Latest, true);
2897
+ const rawContent = fs7.readFileSync(fullPath, "utf8");
2898
+ const sourceFile = parseSourceText(fullPath, rawContent);
2779
2899
  const { availableExports, fileImports } = parseFileTypeContext(rawContent);
2780
- const program = getServerProgram();
2781
- const checker = program.getTypeChecker();
2900
+ const { program, checker } = getServerProgram();
2782
2901
  const programSource = program.getSourceFile(fullPath);
2783
2902
  const exports = /* @__PURE__ */ new Map();
2784
2903
  let defaultExportName = null;
2785
2904
  let wildcardReExport = null;
2786
2905
  for (const statement of sourceFile.statements) {
2787
- const hasExport = statement.modifiers?.some((m) => m.kind === ts7.SyntaxKind.ExportKeyword);
2788
- if (ts7.isVariableStatement(statement) && hasExport) {
2906
+ const hasExport = hasExportModifier(statement);
2907
+ if (isVariableStatement3(statement) && hasExport) {
2789
2908
  for (const decl of statement.declarationList.declarations) {
2790
- if (ts7.isIdentifier(decl.name)) {
2909
+ if (isIdentifier6(decl.name)) {
2791
2910
  const exportName = decl.name.text;
2792
- if (decl.initializer && (ts7.isArrowFunction(decl.initializer) || ts7.isFunctionExpression(decl.initializer))) {
2911
+ if (decl.initializer && (isArrowFunction2(decl.initializer) || isFunctionExpression2(decl.initializer))) {
2793
2912
  exports.set(exportName, findSignatureForExport(exportName, sourceFile, rawContent, fullPath, availableExports, fileImports, collectors, checker, programSource ?? void 0));
2794
2913
  continue;
2795
2914
  }
@@ -2807,11 +2926,11 @@ var parseFunctionFile = (fullPath, collectors) => {
2807
2926
  }
2808
2927
  }
2809
2928
  }
2810
- if (ts7.isFunctionDeclaration(statement) && hasExport && statement.name) {
2929
+ if (isFunctionDeclaration3(statement) && hasExport && statement.name) {
2811
2930
  exports.set(statement.name.text, findSignatureForExport(statement.name.text, sourceFile, rawContent, fullPath, availableExports, fileImports, collectors, checker, programSource ?? void 0));
2812
2931
  }
2813
- if (ts7.isExportDeclaration(statement) && statement.exportClause && ts7.isNamedExports(statement.exportClause)) {
2814
- const moduleSpecifier = statement.moduleSpecifier && ts7.isStringLiteral(statement.moduleSpecifier) ? statement.moduleSpecifier.text : null;
2932
+ if (isExportDeclaration(statement) && statement.exportClause && isNamedExports(statement.exportClause)) {
2933
+ const moduleSpecifier = statement.moduleSpecifier && isStringLiteral5(statement.moduleSpecifier) ? statement.moduleSpecifier.text : null;
2815
2934
  for (const specifier of statement.exportClause.elements) {
2816
2935
  const exportName = specifier.name.text;
2817
2936
  const originalName = specifier.propertyName ? specifier.propertyName.text : exportName;
@@ -2826,7 +2945,7 @@ var parseFunctionFile = (fullPath, collectors) => {
2826
2945
  continue;
2827
2946
  }
2828
2947
  const exportDeclaration = findSourceVariableDeclaration(sourceFile, originalName);
2829
- if (exportDeclaration && ts7.isIdentifier(exportDeclaration.name)) {
2948
+ if (exportDeclaration && isIdentifier6(exportDeclaration.name)) {
2830
2949
  exports.set(exportName, inferValueTypeForExport({
2831
2950
  exportName: originalName,
2832
2951
  declaration: exportDeclaration,
@@ -2843,10 +2962,10 @@ var parseFunctionFile = (fullPath, collectors) => {
2843
2962
  exports.set(exportName, "any");
2844
2963
  }
2845
2964
  }
2846
- if (ts7.isExportAssignment(statement) && !statement.isExportEquals && ts7.isIdentifier(statement.expression)) {
2965
+ if (isExportAssignment(statement) && !statement.isExportEquals && isIdentifier6(statement.expression)) {
2847
2966
  defaultExportName = statement.expression.text;
2848
2967
  }
2849
- if (ts7.isExportDeclaration(statement) && !statement.exportClause && statement.moduleSpecifier && ts7.isStringLiteral(statement.moduleSpecifier)) {
2968
+ if (isExportDeclaration(statement) && !statement.exportClause && statement.moduleSpecifier && isStringLiteral5(statement.moduleSpecifier)) {
2850
2969
  wildcardReExport = relativizeModuleSpecifier(statement.moduleSpecifier.text, fullPath);
2851
2970
  }
2852
2971
  }
@@ -2920,7 +3039,7 @@ var generateServerFunctions = (collectors) => {
2920
3039
  if (modules.length === 0) return "";
2921
3040
  const merged = { kind: "dir", children: /* @__PURE__ */ new Map(), sourcePath: "<merged>" };
2922
3041
  for (const module of modules) {
2923
- const absolutePath = path9.resolve(ROOT_DIR5, module.sourcePath);
3042
+ const absolutePath = path10.resolve(ROOT_DIR5, module.sourcePath);
2924
3043
  const parsed = parseFunctionFile(absolutePath, collectors);
2925
3044
  if (!parsed) continue;
2926
3045
  if (parsed.exports.size === 0 && parsed.defaultExportName === null && parsed.wildcardReExport === null) {
@@ -3047,7 +3166,7 @@ var collectSyncTypes = (syncServerFiles, syncClientFiles, collectors) => {
3047
3166
  }
3048
3167
  return syncTypesByPage;
3049
3168
  };
3050
- var generateTypeMapFile = (options = {}) => {
3169
+ var runTypeMapGeneration = (options) => {
3051
3170
  const { quiet = false } = options;
3052
3171
  assertValidRouteNaming({
3053
3172
  srcDir: getSrcDir2(),
@@ -3085,6 +3204,13 @@ var generateTypeMapFile = (options = {}) => {
3085
3204
  });
3086
3205
  writeTypeMapArtifacts({ content, docsData, schemasContent, diagnosticsData });
3087
3206
  };
3207
+ var generateTypeMapFile = (options = {}) => {
3208
+ try {
3209
+ runTypeMapGeneration(options);
3210
+ } finally {
3211
+ disposeTsApi();
3212
+ }
3213
+ };
3088
3214
 
3089
3215
  // src/templateRegistry.ts
3090
3216
  var BUILT_IN_TEMPLATE_KINDS = [
@@ -3158,13 +3284,29 @@ var registerDefaultTemplateRules = () => {
3158
3284
  registerDefaultTemplateRules();
3159
3285
 
3160
3286
  // src/loader.ts
3161
- import fs7 from "fs";
3162
- import path10 from "path";
3287
+ import fs8 from "fs";
3288
+ import path11 from "path";
3163
3289
  import { pathToFileURL } from "url";
3164
3290
  import { tryCatch, getSrcDir as getSrcDir3, ROOT_DIR as ROOT_DIR6, isTestFile as isTestFile3 } from "@luckystack/core";
3165
3291
 
3166
3292
  // src/runtimeTypeResolver.ts
3167
- import * as ts8 from "typescript";
3293
+ import { SymbolFlags as SymbolFlags3 } from "typescript-7-api/sync";
3294
+ import { SyntaxKind as SyntaxKind6 } from "typescript-7-api/ast";
3295
+ import {
3296
+ isEnumDeclaration as isEnumDeclaration4,
3297
+ isIdentifier as isIdentifier7,
3298
+ isImportDeclaration as isImportDeclaration3,
3299
+ isIndexSignatureDeclaration as isIndexSignatureDeclaration2,
3300
+ isInterfaceDeclaration as isInterfaceDeclaration5,
3301
+ isLiteralTypeNode as isLiteralTypeNode2,
3302
+ isNamedImports as isNamedImports3,
3303
+ isPropertySignatureDeclaration as isPropertySignatureDeclaration3,
3304
+ isStringLiteral as isStringLiteral6,
3305
+ isTypeAliasDeclaration as isTypeAliasDeclaration5,
3306
+ isTypeLiteralNode as isTypeLiteralNode2,
3307
+ isTypeReferenceNode as isTypeReferenceNode4,
3308
+ isUnionTypeNode as isUnionTypeNode2
3309
+ } from "typescript-7-api/ast/is";
3168
3310
  var MAX_DEPTH = 20;
3169
3311
  var unresolvedPrefix = "__RUNTIME_UNRESOLVED__::";
3170
3312
  var PRIMITIVE_TYPES = /* @__PURE__ */ new Set([
@@ -3244,9 +3386,9 @@ var splitTopLevel = (value, splitter) => {
3244
3386
  };
3245
3387
  var parseTypeNode = (typeText) => {
3246
3388
  const synthetic = `type __RT = ${typeText};`;
3247
- const source = ts8.createSourceFile("__runtime_type.ts", synthetic, ts8.ScriptTarget.Latest, true);
3389
+ const source = parseSourceText("__runtime_type.ts", synthetic);
3248
3390
  const statement = source.statements[0];
3249
- if (!statement || !ts8.isTypeAliasDeclaration(statement)) return null;
3391
+ if (!statement || !isTypeAliasDeclaration5(statement)) return null;
3250
3392
  return statement.type;
3251
3393
  };
3252
3394
  var parseObjectFields = (typeText) => {
@@ -3255,30 +3397,30 @@ var parseObjectFields = (typeText) => {
3255
3397
  return { fields: [], indexSignatures: [] };
3256
3398
  }
3257
3399
  const typeNode = parseTypeNode(clean);
3258
- if (!typeNode || !ts8.isTypeLiteralNode(typeNode)) {
3400
+ if (!typeNode || !isTypeLiteralNode2(typeNode)) {
3259
3401
  return { fields: [], indexSignatures: [] };
3260
3402
  }
3261
3403
  const fields = [];
3262
3404
  const indexSignatures = [];
3263
3405
  for (const member of typeNode.members) {
3264
- if (ts8.isPropertySignature(member) && member.type) {
3406
+ if (isPropertySignatureDeclaration3(member) && member.type) {
3265
3407
  let key = null;
3266
- if (ts8.isIdentifier(member.name)) {
3408
+ if (isIdentifier7(member.name)) {
3267
3409
  key = member.name.text;
3268
- } else if (ts8.isStringLiteral(member.name)) {
3410
+ } else if (isStringLiteral6(member.name)) {
3269
3411
  key = member.name.text;
3270
3412
  }
3271
3413
  if (key === null) continue;
3272
3414
  fields.push({
3273
3415
  key,
3274
- optional: Boolean(member.questionToken),
3416
+ optional: member.postfixToken?.kind === SyntaxKind6.QuestionToken,
3275
3417
  type: member.type.getText().trim()
3276
3418
  });
3277
3419
  continue;
3278
3420
  }
3279
- if (ts8.isIndexSignatureDeclaration(member)) {
3421
+ if (isIndexSignatureDeclaration2(member)) {
3280
3422
  const param = member.parameters[0];
3281
- if (!param || !ts8.isIdentifier(param.name) || !param.type) continue;
3423
+ if (!param || !isIdentifier7(param.name) || !param.type) continue;
3282
3424
  indexSignatures.push({
3283
3425
  keyName: param.name.text,
3284
3426
  keyType: param.type.getText().trim(),
@@ -3303,9 +3445,9 @@ var serializeObjectFields = ({
3303
3445
  return `{ ${segments.join("; ")} }`;
3304
3446
  };
3305
3447
  var extractStringLiteralKey = (node) => {
3306
- if (!ts8.isLiteralTypeNode(node)) return null;
3448
+ if (!isLiteralTypeNode2(node)) return null;
3307
3449
  const literal = node.literal;
3308
- if (!ts8.isStringLiteral(literal)) return null;
3450
+ if (!isStringLiteral6(literal)) return null;
3309
3451
  return literal.text;
3310
3452
  };
3311
3453
  var parseLiteralUnionKeys = (value) => {
@@ -3313,7 +3455,7 @@ var parseLiteralUnionKeys = (value) => {
3313
3455
  if (!trimmed) return null;
3314
3456
  const typeNode = parseTypeNode(trimmed);
3315
3457
  if (!typeNode) return null;
3316
- if (ts8.isUnionTypeNode(typeNode)) {
3458
+ if (isUnionTypeNode2(typeNode)) {
3317
3459
  const keys = [];
3318
3460
  for (const member of typeNode.types) {
3319
3461
  const key = extractStringLiteralKey(member);
@@ -3329,25 +3471,24 @@ var resolveIdentifier = (identifier, filePath) => {
3329
3471
  if (PRIMITIVE_TYPES.has(identifier.toLowerCase())) return identifier.toLowerCase();
3330
3472
  if (SKIP_EXPANSION2.has(identifier)) return identifier;
3331
3473
  try {
3332
- const program = getServerProgram();
3474
+ const { program, checker } = getServerProgram();
3333
3475
  const sourceFile = program.getSourceFile(filePath);
3334
3476
  if (!sourceFile) return toUnresolved(`unresolved type ${identifier}`);
3335
- const checker = program.getTypeChecker();
3336
3477
  for (const stmt of sourceFile.statements) {
3337
- if ((ts8.isInterfaceDeclaration(stmt) || ts8.isTypeAliasDeclaration(stmt) || ts8.isEnumDeclaration(stmt)) && stmt.name.text === identifier) {
3478
+ if ((isInterfaceDeclaration5(stmt) || isTypeAliasDeclaration5(stmt) || isEnumDeclaration4(stmt)) && stmt.name.text === identifier) {
3338
3479
  const symbol = checker.getSymbolAtLocation(stmt.name);
3339
3480
  if (symbol) {
3340
3481
  return expandType(checker.getDeclaredTypeOfSymbol(symbol), checker);
3341
3482
  }
3342
3483
  }
3343
- if (ts8.isImportDeclaration(stmt) && stmt.importClause) {
3484
+ if (isImportDeclaration3(stmt) && stmt.importClause) {
3344
3485
  const { namedBindings, name: defaultName } = stmt.importClause;
3345
- if (namedBindings && ts8.isNamedImports(namedBindings)) {
3486
+ if (namedBindings && isNamedImports3(namedBindings)) {
3346
3487
  for (const specifier of namedBindings.elements) {
3347
3488
  if (specifier.name.text === identifier) {
3348
3489
  const symbol = checker.getSymbolAtLocation(specifier.name);
3349
3490
  if (symbol) {
3350
- const target = symbol.flags & ts8.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
3491
+ const target = symbol.flags & SymbolFlags3.Alias ? checker.getAliasedSymbol(symbol) : symbol;
3351
3492
  return expandType(checker.getDeclaredTypeOfSymbol(target), checker);
3352
3493
  }
3353
3494
  }
@@ -3356,7 +3497,7 @@ var resolveIdentifier = (identifier, filePath) => {
3356
3497
  if (defaultName?.text === identifier) {
3357
3498
  const symbol = checker.getSymbolAtLocation(defaultName);
3358
3499
  if (symbol) {
3359
- const target = symbol.flags & ts8.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
3500
+ const target = symbol.flags & SymbolFlags3.Alias ? checker.getAliasedSymbol(symbol) : symbol;
3360
3501
  return expandType(checker.getDeclaredTypeOfSymbol(target), checker);
3361
3502
  }
3362
3503
  }
@@ -3490,7 +3631,7 @@ var resolveExpression = (typeText, filePath, depth, state) => {
3490
3631
  });
3491
3632
  } else {
3492
3633
  const typeNode = parseTypeNode(type);
3493
- const referenceInfo = typeNode && ts8.isTypeReferenceNode(typeNode) && ts8.isIdentifier(typeNode.typeName) ? { name: typeNode.typeName.text, args: typeNode.typeArguments } : null;
3634
+ const referenceInfo = typeNode && isTypeReferenceNode4(typeNode) && isIdentifier7(typeNode.typeName) ? { name: typeNode.typeName.text, args: typeNode.typeArguments } : null;
3494
3635
  if (referenceInfo?.args && referenceInfo.args.length > 0) {
3495
3636
  const { name: genericName, args: argNodes } = referenceInfo;
3496
3637
  const args = argNodes.map((arg) => arg.getText().trim());
@@ -3541,7 +3682,7 @@ var devSyncs = {};
3541
3682
  var devFunctions = {};
3542
3683
  var normalizePath3 = (value) => value.replaceAll("\\", "/");
3543
3684
  var isIgnoredPath = (absolutePath) => {
3544
- const relativeFromRoot = normalizePath3(path10.relative(ROOT_DIR6, absolutePath));
3685
+ const relativeFromRoot = normalizePath3(path11.relative(ROOT_DIR6, absolutePath));
3545
3686
  return getRoutingRules().ignore(relativeFromRoot);
3546
3687
  };
3547
3688
  var mapApiPageLocation = (pageLocation) => {
@@ -3551,7 +3692,7 @@ var mapSyncPageLocation = (pageLocation) => {
3551
3692
  return pageLocation || "system";
3552
3693
  };
3553
3694
  var resolveApiRouteMetaFromPath = (filePath) => {
3554
- const absolutePath = path10.resolve(filePath);
3695
+ const absolutePath = path11.resolve(filePath);
3555
3696
  const normalizedAbsolutePath = normalizePath3(absolutePath);
3556
3697
  const normalizedSrcDir = normalizePath3(getSrcDir3());
3557
3698
  if (!normalizedAbsolutePath.startsWith(normalizedSrcDir) || !normalizedAbsolutePath.endsWith(".ts")) {
@@ -3561,7 +3702,7 @@ var resolveApiRouteMetaFromPath = (filePath) => {
3561
3702
  return null;
3562
3703
  }
3563
3704
  const rules2 = getRoutingRules();
3564
- const relativePath = normalizePath3(path10.relative(getSrcDir3(), absolutePath));
3705
+ const relativePath = normalizePath3(path11.relative(getSrcDir3(), absolutePath));
3565
3706
  const segments = relativePath.split("/");
3566
3707
  const apiIndex = segments.indexOf(rules2.apiMarker);
3567
3708
  if (apiIndex === -1 || apiIndex === segments.length - 1) {
@@ -3581,7 +3722,7 @@ var resolveApiRouteMetaFromPath = (filePath) => {
3581
3722
  return { routeKey, absolutePath };
3582
3723
  };
3583
3724
  var resolveSyncRouteMetaFromPath = (filePath) => {
3584
- const absolutePath = path10.resolve(filePath);
3725
+ const absolutePath = path11.resolve(filePath);
3585
3726
  const normalizedAbsolutePath = normalizePath3(absolutePath);
3586
3727
  const normalizedSrcDir = normalizePath3(getSrcDir3());
3587
3728
  if (!normalizedAbsolutePath.startsWith(normalizedSrcDir) || !normalizedAbsolutePath.endsWith(".ts")) {
@@ -3591,7 +3732,7 @@ var resolveSyncRouteMetaFromPath = (filePath) => {
3591
3732
  return null;
3592
3733
  }
3593
3734
  const rules2 = getRoutingRules();
3594
- const relativePath = normalizePath3(path10.relative(getSrcDir3(), absolutePath));
3735
+ const relativePath = normalizePath3(path11.relative(getSrcDir3(), absolutePath));
3595
3736
  const segments = relativePath.split("/");
3596
3737
  const syncIndex = segments.indexOf(rules2.syncMarker);
3597
3738
  if (syncIndex === -1 || syncIndex === segments.length - 1) {
@@ -3635,13 +3776,13 @@ var importFile = async (absolutePath) => {
3635
3776
  };
3636
3777
  var collectTsFiles = (dir, relativeTo = "") => {
3637
3778
  const results = [];
3638
- const entries = fs7.readdirSync(dir);
3779
+ const entries = fs8.readdirSync(dir);
3639
3780
  for (const entry of entries) {
3640
3781
  if (entry === "node_modules") continue;
3641
- const entryPath = path10.join(dir, entry);
3782
+ const entryPath = path11.join(dir, entry);
3642
3783
  if (isIgnoredPath(entryPath)) continue;
3643
3784
  const relPath = relativeTo ? `${relativeTo}/${entry}` : entry;
3644
- if (fs7.statSync(entryPath).isDirectory()) {
3785
+ if (fs8.statSync(entryPath).isDirectory()) {
3645
3786
  if (isNonRouteDirectory(entry)) continue;
3646
3787
  results.push(...collectTsFiles(entryPath, relPath));
3647
3788
  } else if (entry.endsWith(".ts") && !isTestFile3(entry)) {
@@ -3673,16 +3814,16 @@ var resolveFunctionModule = (loadedModule, fileName) => {
3673
3814
  var initializeApis = async () => {
3674
3815
  for (const key of Object.keys(devApis)) delete devApis[key];
3675
3816
  clearRuntimeTypeResolverCache();
3676
- const srcFolder = fs7.readdirSync(getSrcDir3());
3817
+ const srcFolder = fs8.readdirSync(getSrcDir3());
3677
3818
  for (const file of srcFolder) {
3678
3819
  await scanApiFolder(file);
3679
3820
  }
3680
3821
  };
3681
3822
  var upsertApiFromFile = async (filePath) => {
3682
- if (isIgnoredPath(path10.resolve(filePath))) return;
3823
+ if (isIgnoredPath(path11.resolve(filePath))) return;
3683
3824
  const routeMeta = resolveApiRouteMetaFromPath(filePath);
3684
3825
  if (!routeMeta) {
3685
- const normalized = normalizePath3(path10.resolve(filePath));
3826
+ const normalized = normalizePath3(path11.resolve(filePath));
3686
3827
  if (normalized.endsWith(".ts") && normalized.includes(apiMarkerSegment()) && isRouteSurfaceFile(normalized)) {
3687
3828
  console.log(
3688
3829
  `[loader][api] invalid filename: ${normalized}. Expected <name>_v<number>.ts. File will not be loaded.`,
@@ -3730,13 +3871,13 @@ var removeApiFromFile = (filePath) => {
3730
3871
  delete devApis[routeMeta.routeKey];
3731
3872
  };
3732
3873
  var scanApiFolder = async (file, basePath = "") => {
3733
- const fullPath = path10.join(getSrcDir3(), basePath, file);
3874
+ const fullPath = path11.join(getSrcDir3(), basePath, file);
3734
3875
  if (isIgnoredPath(fullPath)) return;
3735
- if (!fs7.statSync(fullPath).isDirectory()) return;
3876
+ if (!fs8.statSync(fullPath).isDirectory()) return;
3736
3877
  if (file !== getRoutingRules().apiMarker) {
3737
- const subFolders = fs7.readdirSync(fullPath);
3878
+ const subFolders = fs8.readdirSync(fullPath);
3738
3879
  for (const sub of subFolders) {
3739
- await scanApiFolder(sub, path10.join(basePath, file));
3880
+ await scanApiFolder(sub, path11.join(basePath, file));
3740
3881
  }
3741
3882
  return;
3742
3883
  }
@@ -3749,7 +3890,7 @@ var scanApiFolder = async (file, basePath = "") => {
3749
3890
  const versionMatch = rawApiName.match(apiRules.apiVersionRegex);
3750
3891
  if (!versionMatch) {
3751
3892
  console.log(
3752
- `[loader][api] invalid filename: ${path10.join(fullPath, relFile)}. Expected <name>_v<number>.ts. File will not be loaded.`,
3893
+ `[loader][api] invalid filename: ${path11.join(fullPath, relFile)}. Expected <name>_v<number>.ts. File will not be loaded.`,
3753
3894
  "red"
3754
3895
  );
3755
3896
  continue;
@@ -3757,7 +3898,7 @@ var scanApiFolder = async (file, basePath = "") => {
3757
3898
  const version = `v${versionMatch[1]}`;
3758
3899
  const apiName = rawApiName.replace(apiRules.apiVersionRegex, "");
3759
3900
  const routeKey = `api/${mappedPageLocation}/${apiName}/${version}`;
3760
- const modulePath = path10.resolve(path10.join(fullPath, relFile));
3901
+ const modulePath = path11.resolve(path11.join(fullPath, relFile));
3761
3902
  const [err, module] = await tryCatch(async () => importFile(modulePath));
3762
3903
  if (err) {
3763
3904
  console.log(`[loader][api] failed to import ${routeKey} from ${modulePath}:`, err, "red");
@@ -3786,16 +3927,16 @@ var scanApiFolder = async (file, basePath = "") => {
3786
3927
  var initializeSyncs = async () => {
3787
3928
  for (const key of Object.keys(devSyncs)) delete devSyncs[key];
3788
3929
  clearRuntimeTypeResolverCache();
3789
- const srcFolder = fs7.readdirSync(getSrcDir3());
3930
+ const srcFolder = fs8.readdirSync(getSrcDir3());
3790
3931
  for (const file of srcFolder) {
3791
3932
  await scanSyncFolder(file);
3792
3933
  }
3793
3934
  };
3794
3935
  var upsertSyncFromFile = async (filePath) => {
3795
- if (isIgnoredPath(path10.resolve(filePath))) return;
3936
+ if (isIgnoredPath(path11.resolve(filePath))) return;
3796
3937
  const routeMeta = resolveSyncRouteMetaFromPath(filePath);
3797
3938
  if (!routeMeta) {
3798
- const normalized = normalizePath3(path10.resolve(filePath));
3939
+ const normalized = normalizePath3(path11.resolve(filePath));
3799
3940
  if (normalized.endsWith(".ts") && normalized.includes(syncMarkerSegment()) && isRouteSurfaceFile(normalized)) {
3800
3941
  console.log(
3801
3942
  `[loader][sync] invalid filename: ${normalized}. Expected <name>_server_v<number>.ts or <name>_client_v<number>.ts. File will not be loaded.`,
@@ -3848,13 +3989,13 @@ var removeSyncFromFile = (filePath) => {
3848
3989
  delete devSyncs[routeMeta.routeKey];
3849
3990
  };
3850
3991
  var scanSyncFolder = async (file, basePath = "") => {
3851
- const fullPath = path10.join(getSrcDir3(), basePath, file);
3992
+ const fullPath = path11.join(getSrcDir3(), basePath, file);
3852
3993
  if (isIgnoredPath(fullPath)) return;
3853
- if (!fs7.statSync(fullPath).isDirectory()) return;
3994
+ if (!fs8.statSync(fullPath).isDirectory()) return;
3854
3995
  if (file !== getRoutingRules().syncMarker) {
3855
- const subFolders = fs7.readdirSync(fullPath);
3996
+ const subFolders = fs8.readdirSync(fullPath);
3856
3997
  for (const sub of subFolders) {
3857
- await scanSyncFolder(sub, path10.join(basePath, file));
3998
+ await scanSyncFolder(sub, path11.join(basePath, file));
3858
3999
  }
3859
4000
  return;
3860
4001
  }
@@ -3866,7 +4007,7 @@ var scanSyncFolder = async (file, basePath = "") => {
3866
4007
  const syncMatch = rawSyncFileName.match(syncRules.syncVersionRegex);
3867
4008
  if (!syncMatch) {
3868
4009
  console.log(
3869
- `[loader][sync] invalid filename: ${path10.join(fullPath, relFile)}. Expected <name>_server_v<number>.ts or <name>_client_v<number>.ts. File will not be loaded.`,
4010
+ `[loader][sync] invalid filename: ${path11.join(fullPath, relFile)}. Expected <name>_server_v<number>.ts or <name>_client_v<number>.ts. File will not be loaded.`,
3870
4011
  "red"
3871
4012
  );
3872
4013
  continue;
@@ -3876,7 +4017,7 @@ var scanSyncFolder = async (file, basePath = "") => {
3876
4017
  const syncName = rawSyncFileName.replace(syncRules.syncVersionRegex, "");
3877
4018
  const mappedPageLocation = mapSyncPageLocation(pageLocation);
3878
4019
  const routeBaseKey = `sync/${mappedPageLocation}/${syncName}/${version}`;
3879
- const filePath = path10.resolve(path10.join(fullPath, relFile));
4020
+ const filePath = path11.resolve(path11.join(fullPath, relFile));
3880
4021
  const [fileError, fileResult] = await tryCatch(async () => importFile(filePath));
3881
4022
  if (fileError) {
3882
4023
  console.log(`[loader][sync] failed to import ${filePath}:`, fileError, "red");
@@ -3908,7 +4049,7 @@ var initializeFunctions = async () => {
3908
4049
  }
3909
4050
  });
3910
4051
  for (const functionModule of modules) {
3911
- const absolutePath = path10.resolve(ROOT_DIR6, functionModule.sourcePath);
4052
+ const absolutePath = path11.resolve(ROOT_DIR6, functionModule.sourcePath);
3912
4053
  const [err, module] = await tryCatch(async () => importFile(absolutePath));
3913
4054
  if (err) {
3914
4055
  console.log(`[loader][function] failed to import ${absolutePath}:`, err, "red");
@@ -3931,19 +4072,25 @@ var initializeFunctions = async () => {
3931
4072
 
3932
4073
  // src/hotReload.ts
3933
4074
  import { watch } from "chokidar";
3934
- import fs11 from "fs";
3935
- import path14 from "path";
4075
+ import fs12 from "fs";
4076
+ import path15 from "path";
3936
4077
 
3937
4078
  // src/templateInjector.ts
3938
- import fs8 from "fs";
3939
- import path11 from "path";
4079
+ import fs9 from "fs";
4080
+ import path12 from "path";
3940
4081
  import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "url";
3941
- import * as ts9 from "typescript";
4082
+ import { ScriptKind as ScriptKind3 } from "typescript-7-api/ast";
4083
+ import {
4084
+ isIdentifier as isIdentifier8,
4085
+ isInterfaceDeclaration as isInterfaceDeclaration6,
4086
+ isPropertySignatureDeclaration as isPropertySignatureDeclaration4,
4087
+ isTypeLiteralNode as isTypeLiteralNode3
4088
+ } from "typescript-7-api/ast/is";
3942
4089
  import { ROOT_DIR as ROOT_DIR7, getGeneratedSocketTypesPath as getGeneratedSocketTypesPath6, getSrcDir as getSrcDir4 } from "@luckystack/core";
3943
4090
  var __filename = fileURLToPath(import.meta.url);
3944
- var __dirname = path11.dirname(__filename);
3945
- var templatesDir = path11.join(__dirname, "templates");
3946
- var getConsumerTemplatesDir = () => path11.join(ROOT_DIR7, ".luckystack", "templates");
4091
+ var __dirname = path12.dirname(__filename);
4092
+ var templatesDir = path12.join(__dirname, "templates");
4093
+ var getConsumerTemplatesDir = () => path12.join(ROOT_DIR7, ".luckystack", "templates");
3947
4094
  var templateContentFilenames = (kind) => {
3948
4095
  const builtIn = BUILT_IN_TEMPLATE_FILENAMES[kind];
3949
4096
  if (builtIn) return [builtIn];
@@ -3952,10 +4099,10 @@ var templateContentFilenames = (kind) => {
3952
4099
  var resolveTemplateContent = (kind) => {
3953
4100
  const consumerDir = getConsumerTemplatesDir();
3954
4101
  for (const fileName of templateContentFilenames(kind)) {
3955
- const consumerFile = path11.join(consumerDir, fileName);
3956
- if (fs8.existsSync(consumerFile)) {
4102
+ const consumerFile = path12.join(consumerDir, fileName);
4103
+ if (fs9.existsSync(consumerFile)) {
3957
4104
  try {
3958
- return fs8.readFileSync(consumerFile, "utf8");
4105
+ return fs9.readFileSync(consumerFile, "utf8");
3959
4106
  } catch (error) {
3960
4107
  console.error(`[TemplateInjector] Could not read consumer template: ${consumerFile}`, error);
3961
4108
  }
@@ -3965,9 +4112,9 @@ var resolveTemplateContent = (kind) => {
3965
4112
  if (override !== null) return override;
3966
4113
  const builtInName = BUILT_IN_TEMPLATE_FILENAMES[kind];
3967
4114
  if (builtInName) {
3968
- const bundled = path11.join(templatesDir, builtInName);
4115
+ const bundled = path12.join(templatesDir, builtInName);
3969
4116
  try {
3970
- return fs8.readFileSync(bundled, "utf8");
4117
+ return fs9.readFileSync(bundled, "utf8");
3971
4118
  } catch (error) {
3972
4119
  console.error(`[TemplateInjector] Could not read bundled template: ${bundled}`, error);
3973
4120
  return null;
@@ -3981,11 +4128,11 @@ var ensureConsumerTemplateConfigLoaded = () => {
3981
4128
  consumerTemplateConfig ??= (async () => {
3982
4129
  const dir = getConsumerTemplatesDir();
3983
4130
  for (const fileName of ["templateRules.ts", "templateRules.mjs", "templateRules.js"]) {
3984
- const rulesFile = path11.join(dir, fileName);
3985
- if (!fs8.existsSync(rulesFile)) continue;
3986
- const resolvedRulesFile = path11.resolve(rulesFile);
3987
- const resolvedRoot = path11.resolve(ROOT_DIR7);
3988
- if (!resolvedRulesFile.startsWith(resolvedRoot + path11.sep) && resolvedRulesFile !== resolvedRoot) {
4131
+ const rulesFile = path12.join(dir, fileName);
4132
+ if (!fs9.existsSync(rulesFile)) continue;
4133
+ const resolvedRulesFile = path12.resolve(rulesFile);
4134
+ const resolvedRoot = path12.resolve(ROOT_DIR7);
4135
+ if (!resolvedRulesFile.startsWith(resolvedRoot + path12.sep) && resolvedRulesFile !== resolvedRoot) {
3989
4136
  console.warn(
3990
4137
  `[TemplateInjector] Template rules file resolves outside project root \u2014 skipping: ${rulesFile}`
3991
4138
  );
@@ -4003,7 +4150,7 @@ var ensureConsumerTemplateConfigLoaded = () => {
4003
4150
  };
4004
4151
  var isEmptyFile = (filePath) => {
4005
4152
  try {
4006
- const content = fs8.readFileSync(filePath, "utf8");
4153
+ const content = fs9.readFileSync(filePath, "utf8");
4007
4154
  return content.trim().length === 0;
4008
4155
  } catch {
4009
4156
  return false;
@@ -4011,7 +4158,7 @@ var isEmptyFile = (filePath) => {
4011
4158
  };
4012
4159
  var isCommentOnlyFile = (filePath) => {
4013
4160
  try {
4014
- const content = fs8.readFileSync(filePath, "utf8");
4161
+ const content = fs9.readFileSync(filePath, "utf8");
4015
4162
  const withoutBlockComments = content.replaceAll(/\/\*[\s\S]*?\*\//g, "");
4016
4163
  const withoutLineComments = withoutBlockComments.replaceAll(/(^|\s)\/\/.*$/gm, "$1");
4017
4164
  return withoutLineComments.trim().length === 0;
@@ -4045,7 +4192,7 @@ var isVersionedSyncFile = (filePath) => {
4045
4192
  return isVersionedSyncFileName(filePath);
4046
4193
  };
4047
4194
  var getFileName = (filePath) => {
4048
- return path11.basename(filePath.replaceAll("\\", "/"));
4195
+ return path12.basename(filePath.replaceAll("\\", "/"));
4049
4196
  };
4050
4197
  var stripTsExtension = (fileName) => {
4051
4198
  return fileName.replace(/\.ts$/, "");
@@ -4121,7 +4268,7 @@ var getInvalidVersionMessage = (filePath) => {
4121
4268
  var computeSrcRelativePath = (filePath) => {
4122
4269
  try {
4123
4270
  const srcDir = getSrcDir4();
4124
- const absolute = path11.resolve(filePath);
4271
+ const absolute = path12.resolve(filePath);
4125
4272
  const normalizedSrc = srcDir.replaceAll("\\", "/");
4126
4273
  const normalizedAbs = absolute.replaceAll("\\", "/");
4127
4274
  if (!normalizedAbs.startsWith(`${normalizedSrc}/`)) return null;
@@ -4169,7 +4316,7 @@ var getPairedSyncFile = (filePath) => {
4169
4316
  var hasPairedFile = (filePath) => {
4170
4317
  const pairedPath = getPairedSyncFile(filePath);
4171
4318
  if (!pairedPath) return false;
4172
- return fs8.existsSync(pairedPath);
4319
+ return fs9.existsSync(pairedPath);
4173
4320
  };
4174
4321
  var extractSyncPagePath2 = (filePath) => {
4175
4322
  const normalized = filePath.replaceAll("\\", "/");
@@ -4182,14 +4329,14 @@ var extractSyncName2 = (filePath) => {
4182
4329
  const normalized = filePath.replaceAll("\\", "/");
4183
4330
  const match = /_sync\/(.+)\.ts$/.exec(normalized);
4184
4331
  if (!match) {
4185
- const basename = path11.basename(filePath, ".ts");
4332
+ const basename = path12.basename(filePath, ".ts");
4186
4333
  return basename.replace(/_server_v\d+$/, "").replace(/_client_v\d+$/, "");
4187
4334
  }
4188
4335
  return (match[1] ?? "").replace(/_server_v\d+$/, "").replace(/_client_v\d+$/, "");
4189
4336
  };
4190
4337
  var extractClientInputFromFile = (filePath) => {
4191
4338
  try {
4192
- const content = fs8.readFileSync(filePath, "utf8");
4339
+ const content = fs9.readFileSync(filePath, "utf8");
4193
4340
  const syncParamsMatch = /interface\s+SyncParams\s*\{/.exec(content);
4194
4341
  if (!syncParamsMatch) return null;
4195
4342
  const searchRegion = content.slice(syncParamsMatch.index + syncParamsMatch[0].length);
@@ -4220,7 +4367,7 @@ var extractClientInputFromFile = (filePath) => {
4220
4367
  var extractClientInputFromGeneratedTypes = (pagePath, syncName) => {
4221
4368
  try {
4222
4369
  const generatedTypesPath = getGeneratedSocketTypesPath6();
4223
- const content = fs8.readFileSync(generatedTypesPath, "utf8");
4370
+ const content = fs9.readFileSync(generatedTypesPath, "utf8");
4224
4371
  const escapeRegex = (value) => value.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
4225
4372
  const escapedPagePath = escapeRegex(pagePath);
4226
4373
  const escapedSyncName = escapeRegex(syncName);
@@ -4266,7 +4413,7 @@ var calculateRelativePath = (filePath) => {
4266
4413
  const srcRelative = computeSrcRelativePath(filePath);
4267
4414
  if (srcRelative !== null) {
4268
4415
  try {
4269
- const srcDepthFromRoot = path11.relative(ROOT_DIR7, getSrcDir4()).replaceAll("\\", "/").split("/").filter((segment) => segment.length > 0).length;
4416
+ const srcDepthFromRoot = path12.relative(ROOT_DIR7, getSrcDir4()).replaceAll("\\", "/").split("/").filter((segment) => segment.length > 0).length;
4270
4417
  const dirSegmentsAfterSrc = Math.max(
4271
4418
  0,
4272
4419
  srcRelative.split("/").filter((segment) => segment.length > 0).length - 1
@@ -4345,7 +4492,7 @@ var getTemplate = (filePath) => {
4345
4492
  var injectTemplate = async (filePath) => {
4346
4493
  await ensureConsumerTemplateConfigLoaded();
4347
4494
  if (getRouteFilenameValidationMessage(filePath)) {
4348
- fs8.writeFileSync(filePath, getInvalidVersionMessage(filePath), "utf8");
4495
+ fs9.writeFileSync(filePath, getInvalidVersionMessage(filePath), "utf8");
4349
4496
  console.log(`[TemplateInjector] Invalid route filename, injected guidance: ${filePath}`);
4350
4497
  return true;
4351
4498
  }
@@ -4354,7 +4501,7 @@ var injectTemplate = async (filePath) => {
4354
4501
  return false;
4355
4502
  }
4356
4503
  try {
4357
- fs8.writeFileSync(filePath, template, "utf8");
4504
+ fs9.writeFileSync(filePath, template, "utf8");
4358
4505
  console.log(`[TemplateInjector] Injected template into: ${filePath}`);
4359
4506
  return true;
4360
4507
  } catch (error) {
@@ -4410,18 +4557,10 @@ var rewriteClientInputType = (content) => {
4410
4557
  );
4411
4558
  };
4412
4559
  var rewriteClientInputTypeAst = (content, sourceFileName) => {
4413
- const parseSource = (src) => ts9.createSourceFile(
4414
- sourceFileName,
4415
- src,
4416
- ts9.ScriptTarget.Latest,
4417
- /* setParentNodes */
4418
- true,
4419
- ts9.ScriptKind.TS
4420
- );
4421
- const sourceFile = parseSource(content);
4560
+ const sourceFile = parseSourceText(sourceFileName, content, ScriptKind3.TS);
4422
4561
  let syncParamsInterface;
4423
4562
  for (const stmt of sourceFile.statements) {
4424
- if (ts9.isInterfaceDeclaration(stmt) && stmt.name.text === "SyncParams") {
4563
+ if (isInterfaceDeclaration6(stmt) && stmt.name.text === "SyncParams") {
4425
4564
  syncParamsInterface = stmt;
4426
4565
  break;
4427
4566
  }
@@ -4429,30 +4568,18 @@ var rewriteClientInputTypeAst = (content, sourceFileName) => {
4429
4568
  if (!syncParamsInterface) return null;
4430
4569
  let clientInputMember;
4431
4570
  for (const member of syncParamsInterface.members) {
4432
- if (ts9.isPropertySignature(member) && ts9.isIdentifier(member.name) && member.name.text === "clientInput") {
4571
+ if (isPropertySignatureDeclaration4(member) && isIdentifier8(member.name) && member.name.text === "clientInput") {
4433
4572
  clientInputMember = member;
4434
4573
  break;
4435
4574
  }
4436
4575
  }
4437
4576
  if (!clientInputMember?.type) return null;
4438
- if (!ts9.isTypeLiteralNode(clientInputMember.type)) return null;
4577
+ if (!isTypeLiteralNode3(clientInputMember.type)) return null;
4439
4578
  const typeNode = clientInputMember.type;
4440
4579
  const start = typeNode.getStart(sourceFile);
4441
4580
  const end = typeNode.getEnd();
4442
4581
  const rewritten = `${content.slice(0, start)}SyncClientInput<PagePath, SyncName>${content.slice(end)}`;
4443
- const reparsedFile = parseSource(rewritten);
4444
- const verifyProgram = ts9.createProgram({
4445
- rootNames: [sourceFileName],
4446
- options: { noResolve: true, skipLibCheck: true },
4447
- // Supply the in-memory source so `ts.createProgram` never touches the disk.
4448
- host: {
4449
- ...ts9.createCompilerHost({}),
4450
- getSourceFile: (name) => name === sourceFileName ? reparsedFile : void 0,
4451
- fileExists: (name) => name === sourceFileName,
4452
- readFile: (name) => name === sourceFileName ? rewritten : void 0
4453
- }
4454
- });
4455
- const syntaxErrors = verifyProgram.getSyntacticDiagnostics(reparsedFile);
4582
+ const syntaxErrors = transpileSourceText(sourceFileName, rewritten).diagnostics ?? [];
4456
4583
  if (syntaxErrors.length > 0) {
4457
4584
  console.log(
4458
4585
  `[TemplateInjector] AST rewrite produced invalid TypeScript for ${sourceFileName} \u2014 leaving untouched`,
@@ -4482,10 +4609,10 @@ var updateClientFileForPairedServer = async (clientFilePath) => {
4482
4609
  try {
4483
4610
  const pagePath = extractSyncPagePath2(clientFilePath);
4484
4611
  const syncName = extractSyncName2(clientFilePath);
4485
- let content = fs8.readFileSync(clientFilePath, "utf8");
4612
+ let content = fs9.readFileSync(clientFilePath, "utf8");
4486
4613
  content = ensureImportedTypes(content, clientFilePath);
4487
4614
  content = insertTypeAliases(content, pagePath, syncName);
4488
- const astResult = rewriteClientInputTypeAst(content, path11.basename(clientFilePath));
4615
+ const astResult = rewriteClientInputTypeAst(content, path12.basename(clientFilePath));
4489
4616
  if (astResult === null) {
4490
4617
  console.log(
4491
4618
  `[TemplateInjector] AST clientInput rewrite unavailable for ${clientFilePath} \u2014 using regex fallback`,
@@ -4497,7 +4624,7 @@ var updateClientFileForPairedServer = async (clientFilePath) => {
4497
4624
  }
4498
4625
  content = addServerOutputToParams(content);
4499
4626
  content = addServerOutputToDestructuring(content);
4500
- fs8.writeFileSync(clientFilePath, content, "utf8");
4627
+ fs9.writeFileSync(clientFilePath, content, "utf8");
4501
4628
  console.log(`[TemplateInjector] Updated client file to use paired types (preserved code): ${clientFilePath}`);
4502
4629
  return true;
4503
4630
  } catch (error) {
@@ -4538,7 +4665,7 @@ var splitAtMainBody = (content) => {
4538
4665
  };
4539
4666
  var updateClientFileForDeletedServer = async (clientFilePath, clientInputTypes) => {
4540
4667
  try {
4541
- let content = fs8.readFileSync(clientFilePath, "utf8");
4668
+ let content = fs9.readFileSync(clientFilePath, "utf8");
4542
4669
  content = inlineClientInputType(content, clientInputTypes);
4543
4670
  const [header, body] = splitAtMainBody(content);
4544
4671
  const cleanedHeader = removeServerOutputFromDestructuring(removeServerOutputFromParams(header));
@@ -4546,7 +4673,7 @@ var updateClientFileForDeletedServer = async (clientFilePath, clientInputTypes)
4546
4673
  content = removeGeneratedTypeImports(content);
4547
4674
  content = removeTypeAliases(content);
4548
4675
  content = content.replaceAll(/\n{3,}/g, "\n\n");
4549
- fs8.writeFileSync(clientFilePath, content, "utf8");
4676
+ fs9.writeFileSync(clientFilePath, content, "utf8");
4550
4677
  console.log(`[TemplateInjector] Updated client file for deleted server (preserved code): ${clientFilePath}`);
4551
4678
  return true;
4552
4679
  } catch (error) {
@@ -4572,7 +4699,7 @@ var injectServerTemplateWithClientInput = async (serverFilePath, clientInputType
4572
4699
  /clientInput:\s*\{[^}]*\}/s,
4573
4700
  (_match) => `clientInput: ${clientInputTypes}`
4574
4701
  );
4575
- fs8.writeFileSync(serverFilePath, content, "utf8");
4702
+ fs9.writeFileSync(serverFilePath, content, "utf8");
4576
4703
  console.log(`[TemplateInjector] Injected server template with clientInput: ${serverFilePath}`);
4577
4704
  return true;
4578
4705
  } catch (error) {
@@ -4582,24 +4709,24 @@ var injectServerTemplateWithClientInput = async (serverFilePath, clientInputType
4582
4709
  };
4583
4710
 
4584
4711
  // src/importDependencyGraph.ts
4585
- import fs9 from "fs";
4586
- import path12 from "path";
4712
+ import fs10 from "fs";
4713
+ import path13 from "path";
4587
4714
  import { ROOT_DIR as ROOT_DIR8, getServerFunctionDirs as getServerFunctionDirs2, getSharedDir, getSrcDir as getSrcDir5 } from "@luckystack/core";
4588
4715
  var SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mts", ".cts"];
4589
- var normalizePath4 = (value) => path12.resolve(value).replaceAll("\\", "/");
4716
+ var normalizePath4 = (value) => path13.resolve(value).replaceAll("\\", "/");
4590
4717
  var isSupportedScriptFile = (value) => {
4591
4718
  return SUPPORTED_EXTENSIONS.some((extension) => value.endsWith(extension));
4592
4719
  };
4593
4720
  var existsFile = (value) => {
4594
4721
  try {
4595
- return fs9.existsSync(value) && fs9.statSync(value).isFile();
4722
+ return fs10.existsSync(value) && fs10.statSync(value).isFile();
4596
4723
  } catch {
4597
4724
  return false;
4598
4725
  }
4599
4726
  };
4600
4727
  var existsDirectory = (value) => {
4601
4728
  try {
4602
- return fs9.existsSync(value) && fs9.statSync(value).isDirectory();
4729
+ return fs10.existsSync(value) && fs10.statSync(value).isDirectory();
4603
4730
  } catch {
4604
4731
  return false;
4605
4732
  }
@@ -4610,16 +4737,16 @@ var collectScriptFiles = (dir, output, visited = /* @__PURE__ */ new Set()) => {
4610
4737
  }
4611
4738
  let realDir;
4612
4739
  try {
4613
- realDir = fs9.realpathSync(dir);
4740
+ realDir = fs10.realpathSync(dir);
4614
4741
  } catch {
4615
4742
  return;
4616
4743
  }
4617
4744
  if (visited.has(realDir)) return;
4618
4745
  visited.add(realDir);
4619
- const entries = fs9.readdirSync(dir, { withFileTypes: true });
4746
+ const entries = fs10.readdirSync(dir, { withFileTypes: true });
4620
4747
  for (const entry of entries) {
4621
4748
  if (entry.name === "node_modules") continue;
4622
- const fullPath = path12.join(dir, entry.name);
4749
+ const fullPath = path13.join(dir, entry.name);
4623
4750
  if (entry.isDirectory() || entry.isSymbolicLink()) {
4624
4751
  if (existsDirectory(fullPath)) {
4625
4752
  collectScriptFiles(fullPath, output, visited);
@@ -4638,7 +4765,7 @@ var SCOPED_FILES_TTL_MS = 1e3;
4638
4765
  var extractImportSpecifiers = (filePath) => {
4639
4766
  let mtimeMs = 0;
4640
4767
  try {
4641
- mtimeMs = fs9.statSync(filePath).mtimeMs;
4768
+ mtimeMs = fs10.statSync(filePath).mtimeMs;
4642
4769
  } catch {
4643
4770
  specifiersCache.delete(filePath);
4644
4771
  return [];
@@ -4648,7 +4775,7 @@ var extractImportSpecifiers = (filePath) => {
4648
4775
  return cached.specifiers;
4649
4776
  }
4650
4777
  try {
4651
- const source = fs9.readFileSync(filePath, "utf8");
4778
+ const source = fs10.readFileSync(filePath, "utf8");
4652
4779
  const specifiers = /* @__PURE__ */ new Set();
4653
4780
  const importExportRegex = /(?:import|export)\s+(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g;
4654
4781
  const dynamicImportRegex = /import\(\s*['"]([^'"]+)['"]\s*\)/g;
@@ -4683,7 +4810,7 @@ var tryResolveWithExtensions = (basePath) => {
4683
4810
  }
4684
4811
  if (existsDirectory(basePath)) {
4685
4812
  for (const extension of SUPPORTED_EXTENSIONS) {
4686
- const indexFile = path12.join(basePath, `index${extension}`);
4813
+ const indexFile = path13.join(basePath, `index${extension}`);
4687
4814
  if (existsFile(indexFile)) {
4688
4815
  return normalizePath4(indexFile);
4689
4816
  }
@@ -4696,18 +4823,18 @@ var resolveImportToFile = (importerPath, specifier) => {
4696
4823
  return null;
4697
4824
  }
4698
4825
  if (specifier === "config") {
4699
- return tryResolveWithExtensions(path12.join(ROOT_DIR8, "config"));
4826
+ return tryResolveWithExtensions(path13.join(ROOT_DIR8, "config"));
4700
4827
  }
4701
4828
  if (specifier.startsWith("./") || specifier.startsWith("../")) {
4702
- const relativeBase = path12.resolve(path12.dirname(importerPath), specifier);
4829
+ const relativeBase = path13.resolve(path13.dirname(importerPath), specifier);
4703
4830
  return tryResolveWithExtensions(relativeBase);
4704
4831
  }
4705
4832
  if (specifier.startsWith("src/") || specifier.startsWith("@/")) {
4706
4833
  const sourcePath = specifier.startsWith("@/") ? specifier.slice(2) : specifier.slice(4);
4707
- return tryResolveWithExtensions(path12.join(getSrcDir5(), sourcePath));
4834
+ return tryResolveWithExtensions(path13.join(getSrcDir5(), sourcePath));
4708
4835
  }
4709
4836
  if (specifier.startsWith("shared/")) {
4710
- return tryResolveWithExtensions(path12.join(getSharedDir(), specifier.slice(7)));
4837
+ return tryResolveWithExtensions(path13.join(getSharedDir(), specifier.slice(7)));
4711
4838
  }
4712
4839
  return null;
4713
4840
  };
@@ -4725,7 +4852,7 @@ var collectScopedFiles = () => {
4725
4852
  for (const dir of getServerFunctionDirs2()) {
4726
4853
  collectScriptFiles(dir, files);
4727
4854
  }
4728
- const configFile = tryResolveWithExtensions(path12.join(ROOT_DIR8, "config"));
4855
+ const configFile = tryResolveWithExtensions(path13.join(ROOT_DIR8, "config"));
4729
4856
  if (configFile) {
4730
4857
  files.add(configFile);
4731
4858
  }
@@ -4773,19 +4900,19 @@ var findDependentRouteFiles = (changedFilePath) => {
4773
4900
  };
4774
4901
 
4775
4902
  // src/prismaClientCheck.ts
4776
- import fs10 from "fs";
4777
- import path13 from "path";
4903
+ import fs11 from "fs";
4904
+ import path14 from "path";
4778
4905
  import { spawn } from "child_process";
4779
4906
  import { ROOT_DIR as ROOT_DIR9, tryCatch as tryCatch2 } from "@luckystack/core";
4780
- var GENERATED_CLIENT_DIR = path13.join(ROOT_DIR9, "node_modules", ".prisma", "client");
4781
- var GENERATED_CLIENT_MARKER = path13.join(GENERATED_CLIENT_DIR, "schema.prisma");
4782
- var DEFAULT_SCHEMA_PATH = path13.join(ROOT_DIR9, "prisma", "schema.prisma");
4783
- var isPrismaClientMissing = () => fs10.existsSync(DEFAULT_SCHEMA_PATH) && !fs10.existsSync(GENERATED_CLIENT_MARKER);
4907
+ var GENERATED_CLIENT_DIR = path14.join(ROOT_DIR9, "node_modules", ".prisma", "client");
4908
+ var GENERATED_CLIENT_MARKER = path14.join(GENERATED_CLIENT_DIR, "schema.prisma");
4909
+ var DEFAULT_SCHEMA_PATH = path14.join(ROOT_DIR9, "prisma", "schema.prisma");
4910
+ var isPrismaClientMissing = () => fs11.existsSync(DEFAULT_SCHEMA_PATH) && !fs11.existsSync(GENERATED_CLIENT_MARKER);
4784
4911
  var runPrismaGenerate = async () => tryCatch2(
4785
4912
  () => new Promise((resolve, reject) => {
4786
4913
  const localBinName = process.platform === "win32" ? "prisma.cmd" : "prisma";
4787
- const localBin = path13.join(ROOT_DIR9, "node_modules", ".bin", localBinName);
4788
- const useLocal = fs10.existsSync(localBin);
4914
+ const localBin = path14.join(ROOT_DIR9, "node_modules", ".bin", localBinName);
4915
+ const useLocal = fs11.existsSync(localBin);
4789
4916
  const [cmd, args] = useLocal ? [localBin, ["generate"]] : [process.platform === "win32" ? "npx.cmd" : "npx", ["prisma", "generate"]];
4790
4917
  const isWinShim = process.platform === "win32" && /\.(cmd|bat)$/i.test(cmd);
4791
4918
  const child = isWinShim ? spawn(
@@ -4806,7 +4933,7 @@ var runPrismaGenerate = async () => tryCatch2(
4806
4933
 
4807
4934
  // src/hotReload.ts
4808
4935
  import { tryCatch as tryCatch3, getProjectConfig, getLocaleReloader, isProductionRuntime } from "@luckystack/core";
4809
- var normalizeFsPath = (value) => path14.resolve(value).replaceAll("\\", "/");
4936
+ var normalizeFsPath = (value) => path15.resolve(value).replaceAll("\\", "/");
4810
4937
  var isGeneratedPath = (normalizedPath) => {
4811
4938
  return normalizedPath.includes("apiTypes.generated.ts") || normalizedPath.includes("apiDocs.generated.json");
4812
4939
  };
@@ -5014,7 +5141,7 @@ var setupWatchers = () => {
5014
5141
  if (shouldInjectTemplate(filePath, { isNewFile: true })) {
5015
5142
  if (isSyncServerFile(normalizedPath)) {
5016
5143
  const clientPath = getPairedSyncFile(normalizedPath);
5017
- if (clientPath && fs11.existsSync(clientPath) && !isEmptyFile(clientPath)) {
5144
+ if (clientPath && fs12.existsSync(clientPath) && !isEmptyFile(clientPath)) {
5018
5145
  const clientInputTypes = extractClientInputFromFile(clientPath);
5019
5146
  if (clientInputTypes) {
5020
5147
  await injectServerTemplateWithClientInput(filePath, clientInputTypes);
@@ -5177,7 +5304,7 @@ var setupWatchers = () => {
5177
5304
  scheduleReload("sync", async () => {
5178
5305
  if (isSyncServerFile(normalizedPath)) {
5179
5306
  const clientPath = getPairedSyncFile(normalizedPath);
5180
- if (clientPath && fs11.existsSync(clientPath)) {
5307
+ if (clientPath && fs12.existsSync(clientPath)) {
5181
5308
  const pagePath = extractSyncPagePath2(normalizedPath);
5182
5309
  const syncName = extractSyncName2(normalizedPath);
5183
5310
  const clientInputTypes = extractClientInputFromGeneratedTypes(pagePath, syncName);