@dudousxd/nestjs-inertia-codegen 1.0.0 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # Changelog — @dudousxd/nestjs-inertia-codegen
2
2
 
3
+ ## 1.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - fix(codegen): resolve DTOs imported from separate files — cross-file class resolution via ts-morph import following
8
+
9
+ - Updated dependencies []:
10
+ - @dudousxd/nestjs-inertia@1.0.4
11
+
12
+ ## 1.0.3
13
+
14
+ ### Patch Changes
15
+
16
+ - [`c79cc6d`](https://github.com/DavideCarvalho/nestjs-inertia/commit/c79cc6dad64342bce17c28a705ae27911c3f4c74) - Fix React Refresh preamble in @vite directive, watcher initial pass runs full discovery, auto-sync VERSION constants
17
+
18
+ - Updated dependencies [[`c79cc6d`](https://github.com/DavideCarvalho/nestjs-inertia/commit/c79cc6dad64342bce17c28a705ae27911c3f4c74)]:
19
+ - @dudousxd/nestjs-inertia@1.0.3
20
+
21
+ ## 1.0.2
22
+
23
+ ### Patch Changes
24
+
25
+ - [`27e0bab`](https://github.com/DavideCarvalho/nestjs-inertia/commit/27e0bab4b7f8752a4dd179cc715b4e3d64161624) - Fix: @vite directive includes React Refresh preamble, watcher initial pass runs full route+contract discovery from DTOs
26
+
27
+ - Updated dependencies [[`27e0bab`](https://github.com/DavideCarvalho/nestjs-inertia/commit/27e0bab4b7f8752a4dd179cc715b4e3d64161624)]:
28
+ - @dudousxd/nestjs-inertia@1.0.2
29
+
30
+ ## 1.0.1
31
+
32
+ ### Patch Changes
33
+
34
+ - [`a33c81b`](https://github.com/DavideCarvalho/nestjs-inertia/commit/a33c81b0a53077559b1f9433824cfaee1b01c80c) - Fix: @vite directive includes React Refresh preamble in dev, watcher initial pass runs full route+contract discovery
35
+
36
+ - Updated dependencies [[`a33c81b`](https://github.com/DavideCarvalho/nestjs-inertia/commit/a33c81b0a53077559b1f9433824cfaee1b01c80c)]:
37
+ - @dudousxd/nestjs-inertia@1.0.1
38
+
3
39
  ## 1.0.0
4
40
 
5
41
  ### Minor Changes
package/dist/cli/main.cjs CHANGED
@@ -713,7 +713,7 @@ async function discoverContractsFast(opts) {
713
713
  }
714
714
  const routes = [];
715
715
  for (const sourceFile of project.getSourceFiles()) {
716
- routes.push(...extractFromSourceFile(sourceFile));
716
+ routes.push(...extractFromSourceFile(sourceFile, project));
717
717
  }
718
718
  return routes;
719
719
  }
@@ -878,11 +878,50 @@ function extractParams(path) {
878
878
  }));
879
879
  }
880
880
  __name(extractParams, "extractParams");
881
- function resolveTypeNodeToString(typeNode, sourceFile, depth) {
881
+ function resolveImportedClass(name, sourceFile, project) {
882
+ for (const importDecl of sourceFile.getImportDeclarations()) {
883
+ const namedImport = importDecl.getNamedImports().find((n) => n.getName() === name);
884
+ if (!namedImport) continue;
885
+ const moduleSpecifier = importDecl.getModuleSpecifierValue();
886
+ if (!moduleSpecifier.startsWith(".")) return null;
887
+ const dir = (0, import_node_path8.dirname)(sourceFile.getFilePath());
888
+ const candidates = [
889
+ (0, import_node_path8.resolve)(dir, `${moduleSpecifier}.ts`),
890
+ (0, import_node_path8.resolve)(dir, moduleSpecifier, "index.ts")
891
+ ];
892
+ for (const candidate of candidates) {
893
+ let importedFile = project.getSourceFile(candidate);
894
+ if (!importedFile) {
895
+ try {
896
+ importedFile = project.addSourceFileAtPath(candidate);
897
+ } catch {
898
+ continue;
899
+ }
900
+ }
901
+ const cls = importedFile.getClass(name);
902
+ if (cls) return {
903
+ cls,
904
+ file: importedFile
905
+ };
906
+ }
907
+ }
908
+ return null;
909
+ }
910
+ __name(resolveImportedClass, "resolveImportedClass");
911
+ function findClass(name, sourceFile, project) {
912
+ const local = sourceFile.getClass(name);
913
+ if (local) return {
914
+ cls: local,
915
+ file: sourceFile
916
+ };
917
+ return resolveImportedClass(name, sourceFile, project);
918
+ }
919
+ __name(findClass, "findClass");
920
+ function resolveTypeNodeToString(typeNode, sourceFile, project, depth) {
882
921
  if (depth <= 0) return "unknown";
883
922
  if (import_ts_morph.Node.isArrayTypeNode(typeNode)) {
884
923
  const elementType = typeNode.getElementTypeNode();
885
- return `Array<${resolveTypeNodeToString(elementType, sourceFile, depth)}>`;
924
+ return `Array<${resolveTypeNodeToString(elementType, sourceFile, project, depth)}>`;
886
925
  }
887
926
  if (import_ts_morph.Node.isTypeReference(typeNode)) {
888
927
  const typeName = typeNode.getTypeName();
@@ -894,7 +933,7 @@ function resolveTypeNodeToString(typeNode, sourceFile, depth) {
894
933
  const typeArgs = typeNode.getTypeArguments();
895
934
  const firstTypeArg = typeArgs[0];
896
935
  if (typeArgs.length > 0 && firstTypeArg !== void 0) {
897
- return `Array<${resolveTypeNodeToString(firstTypeArg, sourceFile, depth)}>`;
936
+ return `Array<${resolveTypeNodeToString(firstTypeArg, sourceFile, project, depth)}>`;
898
937
  }
899
938
  return "Array<unknown>";
900
939
  }
@@ -902,13 +941,13 @@ function resolveTypeNodeToString(typeNode, sourceFile, depth) {
902
941
  const typeArgs = typeNode.getTypeArguments();
903
942
  const firstTypeArg = typeArgs[0];
904
943
  if (typeArgs.length > 0 && firstTypeArg !== void 0) {
905
- return resolveTypeNodeToString(firstTypeArg, sourceFile, depth);
944
+ return resolveTypeNodeToString(firstTypeArg, sourceFile, project, depth);
906
945
  }
907
946
  return "unknown";
908
947
  }
909
- const classDec = sourceFile.getClass(name);
910
- if (classDec) {
911
- return resolveClassDeclaration(classDec, sourceFile, depth - 1);
948
+ const resolved = findClass(name, sourceFile, project);
949
+ if (resolved) {
950
+ return resolveClassDeclaration(resolved.cls, resolved.file, project, depth - 1);
912
951
  }
913
952
  return name;
914
953
  }
@@ -921,7 +960,7 @@ function resolveTypeNodeToString(typeNode, sourceFile, depth) {
921
960
  return typeNode.getText();
922
961
  }
923
962
  __name(resolveTypeNodeToString, "resolveTypeNodeToString");
924
- function resolveClassDeclaration(cls, sourceFile, depth) {
963
+ function resolveClassDeclaration(cls, sourceFile, project, depth) {
925
964
  if (depth < 0) return "unknown";
926
965
  const lines = [];
927
966
  for (const prop of cls.getProperties()) {
@@ -930,14 +969,14 @@ function resolveClassDeclaration(cls, sourceFile, depth) {
930
969
  const propTypeNode = prop.getTypeNode();
931
970
  let propType = "unknown";
932
971
  if (propTypeNode) {
933
- propType = resolveTypeNodeToString(propTypeNode, sourceFile, depth);
972
+ propType = resolveTypeNodeToString(propTypeNode, sourceFile, project, depth);
934
973
  }
935
974
  lines.push(`${propName}${isOptional ? "?" : ""}: ${propType}`);
936
975
  }
937
976
  return `{ ${lines.join("; ")} }`;
938
977
  }
939
978
  __name(resolveClassDeclaration, "resolveClassDeclaration");
940
- function extractBodyType(method, sourceFile) {
979
+ function extractBodyType(method, sourceFile, project) {
941
980
  for (const param of method.getParameters()) {
942
981
  const bodyDecorator = param.getDecorators().find((d) => d.getName() === "Body");
943
982
  if (!bodyDecorator) continue;
@@ -945,13 +984,13 @@ function extractBodyType(method, sourceFile) {
945
984
  if (bodyArgs.length > 0) continue;
946
985
  const typeNode = param.getTypeNode();
947
986
  if (typeNode) {
948
- return resolveTypeNodeToString(typeNode, sourceFile, 3);
987
+ return resolveTypeNodeToString(typeNode, sourceFile, project, 3);
949
988
  }
950
989
  }
951
990
  return null;
952
991
  }
953
992
  __name(extractBodyType, "extractBodyType");
954
- function extractQueryType(method, sourceFile) {
993
+ function extractQueryType(method, sourceFile, project) {
955
994
  for (const param of method.getParameters()) {
956
995
  const queryDecorator = param.getDecorators().find((d) => d.getName() === "Query");
957
996
  if (!queryDecorator) continue;
@@ -959,13 +998,13 @@ function extractQueryType(method, sourceFile) {
959
998
  if (queryArgs.length > 0) continue;
960
999
  const typeNode = param.getTypeNode();
961
1000
  if (typeNode) {
962
- return resolveTypeNodeToString(typeNode, sourceFile, 3);
1001
+ return resolveTypeNodeToString(typeNode, sourceFile, project, 3);
963
1002
  }
964
1003
  }
965
1004
  return null;
966
1005
  }
967
1006
  __name(extractQueryType, "extractQueryType");
968
- function extractParamsType(method, sourceFile) {
1007
+ function extractParamsType(method, sourceFile, project) {
969
1008
  const entries = [];
970
1009
  for (const param of method.getParameters()) {
971
1010
  const paramDecorator = param.getDecorators().find((d) => d.getName() === "Param");
@@ -976,13 +1015,13 @@ function extractParamsType(method, sourceFile) {
976
1015
  if (!import_ts_morph.Node.isStringLiteral(nameArg)) continue;
977
1016
  const paramName = nameArg.getLiteralValue();
978
1017
  const typeNode = param.getTypeNode();
979
- const paramType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, 3) : "string";
1018
+ const paramType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
980
1019
  entries.push(`${paramName}: ${paramType}`);
981
1020
  }
982
1021
  return entries.length > 0 ? `{ ${entries.join("; ")} }` : null;
983
1022
  }
984
1023
  __name(extractParamsType, "extractParamsType");
985
- function extractResponseType(method, sourceFile) {
1024
+ function extractResponseType(method, sourceFile, project) {
986
1025
  const apiResponseDecorator = method.getDecorator("ApiResponse");
987
1026
  if (apiResponseDecorator) {
988
1027
  const args = apiResponseDecorator.getArguments();
@@ -997,37 +1036,37 @@ function extractResponseType(method, sourceFile) {
997
1036
  const elements = val.getElements();
998
1037
  const firstEl = elements[0];
999
1038
  if (elements.length > 0 && firstEl !== void 0) {
1000
- const innerType = resolveIdentifierToClassType(firstEl, sourceFile, 3);
1039
+ const innerType = resolveIdentifierToClassType(firstEl, sourceFile, project, 3);
1001
1040
  return `Array<${innerType}>`;
1002
1041
  }
1003
1042
  return "Array<unknown>";
1004
1043
  }
1005
- return resolveIdentifierToClassType(val, sourceFile, 3);
1044
+ return resolveIdentifierToClassType(val, sourceFile, project, 3);
1006
1045
  }
1007
1046
  }
1008
1047
  }
1009
1048
  const returnTypeNode = method.getReturnTypeNode();
1010
1049
  if (returnTypeNode) {
1011
- return resolveTypeNodeToString(returnTypeNode, sourceFile, 3);
1050
+ return resolveTypeNodeToString(returnTypeNode, sourceFile, project, 3);
1012
1051
  }
1013
1052
  return "unknown";
1014
1053
  }
1015
1054
  __name(extractResponseType, "extractResponseType");
1016
- function resolveIdentifierToClassType(node, sourceFile, depth) {
1055
+ function resolveIdentifierToClassType(node, sourceFile, project, depth) {
1017
1056
  if (!import_ts_morph.Node.isIdentifier(node)) return "unknown";
1018
1057
  const name = node.getText();
1019
- const classDec = sourceFile.getClass(name);
1020
- if (classDec) {
1021
- return resolveClassDeclaration(classDec, sourceFile, depth - 1);
1058
+ const resolved = findClass(name, sourceFile, project);
1059
+ if (resolved) {
1060
+ return resolveClassDeclaration(resolved.cls, resolved.file, project, depth - 1);
1022
1061
  }
1023
1062
  return name;
1024
1063
  }
1025
1064
  __name(resolveIdentifierToClassType, "resolveIdentifierToClassType");
1026
- function extractDtoContract(method, sourceFile) {
1027
- const body = extractBodyType(method, sourceFile);
1028
- const query = extractQueryType(method, sourceFile);
1029
- const paramsType = extractParamsType(method, sourceFile);
1030
- const response = extractResponseType(method, sourceFile);
1065
+ function extractDtoContract(method, sourceFile, project) {
1066
+ const body = extractBodyType(method, sourceFile, project);
1067
+ const query = extractQueryType(method, sourceFile, project);
1068
+ const paramsType = extractParamsType(method, sourceFile, project);
1069
+ const response = extractResponseType(method, sourceFile, project);
1031
1070
  if (body === null && query === null && paramsType === null && response === "unknown") {
1032
1071
  return null;
1033
1072
  }
@@ -1049,7 +1088,7 @@ var HTTP_METHOD_DECORATORS = {
1049
1088
  Head: "HEAD",
1050
1089
  All: "ALL"
1051
1090
  };
1052
- function extractFromSourceFile(sourceFile) {
1091
+ function extractFromSourceFile(sourceFile, project) {
1053
1092
  const routes = [];
1054
1093
  const seenNames = /* @__PURE__ */ new Map();
1055
1094
  const classes = sourceFile.getClasses();
@@ -1148,7 +1187,7 @@ function extractFromSourceFile(sourceFile) {
1148
1187
  const params = extractParams(combined);
1149
1188
  const methodName = method.getName();
1150
1189
  const routeName = `${className}.${methodName}`;
1151
- const dtoContract = extractDtoContract(method, sourceFile);
1190
+ const dtoContract = extractDtoContract(method, sourceFile, project);
1152
1191
  routes.push({
1153
1192
  method: httpMethod,
1154
1193
  path: combined,
@@ -1235,8 +1274,20 @@ async function watch(config, onChange) {
1235
1274
  return NO_OP_WATCHER;
1236
1275
  }
1237
1276
  try {
1238
- await generate(config);
1239
- } catch {
1277
+ const initialRoutes = await discoverContractsFast({
1278
+ cwd: config.codegen.cwd,
1279
+ glob: config.contracts.glob,
1280
+ ...config.app?.tsconfig ? {
1281
+ tsconfig: config.app.tsconfig
1282
+ } : {}
1283
+ });
1284
+ await generate(config, initialRoutes);
1285
+ } catch (err) {
1286
+ console.warn(`[nestjs-inertia-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`);
1287
+ try {
1288
+ await generate(config);
1289
+ } catch {
1290
+ }
1240
1291
  }
1241
1292
  let pagesDebounceTimer;
1242
1293
  const pagesWatcher = import_chokidar.default.watch((0, import_node_path10.join)(config.codegen.cwd, config.pages.glob), {
@@ -1321,7 +1372,7 @@ async function watch(config, onChange) {
1321
1372
  __name(watch, "watch");
1322
1373
 
1323
1374
  // src/index.ts
1324
- var VERSION = "1.0.0";
1375
+ var VERSION = "1.0.4";
1325
1376
 
1326
1377
  // src/cli/codegen.ts
1327
1378
  async function runCodegen(opts = {}) {