@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/CHANGELOG.md +11 -0
- package/dist/cli/main.cjs +137 -8
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +138 -9
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +137 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +138 -9
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
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 = "
|
|
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,
|