@dudousxd/nestjs-inertia-codegen 1.0.7 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/main.js CHANGED
@@ -185,12 +185,12 @@ __name(extractPropsSource, "extractPropsSource");
185
185
 
186
186
  // src/emit/emit-api.ts
187
187
  import { mkdir, writeFile } from "fs/promises";
188
- import { join as join2 } from "path";
188
+ import { join as join2, relative as relative3 } from "path";
189
189
  async function emitApi(routes, outDir) {
190
190
  await mkdir(outDir, {
191
191
  recursive: true
192
192
  });
193
- const content = buildApiFile(routes);
193
+ const content = buildApiFile(routes, outDir);
194
194
  await writeFile(join2(outDir, "api.ts"), content, "utf8");
195
195
  }
196
196
  __name(emitApi, "emitApi");
@@ -255,7 +255,20 @@ function insertIntoTree(tree, segments, leaf, fullName) {
255
255
  }
256
256
  }
257
257
  __name(insertIntoTree, "insertIntoTree");
258
- function emitRouterTypeBlock(tree, indent) {
258
+ function buildResponseType(c, outDir) {
259
+ if (c.controllerRef) {
260
+ let relPath = relative3(outDir, c.controllerRef.filePath).replace(/\.ts$/, "");
261
+ if (!relPath.startsWith(".")) relPath = `./${relPath}`;
262
+ return `Awaited<ReturnType<import('${relPath}').${c.controllerRef.className}['${c.controllerRef.methodName}']>>`;
263
+ }
264
+ const respRef = c.contractSource.responseRef;
265
+ if (respRef) {
266
+ return respRef.isArray ? `Array<${respRef.name}>` : respRef.name;
267
+ }
268
+ return c.contractSource.response;
269
+ }
270
+ __name(buildResponseType, "buildResponseType");
271
+ function emitRouterTypeBlock(tree, indent, outDir) {
259
272
  const pad = " ".repeat(indent);
260
273
  const lines = [];
261
274
  for (const [key, node] of tree) {
@@ -263,15 +276,17 @@ function emitRouterTypeBlock(tree, indent) {
263
276
  if (node.kind === "leaf") {
264
277
  const c = node;
265
278
  const method = c.method.toUpperCase();
266
- const query = c.contractSource.query ?? "never";
267
- const body = method === "GET" ? "never" : c.contractSource.body ?? "never";
268
- const response = c.contractSource.response;
279
+ const queryRef = c.contractSource.queryRef;
280
+ const query = queryRef ? queryRef.isArray ? `Array<${queryRef.name}>` : queryRef.name : c.contractSource.query ?? "never";
281
+ const bodyRef = c.contractSource.bodyRef;
282
+ const body = method === "GET" ? "never" : bodyRef ? bodyRef.isArray ? `Array<${bodyRef.name}>` : bodyRef.name : c.contractSource.body ?? "never";
283
+ const response = buildResponseType(c, outDir);
269
284
  const safeMethod = JSON.stringify(method);
270
285
  const safeUrl = JSON.stringify(c.path);
271
286
  lines.push(`${pad}${objKey}: { method: ${safeMethod}; url: ${safeUrl}; query: ${query}; body: ${body}; response: ${response} };`);
272
287
  } else {
273
288
  lines.push(`${pad}${objKey}: {`);
274
- lines.push(...emitRouterTypeBlock(node.children, indent + 2));
289
+ lines.push(...emitRouterTypeBlock(node.children, indent + 2, outDir));
275
290
  lines.push(`${pad}};`);
276
291
  }
277
292
  }
@@ -292,18 +307,21 @@ function emitApiObjectBlock(tree, indent) {
292
307
  if (method === "GET") {
293
308
  const typeAccess = buildRouterTypeAccess(c.name);
294
309
  lines.push(`${pad}${objKey}: {`);
310
+ lines.push(`${pad} queryKey: (query?: ${typeAccess}['query']) => query !== undefined ? [${flatName}, query] as const : [${flatName}] as const,`);
295
311
  lines.push(`${pad} queryOptions: (query?: ${typeAccess}['query']) =>`);
296
- lines.push(`${pad} queryOptions({`);
297
- lines.push(`${pad} queryKey: [${flatName}, query],`);
312
+ lines.push(`${pad} _queryOptions({`);
313
+ lines.push(`${pad} queryKey: query !== undefined ? [${flatName}, query] as const : [${flatName}] as const,`);
298
314
  lines.push(`${pad} queryFn: () => fetcher.get<${typeAccess}['response']>(route(${flatName} as never) || ${safePath}, { query }),`);
299
315
  lines.push(`${pad} }),`);
300
316
  lines.push(`${pad}},`);
301
317
  } else {
302
318
  const typeAccess = buildRouterTypeAccess(c.name);
303
319
  lines.push(`${pad}${objKey}: {`);
304
- lines.push(`${pad} mutationOptions: () => ({`);
305
- lines.push(`${pad} mutationFn: (body: ${typeAccess}['body']) => fetcher.${fetcherMethod}<${typeAccess}['response']>(route(${flatName} as never) || ${safePath}, { body }),`);
306
- lines.push(`${pad} }),`);
320
+ lines.push(`${pad} queryKey: () => [${flatName}] as const,`);
321
+ lines.push(`${pad} mutationOptions: () =>`);
322
+ lines.push(`${pad} _mutationOptions({`);
323
+ lines.push(`${pad} mutationFn: (body: ${typeAccess}['body']) => fetcher.${fetcherMethod}<${typeAccess}['response']>(route(${flatName} as never) || ${safePath}, { body }),`);
324
+ lines.push(`${pad} }),`);
307
325
  lines.push(`${pad}},`);
308
326
  }
309
327
  } else {
@@ -320,18 +338,55 @@ function buildRouterTypeAccess(name) {
320
338
  return `ApiRouter${segments.map((s) => `[${JSON.stringify(s)}]`).join("")}`;
321
339
  }
322
340
  __name(buildRouterTypeAccess, "buildRouterTypeAccess");
323
- function buildApiFile(routes) {
341
+ function buildApiFile(routes, outDir) {
324
342
  const contracted = routes.filter((r) => r.contract);
343
+ const importsByFile = /* @__PURE__ */ new Map();
344
+ for (const r of contracted) {
345
+ const cs = r.contract?.contractSource;
346
+ if (!cs) continue;
347
+ const refs = r.controllerRef ? [
348
+ cs.queryRef,
349
+ cs.bodyRef
350
+ ] : [
351
+ cs.queryRef,
352
+ cs.bodyRef,
353
+ cs.responseRef
354
+ ];
355
+ for (const ref of refs) {
356
+ if (!ref) continue;
357
+ let names = importsByFile.get(ref.filePath);
358
+ if (!names) {
359
+ names = /* @__PURE__ */ new Set();
360
+ importsByFile.set(ref.filePath, names);
361
+ }
362
+ names.add(ref.name);
363
+ }
364
+ }
325
365
  const hasGetRoutes = contracted.some((r) => r.method === "GET");
366
+ const hasMutationRoutes = contracted.some((r) => r.method !== "GET");
326
367
  const lines = [
327
368
  "// Generated by @dudousxd/nestjs-inertia-codegen. Do not edit.",
328
369
  ""
329
370
  ];
330
- if (hasGetRoutes) {
331
- lines.push("import { queryOptions } from '@tanstack/query-core';");
371
+ const tqImports = [];
372
+ if (hasGetRoutes) tqImports.push("queryOptions as _queryOptions");
373
+ if (hasMutationRoutes) tqImports.push("mutationOptions as _mutationOptions");
374
+ if (tqImports.length > 0) {
375
+ lines.push(`import { ${tqImports.join(", ")} } from '@tanstack/react-query';`);
332
376
  }
333
377
  lines.push("import { route } from './routes.js';");
334
378
  lines.push("import { createFetcher } from '@dudousxd/nestjs-inertia-client';");
379
+ if (importsByFile.size > 0 && outDir) {
380
+ lines.push("");
381
+ for (const [filePath, names] of importsByFile) {
382
+ let relPath = relative3(outDir, filePath).replace(/\.ts$/, "");
383
+ if (!relPath.startsWith(".")) relPath = `./${relPath}`;
384
+ const sortedNames = [
385
+ ...names
386
+ ].sort();
387
+ lines.push(`import type { ${sortedNames.join(", ")} } from '${relPath}';`);
388
+ }
389
+ }
335
390
  lines.push("");
336
391
  lines.push("export const fetcher = createFetcher();");
337
392
  lines.push("");
@@ -372,13 +427,14 @@ function buildApiFile(routes) {
372
427
  method: r.method,
373
428
  name,
374
429
  path: r.path,
430
+ controllerRef: r.controllerRef,
375
431
  contractSource: c.contractSource
376
432
  };
377
433
  insertIntoTree(tree, segments, leaf, name);
378
434
  }
379
435
  void detectCollisions;
380
436
  lines.push("export type ApiRouter = {");
381
- lines.push(...emitRouterTypeBlock(tree, 2));
437
+ lines.push(...emitRouterTypeBlock(tree, 2, outDir ?? ""));
382
438
  lines.push("};");
383
439
  lines.push("");
384
440
  lines.push("export const api = {");
@@ -648,9 +704,28 @@ import { join as join9 } from "path";
648
704
  import chokidar from "chokidar";
649
705
 
650
706
  // src/discovery/contracts-fast.ts
707
+ import { readFileSync } from "fs";
651
708
  import { dirname, join as join7, resolve as resolve2 } from "path";
652
709
  import fg2 from "fast-glob";
653
710
  import { Node, Project, SyntaxKind } from "ts-morph";
711
+ var _projectRoot = "";
712
+ var _tsconfigPaths = null;
713
+ var _debug = process.env.NESTJS_INERTIA_DEBUG === "1";
714
+ function dbg(...args) {
715
+ if (_debug) console.log("[codegen:debug]", ...args);
716
+ }
717
+ __name(dbg, "dbg");
718
+ function loadTsconfigPaths(tsconfigPath) {
719
+ try {
720
+ const raw = readFileSync(tsconfigPath, "utf8");
721
+ const stripped = raw.replace(/\/\/.*$/gm, "");
722
+ const parsed = JSON.parse(stripped);
723
+ return parsed.compilerOptions?.paths ?? null;
724
+ } catch {
725
+ return null;
726
+ }
727
+ }
728
+ __name(loadTsconfigPaths, "loadTsconfigPaths");
654
729
  async function discoverContractsFast(opts) {
655
730
  const { cwd, glob, tsconfig } = opts;
656
731
  const tsconfigPath = tsconfig ? resolve2(tsconfig) : join7(cwd, "tsconfig.json");
@@ -683,6 +758,8 @@ async function discoverContractsFast(opts) {
683
758
  project.addSourceFileAtPath(f);
684
759
  }
685
760
  const routes = [];
761
+ _projectRoot = cwd;
762
+ _tsconfigPaths = loadTsconfigPaths(tsconfigPath);
686
763
  for (const sourceFile of project.getSourceFiles()) {
687
764
  routes.push(...extractFromSourceFile(sourceFile, project));
688
765
  }
@@ -884,17 +961,41 @@ function findTypeInFile(name, file) {
884
961
  return null;
885
962
  }
886
963
  __name(findTypeInFile, "findTypeInFile");
964
+ function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
965
+ if (moduleSpecifier.startsWith(".")) {
966
+ const dir = dirname(sourceFile.getFilePath());
967
+ return [
968
+ resolve2(dir, `${moduleSpecifier}.ts`),
969
+ resolve2(dir, moduleSpecifier, "index.ts")
970
+ ];
971
+ }
972
+ const baseUrl = _projectRoot;
973
+ dbg("resolveModuleSpecifier", moduleSpecifier, "paths:", JSON.stringify(_tsconfigPaths), "baseUrl:", baseUrl);
974
+ if (_tsconfigPaths) {
975
+ for (const [pattern, mappings] of Object.entries(_tsconfigPaths)) {
976
+ const prefix = pattern.replace("*", "");
977
+ if (moduleSpecifier.startsWith(prefix)) {
978
+ const rest = moduleSpecifier.slice(prefix.length);
979
+ const candidates = [];
980
+ for (const mapping of mappings) {
981
+ const resolved = resolve2(baseUrl, mapping.replace("*", rest));
982
+ candidates.push(`${resolved}.ts`, resolve2(resolved, "index.ts"));
983
+ }
984
+ dbg(" resolved candidates:", candidates);
985
+ return candidates;
986
+ }
987
+ }
988
+ }
989
+ return [];
990
+ }
991
+ __name(resolveModuleSpecifier, "resolveModuleSpecifier");
887
992
  function resolveImportedType(name, sourceFile, project) {
888
993
  for (const importDecl of sourceFile.getImportDeclarations()) {
889
994
  const namedImport = importDecl.getNamedImports().find((n) => n.getName() === name);
890
995
  if (!namedImport) continue;
891
996
  const moduleSpecifier = importDecl.getModuleSpecifierValue();
892
- if (!moduleSpecifier.startsWith(".")) return null;
893
- const dir = dirname(sourceFile.getFilePath());
894
- const candidates = [
895
- resolve2(dir, `${moduleSpecifier}.ts`),
896
- resolve2(dir, moduleSpecifier, "index.ts")
897
- ];
997
+ const candidates = resolveModuleSpecifier(moduleSpecifier, sourceFile, project);
998
+ if (candidates.length === 0) continue;
898
999
  for (const candidate of candidates) {
899
1000
  let importedFile = project.getSourceFile(candidate);
900
1001
  if (!importedFile) {
@@ -928,7 +1029,8 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth) {
928
1029
  const name = Node.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
929
1030
  if (name === "string" || name === "number" || name === "boolean") return name;
930
1031
  if (name === "Date") return "string";
931
- if (name === "unknown" || name === "any") return "unknown";
1032
+ if (name === "unknown" || name === "any" || name === "void") return "unknown";
1033
+ if (name === "StreamableFile" || name === "Observable" || name === "ReadableStream") return "unknown";
932
1034
  if (name === "Array") {
933
1035
  const typeArgs = typeNode.getTypeArguments();
934
1036
  const firstTypeArg = typeArgs[0];
@@ -937,6 +1039,18 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth) {
937
1039
  }
938
1040
  return "Array<unknown>";
939
1041
  }
1042
+ if ([
1043
+ "Record",
1044
+ "Omit",
1045
+ "Pick",
1046
+ "Partial",
1047
+ "Required",
1048
+ "Readonly",
1049
+ "Map",
1050
+ "Set"
1051
+ ].includes(name)) {
1052
+ return typeNode.getText();
1053
+ }
940
1054
  if (name === "Promise") {
941
1055
  const typeArgs = typeNode.getTypeArguments();
942
1056
  const firstTypeArg = typeArgs[0];
@@ -949,7 +1063,8 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth) {
949
1063
  if (resolved) {
950
1064
  return expandTypeDecl(resolved, project, depth - 1);
951
1065
  }
952
- return name;
1066
+ dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
1067
+ return "unknown";
953
1068
  }
954
1069
  const kind = typeNode.getKind();
955
1070
  if (kind === SyntaxKind.StringKeyword) return "string";
@@ -1076,6 +1191,68 @@ function resolveIdentifierToClassType(node, sourceFile, project, depth) {
1076
1191
  return name;
1077
1192
  }
1078
1193
  __name(resolveIdentifierToClassType, "resolveIdentifierToClassType");
1194
+ function tryResolveTypeRef(typeNode, sourceFile, project) {
1195
+ if (Node.isTypeReference(typeNode)) {
1196
+ const typeName = typeNode.getTypeName();
1197
+ const name = Node.isIdentifier(typeName) ? typeName.getText() : null;
1198
+ if (!name) return null;
1199
+ if (name === "Promise") {
1200
+ const typeArgs = typeNode.getTypeArguments();
1201
+ const first = typeArgs[0];
1202
+ if (first) return tryResolveTypeRef(first, sourceFile, project);
1203
+ return null;
1204
+ }
1205
+ if (name === "Array") {
1206
+ const typeArgs = typeNode.getTypeArguments();
1207
+ const first = typeArgs[0];
1208
+ if (first) {
1209
+ const inner = tryResolveTypeRef(first, sourceFile, project);
1210
+ if (inner) return {
1211
+ ...inner,
1212
+ isArray: true
1213
+ };
1214
+ }
1215
+ return null;
1216
+ }
1217
+ if ([
1218
+ "string",
1219
+ "number",
1220
+ "boolean",
1221
+ "void",
1222
+ "unknown",
1223
+ "any",
1224
+ "Date"
1225
+ ].includes(name)) {
1226
+ return null;
1227
+ }
1228
+ const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
1229
+ if (localDecl?.isExported()) {
1230
+ return {
1231
+ name,
1232
+ filePath: sourceFile.getFilePath()
1233
+ };
1234
+ }
1235
+ const resolved = resolveImportedType(name, sourceFile, project);
1236
+ if (resolved && (resolved.kind === "class" || resolved.kind === "interface")) {
1237
+ const decl = resolved.decl;
1238
+ if (decl.isExported()) {
1239
+ return {
1240
+ name,
1241
+ filePath: resolved.file.getFilePath()
1242
+ };
1243
+ }
1244
+ }
1245
+ }
1246
+ if (Node.isArrayTypeNode(typeNode)) {
1247
+ const inner = tryResolveTypeRef(typeNode.getElementTypeNode(), sourceFile, project);
1248
+ if (inner) return {
1249
+ ...inner,
1250
+ isArray: true
1251
+ };
1252
+ }
1253
+ return null;
1254
+ }
1255
+ __name(tryResolveTypeRef, "tryResolveTypeRef");
1079
1256
  function extractDtoContract(method, sourceFile, project) {
1080
1257
  const body = extractBodyType(method, sourceFile, project);
1081
1258
  const query = extractQueryType(method, sourceFile, project);
@@ -1084,11 +1261,61 @@ function extractDtoContract(method, sourceFile, project) {
1084
1261
  if (body === null && query === null && paramsType === null && response === "unknown") {
1085
1262
  return null;
1086
1263
  }
1264
+ let bodyRef = null;
1265
+ let queryRef = null;
1266
+ let responseRef = null;
1267
+ for (const param of method.getParameters()) {
1268
+ if (param.getDecorators().some((d) => d.getName() === "Body") && param.getTypeNode()) {
1269
+ bodyRef = tryResolveTypeRef(param.getTypeNode(), sourceFile, project);
1270
+ }
1271
+ if (param.getDecorators().some((d) => d.getName() === "Query") && param.getTypeNode()) {
1272
+ queryRef = tryResolveTypeRef(param.getTypeNode(), sourceFile, project);
1273
+ }
1274
+ }
1275
+ const returnTypeNode = method.getReturnTypeNode();
1276
+ if (returnTypeNode) {
1277
+ responseRef = tryResolveTypeRef(returnTypeNode, sourceFile, project);
1278
+ }
1279
+ if (!responseRef) {
1280
+ const apiResp = method.getDecorator("ApiResponse");
1281
+ if (apiResp) {
1282
+ const args = apiResp.getArguments();
1283
+ const optsArg = args[0];
1284
+ if (optsArg && Node.isObjectLiteralExpression(optsArg)) {
1285
+ for (const prop of optsArg.getProperties()) {
1286
+ if (Node.isPropertyAssignment(prop) && prop.getName() === "type") {
1287
+ const val = prop.getInitializer();
1288
+ if (val && Node.isIdentifier(val)) {
1289
+ const name = val.getText();
1290
+ const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
1291
+ if (localDecl?.isExported()) {
1292
+ responseRef = {
1293
+ name,
1294
+ filePath: sourceFile.getFilePath()
1295
+ };
1296
+ } else {
1297
+ const resolved = resolveImportedType(name, sourceFile, project);
1298
+ if (resolved && (resolved.kind === "class" || resolved.kind === "interface") && resolved.decl.isExported()) {
1299
+ responseRef = {
1300
+ name,
1301
+ filePath: resolved.file.getFilePath()
1302
+ };
1303
+ }
1304
+ }
1305
+ }
1306
+ }
1307
+ }
1308
+ }
1309
+ }
1310
+ }
1087
1311
  return {
1088
1312
  query,
1089
1313
  body,
1090
1314
  response,
1091
- params: paramsType
1315
+ params: paramsType,
1316
+ queryRef,
1317
+ bodyRef,
1318
+ responseRef
1092
1319
  };
1093
1320
  }
1094
1321
  __name(extractDtoContract, "extractDtoContract");
@@ -1187,6 +1414,11 @@ function extractFromSourceFile(sourceFile, project) {
1187
1414
  path: combined,
1188
1415
  name: routeName,
1189
1416
  params,
1417
+ controllerRef: {
1418
+ className,
1419
+ methodName,
1420
+ filePath: sourceFile.getFilePath()
1421
+ },
1190
1422
  contract: {
1191
1423
  contractSource: {
1192
1424
  query: contractDef.query,
@@ -1221,13 +1453,20 @@ function extractFromSourceFile(sourceFile, project) {
1221
1453
  path: combined,
1222
1454
  name: routeName,
1223
1455
  params,
1224
- // Attach contract if DTO extraction produced useful type info
1456
+ controllerRef: {
1457
+ className,
1458
+ methodName,
1459
+ filePath: sourceFile.getFilePath()
1460
+ },
1225
1461
  ...dtoContract ? {
1226
1462
  contract: {
1227
1463
  contractSource: {
1228
1464
  query: dtoContract.query,
1229
1465
  body: dtoContract.body,
1230
- response: dtoContract.response
1466
+ response: dtoContract.response,
1467
+ queryRef: dtoContract.queryRef,
1468
+ bodyRef: dtoContract.bodyRef,
1469
+ responseRef: dtoContract.responseRef
1231
1470
  }
1232
1471
  }
1233
1472
  } : {}
@@ -1400,7 +1639,7 @@ async function watch(config, onChange) {
1400
1639
  __name(watch, "watch");
1401
1640
 
1402
1641
  // src/index.ts
1403
- var VERSION = "1.0.7";
1642
+ var VERSION = "1.3.0";
1404
1643
 
1405
1644
  // src/cli/codegen.ts
1406
1645
  async function runCodegen(opts = {}) {
@@ -1432,7 +1671,7 @@ __name(runCodegen, "runCodegen");
1432
1671
 
1433
1672
  // src/cli/init.ts
1434
1673
  import { execSync } from "child_process";
1435
- import { readFileSync, writeFileSync } from "fs";
1674
+ import { readFileSync as readFileSync2, writeFileSync } from "fs";
1436
1675
  import { access as access2, mkdir as mkdir7, readFile as readFile4, writeFile as writeFile7 } from "fs/promises";
1437
1676
  import { join as join10 } from "path";
1438
1677
  import { createInterface } from "readline";
@@ -1656,7 +1895,7 @@ __name(findAfterLastImport, "findAfterLastImport");
1656
1895
  function patchAppModule(filePath, rootView) {
1657
1896
  let content;
1658
1897
  try {
1659
- content = readFileSync(filePath, "utf8");
1898
+ content = readFileSync2(filePath, "utf8");
1660
1899
  } catch {
1661
1900
  return "skipped";
1662
1901
  }
@@ -1701,7 +1940,7 @@ __name(patchAppModule, "patchAppModule");
1701
1940
  function patchMainTs(filePath) {
1702
1941
  let content;
1703
1942
  try {
1704
- content = readFileSync(filePath, "utf8");
1943
+ content = readFileSync2(filePath, "utf8");
1705
1944
  } catch {
1706
1945
  return "skipped";
1707
1946
  }
@@ -1774,11 +2013,19 @@ function htmlShellTemplate(framework, _engine) {
1774
2013
  __name(htmlShellTemplate, "htmlShellTemplate");
1775
2014
  function viteConfigTemplate(framework) {
1776
2015
  const pluginOption = `{ ${framework}: true }`;
1777
- return `import { defineConfig } from 'vite';
2016
+ return `import { resolve } from 'node:path';
2017
+ import { defineConfig } from 'vite';
1778
2018
  import nestInertia from '@dudousxd/nestjs-inertia-vite/plugin';
1779
2019
 
1780
2020
  export default defineConfig({
1781
2021
  plugins: [nestInertia(${pluginOption})],
2022
+ resolve: {
2023
+ alias: {
2024
+ '@': resolve(__dirname, 'src'),
2025
+ '~': resolve(__dirname, 'inertia'),
2026
+ '~codegen': resolve(__dirname, '.nestjs-inertia'),
2027
+ },
2028
+ },
1782
2029
  });
1783
2030
  `;
1784
2031
  }