@dudousxd/nestjs-inertia-codegen 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -243,7 +243,7 @@ async function emitApi(routes, outDir) {
243
243
  await (0, import_promises3.mkdir)(outDir, {
244
244
  recursive: true
245
245
  });
246
- const content = buildApiFile(routes);
246
+ const content = buildApiFile(routes, outDir);
247
247
  await (0, import_promises3.writeFile)((0, import_node_path3.join)(outDir, "api.ts"), content, "utf8");
248
248
  }
249
249
  __name(emitApi, "emitApi");
@@ -316,9 +316,9 @@ function emitRouterTypeBlock(tree, indent) {
316
316
  if (node.kind === "leaf") {
317
317
  const c = node;
318
318
  const method = c.method.toUpperCase();
319
- const query = c.contractSource.query ?? "never";
320
- const body = method === "GET" ? "never" : c.contractSource.body ?? "never";
321
- const response = c.contractSource.response;
319
+ const query = c.contractSource.queryRef ? c.contractSource.queryRef.name : c.contractSource.query ?? "never";
320
+ const body = method === "GET" ? "never" : c.contractSource.bodyRef ? c.contractSource.bodyRef.name : c.contractSource.body ?? "never";
321
+ const response = c.contractSource.responseRef ? c.contractSource.responseRef.name : c.contractSource.response;
322
322
  const safeMethod = JSON.stringify(method);
323
323
  const safeUrl = JSON.stringify(c.path);
324
324
  lines.push(`${pad}${objKey}: { method: ${safeMethod}; url: ${safeUrl}; query: ${query}; body: ${body}; response: ${response} };`);
@@ -374,14 +374,43 @@ function buildRouterTypeAccess(name) {
374
374
  return `ApiRouter${segments.map((s) => `[${JSON.stringify(s)}]`).join("")}`;
375
375
  }
376
376
  __name(buildRouterTypeAccess, "buildRouterTypeAccess");
377
- function buildApiFile(routes) {
377
+ function buildApiFile(routes, outDir) {
378
378
  const contracted = routes.filter((r) => r.contract);
379
+ const importsByFile = /* @__PURE__ */ new Map();
380
+ for (const r of contracted) {
381
+ const cs = r.contract?.contractSource;
382
+ if (!cs) continue;
383
+ for (const ref of [
384
+ cs.queryRef,
385
+ cs.bodyRef,
386
+ cs.responseRef
387
+ ]) {
388
+ if (!ref) continue;
389
+ let names = importsByFile.get(ref.filePath);
390
+ if (!names) {
391
+ names = /* @__PURE__ */ new Set();
392
+ importsByFile.set(ref.filePath, names);
393
+ }
394
+ names.add(ref.name);
395
+ }
396
+ }
379
397
  const lines = [
380
398
  "// Generated by @dudousxd/nestjs-inertia-codegen. Do not edit.",
381
399
  ""
382
400
  ];
383
401
  lines.push("import { route } from './routes.js';");
384
402
  lines.push("import { createFetcher } from '@dudousxd/nestjs-inertia-client';");
403
+ if (importsByFile.size > 0 && outDir) {
404
+ lines.push("");
405
+ for (const [filePath, names] of importsByFile) {
406
+ let relPath = (0, import_node_path3.relative)(outDir, filePath).replace(/\.ts$/, "");
407
+ if (!relPath.startsWith(".")) relPath = `./${relPath}`;
408
+ const sortedNames = [
409
+ ...names
410
+ ].sort();
411
+ lines.push(`import type { ${sortedNames.join(", ")} } from '${relPath}';`);
412
+ }
413
+ }
385
414
  lines.push("");
386
415
  lines.push("export const fetcher = createFetcher();");
387
416
  lines.push("");
@@ -1126,6 +1155,53 @@ function resolveIdentifierToClassType(node, sourceFile, project, depth) {
1126
1155
  return name;
1127
1156
  }
1128
1157
  __name(resolveIdentifierToClassType, "resolveIdentifierToClassType");
1158
+ function tryResolveTypeRef(typeNode, sourceFile, project) {
1159
+ if (import_ts_morph.Node.isTypeReference(typeNode)) {
1160
+ const typeName = typeNode.getTypeName();
1161
+ const name = import_ts_morph.Node.isIdentifier(typeName) ? typeName.getText() : null;
1162
+ if (!name) return null;
1163
+ if (name === "Promise") {
1164
+ const typeArgs = typeNode.getTypeArguments();
1165
+ const first = typeArgs[0];
1166
+ if (first) return tryResolveTypeRef(first, sourceFile, project);
1167
+ return null;
1168
+ }
1169
+ if ([
1170
+ "string",
1171
+ "number",
1172
+ "boolean",
1173
+ "void",
1174
+ "unknown",
1175
+ "any",
1176
+ "Date",
1177
+ "Array"
1178
+ ].includes(name)) {
1179
+ return null;
1180
+ }
1181
+ const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
1182
+ if (localDecl && localDecl.isExported()) {
1183
+ return {
1184
+ name,
1185
+ filePath: sourceFile.getFilePath()
1186
+ };
1187
+ }
1188
+ const resolved = resolveImportedType(name, sourceFile, project);
1189
+ if (resolved && (resolved.kind === "class" || resolved.kind === "interface")) {
1190
+ const decl = resolved.decl;
1191
+ if (decl.isExported()) {
1192
+ return {
1193
+ name,
1194
+ filePath: resolved.file.getFilePath()
1195
+ };
1196
+ }
1197
+ }
1198
+ }
1199
+ if (import_ts_morph.Node.isArrayTypeNode(typeNode)) {
1200
+ return tryResolveTypeRef(typeNode.getElementTypeNode(), sourceFile, project);
1201
+ }
1202
+ return null;
1203
+ }
1204
+ __name(tryResolveTypeRef, "tryResolveTypeRef");
1129
1205
  function extractDtoContract(method, sourceFile, project) {
1130
1206
  const body = extractBodyType(method, sourceFile, project);
1131
1207
  const query = extractQueryType(method, sourceFile, project);
@@ -1134,11 +1210,61 @@ function extractDtoContract(method, sourceFile, project) {
1134
1210
  if (body === null && query === null && paramsType === null && response === "unknown") {
1135
1211
  return null;
1136
1212
  }
1213
+ let bodyRef = null;
1214
+ let queryRef = null;
1215
+ let responseRef = null;
1216
+ for (const param of method.getParameters()) {
1217
+ if (param.getDecorators().some((d) => d.getName() === "Body") && param.getTypeNode()) {
1218
+ bodyRef = tryResolveTypeRef(param.getTypeNode(), sourceFile, project);
1219
+ }
1220
+ if (param.getDecorators().some((d) => d.getName() === "Query") && param.getTypeNode()) {
1221
+ queryRef = tryResolveTypeRef(param.getTypeNode(), sourceFile, project);
1222
+ }
1223
+ }
1224
+ const returnTypeNode = method.getReturnTypeNode();
1225
+ if (returnTypeNode) {
1226
+ responseRef = tryResolveTypeRef(returnTypeNode, sourceFile, project);
1227
+ }
1228
+ if (!responseRef) {
1229
+ const apiResp = method.getDecorator("ApiResponse");
1230
+ if (apiResp) {
1231
+ const args = apiResp.getArguments();
1232
+ const optsArg = args[0];
1233
+ if (optsArg && import_ts_morph.Node.isObjectLiteralExpression(optsArg)) {
1234
+ for (const prop of optsArg.getProperties()) {
1235
+ if (import_ts_morph.Node.isPropertyAssignment(prop) && prop.getName() === "type") {
1236
+ const val = prop.getInitializer();
1237
+ if (val && import_ts_morph.Node.isIdentifier(val)) {
1238
+ const name = val.getText();
1239
+ const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
1240
+ if (localDecl && localDecl.isExported()) {
1241
+ responseRef = {
1242
+ name,
1243
+ filePath: sourceFile.getFilePath()
1244
+ };
1245
+ } else {
1246
+ const resolved = resolveImportedType(name, sourceFile, project);
1247
+ if (resolved && (resolved.kind === "class" || resolved.kind === "interface") && resolved.decl.isExported()) {
1248
+ responseRef = {
1249
+ name,
1250
+ filePath: resolved.file.getFilePath()
1251
+ };
1252
+ }
1253
+ }
1254
+ }
1255
+ }
1256
+ }
1257
+ }
1258
+ }
1259
+ }
1137
1260
  return {
1138
1261
  query,
1139
1262
  body,
1140
1263
  response,
1141
- params: paramsType
1264
+ params: paramsType,
1265
+ queryRef,
1266
+ bodyRef,
1267
+ responseRef
1142
1268
  };
1143
1269
  }
1144
1270
  __name(extractDtoContract, "extractDtoContract");
@@ -1277,7 +1403,10 @@ function extractFromSourceFile(sourceFile, project) {
1277
1403
  contractSource: {
1278
1404
  query: dtoContract.query,
1279
1405
  body: dtoContract.body,
1280
- response: dtoContract.response
1406
+ response: dtoContract.response,
1407
+ queryRef: dtoContract.queryRef,
1408
+ bodyRef: dtoContract.bodyRef,
1409
+ responseRef: dtoContract.responseRef
1281
1410
  }
1282
1411
  }
1283
1412
  } : {}
@@ -1450,7 +1579,7 @@ async function watch(config, onChange) {
1450
1579
  __name(watch, "watch");
1451
1580
 
1452
1581
  // src/index.ts
1453
- var VERSION = "2.0.1";
1582
+ var VERSION = "3.0.0";
1454
1583
  // Annotate the CommonJS export names for ESM import in node:
1455
1584
  0 && (module.exports = {
1456
1585
  CodegenError,