@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.d.cts
CHANGED
|
@@ -62,10 +62,17 @@ declare class CodegenError extends Error {
|
|
|
62
62
|
constructor(message: string, options?: ErrorOptions);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
interface TypeRef {
|
|
66
|
+
name: string;
|
|
67
|
+
filePath: string;
|
|
68
|
+
}
|
|
65
69
|
interface ContractSource {
|
|
66
70
|
query: string | null;
|
|
67
71
|
body: string | null;
|
|
68
72
|
response: string;
|
|
73
|
+
queryRef?: TypeRef | null;
|
|
74
|
+
bodyRef?: TypeRef | null;
|
|
75
|
+
responseRef?: TypeRef | null;
|
|
69
76
|
}
|
|
70
77
|
interface ContractDescriptor {
|
|
71
78
|
contractSource: ContractSource;
|
|
@@ -120,6 +127,6 @@ declare function acquireLock(outDir: string): Promise<{
|
|
|
120
127
|
release: () => Promise<void>;
|
|
121
128
|
} | null>;
|
|
122
129
|
|
|
123
|
-
declare const VERSION = "
|
|
130
|
+
declare const VERSION = "3.0.0";
|
|
124
131
|
|
|
125
132
|
export { CodegenError, ConfigError, type ResolvedConfig, type ScopeConfig, type UserConfig, VERSION, type Watcher, acquireLock, defineConfig, generate, loadConfig, watch };
|
package/dist/index.d.ts
CHANGED
|
@@ -62,10 +62,17 @@ declare class CodegenError extends Error {
|
|
|
62
62
|
constructor(message: string, options?: ErrorOptions);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
interface TypeRef {
|
|
66
|
+
name: string;
|
|
67
|
+
filePath: string;
|
|
68
|
+
}
|
|
65
69
|
interface ContractSource {
|
|
66
70
|
query: string | null;
|
|
67
71
|
body: string | null;
|
|
68
72
|
response: string;
|
|
73
|
+
queryRef?: TypeRef | null;
|
|
74
|
+
bodyRef?: TypeRef | null;
|
|
75
|
+
responseRef?: TypeRef | null;
|
|
69
76
|
}
|
|
70
77
|
interface ContractDescriptor {
|
|
71
78
|
contractSource: ContractSource;
|
|
@@ -120,6 +127,6 @@ declare function acquireLock(outDir: string): Promise<{
|
|
|
120
127
|
release: () => Promise<void>;
|
|
121
128
|
} | null>;
|
|
122
129
|
|
|
123
|
-
declare const VERSION = "
|
|
130
|
+
declare const VERSION = "3.0.0";
|
|
124
131
|
|
|
125
132
|
export { CodegenError, ConfigError, type ResolvedConfig, type ScopeConfig, type UserConfig, VERSION, type Watcher, acquireLock, defineConfig, generate, loadConfig, watch };
|
package/dist/index.js
CHANGED
|
@@ -197,12 +197,12 @@ __name(extractPropsSource, "extractPropsSource");
|
|
|
197
197
|
|
|
198
198
|
// src/emit/emit-api.ts
|
|
199
199
|
import { mkdir, writeFile } from "fs/promises";
|
|
200
|
-
import { join as join2 } from "path";
|
|
200
|
+
import { join as join2, relative as relative3 } from "path";
|
|
201
201
|
async function emitApi(routes, outDir) {
|
|
202
202
|
await mkdir(outDir, {
|
|
203
203
|
recursive: true
|
|
204
204
|
});
|
|
205
|
-
const content = buildApiFile(routes);
|
|
205
|
+
const content = buildApiFile(routes, outDir);
|
|
206
206
|
await writeFile(join2(outDir, "api.ts"), content, "utf8");
|
|
207
207
|
}
|
|
208
208
|
__name(emitApi, "emitApi");
|
|
@@ -275,9 +275,9 @@ function emitRouterTypeBlock(tree, indent) {
|
|
|
275
275
|
if (node.kind === "leaf") {
|
|
276
276
|
const c = node;
|
|
277
277
|
const method = c.method.toUpperCase();
|
|
278
|
-
const query = c.contractSource.query ?? "never";
|
|
279
|
-
const body = method === "GET" ? "never" : c.contractSource.body ?? "never";
|
|
280
|
-
const response = c.contractSource.response;
|
|
278
|
+
const query = c.contractSource.queryRef ? c.contractSource.queryRef.name : c.contractSource.query ?? "never";
|
|
279
|
+
const body = method === "GET" ? "never" : c.contractSource.bodyRef ? c.contractSource.bodyRef.name : c.contractSource.body ?? "never";
|
|
280
|
+
const response = c.contractSource.responseRef ? c.contractSource.responseRef.name : c.contractSource.response;
|
|
281
281
|
const safeMethod = JSON.stringify(method);
|
|
282
282
|
const safeUrl = JSON.stringify(c.path);
|
|
283
283
|
lines.push(`${pad}${objKey}: { method: ${safeMethod}; url: ${safeUrl}; query: ${query}; body: ${body}; response: ${response} };`);
|
|
@@ -333,14 +333,43 @@ function buildRouterTypeAccess(name) {
|
|
|
333
333
|
return `ApiRouter${segments.map((s) => `[${JSON.stringify(s)}]`).join("")}`;
|
|
334
334
|
}
|
|
335
335
|
__name(buildRouterTypeAccess, "buildRouterTypeAccess");
|
|
336
|
-
function buildApiFile(routes) {
|
|
336
|
+
function buildApiFile(routes, outDir) {
|
|
337
337
|
const contracted = routes.filter((r) => r.contract);
|
|
338
|
+
const importsByFile = /* @__PURE__ */ new Map();
|
|
339
|
+
for (const r of contracted) {
|
|
340
|
+
const cs = r.contract?.contractSource;
|
|
341
|
+
if (!cs) continue;
|
|
342
|
+
for (const ref of [
|
|
343
|
+
cs.queryRef,
|
|
344
|
+
cs.bodyRef,
|
|
345
|
+
cs.responseRef
|
|
346
|
+
]) {
|
|
347
|
+
if (!ref) continue;
|
|
348
|
+
let names = importsByFile.get(ref.filePath);
|
|
349
|
+
if (!names) {
|
|
350
|
+
names = /* @__PURE__ */ new Set();
|
|
351
|
+
importsByFile.set(ref.filePath, names);
|
|
352
|
+
}
|
|
353
|
+
names.add(ref.name);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
338
356
|
const lines = [
|
|
339
357
|
"// Generated by @dudousxd/nestjs-inertia-codegen. Do not edit.",
|
|
340
358
|
""
|
|
341
359
|
];
|
|
342
360
|
lines.push("import { route } from './routes.js';");
|
|
343
361
|
lines.push("import { createFetcher } from '@dudousxd/nestjs-inertia-client';");
|
|
362
|
+
if (importsByFile.size > 0 && outDir) {
|
|
363
|
+
lines.push("");
|
|
364
|
+
for (const [filePath, names] of importsByFile) {
|
|
365
|
+
let relPath = relative3(outDir, filePath).replace(/\.ts$/, "");
|
|
366
|
+
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
367
|
+
const sortedNames = [
|
|
368
|
+
...names
|
|
369
|
+
].sort();
|
|
370
|
+
lines.push(`import type { ${sortedNames.join(", ")} } from '${relPath}';`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
344
373
|
lines.push("");
|
|
345
374
|
lines.push("export const fetcher = createFetcher();");
|
|
346
375
|
lines.push("");
|
|
@@ -1085,6 +1114,53 @@ function resolveIdentifierToClassType(node, sourceFile, project, depth) {
|
|
|
1085
1114
|
return name;
|
|
1086
1115
|
}
|
|
1087
1116
|
__name(resolveIdentifierToClassType, "resolveIdentifierToClassType");
|
|
1117
|
+
function tryResolveTypeRef(typeNode, sourceFile, project) {
|
|
1118
|
+
if (Node.isTypeReference(typeNode)) {
|
|
1119
|
+
const typeName = typeNode.getTypeName();
|
|
1120
|
+
const name = Node.isIdentifier(typeName) ? typeName.getText() : null;
|
|
1121
|
+
if (!name) return null;
|
|
1122
|
+
if (name === "Promise") {
|
|
1123
|
+
const typeArgs = typeNode.getTypeArguments();
|
|
1124
|
+
const first = typeArgs[0];
|
|
1125
|
+
if (first) return tryResolveTypeRef(first, sourceFile, project);
|
|
1126
|
+
return null;
|
|
1127
|
+
}
|
|
1128
|
+
if ([
|
|
1129
|
+
"string",
|
|
1130
|
+
"number",
|
|
1131
|
+
"boolean",
|
|
1132
|
+
"void",
|
|
1133
|
+
"unknown",
|
|
1134
|
+
"any",
|
|
1135
|
+
"Date",
|
|
1136
|
+
"Array"
|
|
1137
|
+
].includes(name)) {
|
|
1138
|
+
return null;
|
|
1139
|
+
}
|
|
1140
|
+
const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
|
|
1141
|
+
if (localDecl && localDecl.isExported()) {
|
|
1142
|
+
return {
|
|
1143
|
+
name,
|
|
1144
|
+
filePath: sourceFile.getFilePath()
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
const resolved = resolveImportedType(name, sourceFile, project);
|
|
1148
|
+
if (resolved && (resolved.kind === "class" || resolved.kind === "interface")) {
|
|
1149
|
+
const decl = resolved.decl;
|
|
1150
|
+
if (decl.isExported()) {
|
|
1151
|
+
return {
|
|
1152
|
+
name,
|
|
1153
|
+
filePath: resolved.file.getFilePath()
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
if (Node.isArrayTypeNode(typeNode)) {
|
|
1159
|
+
return tryResolveTypeRef(typeNode.getElementTypeNode(), sourceFile, project);
|
|
1160
|
+
}
|
|
1161
|
+
return null;
|
|
1162
|
+
}
|
|
1163
|
+
__name(tryResolveTypeRef, "tryResolveTypeRef");
|
|
1088
1164
|
function extractDtoContract(method, sourceFile, project) {
|
|
1089
1165
|
const body = extractBodyType(method, sourceFile, project);
|
|
1090
1166
|
const query = extractQueryType(method, sourceFile, project);
|
|
@@ -1093,11 +1169,61 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
1093
1169
|
if (body === null && query === null && paramsType === null && response === "unknown") {
|
|
1094
1170
|
return null;
|
|
1095
1171
|
}
|
|
1172
|
+
let bodyRef = null;
|
|
1173
|
+
let queryRef = null;
|
|
1174
|
+
let responseRef = null;
|
|
1175
|
+
for (const param of method.getParameters()) {
|
|
1176
|
+
if (param.getDecorators().some((d) => d.getName() === "Body") && param.getTypeNode()) {
|
|
1177
|
+
bodyRef = tryResolveTypeRef(param.getTypeNode(), sourceFile, project);
|
|
1178
|
+
}
|
|
1179
|
+
if (param.getDecorators().some((d) => d.getName() === "Query") && param.getTypeNode()) {
|
|
1180
|
+
queryRef = tryResolveTypeRef(param.getTypeNode(), sourceFile, project);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
const returnTypeNode = method.getReturnTypeNode();
|
|
1184
|
+
if (returnTypeNode) {
|
|
1185
|
+
responseRef = tryResolveTypeRef(returnTypeNode, sourceFile, project);
|
|
1186
|
+
}
|
|
1187
|
+
if (!responseRef) {
|
|
1188
|
+
const apiResp = method.getDecorator("ApiResponse");
|
|
1189
|
+
if (apiResp) {
|
|
1190
|
+
const args = apiResp.getArguments();
|
|
1191
|
+
const optsArg = args[0];
|
|
1192
|
+
if (optsArg && Node.isObjectLiteralExpression(optsArg)) {
|
|
1193
|
+
for (const prop of optsArg.getProperties()) {
|
|
1194
|
+
if (Node.isPropertyAssignment(prop) && prop.getName() === "type") {
|
|
1195
|
+
const val = prop.getInitializer();
|
|
1196
|
+
if (val && Node.isIdentifier(val)) {
|
|
1197
|
+
const name = val.getText();
|
|
1198
|
+
const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
|
|
1199
|
+
if (localDecl && localDecl.isExported()) {
|
|
1200
|
+
responseRef = {
|
|
1201
|
+
name,
|
|
1202
|
+
filePath: sourceFile.getFilePath()
|
|
1203
|
+
};
|
|
1204
|
+
} else {
|
|
1205
|
+
const resolved = resolveImportedType(name, sourceFile, project);
|
|
1206
|
+
if (resolved && (resolved.kind === "class" || resolved.kind === "interface") && resolved.decl.isExported()) {
|
|
1207
|
+
responseRef = {
|
|
1208
|
+
name,
|
|
1209
|
+
filePath: resolved.file.getFilePath()
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1096
1219
|
return {
|
|
1097
1220
|
query,
|
|
1098
1221
|
body,
|
|
1099
1222
|
response,
|
|
1100
|
-
params: paramsType
|
|
1223
|
+
params: paramsType,
|
|
1224
|
+
queryRef,
|
|
1225
|
+
bodyRef,
|
|
1226
|
+
responseRef
|
|
1101
1227
|
};
|
|
1102
1228
|
}
|
|
1103
1229
|
__name(extractDtoContract, "extractDtoContract");
|
|
@@ -1236,7 +1362,10 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
1236
1362
|
contractSource: {
|
|
1237
1363
|
query: dtoContract.query,
|
|
1238
1364
|
body: dtoContract.body,
|
|
1239
|
-
response: dtoContract.response
|
|
1365
|
+
response: dtoContract.response,
|
|
1366
|
+
queryRef: dtoContract.queryRef,
|
|
1367
|
+
bodyRef: dtoContract.bodyRef,
|
|
1368
|
+
responseRef: dtoContract.responseRef
|
|
1240
1369
|
}
|
|
1241
1370
|
}
|
|
1242
1371
|
} : {}
|
|
@@ -1409,7 +1538,7 @@ async function watch(config, onChange) {
|
|
|
1409
1538
|
__name(watch, "watch");
|
|
1410
1539
|
|
|
1411
1540
|
// src/index.ts
|
|
1412
|
-
var VERSION = "
|
|
1541
|
+
var VERSION = "3.0.0";
|
|
1413
1542
|
export {
|
|
1414
1543
|
CodegenError,
|
|
1415
1544
|
ConfigError,
|