@dudousxd/nestjs-codegen 0.15.0 → 0.17.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 +56 -0
- package/dist/cli/main.cjs +299 -147
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +239 -87
- package/dist/cli/main.js.map +1 -1
- package/dist/extension/index.cjs.map +1 -1
- package/dist/extension/index.d.cts +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/{index-CjIDPMsV.d.cts → index-DCF9QSPY.d.cts} +47 -0
- package/dist/{index-CjIDPMsV.d.ts → index-DCF9QSPY.d.ts} +47 -0
- package/dist/index.cjs +262 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +233 -81
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +261 -110
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +1 -1
- package/dist/nest/index.d.ts +1 -1
- package/dist/nest/index.js +232 -81
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.cjs
CHANGED
|
@@ -219,7 +219,7 @@ Run \`nestjs-codegen init\` to create a starter config.`
|
|
|
219
219
|
|
|
220
220
|
// src/generate.ts
|
|
221
221
|
var import_promises12 = require("fs/promises");
|
|
222
|
-
var
|
|
222
|
+
var import_node_path14 = require("path");
|
|
223
223
|
|
|
224
224
|
// src/discovery/pages.ts
|
|
225
225
|
var import_promises2 = require("fs/promises");
|
|
@@ -548,9 +548,10 @@ function inferExpressionType(node) {
|
|
|
548
548
|
|
|
549
549
|
// src/emit/emit-api.ts
|
|
550
550
|
var import_promises3 = require("fs/promises");
|
|
551
|
-
var
|
|
551
|
+
var import_node_path5 = require("path");
|
|
552
552
|
|
|
553
553
|
// src/extension/registry.ts
|
|
554
|
+
var import_node_path4 = require("path");
|
|
554
555
|
var import_ts_morph2 = require("ts-morph");
|
|
555
556
|
function resolveApiSlots(extensions) {
|
|
556
557
|
let layer;
|
|
@@ -583,7 +584,7 @@ function mergeExclusive(target, incoming, {
|
|
|
583
584
|
target.set(key, { value, owner });
|
|
584
585
|
}
|
|
585
586
|
}
|
|
586
|
-
function createExtensionContext(config, getRoutes) {
|
|
587
|
+
function createExtensionContext(config, getRoutes, trackedInputs) {
|
|
587
588
|
let project;
|
|
588
589
|
return {
|
|
589
590
|
cwd: config.codegen.cwd,
|
|
@@ -592,6 +593,13 @@ function createExtensionContext(config, getRoutes) {
|
|
|
592
593
|
get routes() {
|
|
593
594
|
return getRoutes();
|
|
594
595
|
},
|
|
596
|
+
trackInput(...paths) {
|
|
597
|
+
if (!trackedInputs) return;
|
|
598
|
+
for (const path of paths) {
|
|
599
|
+
if (!path) continue;
|
|
600
|
+
trackedInputs.add((0, import_node_path4.relative)(config.codegen.cwd, (0, import_node_path4.resolve)(config.codegen.cwd, path)));
|
|
601
|
+
}
|
|
602
|
+
},
|
|
595
603
|
project() {
|
|
596
604
|
if (!project) {
|
|
597
605
|
project = new import_ts_morph2.Project({
|
|
@@ -651,7 +659,7 @@ function requestShape(route) {
|
|
|
651
659
|
async function emitApi(routes, outDir, opts = {}) {
|
|
652
660
|
await (0, import_promises3.mkdir)(outDir, { recursive: true });
|
|
653
661
|
const content = buildApiFile(routes, outDir, opts);
|
|
654
|
-
await (0, import_promises3.writeFile)((0,
|
|
662
|
+
await (0, import_promises3.writeFile)((0, import_node_path5.join)(outDir, "api.ts"), content, "utf8");
|
|
655
663
|
}
|
|
656
664
|
function splitName(name) {
|
|
657
665
|
return name.split(".");
|
|
@@ -759,7 +767,7 @@ function rawResponseType(c, outDir) {
|
|
|
759
767
|
return c.contractSource.response;
|
|
760
768
|
}
|
|
761
769
|
if (c.controllerRef) {
|
|
762
|
-
let relPath = (0,
|
|
770
|
+
let relPath = (0, import_node_path5.relative)(outDir, c.controllerRef.filePath).replace(/\.ts$/, "");
|
|
763
771
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
764
772
|
return `Awaited<ReturnType<import('${relPath}').${c.controllerRef.className}['${c.controllerRef.methodName}']>>`;
|
|
765
773
|
}
|
|
@@ -1085,6 +1093,11 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
1085
1093
|
config: {},
|
|
1086
1094
|
project: () => {
|
|
1087
1095
|
throw new Error("ExtensionContext.project() is unavailable in standalone emitApi.");
|
|
1096
|
+
},
|
|
1097
|
+
// No manifest is written on the standalone path, so there is nothing for
|
|
1098
|
+
// tracked dependencies to be recorded into — accept and discard them
|
|
1099
|
+
// rather than making every caller supply a sink.
|
|
1100
|
+
trackInput: () => {
|
|
1088
1101
|
}
|
|
1089
1102
|
};
|
|
1090
1103
|
const importsByFile = /* @__PURE__ */ new Map();
|
|
@@ -1140,8 +1153,8 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
1140
1153
|
const emittedNames = /* @__PURE__ */ new Set();
|
|
1141
1154
|
for (const [filePath, names] of importsByFile) {
|
|
1142
1155
|
let relPath;
|
|
1143
|
-
if ((0,
|
|
1144
|
-
relPath = (0,
|
|
1156
|
+
if ((0, import_node_path5.isAbsolute)(filePath)) {
|
|
1157
|
+
relPath = (0, import_node_path5.relative)(outDir, filePath).replace(/\.ts$/, "");
|
|
1145
1158
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
1146
1159
|
} else {
|
|
1147
1160
|
relPath = filePath;
|
|
@@ -1235,7 +1248,7 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
1235
1248
|
|
|
1236
1249
|
// src/emit/emit-cache.ts
|
|
1237
1250
|
var import_promises4 = require("fs/promises");
|
|
1238
|
-
var
|
|
1251
|
+
var import_node_path6 = require("path");
|
|
1239
1252
|
async function emitCache(pages, outDir) {
|
|
1240
1253
|
await (0, import_promises4.mkdir)(outDir, { recursive: true });
|
|
1241
1254
|
const entries = await Promise.all(
|
|
@@ -1249,19 +1262,19 @@ async function emitCache(pages, outDir) {
|
|
|
1249
1262
|
})
|
|
1250
1263
|
);
|
|
1251
1264
|
const cache = { pages: entries };
|
|
1252
|
-
await (0, import_promises4.writeFile)((0,
|
|
1265
|
+
await (0, import_promises4.writeFile)((0, import_node_path6.join)(outDir, "components.json"), `${JSON.stringify(cache, null, 2)}
|
|
1253
1266
|
`, "utf8");
|
|
1254
1267
|
}
|
|
1255
1268
|
|
|
1256
1269
|
// src/emit/emit-forms.ts
|
|
1257
1270
|
var import_promises5 = require("fs/promises");
|
|
1258
|
-
var
|
|
1271
|
+
var import_node_path7 = require("path");
|
|
1259
1272
|
async function emitForms(routes, outDir, config, adapter) {
|
|
1260
1273
|
if (config && config.enabled === false) return false;
|
|
1261
1274
|
const content = buildFormsFileWithAdapter(routes, outDir, adapter, config);
|
|
1262
1275
|
if (content === null) return false;
|
|
1263
1276
|
await (0, import_promises5.mkdir)(outDir, { recursive: true });
|
|
1264
|
-
await (0, import_promises5.writeFile)((0,
|
|
1277
|
+
await (0, import_promises5.writeFile)((0, import_node_path7.join)(outDir, "forms.ts"), content, "utf8");
|
|
1265
1278
|
return true;
|
|
1266
1279
|
}
|
|
1267
1280
|
function pascal(segment) {
|
|
@@ -1274,7 +1287,7 @@ function deriveBaseName(routeName) {
|
|
|
1274
1287
|
return { method, full };
|
|
1275
1288
|
}
|
|
1276
1289
|
function relImport(outDir, filePath) {
|
|
1277
|
-
let relPath = (0,
|
|
1290
|
+
let relPath = (0, import_node_path7.relative)(outDir, filePath).replace(/\.ts$/, "");
|
|
1278
1291
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
1279
1292
|
return relPath;
|
|
1280
1293
|
}
|
|
@@ -1548,7 +1561,7 @@ function buildFormsFileWithAdapter(routes, outDir, adapter, config) {
|
|
|
1548
1561
|
|
|
1549
1562
|
// src/emit/emit-index.ts
|
|
1550
1563
|
var import_promises6 = require("fs/promises");
|
|
1551
|
-
var
|
|
1564
|
+
var import_node_path8 = require("path");
|
|
1552
1565
|
async function emitIndex(outDir, hasContracts = false, hasForms = false) {
|
|
1553
1566
|
await (0, import_promises6.mkdir)(outDir, { recursive: true });
|
|
1554
1567
|
const exports2 = ["export * from './pages.js';", "export * from './routes.js';"];
|
|
@@ -1561,12 +1574,12 @@ async function emitIndex(outDir, hasContracts = false, hasForms = false) {
|
|
|
1561
1574
|
const content = ["// Generated by @dudousxd/nestjs-codegen. Do not edit.", ...exports2, ""].join(
|
|
1562
1575
|
"\n"
|
|
1563
1576
|
);
|
|
1564
|
-
await (0, import_promises6.writeFile)((0,
|
|
1577
|
+
await (0, import_promises6.writeFile)((0, import_node_path8.join)(outDir, "index.d.ts"), content, "utf8");
|
|
1565
1578
|
}
|
|
1566
1579
|
|
|
1567
1580
|
// src/emit/emit-mocks.ts
|
|
1568
1581
|
var import_promises7 = require("fs/promises");
|
|
1569
|
-
var
|
|
1582
|
+
var import_node_path9 = require("path");
|
|
1570
1583
|
|
|
1571
1584
|
// src/ir/schema-node-to-json-schema.ts
|
|
1572
1585
|
var DEFAULT_CTX = { refPrefix: "#/components/schemas/" };
|
|
@@ -1890,12 +1903,12 @@ async function emitMocks(routes, outDir, opts = {}) {
|
|
|
1890
1903
|
await (0, import_promises7.mkdir)(outDir, { recursive: true });
|
|
1891
1904
|
const content = buildMocksFile(routes, opts);
|
|
1892
1905
|
const fileName = opts.fileName ?? "mocks.ts";
|
|
1893
|
-
await (0, import_promises7.writeFile)((0,
|
|
1906
|
+
await (0, import_promises7.writeFile)((0, import_node_path9.join)(outDir, fileName), content, "utf8");
|
|
1894
1907
|
}
|
|
1895
1908
|
|
|
1896
1909
|
// src/emit/emit-openapi.ts
|
|
1897
1910
|
var import_promises8 = require("fs/promises");
|
|
1898
|
-
var
|
|
1911
|
+
var import_node_path10 = require("path");
|
|
1899
1912
|
var REF_PREFIX2 = "#/components/schemas/";
|
|
1900
1913
|
function toOpenApiPath(path) {
|
|
1901
1914
|
return path.replace(/:([^/]+)/g, "{$1}");
|
|
@@ -2016,13 +2029,13 @@ async function emitOpenApi(routes, outDir, opts = {}) {
|
|
|
2016
2029
|
await (0, import_promises8.mkdir)(outDir, { recursive: true });
|
|
2017
2030
|
const doc = buildOpenApiSpec(routes, opts);
|
|
2018
2031
|
const fileName = opts.fileName ?? "openapi.json";
|
|
2019
|
-
await (0, import_promises8.writeFile)((0,
|
|
2032
|
+
await (0, import_promises8.writeFile)((0, import_node_path10.join)(outDir, fileName), `${JSON.stringify(doc, null, 2)}
|
|
2020
2033
|
`, "utf8");
|
|
2021
2034
|
}
|
|
2022
2035
|
|
|
2023
2036
|
// src/emit/emit-pages.ts
|
|
2024
2037
|
var import_promises9 = require("fs/promises");
|
|
2025
|
-
var
|
|
2038
|
+
var import_node_path11 = require("path");
|
|
2026
2039
|
async function emitPages(pages, outDir, _options = {}) {
|
|
2027
2040
|
await (0, import_promises9.mkdir)(outDir, { recursive: true });
|
|
2028
2041
|
const pageNameUnion = pages.length > 0 ? pages.map((p) => JSON.stringify(p.name)).join(" | ") : "never";
|
|
@@ -2043,7 +2056,7 @@ ${augBody}
|
|
|
2043
2056
|
}
|
|
2044
2057
|
${sharedPropsBlock}}
|
|
2045
2058
|
`;
|
|
2046
|
-
await (0, import_promises9.writeFile)((0,
|
|
2059
|
+
await (0, import_promises9.writeFile)((0, import_node_path11.join)(outDir, "pages.d.ts"), content, "utf8");
|
|
2047
2060
|
}
|
|
2048
2061
|
function buildSharedPropsBlock(sharedProps) {
|
|
2049
2062
|
if (!sharedProps) return "";
|
|
@@ -2062,7 +2075,7 @@ ${propsBody}
|
|
|
2062
2075
|
`;
|
|
2063
2076
|
}
|
|
2064
2077
|
function buildAugmentationType(page, outDir) {
|
|
2065
|
-
let importPath = (0,
|
|
2078
|
+
let importPath = (0, import_node_path11.relative)(outDir, page.absolutePath).replace(/\.(tsx?|vue|svelte)$/, "");
|
|
2066
2079
|
if (!importPath.startsWith(".")) {
|
|
2067
2080
|
importPath = `./${importPath}`;
|
|
2068
2081
|
}
|
|
@@ -2074,11 +2087,11 @@ function needsQuotes(name) {
|
|
|
2074
2087
|
|
|
2075
2088
|
// src/emit/emit-routes.ts
|
|
2076
2089
|
var import_promises10 = require("fs/promises");
|
|
2077
|
-
var
|
|
2090
|
+
var import_node_path12 = require("path");
|
|
2078
2091
|
async function emitRoutes(routes, outDir) {
|
|
2079
2092
|
await (0, import_promises10.mkdir)(outDir, { recursive: true });
|
|
2080
2093
|
const content = buildRoutesFile(routes);
|
|
2081
|
-
await (0, import_promises10.writeFile)((0,
|
|
2094
|
+
await (0, import_promises10.writeFile)((0, import_node_path12.join)(outDir, "routes.ts"), content, "utf8");
|
|
2082
2095
|
}
|
|
2083
2096
|
function buildRoutesFile(routes) {
|
|
2084
2097
|
if (routes.length === 0) {
|
|
@@ -2193,7 +2206,7 @@ function buildEmpty() {
|
|
|
2193
2206
|
// src/generate-manifest.ts
|
|
2194
2207
|
var import_node_crypto = require("crypto");
|
|
2195
2208
|
var import_promises11 = require("fs/promises");
|
|
2196
|
-
var
|
|
2209
|
+
var import_node_path13 = require("path");
|
|
2197
2210
|
var import_fast_glob2 = __toESM(require("fast-glob"), 1);
|
|
2198
2211
|
var MANIFEST_FILE = ".codegen-manifest.json";
|
|
2199
2212
|
var LOCK_FILE = ".watcher.lock";
|
|
@@ -2216,6 +2229,9 @@ function isManifestShape(value) {
|
|
|
2216
2229
|
if (candidate.configKeyHashes !== void 0 && !isStringRecord(candidate.configKeyHashes)) {
|
|
2217
2230
|
return false;
|
|
2218
2231
|
}
|
|
2232
|
+
if (candidate.extraInputs !== void 0 && (!Array.isArray(candidate.extraInputs) || !candidate.extraInputs.every((entry) => typeof entry === "string"))) {
|
|
2233
|
+
return false;
|
|
2234
|
+
}
|
|
2219
2235
|
if (!Array.isArray(candidate.files)) return false;
|
|
2220
2236
|
return candidate.files.every((entry) => typeof entry === "string");
|
|
2221
2237
|
}
|
|
@@ -2255,26 +2271,35 @@ async function discoverInputFiles(config) {
|
|
|
2255
2271
|
const matched = await (0, import_fast_glob2.default)(globs, { cwd, absolute: true, onlyFiles: true });
|
|
2256
2272
|
return [...new Set(matched)].sort();
|
|
2257
2273
|
}
|
|
2258
|
-
async function computeInputsHash(config) {
|
|
2274
|
+
async function computeInputsHash(config, extraInputs = []) {
|
|
2259
2275
|
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
2260
2276
|
hash.update(`version:${VERSION}
|
|
2261
2277
|
`);
|
|
2262
2278
|
hash.update(`config:${serializeConfig(config)}
|
|
2263
2279
|
`);
|
|
2264
|
-
const inputFiles = await discoverInputFiles(config);
|
|
2265
2280
|
const cwd = config.codegen.cwd;
|
|
2266
|
-
|
|
2281
|
+
const globbed = await discoverInputFiles(config);
|
|
2282
|
+
const globbedRelative = new Set(globbed.map((file) => (0, import_node_path13.relative)(cwd, file)));
|
|
2283
|
+
const extra = [...new Set(extraInputs)].filter((file) => !globbedRelative.has(file)).sort();
|
|
2284
|
+
for (const file of globbed) {
|
|
2267
2285
|
const contents = await (0, import_promises11.readFile)(file, "utf8");
|
|
2268
|
-
hash.update(`file:${(0,
|
|
2286
|
+
hash.update(`file:${(0, import_node_path13.relative)(cwd, file)}
|
|
2269
2287
|
`);
|
|
2270
2288
|
hash.update(contents);
|
|
2271
2289
|
hash.update("\n");
|
|
2272
2290
|
}
|
|
2291
|
+
for (const file of extra) {
|
|
2292
|
+
const contents = await (0, import_promises11.readFile)((0, import_node_path13.join)(cwd, file), "utf8").catch(() => null);
|
|
2293
|
+
hash.update(`extra:${file}
|
|
2294
|
+
`);
|
|
2295
|
+
hash.update(contents ?? "\0missing");
|
|
2296
|
+
hash.update("\n");
|
|
2297
|
+
}
|
|
2273
2298
|
return hash.digest("hex");
|
|
2274
2299
|
}
|
|
2275
2300
|
async function readManifest(outDir) {
|
|
2276
2301
|
try {
|
|
2277
|
-
const raw = await (0, import_promises11.readFile)((0,
|
|
2302
|
+
const raw = await (0, import_promises11.readFile)((0, import_node_path13.join)(outDir, MANIFEST_FILE), "utf8");
|
|
2278
2303
|
const parsed = JSON.parse(raw);
|
|
2279
2304
|
if (!isManifestShape(parsed)) return null;
|
|
2280
2305
|
return {
|
|
@@ -2283,6 +2308,7 @@ async function readManifest(outDir) {
|
|
|
2283
2308
|
...parsed.entryPoint ? { entryPoint: parsed.entryPoint } : {},
|
|
2284
2309
|
...parsed.configHash ? { configHash: parsed.configHash } : {},
|
|
2285
2310
|
...parsed.configKeyHashes ? { configKeyHashes: parsed.configKeyHashes } : {},
|
|
2311
|
+
...parsed.extraInputs ? { extraInputs: parsed.extraInputs } : {},
|
|
2286
2312
|
files: parsed.files
|
|
2287
2313
|
};
|
|
2288
2314
|
} catch {
|
|
@@ -2293,7 +2319,7 @@ function computeConfigHash(config) {
|
|
|
2293
2319
|
return (0, import_node_crypto.createHash)("sha256").update(serializeConfig(config)).digest("hex");
|
|
2294
2320
|
}
|
|
2295
2321
|
async function writeManifest(outDir, manifest) {
|
|
2296
|
-
await (0, import_promises11.writeFile)((0,
|
|
2322
|
+
await (0, import_promises11.writeFile)((0, import_node_path13.join)(outDir, MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
|
|
2297
2323
|
`, "utf8");
|
|
2298
2324
|
}
|
|
2299
2325
|
async function listOutputFiles(outDir) {
|
|
@@ -2301,11 +2327,11 @@ async function listOutputFiles(outDir) {
|
|
|
2301
2327
|
async function walk(dir) {
|
|
2302
2328
|
const entries = await (0, import_promises11.readdir)(dir, { withFileTypes: true }).catch(() => []);
|
|
2303
2329
|
for (const entry of entries) {
|
|
2304
|
-
const abs = (0,
|
|
2330
|
+
const abs = (0, import_node_path13.join)(dir, entry.name);
|
|
2305
2331
|
if (entry.isDirectory()) {
|
|
2306
2332
|
await walk(abs);
|
|
2307
2333
|
} else if (entry.isFile()) {
|
|
2308
|
-
const rel = (0,
|
|
2334
|
+
const rel = (0, import_node_path13.relative)(outDir, abs);
|
|
2309
2335
|
if (rel === MANIFEST_FILE || rel === LOCK_FILE) continue;
|
|
2310
2336
|
found.push(rel);
|
|
2311
2337
|
}
|
|
@@ -2342,8 +2368,8 @@ function driftGuardMessage(outDir, previousEntryPoint, currentEntryPoint, differ
|
|
|
2342
2368
|
}
|
|
2343
2369
|
async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
2344
2370
|
setCodegenDebug(config.debug);
|
|
2345
|
-
const inputsHash = await computeInputsHash(config);
|
|
2346
2371
|
const manifest = await readManifest(config.codegen.outDir);
|
|
2372
|
+
const inputsHash = await computeInputsHash(config, manifest?.extraInputs ?? []);
|
|
2347
2373
|
if (await isManifestFresh(config.codegen.outDir, manifest, inputsHash)) {
|
|
2348
2374
|
console.log(`[nestjs-codegen] ${config.codegen.outDir} up to date, skipped`);
|
|
2349
2375
|
return;
|
|
@@ -2364,7 +2390,8 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
2364
2390
|
}
|
|
2365
2391
|
const extensions = config.extensions ?? [];
|
|
2366
2392
|
let routes = inputRoutes;
|
|
2367
|
-
const
|
|
2393
|
+
const trackedInputs = /* @__PURE__ */ new Set();
|
|
2394
|
+
const ctx = createExtensionContext(config, () => routes, trackedInputs);
|
|
2368
2395
|
if (extensions.length > 0) {
|
|
2369
2396
|
routes = await applyTransformRoutes(routes, extensions, ctx);
|
|
2370
2397
|
}
|
|
@@ -2418,31 +2445,34 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
2418
2445
|
if (extensions.length > 0) {
|
|
2419
2446
|
const extraFiles = await collectEmittedFiles(extensions, ctx);
|
|
2420
2447
|
for (const file of extraFiles) {
|
|
2421
|
-
const dest = (0,
|
|
2422
|
-
await (0, import_promises12.mkdir)((0,
|
|
2448
|
+
const dest = (0, import_node_path14.join)(config.codegen.outDir, file.path);
|
|
2449
|
+
await (0, import_promises12.mkdir)((0, import_node_path14.dirname)(dest), { recursive: true });
|
|
2423
2450
|
await (0, import_promises12.writeFile)(dest, file.contents, "utf8");
|
|
2424
2451
|
}
|
|
2425
2452
|
}
|
|
2426
2453
|
const outputFiles = await listOutputFiles(config.codegen.outDir);
|
|
2454
|
+
const extraInputs = [...trackedInputs].sort();
|
|
2455
|
+
const recordedHash = extraInputs.length > 0 ? await computeInputsHash(config, extraInputs) : inputsHash;
|
|
2427
2456
|
await writeManifest(config.codegen.outDir, {
|
|
2428
2457
|
version: VERSION,
|
|
2429
|
-
hash:
|
|
2458
|
+
hash: recordedHash,
|
|
2430
2459
|
entryPoint,
|
|
2431
2460
|
configHash,
|
|
2432
2461
|
configKeyHashes,
|
|
2433
|
-
files: outputFiles
|
|
2462
|
+
files: outputFiles,
|
|
2463
|
+
...extraInputs.length > 0 ? { extraInputs } : {}
|
|
2434
2464
|
});
|
|
2435
2465
|
}
|
|
2436
2466
|
|
|
2437
2467
|
// src/watch/watcher.ts
|
|
2438
2468
|
var import_promises15 = require("fs/promises");
|
|
2439
|
-
var
|
|
2469
|
+
var import_node_path18 = require("path");
|
|
2440
2470
|
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
2441
2471
|
|
|
2442
2472
|
// src/discovery/contracts-fast.ts
|
|
2443
|
-
var
|
|
2473
|
+
var import_node_path16 = require("path");
|
|
2444
2474
|
var import_fast_glob3 = __toESM(require("fast-glob"), 1);
|
|
2445
|
-
var
|
|
2475
|
+
var import_ts_morph10 = require("ts-morph");
|
|
2446
2476
|
|
|
2447
2477
|
// src/discovery/dto-type-resolver.ts
|
|
2448
2478
|
var import_ts_morph7 = require("ts-morph");
|
|
@@ -2452,7 +2482,7 @@ var import_ts_morph4 = require("ts-morph");
|
|
|
2452
2482
|
|
|
2453
2483
|
// src/discovery/type-ref-resolution.ts
|
|
2454
2484
|
var import_node_fs = require("fs");
|
|
2455
|
-
var
|
|
2485
|
+
var import_node_path15 = require("path");
|
|
2456
2486
|
var import_ts_morph3 = require("ts-morph");
|
|
2457
2487
|
var _EMPTY_CTX = { projectRoot: "", tsconfigPaths: null };
|
|
2458
2488
|
var _ctxByProject = /* @__PURE__ */ new WeakMap();
|
|
@@ -2504,12 +2534,12 @@ function findTypeInFile(name, file) {
|
|
|
2504
2534
|
}
|
|
2505
2535
|
function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
|
|
2506
2536
|
if (moduleSpecifier.startsWith(".")) {
|
|
2507
|
-
const dir = (0,
|
|
2537
|
+
const dir = (0, import_node_path15.dirname)(sourceFile.getFilePath());
|
|
2508
2538
|
const noExt = moduleSpecifier.replace(/\.(js|ts)$/, "");
|
|
2509
2539
|
return [
|
|
2510
|
-
(0,
|
|
2511
|
-
(0,
|
|
2512
|
-
(0,
|
|
2540
|
+
(0, import_node_path15.resolve)(dir, `${noExt}.ts`),
|
|
2541
|
+
(0, import_node_path15.resolve)(dir, `${moduleSpecifier}.ts`),
|
|
2542
|
+
(0, import_node_path15.resolve)(dir, moduleSpecifier, "index.ts")
|
|
2513
2543
|
];
|
|
2514
2544
|
}
|
|
2515
2545
|
const ctx = _ctxFor(project);
|
|
@@ -2530,8 +2560,8 @@ function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
|
|
|
2530
2560
|
const rest = moduleSpecifier.slice(prefix.length);
|
|
2531
2561
|
const candidates = [];
|
|
2532
2562
|
for (const mapping of mappings) {
|
|
2533
|
-
const resolved = (0,
|
|
2534
|
-
candidates.push(`${resolved}.ts`, (0,
|
|
2563
|
+
const resolved = (0, import_node_path15.resolve)(baseUrl, mapping.replace("*", rest));
|
|
2564
|
+
candidates.push(`${resolved}.ts`, (0, import_node_path15.resolve)(resolved, "index.ts"));
|
|
2535
2565
|
}
|
|
2536
2566
|
dbg(" resolved candidates:", candidates);
|
|
2537
2567
|
return candidates;
|
|
@@ -3421,6 +3451,12 @@ function toFilterFieldType(name, r) {
|
|
|
3421
3451
|
}
|
|
3422
3452
|
|
|
3423
3453
|
// src/discovery/filter-for.ts
|
|
3454
|
+
function resolveMixinEntityClass(mixin, project) {
|
|
3455
|
+
const entityArg = mixin?.classArgs[0];
|
|
3456
|
+
if (!entityArg) return void 0;
|
|
3457
|
+
const file = project.getSourceFile(entityArg.filePath) ?? project.addSourceFileAtPathIfExists(entityArg.filePath);
|
|
3458
|
+
return file?.getClass(entityArg.name);
|
|
3459
|
+
}
|
|
3424
3460
|
function classifyFilterForHint(typeInit) {
|
|
3425
3461
|
if (import_ts_morph6.Node.isStringLiteral(typeInit)) {
|
|
3426
3462
|
switch (typeInit.getLiteralValue()) {
|
|
@@ -3494,7 +3530,9 @@ function extractFilterForHints(classDecl, project) {
|
|
|
3494
3530
|
}
|
|
3495
3531
|
return hints;
|
|
3496
3532
|
}
|
|
3497
|
-
function extractApplyFilterInfo(method, sourceFile, project) {
|
|
3533
|
+
function extractApplyFilterInfo(method, sourceFile, project, mixin) {
|
|
3534
|
+
const declFile = method.getSourceFile();
|
|
3535
|
+
const mixinEntity = resolveMixinEntityClass(mixin, project);
|
|
3498
3536
|
for (const param of method.getParameters()) {
|
|
3499
3537
|
const filterDecorator = param.getDecorators().find((d) => d.getName() === "ApplyFilter");
|
|
3500
3538
|
if (!filterDecorator) continue;
|
|
@@ -3514,12 +3552,12 @@ function extractApplyFilterInfo(method, sourceFile, project) {
|
|
|
3514
3552
|
}
|
|
3515
3553
|
}
|
|
3516
3554
|
const filterClassName = filterClassArg.getText();
|
|
3517
|
-
const resolved = findType(filterClassName,
|
|
3518
|
-
|
|
3519
|
-
|
|
3555
|
+
const resolved = findType(filterClassName, declFile, project);
|
|
3556
|
+
const classDecl = resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg);
|
|
3557
|
+
if (classDecl) {
|
|
3520
3558
|
let fieldTypes = extractClassPropertyTypes(classDecl, project);
|
|
3521
3559
|
if (fieldTypes.length === 0) {
|
|
3522
|
-
fieldTypes = extractFilterableEntityFields(classDecl, project);
|
|
3560
|
+
fieldTypes = extractFilterableEntityFields(classDecl, project, mixinEntity);
|
|
3523
3561
|
}
|
|
3524
3562
|
const filterForHints = extractFilterForHints(classDecl, project);
|
|
3525
3563
|
if (filterForHints.size > 0) {
|
|
@@ -3604,22 +3642,29 @@ function extractClassPropertyTypes(classDecl, project) {
|
|
|
3604
3642
|
}
|
|
3605
3643
|
return fields;
|
|
3606
3644
|
}
|
|
3607
|
-
function
|
|
3645
|
+
function resolveLocalClassDeclaration(identifier) {
|
|
3646
|
+
if (!import_ts_morph6.Node.isIdentifier(identifier)) return void 0;
|
|
3647
|
+
return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph6.Node.isClassDeclaration(n));
|
|
3648
|
+
}
|
|
3649
|
+
function resolveDeclaredEntity(optionsArg, filterClass, project) {
|
|
3650
|
+
if (!import_ts_morph6.Node.isObjectLiteralExpression(optionsArg)) return void 0;
|
|
3651
|
+
const entityProp = optionsArg.getProperty("entity");
|
|
3652
|
+
if (!entityProp || !import_ts_morph6.Node.isPropertyAssignment(entityProp)) return void 0;
|
|
3653
|
+
const entityInit = entityProp.getInitializer();
|
|
3654
|
+
if (!entityInit || !import_ts_morph6.Node.isIdentifier(entityInit)) return void 0;
|
|
3655
|
+
const resolved = findType(entityInit.getText(), filterClass.getSourceFile(), project);
|
|
3656
|
+
if (!resolved || resolved.kind !== "class") return void 0;
|
|
3657
|
+
return resolved.decl;
|
|
3658
|
+
}
|
|
3659
|
+
function extractFilterableEntityFields(filterClass, project, entityOverride) {
|
|
3608
3660
|
const filterableDecorator = filterClass.getDecorators().find((d) => d.getName() === "Filterable");
|
|
3609
3661
|
if (!filterableDecorator) return [];
|
|
3610
3662
|
const args = filterableDecorator.getArguments();
|
|
3611
3663
|
if (args.length === 0) return [];
|
|
3612
3664
|
const optionsArg = args[0];
|
|
3613
3665
|
if (!import_ts_morph6.Node.isObjectLiteralExpression(optionsArg)) return [];
|
|
3614
|
-
const
|
|
3615
|
-
if (!
|
|
3616
|
-
const entityInit = entityProp.getInitializer();
|
|
3617
|
-
if (!entityInit || !import_ts_morph6.Node.isIdentifier(entityInit)) return [];
|
|
3618
|
-
const entityName = entityInit.getText();
|
|
3619
|
-
const filterSourceFile = filterClass.getSourceFile();
|
|
3620
|
-
const resolvedEntity = findType(entityName, filterSourceFile, project);
|
|
3621
|
-
if (!resolvedEntity || resolvedEntity.kind !== "class") return [];
|
|
3622
|
-
const entityDecl = resolvedEntity.decl;
|
|
3666
|
+
const entityDecl = entityOverride ?? resolveDeclaredEntity(optionsArg, filterClass, project);
|
|
3667
|
+
if (!entityDecl) return [];
|
|
3623
3668
|
const fields = collectEntityFields(
|
|
3624
3669
|
entityDecl,
|
|
3625
3670
|
entityDecl.getSourceFile(),
|
|
@@ -4044,9 +4089,9 @@ function unwrapNamedContainer(node, names) {
|
|
|
4044
4089
|
}
|
|
4045
4090
|
return node;
|
|
4046
4091
|
}
|
|
4047
|
-
function extractDtoContract(method, sourceFile, project) {
|
|
4092
|
+
function extractDtoContract(method, sourceFile, project, mixin) {
|
|
4048
4093
|
let body = extractBodyType(method, sourceFile, project);
|
|
4049
|
-
const filterInfo = extractApplyFilterInfo(method, sourceFile, project);
|
|
4094
|
+
const filterInfo = extractApplyFilterInfo(method, sourceFile, project, mixin);
|
|
4050
4095
|
const query = extractQueryType(method, sourceFile, project);
|
|
4051
4096
|
const uploads = extractUploadedFiles(method);
|
|
4052
4097
|
const multipartBody = uploads.fields ? `{ ${uploads.fields} }` : null;
|
|
@@ -4156,12 +4201,94 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
|
|
|
4156
4201
|
return null;
|
|
4157
4202
|
}
|
|
4158
4203
|
|
|
4159
|
-
// src/discovery/
|
|
4204
|
+
// src/discovery/heritage.ts
|
|
4160
4205
|
var import_ts_morph8 = require("ts-morph");
|
|
4206
|
+
function unwrapExpression(node) {
|
|
4207
|
+
let current = node;
|
|
4208
|
+
while (import_ts_morph8.Node.isAsExpression(current) || import_ts_morph8.Node.isSatisfiesExpression(current) || import_ts_morph8.Node.isParenthesizedExpression(current) || import_ts_morph8.Node.isTypeAssertion(current)) {
|
|
4209
|
+
current = current.getExpression();
|
|
4210
|
+
}
|
|
4211
|
+
return current;
|
|
4212
|
+
}
|
|
4213
|
+
function resolveReturnedClass(factoryDecl) {
|
|
4214
|
+
const body = factoryDecl.getBody();
|
|
4215
|
+
if (!body) return void 0;
|
|
4216
|
+
const returns = body.getDescendants().filter((n) => import_ts_morph8.Node.isReturnStatement(n));
|
|
4217
|
+
for (const ret of returns) {
|
|
4218
|
+
const expr = ret.getExpression();
|
|
4219
|
+
if (!expr) continue;
|
|
4220
|
+
const inner = unwrapExpression(expr);
|
|
4221
|
+
if (import_ts_morph8.Node.isClassExpression(inner)) {
|
|
4222
|
+
return inner;
|
|
4223
|
+
}
|
|
4224
|
+
if (import_ts_morph8.Node.isIdentifier(inner)) {
|
|
4225
|
+
const name = inner.getText();
|
|
4226
|
+
const decl = body.getDescendants().find((n) => import_ts_morph8.Node.isClassDeclaration(n) && n.getName() === name);
|
|
4227
|
+
if (decl) return decl;
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
return void 0;
|
|
4231
|
+
}
|
|
4232
|
+
function resolveInheritedMethods(cls) {
|
|
4233
|
+
const expr = cls.getExtends()?.getExpression();
|
|
4234
|
+
if (!expr || !import_ts_morph8.Node.isCallExpression(expr)) return void 0;
|
|
4235
|
+
const callee = expr.getExpression();
|
|
4236
|
+
if (!import_ts_morph8.Node.isIdentifier(callee)) return void 0;
|
|
4237
|
+
const factoryDecl = callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph8.Node.isFunctionDeclaration(n));
|
|
4238
|
+
if (!factoryDecl) return void 0;
|
|
4239
|
+
const returnedClass = resolveReturnedClass(factoryDecl);
|
|
4240
|
+
if (!returnedClass) return void 0;
|
|
4241
|
+
const classArgs = [];
|
|
4242
|
+
for (const arg of expr.getArguments()) {
|
|
4243
|
+
if (!import_ts_morph8.Node.isIdentifier(arg)) continue;
|
|
4244
|
+
const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph8.Node.isClassDeclaration(n));
|
|
4245
|
+
if (decl) {
|
|
4246
|
+
classArgs.push({
|
|
4247
|
+
name: decl.getName() ?? arg.getText(),
|
|
4248
|
+
filePath: decl.getSourceFile().getFilePath()
|
|
4249
|
+
});
|
|
4250
|
+
}
|
|
4251
|
+
}
|
|
4252
|
+
return {
|
|
4253
|
+
methods: returnedClass.getMethods(),
|
|
4254
|
+
factoryName: callee.getText(),
|
|
4255
|
+
factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
|
|
4256
|
+
classArgs
|
|
4257
|
+
};
|
|
4258
|
+
}
|
|
4259
|
+
var mixinTypeProject;
|
|
4260
|
+
function getMixinTypeProject() {
|
|
4261
|
+
mixinTypeProject ??= new import_ts_morph8.Project({
|
|
4262
|
+
skipAddingFilesFromTsConfig: true,
|
|
4263
|
+
compilerOptions: { strict: true }
|
|
4264
|
+
});
|
|
4265
|
+
return mixinTypeProject;
|
|
4266
|
+
}
|
|
4267
|
+
function clearMixinTypeProject() {
|
|
4268
|
+
mixinTypeProject = void 0;
|
|
4269
|
+
}
|
|
4270
|
+
function resolveInstantiatedReturnType(cls, methodName) {
|
|
4271
|
+
const filePath = cls.getSourceFile().getFilePath();
|
|
4272
|
+
const className = cls.getName();
|
|
4273
|
+
if (!className) return void 0;
|
|
4274
|
+
const project = getMixinTypeProject();
|
|
4275
|
+
const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
|
|
4276
|
+
const typedCls = sourceFile?.getClass(className);
|
|
4277
|
+
if (!typedCls) return void 0;
|
|
4278
|
+
const prop = typedCls.getType().getProperty(methodName);
|
|
4279
|
+
if (!prop) return void 0;
|
|
4280
|
+
const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
|
|
4281
|
+
if (!returnType) return void 0;
|
|
4282
|
+
const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
|
|
4283
|
+
return unwrapped.getText(typedCls);
|
|
4284
|
+
}
|
|
4285
|
+
|
|
4286
|
+
// src/discovery/zod-ast-to-ts.ts
|
|
4287
|
+
var import_ts_morph9 = require("ts-morph");
|
|
4161
4288
|
function zodAstToTs(node) {
|
|
4162
|
-
if (!
|
|
4289
|
+
if (!import_ts_morph9.Node.isCallExpression(node)) return "unknown";
|
|
4163
4290
|
const expr = node.getExpression();
|
|
4164
|
-
if (
|
|
4291
|
+
if (import_ts_morph9.Node.isPropertyAccessExpression(expr)) {
|
|
4165
4292
|
const methodName = expr.getName();
|
|
4166
4293
|
const receiver = expr.getExpression();
|
|
4167
4294
|
if (methodName === "optional") {
|
|
@@ -4185,17 +4312,17 @@ function zodAstToTs(node) {
|
|
|
4185
4312
|
case "literal": {
|
|
4186
4313
|
const lit = args[0];
|
|
4187
4314
|
if (!lit) return "unknown";
|
|
4188
|
-
if (
|
|
4189
|
-
if (
|
|
4190
|
-
if (lit.getKind() ===
|
|
4191
|
-
if (lit.getKind() ===
|
|
4315
|
+
if (import_ts_morph9.Node.isStringLiteral(lit)) return JSON.stringify(lit.getLiteralValue());
|
|
4316
|
+
if (import_ts_morph9.Node.isNumericLiteral(lit)) return lit.getLiteralValue().toString();
|
|
4317
|
+
if (lit.getKind() === import_ts_morph9.SyntaxKind.TrueKeyword) return "true";
|
|
4318
|
+
if (lit.getKind() === import_ts_morph9.SyntaxKind.FalseKeyword) return "false";
|
|
4192
4319
|
return "unknown";
|
|
4193
4320
|
}
|
|
4194
4321
|
case "enum": {
|
|
4195
4322
|
const arrArg = args[0];
|
|
4196
|
-
if (!arrArg || !
|
|
4323
|
+
if (!arrArg || !import_ts_morph9.Node.isArrayLiteralExpression(arrArg)) return "unknown";
|
|
4197
4324
|
const members = arrArg.getElements().map(
|
|
4198
|
-
(el) =>
|
|
4325
|
+
(el) => import_ts_morph9.Node.isStringLiteral(el) ? JSON.stringify(el.getLiteralValue()) : "unknown"
|
|
4199
4326
|
);
|
|
4200
4327
|
return members.join(" | ");
|
|
4201
4328
|
}
|
|
@@ -4206,10 +4333,10 @@ function zodAstToTs(node) {
|
|
|
4206
4333
|
}
|
|
4207
4334
|
case "object": {
|
|
4208
4335
|
const objArg = args[0];
|
|
4209
|
-
if (!objArg || !
|
|
4336
|
+
if (!objArg || !import_ts_morph9.Node.isObjectLiteralExpression(objArg)) return "unknown";
|
|
4210
4337
|
const lines = [];
|
|
4211
4338
|
for (const prop of objArg.getProperties()) {
|
|
4212
|
-
if (!
|
|
4339
|
+
if (!import_ts_morph9.Node.isPropertyAssignment(prop)) continue;
|
|
4213
4340
|
const key = prop.getName();
|
|
4214
4341
|
const valNode = prop.getInitializer();
|
|
4215
4342
|
if (!valNode) continue;
|
|
@@ -4221,7 +4348,7 @@ function zodAstToTs(node) {
|
|
|
4221
4348
|
}
|
|
4222
4349
|
case "union": {
|
|
4223
4350
|
const arrArg = args[0];
|
|
4224
|
-
if (!arrArg || !
|
|
4351
|
+
if (!arrArg || !import_ts_morph9.Node.isArrayLiteralExpression(arrArg)) return "unknown";
|
|
4225
4352
|
return arrArg.getElements().map(zodAstToTs).join(" | ");
|
|
4226
4353
|
}
|
|
4227
4354
|
case "record": {
|
|
@@ -4231,7 +4358,7 @@ function zodAstToTs(node) {
|
|
|
4231
4358
|
}
|
|
4232
4359
|
case "tuple": {
|
|
4233
4360
|
const arrArg = args[0];
|
|
4234
|
-
if (!arrArg || !
|
|
4361
|
+
if (!arrArg || !import_ts_morph9.Node.isArrayLiteralExpression(arrArg)) return "unknown";
|
|
4235
4362
|
return `[${arrArg.getElements().map(zodAstToTs).join(", ")}]`;
|
|
4236
4363
|
}
|
|
4237
4364
|
default:
|
|
@@ -4241,18 +4368,18 @@ function zodAstToTs(node) {
|
|
|
4241
4368
|
return "unknown";
|
|
4242
4369
|
}
|
|
4243
4370
|
function isOptionalChain(node) {
|
|
4244
|
-
if (!
|
|
4371
|
+
if (!import_ts_morph9.Node.isCallExpression(node)) return false;
|
|
4245
4372
|
const expr = node.getExpression();
|
|
4246
|
-
return
|
|
4373
|
+
return import_ts_morph9.Node.isPropertyAccessExpression(expr) && expr.getName() === "optional";
|
|
4247
4374
|
}
|
|
4248
4375
|
function parseDefineContractCall(callExpr) {
|
|
4249
|
-
if (!
|
|
4376
|
+
if (!import_ts_morph9.Node.isCallExpression(callExpr)) return null;
|
|
4250
4377
|
const callee = callExpr.getExpression();
|
|
4251
|
-
const calleeName =
|
|
4378
|
+
const calleeName = import_ts_morph9.Node.isIdentifier(callee) ? callee.getText() : import_ts_morph9.Node.isPropertyAccessExpression(callee) ? callee.getName() : "";
|
|
4252
4379
|
if (calleeName !== "defineContract") return null;
|
|
4253
4380
|
const args = callExpr.getArguments();
|
|
4254
4381
|
const optsArg = args[0];
|
|
4255
|
-
if (!optsArg || !
|
|
4382
|
+
if (!optsArg || !import_ts_morph9.Node.isObjectLiteralExpression(optsArg)) return null;
|
|
4256
4383
|
let query = null;
|
|
4257
4384
|
let body = null;
|
|
4258
4385
|
let response = "unknown";
|
|
@@ -4260,7 +4387,7 @@ function parseDefineContractCall(callExpr) {
|
|
|
4260
4387
|
let bodyZodText = null;
|
|
4261
4388
|
let queryZodText = null;
|
|
4262
4389
|
for (const prop of optsArg.getProperties()) {
|
|
4263
|
-
if (!
|
|
4390
|
+
if (!import_ts_morph9.Node.isPropertyAssignment(prop)) continue;
|
|
4264
4391
|
const propName = prop.getName();
|
|
4265
4392
|
const val = prop.getInitializer();
|
|
4266
4393
|
if (!val) continue;
|
|
@@ -4289,21 +4416,22 @@ async function discoverContractsFast(opts) {
|
|
|
4289
4416
|
project.addSourceFileAtPath(f);
|
|
4290
4417
|
}
|
|
4291
4418
|
bindDiscoveryContext(project, cwd, tsconfigPath);
|
|
4419
|
+
clearMixinTypeProject();
|
|
4292
4420
|
return extractAllRoutes(project);
|
|
4293
4421
|
}
|
|
4294
4422
|
function resolveTsconfigPath(cwd, tsconfig) {
|
|
4295
|
-
return tsconfig ? (0,
|
|
4423
|
+
return tsconfig ? (0, import_node_path16.resolve)(tsconfig) : (0, import_node_path16.join)(cwd, "tsconfig.json");
|
|
4296
4424
|
}
|
|
4297
4425
|
function createDiscoveryProject(tsconfigPath) {
|
|
4298
4426
|
try {
|
|
4299
|
-
return new
|
|
4427
|
+
return new import_ts_morph10.Project({
|
|
4300
4428
|
tsConfigFilePath: tsconfigPath,
|
|
4301
4429
|
skipAddingFilesFromTsConfig: true,
|
|
4302
4430
|
skipLoadingLibFiles: true,
|
|
4303
4431
|
skipFileDependencyResolution: true
|
|
4304
4432
|
});
|
|
4305
4433
|
} catch {
|
|
4306
|
-
return new
|
|
4434
|
+
return new import_ts_morph10.Project({
|
|
4307
4435
|
skipAddingFilesFromTsConfig: true,
|
|
4308
4436
|
skipLoadingLibFiles: true,
|
|
4309
4437
|
skipFileDependencyResolution: true,
|
|
@@ -4378,7 +4506,7 @@ var PersistentDiscovery = class _PersistentDiscovery {
|
|
|
4378
4506
|
async rediscover(changedPaths) {
|
|
4379
4507
|
if (changedPaths) {
|
|
4380
4508
|
for (const p of changedPaths) {
|
|
4381
|
-
const abs = (0,
|
|
4509
|
+
const abs = (0, import_node_path16.resolve)(p);
|
|
4382
4510
|
const sf = this.project.getSourceFile(abs);
|
|
4383
4511
|
if (sf) {
|
|
4384
4512
|
await sf.refreshFromFileSystem();
|
|
@@ -4410,15 +4538,16 @@ var PersistentDiscovery = class _PersistentDiscovery {
|
|
|
4410
4538
|
runExtraction() {
|
|
4411
4539
|
clearTypeResolutionCaches(this.project);
|
|
4412
4540
|
clearEnumCache(this.project);
|
|
4541
|
+
clearMixinTypeProject();
|
|
4413
4542
|
return extractRoutesFrom(this.project, this.controllerPaths);
|
|
4414
4543
|
}
|
|
4415
4544
|
};
|
|
4416
4545
|
function decoratorStringArg(decoratorExpr) {
|
|
4417
4546
|
if (!decoratorExpr) return void 0;
|
|
4418
|
-
if (
|
|
4419
|
-
if (
|
|
4547
|
+
if (import_ts_morph10.Node.isStringLiteral(decoratorExpr)) return decoratorExpr.getLiteralValue();
|
|
4548
|
+
if (import_ts_morph10.Node.isArrayLiteralExpression(decoratorExpr)) {
|
|
4420
4549
|
const first = decoratorExpr.getElements()[0];
|
|
4421
|
-
if (first &&
|
|
4550
|
+
if (first && import_ts_morph10.Node.isStringLiteral(first)) return first.getLiteralValue();
|
|
4422
4551
|
}
|
|
4423
4552
|
return void 0;
|
|
4424
4553
|
}
|
|
@@ -4440,7 +4569,8 @@ function joinPaths(prefix, suffix) {
|
|
|
4440
4569
|
if (!prefix && !suffix) return "/";
|
|
4441
4570
|
if (!prefix) return suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
4442
4571
|
if (!suffix) return prefix.startsWith("/") ? prefix : `/${prefix}`;
|
|
4443
|
-
const
|
|
4572
|
+
const withLeadingSlash = prefix.startsWith("/") ? prefix : `/${prefix}`;
|
|
4573
|
+
const p = withLeadingSlash.endsWith("/") ? withLeadingSlash.slice(0, -1) : withLeadingSlash;
|
|
4444
4574
|
const s = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
4445
4575
|
const combined = p + s;
|
|
4446
4576
|
return combined === "" ? "/" : combined;
|
|
@@ -4494,7 +4624,8 @@ function buildRoute(args) {
|
|
|
4494
4624
|
methodAs,
|
|
4495
4625
|
sourceFile,
|
|
4496
4626
|
seenNames,
|
|
4497
|
-
contractSource
|
|
4627
|
+
contractSource,
|
|
4628
|
+
mixin
|
|
4498
4629
|
} = args;
|
|
4499
4630
|
const routeName = resolveRouteName(className, methodName, classAs, methodAs);
|
|
4500
4631
|
const qualifiedRef = `${className}.${methodName}`;
|
|
@@ -4510,7 +4641,12 @@ function buildRoute(args) {
|
|
|
4510
4641
|
path: combinedPath,
|
|
4511
4642
|
name: routeName,
|
|
4512
4643
|
params: extractParams(combinedPath),
|
|
4513
|
-
controllerRef: {
|
|
4644
|
+
controllerRef: {
|
|
4645
|
+
className,
|
|
4646
|
+
methodName,
|
|
4647
|
+
filePath: sourceFile.getFilePath(),
|
|
4648
|
+
...mixin ? { mixin } : {}
|
|
4649
|
+
},
|
|
4514
4650
|
contract: { contractSource }
|
|
4515
4651
|
};
|
|
4516
4652
|
}
|
|
@@ -4524,16 +4660,17 @@ function extractContractRoute(args) {
|
|
|
4524
4660
|
className,
|
|
4525
4661
|
sourceFile,
|
|
4526
4662
|
project,
|
|
4527
|
-
seenNames
|
|
4663
|
+
seenNames,
|
|
4664
|
+
mixin
|
|
4528
4665
|
} = args;
|
|
4529
4666
|
const firstDecoratorArg = applyContractDecorator.getArguments()[0];
|
|
4530
4667
|
if (!firstDecoratorArg) return null;
|
|
4531
4668
|
let contractDef = null;
|
|
4532
4669
|
let bodyZodRef = null;
|
|
4533
4670
|
let queryZodRef = null;
|
|
4534
|
-
if (
|
|
4671
|
+
if (import_ts_morph10.Node.isCallExpression(firstDecoratorArg)) {
|
|
4535
4672
|
contractDef = parseDefineContractCall(firstDecoratorArg);
|
|
4536
|
-
} else if (
|
|
4673
|
+
} else if (import_ts_morph10.Node.isIdentifier(firstDecoratorArg)) {
|
|
4537
4674
|
const identName = firstDecoratorArg.getText();
|
|
4538
4675
|
const resolvedVar = resolveImportedVariable(identName, sourceFile, project);
|
|
4539
4676
|
if (!resolvedVar) {
|
|
@@ -4576,6 +4713,7 @@ function extractContractRoute(args) {
|
|
|
4576
4713
|
methodAs,
|
|
4577
4714
|
sourceFile,
|
|
4578
4715
|
seenNames,
|
|
4716
|
+
mixin,
|
|
4579
4717
|
contractSource: {
|
|
4580
4718
|
query: contractDef.query,
|
|
4581
4719
|
body: contractDef.body,
|
|
@@ -4592,13 +4730,14 @@ function extractContractRoute(args) {
|
|
|
4592
4730
|
});
|
|
4593
4731
|
}
|
|
4594
4732
|
function extractDtoRoute(args) {
|
|
4595
|
-
const { cls, method, verb, prefix, className, sourceFile, project, seenNames } = args;
|
|
4733
|
+
const { cls, method, verb, prefix, className, sourceFile, project, seenNames, mixin } = args;
|
|
4596
4734
|
if (!verb) return null;
|
|
4597
4735
|
const combined = joinPaths(prefix, verb.handlerPath);
|
|
4598
4736
|
const methodName = method.getName();
|
|
4599
4737
|
const classAs = readAsDecorator(cls, `class ${className}`);
|
|
4600
4738
|
const methodAs = readAsDecorator(method, `${className}.${methodName}`);
|
|
4601
|
-
const dtoContract = extractDtoContract(method, sourceFile, project);
|
|
4739
|
+
const dtoContract = extractDtoContract(method, sourceFile, project, mixin);
|
|
4740
|
+
const mixinResponse = mixin ? resolveInstantiatedReturnType(cls, methodName) : void 0;
|
|
4602
4741
|
return buildRoute({
|
|
4603
4742
|
className,
|
|
4604
4743
|
methodName,
|
|
@@ -4608,10 +4747,11 @@ function extractDtoRoute(args) {
|
|
|
4608
4747
|
methodAs,
|
|
4609
4748
|
sourceFile,
|
|
4610
4749
|
seenNames,
|
|
4750
|
+
mixin,
|
|
4611
4751
|
contractSource: {
|
|
4612
4752
|
query: dtoContract?.query ?? null,
|
|
4613
4753
|
body: dtoContract?.body ?? null,
|
|
4614
|
-
response: dtoContract?.response ?? "unknown",
|
|
4754
|
+
response: mixinResponse ?? dtoContract?.response ?? "unknown",
|
|
4615
4755
|
error: dtoContract?.error ?? null,
|
|
4616
4756
|
queryRef: dtoContract?.queryRef ?? null,
|
|
4617
4757
|
bodyRef: dtoContract?.bodyRef ?? null,
|
|
@@ -4640,7 +4780,17 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4640
4780
|
const firstArg2 = controllerDecorator.getArguments()[0];
|
|
4641
4781
|
const prefix = decoratorStringArg(firstArg2) ?? "";
|
|
4642
4782
|
const className = cls.getName() ?? "Unknown";
|
|
4643
|
-
|
|
4783
|
+
const inherited = resolveInheritedMethods(cls);
|
|
4784
|
+
const mixinBinding = inherited ? {
|
|
4785
|
+
factoryName: inherited.factoryName,
|
|
4786
|
+
factoryFilePath: inherited.factoryFilePath,
|
|
4787
|
+
classArgs: inherited.classArgs
|
|
4788
|
+
} : void 0;
|
|
4789
|
+
const methods = [
|
|
4790
|
+
...cls.getMethods().map((method) => ({ method })),
|
|
4791
|
+
...(inherited?.methods ?? []).map((method) => ({ method, mixin: mixinBinding }))
|
|
4792
|
+
];
|
|
4793
|
+
for (const { method, mixin } of methods) {
|
|
4644
4794
|
const verb = resolveVerb(method);
|
|
4645
4795
|
const applyContractDecorator = method.getDecorator("ApplyContract");
|
|
4646
4796
|
const route = applyContractDecorator ? extractContractRoute({
|
|
@@ -4652,7 +4802,8 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4652
4802
|
className,
|
|
4653
4803
|
sourceFile,
|
|
4654
4804
|
project,
|
|
4655
|
-
seenNames
|
|
4805
|
+
seenNames,
|
|
4806
|
+
mixin
|
|
4656
4807
|
}) : extractDtoRoute({
|
|
4657
4808
|
cls,
|
|
4658
4809
|
method,
|
|
@@ -4661,7 +4812,8 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4661
4812
|
className,
|
|
4662
4813
|
sourceFile,
|
|
4663
4814
|
project,
|
|
4664
|
-
seenNames
|
|
4815
|
+
seenNames,
|
|
4816
|
+
mixin
|
|
4665
4817
|
});
|
|
4666
4818
|
if (route) routes.push(route);
|
|
4667
4819
|
}
|
|
@@ -4672,7 +4824,7 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4672
4824
|
// src/watch/lock-file.ts
|
|
4673
4825
|
var import_promises13 = require("fs/promises");
|
|
4674
4826
|
var import_promises14 = require("fs/promises");
|
|
4675
|
-
var
|
|
4827
|
+
var import_node_path17 = require("path");
|
|
4676
4828
|
var LOCK_FILE2 = ".watcher.lock";
|
|
4677
4829
|
function isProcessAlive(pid) {
|
|
4678
4830
|
try {
|
|
@@ -4684,7 +4836,7 @@ function isProcessAlive(pid) {
|
|
|
4684
4836
|
}
|
|
4685
4837
|
async function acquireLock(outDir) {
|
|
4686
4838
|
await (0, import_promises14.mkdir)(outDir, { recursive: true });
|
|
4687
|
-
const lockPath = (0,
|
|
4839
|
+
const lockPath = (0, import_node_path17.join)(outDir, LOCK_FILE2);
|
|
4688
4840
|
const lockData = { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4689
4841
|
try {
|
|
4690
4842
|
const fd = await (0, import_promises13.open)(lockPath, "wx");
|
|
@@ -4725,7 +4877,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4725
4877
|
if (lock === null) {
|
|
4726
4878
|
let holderPid = "unknown";
|
|
4727
4879
|
try {
|
|
4728
|
-
const raw = await (0, import_promises15.readFile)((0,
|
|
4880
|
+
const raw = await (0, import_promises15.readFile)((0, import_node_path18.join)(config.codegen.outDir, ".watcher.lock"), "utf8");
|
|
4729
4881
|
const data = JSON.parse(raw);
|
|
4730
4882
|
if (data.pid !== void 0) holderPid = String(data.pid);
|
|
4731
4883
|
} catch {
|
|
@@ -4778,7 +4930,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4778
4930
|
}
|
|
4779
4931
|
let pagesDebounceTimer;
|
|
4780
4932
|
const pagesGlob = config.pages?.glob ?? ".nestjs-codegen-no-pages";
|
|
4781
|
-
const pagesWatcher = import_chokidar.default.watch((0,
|
|
4933
|
+
const pagesWatcher = import_chokidar.default.watch((0, import_node_path18.join)(config.codegen.cwd, pagesGlob), {
|
|
4782
4934
|
ignoreInitial: true,
|
|
4783
4935
|
persistent: true,
|
|
4784
4936
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4805,7 +4957,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4805
4957
|
pagesWatcher.on("unlink", schedulePagesRegenerate);
|
|
4806
4958
|
let contractsDebounceTimer;
|
|
4807
4959
|
const pendingChangedPaths = /* @__PURE__ */ new Set();
|
|
4808
|
-
const contractsWatcher = import_chokidar.default.watch((0,
|
|
4960
|
+
const contractsWatcher = import_chokidar.default.watch((0, import_node_path18.join)(config.codegen.cwd, config.contracts.glob), {
|
|
4809
4961
|
ignoreInitial: true,
|
|
4810
4962
|
persistent: true,
|
|
4811
4963
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4835,7 +4987,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4835
4987
|
contractsWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
4836
4988
|
contractsWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
4837
4989
|
contractsWatcher.on("unlink", (p) => scheduleContractsRegenerate(p));
|
|
4838
|
-
const formsWatcher = import_chokidar.default.watch((0,
|
|
4990
|
+
const formsWatcher = import_chokidar.default.watch((0, import_node_path18.join)(config.codegen.cwd, config.forms.watch), {
|
|
4839
4991
|
ignoreInitial: true,
|
|
4840
4992
|
persistent: true,
|
|
4841
4993
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4862,7 +5014,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4862
5014
|
}
|
|
4863
5015
|
|
|
4864
5016
|
// src/index.ts
|
|
4865
|
-
var VERSION = "0.
|
|
5017
|
+
var VERSION = "0.17.0";
|
|
4866
5018
|
|
|
4867
5019
|
// src/cli/codegen.ts
|
|
4868
5020
|
async function runCodegen(opts = {}) {
|
|
@@ -4870,9 +5022,9 @@ async function runCodegen(opts = {}) {
|
|
|
4870
5022
|
const config = await loadConfig(cwd);
|
|
4871
5023
|
if (opts.watch) {
|
|
4872
5024
|
const watcher = await watch(config, void 0, { entryPoint: "cli" });
|
|
4873
|
-
await new Promise((
|
|
5025
|
+
await new Promise((resolve5) => {
|
|
4874
5026
|
function onSignal() {
|
|
4875
|
-
watcher.close().then(
|
|
5027
|
+
watcher.close().then(resolve5).catch(resolve5);
|
|
4876
5028
|
}
|
|
4877
5029
|
process.once("SIGINT", onSignal);
|
|
4878
5030
|
process.once("SIGTERM", onSignal);
|
|
@@ -4891,13 +5043,13 @@ async function runCodegen(opts = {}) {
|
|
|
4891
5043
|
// src/cli/doctor.ts
|
|
4892
5044
|
var import_node_child_process2 = require("child_process");
|
|
4893
5045
|
var import_node_fs4 = require("fs");
|
|
4894
|
-
var
|
|
5046
|
+
var import_node_path20 = require("path");
|
|
4895
5047
|
|
|
4896
5048
|
// src/cli/init.ts
|
|
4897
5049
|
var import_node_child_process = require("child_process");
|
|
4898
5050
|
var import_node_fs3 = require("fs");
|
|
4899
5051
|
var import_promises16 = require("fs/promises");
|
|
4900
|
-
var
|
|
5052
|
+
var import_node_path19 = require("path");
|
|
4901
5053
|
var import_node_readline = require("readline");
|
|
4902
5054
|
|
|
4903
5055
|
// src/cli/patch-utils.ts
|
|
@@ -4959,7 +5111,7 @@ ${bold(title)}`);
|
|
|
4959
5111
|
}
|
|
4960
5112
|
async function readPackageJson(cwd) {
|
|
4961
5113
|
try {
|
|
4962
|
-
const raw = await (0, import_promises16.readFile)((0,
|
|
5114
|
+
const raw = await (0, import_promises16.readFile)((0, import_node_path19.join)(cwd, "package.json"), "utf8");
|
|
4963
5115
|
return JSON.parse(raw);
|
|
4964
5116
|
} catch {
|
|
4965
5117
|
return {};
|
|
@@ -4990,7 +5142,7 @@ async function detectTemplateEngine(cwd) {
|
|
|
4990
5142
|
async function detectPackageManager(cwd) {
|
|
4991
5143
|
async function exists(file) {
|
|
4992
5144
|
try {
|
|
4993
|
-
await (0, import_promises16.access)((0,
|
|
5145
|
+
await (0, import_promises16.access)((0, import_node_path19.join)(cwd, file));
|
|
4994
5146
|
return true;
|
|
4995
5147
|
} catch {
|
|
4996
5148
|
return false;
|
|
@@ -5002,16 +5154,16 @@ async function detectPackageManager(cwd) {
|
|
|
5002
5154
|
}
|
|
5003
5155
|
async function promptFramework() {
|
|
5004
5156
|
if (!process.stdin.isTTY) return "react";
|
|
5005
|
-
return new Promise((
|
|
5157
|
+
return new Promise((resolve5) => {
|
|
5006
5158
|
const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
|
|
5007
5159
|
rl.question(
|
|
5008
5160
|
"[nestjs-codegen] Which frontend framework? (react/vue/svelte) [react]: ",
|
|
5009
5161
|
(answer) => {
|
|
5010
5162
|
rl.close();
|
|
5011
5163
|
const trimmed = answer.trim().toLowerCase();
|
|
5012
|
-
if (trimmed === "vue")
|
|
5013
|
-
else if (trimmed === "svelte")
|
|
5014
|
-
else
|
|
5164
|
+
if (trimmed === "vue") resolve5("vue");
|
|
5165
|
+
else if (trimmed === "svelte") resolve5("svelte");
|
|
5166
|
+
else resolve5("react");
|
|
5015
5167
|
}
|
|
5016
5168
|
);
|
|
5017
5169
|
});
|
|
@@ -5037,7 +5189,7 @@ async function writeIfNotExists(filePath, content, label) {
|
|
|
5037
5189
|
logCreated(label);
|
|
5038
5190
|
}
|
|
5039
5191
|
async function handleViteConfig(cwd, framework) {
|
|
5040
|
-
const filePath = (0,
|
|
5192
|
+
const filePath = (0, import_node_path19.join)(cwd, "vite.config.ts");
|
|
5041
5193
|
if (await fileExists2(filePath)) {
|
|
5042
5194
|
const existing = await (0, import_promises16.readFile)(filePath, "utf8");
|
|
5043
5195
|
const hasPlugin = existing.includes("nestInertia") || existing.includes("nestjs-inertia-vite/plugin");
|
|
@@ -5095,7 +5247,7 @@ function installDeps(pkgManager, deps, dev) {
|
|
|
5095
5247
|
}
|
|
5096
5248
|
}
|
|
5097
5249
|
async function patchPackageJsonScripts(cwd, scripts) {
|
|
5098
|
-
const pkgPath = (0,
|
|
5250
|
+
const pkgPath = (0, import_node_path19.join)(cwd, "package.json");
|
|
5099
5251
|
let pkg = {};
|
|
5100
5252
|
try {
|
|
5101
5253
|
pkg = JSON.parse(await (0, import_promises16.readFile)(pkgPath, "utf8"));
|
|
@@ -5412,7 +5564,7 @@ export class HomeController {
|
|
|
5412
5564
|
}
|
|
5413
5565
|
`;
|
|
5414
5566
|
function patchTsconfigExclude(cwd, dir, filename = "tsconfig.json") {
|
|
5415
|
-
const filePath = (0,
|
|
5567
|
+
const filePath = (0, import_node_path19.join)(cwd, filename);
|
|
5416
5568
|
return patchJsonFile(
|
|
5417
5569
|
filePath,
|
|
5418
5570
|
(json) => {
|
|
@@ -5427,7 +5579,7 @@ function patchTsconfigExclude(cwd, dir, filename = "tsconfig.json") {
|
|
|
5427
5579
|
);
|
|
5428
5580
|
}
|
|
5429
5581
|
function patchNestCliJson(cwd, shellDir) {
|
|
5430
|
-
const filePath = (0,
|
|
5582
|
+
const filePath = (0, import_node_path19.join)(cwd, "nest-cli.json");
|
|
5431
5583
|
return patchJsonFile(filePath, (json) => {
|
|
5432
5584
|
const compiler = json.compilerOptions ?? {};
|
|
5433
5585
|
const assets = compiler.assets ?? [];
|
|
@@ -5450,46 +5602,46 @@ async function scaffoldFiles(ctx) {
|
|
|
5450
5602
|
const { cwd, framework, engine, shellFileName, entryExt, pageExt } = ctx;
|
|
5451
5603
|
logSection("Scaffold files");
|
|
5452
5604
|
await writeIfNotExists(
|
|
5453
|
-
(0,
|
|
5605
|
+
(0, import_node_path19.join)(cwd, "nestjs-inertia.config.ts"),
|
|
5454
5606
|
configTemplate(framework),
|
|
5455
5607
|
"nestjs-inertia.config.ts"
|
|
5456
5608
|
);
|
|
5457
|
-
await writeIfNotExists((0,
|
|
5609
|
+
await writeIfNotExists((0, import_node_path19.join)(cwd, "nestjs-inertia.d.ts"), DTS_TEMPLATE, "nestjs-inertia.d.ts");
|
|
5458
5610
|
await writeIfNotExists(
|
|
5459
|
-
(0,
|
|
5611
|
+
(0, import_node_path19.join)(cwd, "tsconfig.inertia.json"),
|
|
5460
5612
|
TSCONFIG_INERTIA_TEMPLATE,
|
|
5461
5613
|
"tsconfig.inertia.json"
|
|
5462
5614
|
);
|
|
5463
5615
|
await writeIfNotExists(
|
|
5464
|
-
(0,
|
|
5616
|
+
(0, import_node_path19.join)(cwd, "inertia", "tsconfig.json"),
|
|
5465
5617
|
INERTIA_TSCONFIG_TEMPLATE,
|
|
5466
5618
|
"inertia/tsconfig.json"
|
|
5467
5619
|
);
|
|
5468
5620
|
await writeIfNotExists(
|
|
5469
|
-
(0,
|
|
5621
|
+
(0, import_node_path19.join)(cwd, "inertia", shellFileName),
|
|
5470
5622
|
htmlShellTemplate(framework, engine),
|
|
5471
5623
|
`inertia/${shellFileName}`
|
|
5472
5624
|
);
|
|
5473
5625
|
await handleViteConfig(cwd, framework);
|
|
5474
5626
|
await writeIfNotExists(
|
|
5475
|
-
(0,
|
|
5627
|
+
(0, import_node_path19.join)(cwd, "inertia", "app", `client.${entryExt}`),
|
|
5476
5628
|
entryPointTemplate(framework),
|
|
5477
5629
|
`inertia/app/client.${entryExt}`
|
|
5478
5630
|
);
|
|
5479
5631
|
await writeIfNotExists(
|
|
5480
|
-
(0,
|
|
5632
|
+
(0, import_node_path19.join)(cwd, "inertia", "pages", `Home.${pageExt}`),
|
|
5481
5633
|
samplePageTemplate(framework),
|
|
5482
5634
|
`inertia/pages/Home.${pageExt}`
|
|
5483
5635
|
);
|
|
5484
5636
|
await writeIfNotExists(
|
|
5485
|
-
(0,
|
|
5637
|
+
(0, import_node_path19.join)(cwd, "src", "home.controller.ts"),
|
|
5486
5638
|
SAMPLE_CONTROLLER,
|
|
5487
5639
|
"src/home.controller.ts"
|
|
5488
5640
|
);
|
|
5489
5641
|
}
|
|
5490
5642
|
function patchServerAppModule(ctx) {
|
|
5491
5643
|
const { cwd, rootView } = ctx;
|
|
5492
|
-
const appModulePath = (0,
|
|
5644
|
+
const appModulePath = (0, import_node_path19.join)(cwd, "src", "app.module.ts");
|
|
5493
5645
|
const appModuleResult = patchAppModule(appModulePath, rootView);
|
|
5494
5646
|
if (appModuleResult === "patched") {
|
|
5495
5647
|
logPatched("src/app.module.ts", "added InertiaModule.forRoot");
|
|
@@ -5503,7 +5655,7 @@ function patchServerAppModule(ctx) {
|
|
|
5503
5655
|
}
|
|
5504
5656
|
}
|
|
5505
5657
|
function patchServerMainTs(ctx) {
|
|
5506
|
-
const mainTsPath = (0,
|
|
5658
|
+
const mainTsPath = (0, import_node_path19.join)(ctx.cwd, "src", "main.ts");
|
|
5507
5659
|
const mainTsResult = patchMainTs(mainTsPath);
|
|
5508
5660
|
if (mainTsResult === "patched") {
|
|
5509
5661
|
logPatched("src/main.ts", "added setupInertiaVite after NestFactory.create");
|
|
@@ -5538,7 +5690,7 @@ function patchBuildConfigs(ctx) {
|
|
|
5538
5690
|
}
|
|
5539
5691
|
async function patchGitignoreAndDist(ctx) {
|
|
5540
5692
|
const { cwd } = ctx;
|
|
5541
|
-
await patchGitignore((0,
|
|
5693
|
+
await patchGitignore((0, import_node_path19.join)(cwd, ".gitignore"));
|
|
5542
5694
|
const tsconfigDistResult = patchTsconfigExclude(cwd, "dist", "tsconfig.json");
|
|
5543
5695
|
if (tsconfigDistResult === "patched") {
|
|
5544
5696
|
logPatched("tsconfig.json", "excluded dist/ from server compilation");
|
|
@@ -5644,7 +5796,7 @@ ${green("\u2713")} Setup complete! Run: ${bold("nest start --watch")}
|
|
|
5644
5796
|
|
|
5645
5797
|
// src/cli/doctor.ts
|
|
5646
5798
|
function checkFileExists(cwd, file) {
|
|
5647
|
-
return (0, import_node_fs4.existsSync)((0,
|
|
5799
|
+
return (0, import_node_fs4.existsSync)((0, import_node_path20.join)(cwd, file));
|
|
5648
5800
|
}
|
|
5649
5801
|
function readJson(path) {
|
|
5650
5802
|
try {
|
|
@@ -5680,15 +5832,15 @@ function writeJsonField(filePath, dotPath, value) {
|
|
|
5680
5832
|
}
|
|
5681
5833
|
function getPackageVersion(cwd, pkg) {
|
|
5682
5834
|
try {
|
|
5683
|
-
const pkgJson = readJson((0,
|
|
5835
|
+
const pkgJson = readJson((0, import_node_path20.join)(cwd, "node_modules", pkg, "package.json"));
|
|
5684
5836
|
return pkgJson?.version ?? null;
|
|
5685
5837
|
} catch {
|
|
5686
5838
|
return null;
|
|
5687
5839
|
}
|
|
5688
5840
|
}
|
|
5689
5841
|
function detectPkgManager(cwd) {
|
|
5690
|
-
if ((0, import_node_fs4.existsSync)((0,
|
|
5691
|
-
if ((0, import_node_fs4.existsSync)((0,
|
|
5842
|
+
if ((0, import_node_fs4.existsSync)((0, import_node_path20.join)(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
5843
|
+
if ((0, import_node_fs4.existsSync)((0, import_node_path20.join)(cwd, "yarn.lock"))) return "yarn";
|
|
5692
5844
|
return "npm";
|
|
5693
5845
|
}
|
|
5694
5846
|
async function runDoctor(opts) {
|
|
@@ -5726,7 +5878,7 @@ async function runDoctor(opts) {
|
|
|
5726
5878
|
autoFix: () => runInit({ cwd })
|
|
5727
5879
|
});
|
|
5728
5880
|
if (foundShellDir) {
|
|
5729
|
-
const nestCliPath = (0,
|
|
5881
|
+
const nestCliPath = (0, import_node_path20.join)(cwd, "nest-cli.json");
|
|
5730
5882
|
const nestCli = readJson(nestCliPath);
|
|
5731
5883
|
const compiler = nestCli?.compilerOptions ?? {};
|
|
5732
5884
|
const assets = compiler.assets ?? [];
|
|
@@ -5765,7 +5917,7 @@ async function runDoctor(opts) {
|
|
|
5765
5917
|
fix: "Run: nestjs-codegen codegen",
|
|
5766
5918
|
autoFix: () => runCodegen({ cwd })
|
|
5767
5919
|
});
|
|
5768
|
-
const tsconfigPath = (0,
|
|
5920
|
+
const tsconfigPath = (0, import_node_path20.join)(cwd, "tsconfig.json");
|
|
5769
5921
|
const tsconfig = readJson(tsconfigPath);
|
|
5770
5922
|
const paths = tsconfig?.compilerOptions?.paths;
|
|
5771
5923
|
checks.push({
|
|
@@ -5776,7 +5928,7 @@ async function runDoctor(opts) {
|
|
|
5776
5928
|
});
|
|
5777
5929
|
const inertiaDir = foundShellDir ?? "inertia";
|
|
5778
5930
|
for (const tsconfigFile of ["tsconfig.json", "tsconfig.build.json"]) {
|
|
5779
|
-
const tsc = readJson((0,
|
|
5931
|
+
const tsc = readJson((0, import_node_path20.join)(cwd, tsconfigFile));
|
|
5780
5932
|
if (!tsc) continue;
|
|
5781
5933
|
const excl = tsc.exclude ?? [];
|
|
5782
5934
|
const excludesIt = excl.includes(inertiaDir);
|
|
@@ -5802,7 +5954,7 @@ async function runDoctor(opts) {
|
|
|
5802
5954
|
}
|
|
5803
5955
|
});
|
|
5804
5956
|
}
|
|
5805
|
-
const inertiaTsconfigPath = (0,
|
|
5957
|
+
const inertiaTsconfigPath = (0, import_node_path20.join)(cwd, "tsconfig.inertia.json");
|
|
5806
5958
|
const inertiaTsconfig = readJson(inertiaTsconfigPath);
|
|
5807
5959
|
checks.push({
|
|
5808
5960
|
name: "tsconfig.inertia.json exists",
|
|
@@ -5854,7 +6006,7 @@ async function runDoctor(opts) {
|
|
|
5854
6006
|
fix: 'Add "nestjs-inertia.d.ts" to include array (resolves InertiaRegistry augmentation)'
|
|
5855
6007
|
});
|
|
5856
6008
|
}
|
|
5857
|
-
const innerTsconfigPath = (0,
|
|
6009
|
+
const innerTsconfigPath = (0, import_node_path20.join)(cwd, "inertia", "tsconfig.json");
|
|
5858
6010
|
checks.push({
|
|
5859
6011
|
name: "inertia/tsconfig.json exists (VSCode picks up ~codegen alias)",
|
|
5860
6012
|
pass: (0, import_node_fs4.existsSync)(innerTsconfigPath),
|
|
@@ -5864,7 +6016,7 @@ async function runDoctor(opts) {
|
|
|
5864
6016
|
}
|
|
5865
6017
|
});
|
|
5866
6018
|
if (checkFileExists(cwd, "vite.config.ts")) {
|
|
5867
|
-
const viteContent = (0, import_node_fs4.readFileSync)((0,
|
|
6019
|
+
const viteContent = (0, import_node_fs4.readFileSync)((0, import_node_path20.join)(cwd, "vite.config.ts"), "utf8");
|
|
5868
6020
|
checks.push({
|
|
5869
6021
|
name: "vite.config.ts has resolve.alias",
|
|
5870
6022
|
pass: viteContent.includes("resolve") && viteContent.includes("alias"),
|
|
@@ -5929,7 +6081,7 @@ async function runDoctor(opts) {
|
|
|
5929
6081
|
});
|
|
5930
6082
|
}
|
|
5931
6083
|
if (checkFileExists(cwd, ".gitignore")) {
|
|
5932
|
-
const gitignorePath = (0,
|
|
6084
|
+
const gitignorePath = (0, import_node_path20.join)(cwd, ".gitignore");
|
|
5933
6085
|
const gitignore = (0, import_node_fs4.readFileSync)(gitignorePath, "utf8");
|
|
5934
6086
|
checks.push({
|
|
5935
6087
|
name: ".gitignore includes .nestjs-inertia/",
|
|
@@ -5938,7 +6090,7 @@ async function runDoctor(opts) {
|
|
|
5938
6090
|
autoFix: () => (0, import_node_fs4.appendFileSync)(gitignorePath, "\n.nestjs-inertia/\n")
|
|
5939
6091
|
});
|
|
5940
6092
|
}
|
|
5941
|
-
const pkgJsonPath = (0,
|
|
6093
|
+
const pkgJsonPath = (0, import_node_path20.join)(cwd, "package.json");
|
|
5942
6094
|
const pkgJson = readJson(pkgJsonPath);
|
|
5943
6095
|
const scripts = pkgJson?.scripts ?? {};
|
|
5944
6096
|
checks.push({
|