@dudousxd/nestjs-codegen 0.11.0 → 0.13.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 +59 -0
- package/dist/cli/main.cjs +264 -91
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +248 -75
- package/dist/cli/main.js.map +1 -1
- package/dist/extension/index.d.cts +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/{index-CxkGbILp.d.cts → index-DvUzPXdh.d.cts} +7 -0
- package/dist/{index-CxkGbILp.d.ts → index-DvUzPXdh.d.ts} +7 -0
- package/dist/index.cjs +222 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -5
- package/dist/index.d.ts +31 -5
- package/dist/index.js +209 -36
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +267 -75
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +16 -5
- package/dist/nest/index.d.ts +16 -5
- package/dist/nest/index.js +267 -75
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
package/dist/nest/index.cjs
CHANGED
|
@@ -174,8 +174,8 @@ function applyDefaults(userConfig, cwd) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// src/watch/watcher.ts
|
|
177
|
-
var
|
|
178
|
-
var
|
|
177
|
+
var import_promises15 = require("fs/promises");
|
|
178
|
+
var import_node_path17 = require("path");
|
|
179
179
|
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
180
180
|
|
|
181
181
|
// src/discovery/contracts-fast.ts
|
|
@@ -1589,6 +1589,55 @@ function extractParamsType(method, sourceFile, project) {
|
|
|
1589
1589
|
}
|
|
1590
1590
|
return entries.length > 0 ? `{ ${entries.join("; ")} }` : null;
|
|
1591
1591
|
}
|
|
1592
|
+
function extractUploadedFiles(method) {
|
|
1593
|
+
const FILE = "File | Blob";
|
|
1594
|
+
const entries = [];
|
|
1595
|
+
let multipart = false;
|
|
1596
|
+
const hasUploadedFileParam = method.getParameters().some(
|
|
1597
|
+
(p) => p.getDecorators().some((d) => {
|
|
1598
|
+
const name = d.getName();
|
|
1599
|
+
return name === "UploadedFile" || name === "UploadedFiles";
|
|
1600
|
+
})
|
|
1601
|
+
);
|
|
1602
|
+
for (const decorator of method.getDecorators()) {
|
|
1603
|
+
if (decorator.getName() !== "UseInterceptors") continue;
|
|
1604
|
+
for (const arg of decorator.getArguments()) {
|
|
1605
|
+
if (!import_ts_morph5.Node.isCallExpression(arg)) continue;
|
|
1606
|
+
const interceptor = arg.getExpression().getText();
|
|
1607
|
+
const callArgs = arg.getArguments();
|
|
1608
|
+
const firstArg2 = callArgs[0];
|
|
1609
|
+
if (interceptor === "FileInterceptor") {
|
|
1610
|
+
if (firstArg2 && import_ts_morph5.Node.isStringLiteral(firstArg2)) {
|
|
1611
|
+
entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
|
|
1612
|
+
multipart = true;
|
|
1613
|
+
}
|
|
1614
|
+
} else if (interceptor === "FilesInterceptor") {
|
|
1615
|
+
if (firstArg2 && import_ts_morph5.Node.isStringLiteral(firstArg2)) {
|
|
1616
|
+
entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
|
|
1617
|
+
multipart = true;
|
|
1618
|
+
}
|
|
1619
|
+
} else if (interceptor === "FileFieldsInterceptor") {
|
|
1620
|
+
if (firstArg2 && import_ts_morph5.Node.isArrayLiteralExpression(firstArg2)) {
|
|
1621
|
+
for (const el of firstArg2.getElements()) {
|
|
1622
|
+
if (!import_ts_morph5.Node.isObjectLiteralExpression(el)) continue;
|
|
1623
|
+
const nameProp = el.getProperty("name");
|
|
1624
|
+
if (nameProp && import_ts_morph5.Node.isPropertyAssignment(nameProp)) {
|
|
1625
|
+
const init = nameProp.getInitializer();
|
|
1626
|
+
if (init && import_ts_morph5.Node.isStringLiteral(init)) {
|
|
1627
|
+
entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
multipart = true;
|
|
1632
|
+
}
|
|
1633
|
+
} else if (interceptor === "AnyFilesInterceptor") {
|
|
1634
|
+
multipart = true;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
if (hasUploadedFileParam) multipart = true;
|
|
1639
|
+
return { fields: entries.length > 0 ? entries.join("; ") : null, multipart };
|
|
1640
|
+
}
|
|
1592
1641
|
function extractResponseType(method, sourceFile, project) {
|
|
1593
1642
|
const apiResponseDecorator = method.getDecorators().find((d) => d.getName() === "ApiResponse" && (apiResponseStatus(d) ?? 0) < 400);
|
|
1594
1643
|
if (apiResponseDecorator) {
|
|
@@ -1723,6 +1772,11 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
1723
1772
|
let body = extractBodyType(method, sourceFile, project);
|
|
1724
1773
|
const filterInfo = extractApplyFilterInfo(method, sourceFile, project);
|
|
1725
1774
|
const query = extractQueryType(method, sourceFile, project);
|
|
1775
|
+
const uploads = extractUploadedFiles(method);
|
|
1776
|
+
if (uploads.fields) {
|
|
1777
|
+
const fileObject = `{ ${uploads.fields} }`;
|
|
1778
|
+
body = body ? `(${body}) & ${fileObject}` : fileObject;
|
|
1779
|
+
}
|
|
1726
1780
|
const streamElement = detectStreamElement(method);
|
|
1727
1781
|
const isStream = streamElement !== null;
|
|
1728
1782
|
if (filterInfo && filterInfo.source === "body") {
|
|
@@ -1732,7 +1786,7 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
1732
1786
|
const paramsType = extractParamsType(method, sourceFile, project);
|
|
1733
1787
|
const response = isStream ? resolveTypeNodeToString(streamElement, sourceFile, project, 3) : extractResponseType(method, sourceFile, project);
|
|
1734
1788
|
const errorInfo = extractErrorType(method, sourceFile, project);
|
|
1735
|
-
if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream) {
|
|
1789
|
+
if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream && !uploads.multipart) {
|
|
1736
1790
|
return null;
|
|
1737
1791
|
}
|
|
1738
1792
|
let bodyRef = null;
|
|
@@ -1805,7 +1859,8 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
1805
1859
|
formWarnings,
|
|
1806
1860
|
bodySchema,
|
|
1807
1861
|
querySchema,
|
|
1808
|
-
stream: isStream
|
|
1862
|
+
stream: isStream,
|
|
1863
|
+
multipart: uploads.multipart
|
|
1809
1864
|
};
|
|
1810
1865
|
}
|
|
1811
1866
|
function resolveParamClass(method, decoratorName, sourceFile, project) {
|
|
@@ -2272,7 +2327,8 @@ function extractDtoRoute(args) {
|
|
|
2272
2327
|
formWarnings: dtoContract?.formWarnings ?? [],
|
|
2273
2328
|
bodySchema: dtoContract?.bodySchema ?? null,
|
|
2274
2329
|
querySchema: dtoContract?.querySchema ?? null,
|
|
2275
|
-
stream: dtoContract?.stream ?? false
|
|
2330
|
+
stream: dtoContract?.stream ?? false,
|
|
2331
|
+
multipart: dtoContract?.multipart ?? false
|
|
2276
2332
|
}
|
|
2277
2333
|
});
|
|
2278
2334
|
}
|
|
@@ -2315,8 +2371,8 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
2315
2371
|
}
|
|
2316
2372
|
|
|
2317
2373
|
// src/generate.ts
|
|
2318
|
-
var
|
|
2319
|
-
var
|
|
2374
|
+
var import_promises14 = require("fs/promises");
|
|
2375
|
+
var import_node_path16 = require("path");
|
|
2320
2376
|
|
|
2321
2377
|
// src/discovery/pages.ts
|
|
2322
2378
|
var import_promises2 = require("fs/promises");
|
|
@@ -2918,6 +2974,7 @@ function buildRequestModel(c) {
|
|
|
2918
2974
|
const optsParts = [];
|
|
2919
2975
|
if (hasQuery) optsParts.push("query: input?.query as Record<string, unknown> | undefined");
|
|
2920
2976
|
if (hasBody) optsParts.push("body: input?.body");
|
|
2977
|
+
if (hasBody && c.contractSource.multipart) optsParts.push("multipart: true");
|
|
2921
2978
|
const optsExpr = optsParts.length ? `{ ${optsParts.join(", ")} }` : "{}";
|
|
2922
2979
|
return {
|
|
2923
2980
|
routeName: c.name,
|
|
@@ -4211,9 +4268,159 @@ function buildEmpty() {
|
|
|
4211
4268
|
].join("\n");
|
|
4212
4269
|
}
|
|
4213
4270
|
|
|
4271
|
+
// src/generate-manifest.ts
|
|
4272
|
+
var import_node_crypto = require("crypto");
|
|
4273
|
+
var import_promises13 = require("fs/promises");
|
|
4274
|
+
var import_node_path15 = require("path");
|
|
4275
|
+
var import_fast_glob3 = __toESM(require("fast-glob"), 1);
|
|
4276
|
+
|
|
4277
|
+
// src/watch/lock-file.ts
|
|
4278
|
+
var import_promises11 = require("fs/promises");
|
|
4279
|
+
var import_promises12 = require("fs/promises");
|
|
4280
|
+
var import_node_path14 = require("path");
|
|
4281
|
+
var LOCK_FILE = ".watcher.lock";
|
|
4282
|
+
function isProcessAlive(pid) {
|
|
4283
|
+
try {
|
|
4284
|
+
process.kill(pid, 0);
|
|
4285
|
+
return true;
|
|
4286
|
+
} catch {
|
|
4287
|
+
return false;
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
4290
|
+
async function acquireLock(outDir) {
|
|
4291
|
+
await (0, import_promises12.mkdir)(outDir, { recursive: true });
|
|
4292
|
+
const lockPath = (0, import_node_path14.join)(outDir, LOCK_FILE);
|
|
4293
|
+
const lockData = { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4294
|
+
try {
|
|
4295
|
+
const fd = await (0, import_promises11.open)(lockPath, "wx");
|
|
4296
|
+
await fd.writeFile(`${JSON.stringify(lockData, null, 2)}
|
|
4297
|
+
`, "utf8");
|
|
4298
|
+
await fd.close();
|
|
4299
|
+
} catch (err) {
|
|
4300
|
+
if (err.code === "EEXIST") {
|
|
4301
|
+
try {
|
|
4302
|
+
const raw = await (0, import_promises12.readFile)(lockPath, "utf8");
|
|
4303
|
+
const existing = JSON.parse(raw);
|
|
4304
|
+
if (isProcessAlive(existing.pid)) return null;
|
|
4305
|
+
await (0, import_promises12.unlink)(lockPath);
|
|
4306
|
+
return acquireLock(outDir);
|
|
4307
|
+
} catch {
|
|
4308
|
+
return null;
|
|
4309
|
+
}
|
|
4310
|
+
}
|
|
4311
|
+
return null;
|
|
4312
|
+
}
|
|
4313
|
+
return {
|
|
4314
|
+
release: async () => {
|
|
4315
|
+
try {
|
|
4316
|
+
await (0, import_promises12.unlink)(lockPath);
|
|
4317
|
+
} catch {
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
};
|
|
4321
|
+
}
|
|
4322
|
+
|
|
4323
|
+
// src/index.ts
|
|
4324
|
+
var VERSION = "0.13.0";
|
|
4325
|
+
|
|
4326
|
+
// src/generate-manifest.ts
|
|
4327
|
+
var MANIFEST_FILE = ".codegen-manifest.json";
|
|
4328
|
+
var LOCK_FILE2 = ".watcher.lock";
|
|
4329
|
+
function isManifestShape(value) {
|
|
4330
|
+
if (typeof value !== "object" || value === null) return false;
|
|
4331
|
+
const candidate = value;
|
|
4332
|
+
if (typeof candidate.version !== "string") return false;
|
|
4333
|
+
if (typeof candidate.hash !== "string") return false;
|
|
4334
|
+
if (!Array.isArray(candidate.files)) return false;
|
|
4335
|
+
return candidate.files.every((entry) => typeof entry === "string");
|
|
4336
|
+
}
|
|
4337
|
+
function serializeConfig(config) {
|
|
4338
|
+
try {
|
|
4339
|
+
return JSON.stringify(config, (_key, value) => {
|
|
4340
|
+
if (typeof value === "function") return `[fn:${value.name}]${value.toString()}`;
|
|
4341
|
+
return value;
|
|
4342
|
+
});
|
|
4343
|
+
} catch {
|
|
4344
|
+
return `unserializable:${config.codegen.outDir}:${config.contracts.glob}`;
|
|
4345
|
+
}
|
|
4346
|
+
}
|
|
4347
|
+
async function discoverInputFiles(config) {
|
|
4348
|
+
const globs = [config.contracts.glob, config.forms.watch];
|
|
4349
|
+
if (config.pages) globs.push(config.pages.glob);
|
|
4350
|
+
const cwd = config.codegen.cwd;
|
|
4351
|
+
const matched = await (0, import_fast_glob3.default)(globs, { cwd, absolute: true, onlyFiles: true });
|
|
4352
|
+
return [...new Set(matched)].sort();
|
|
4353
|
+
}
|
|
4354
|
+
async function computeInputsHash(config) {
|
|
4355
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
4356
|
+
hash.update(`version:${VERSION}
|
|
4357
|
+
`);
|
|
4358
|
+
hash.update(`config:${serializeConfig(config)}
|
|
4359
|
+
`);
|
|
4360
|
+
const inputFiles = await discoverInputFiles(config);
|
|
4361
|
+
const cwd = config.codegen.cwd;
|
|
4362
|
+
for (const file of inputFiles) {
|
|
4363
|
+
const contents = await (0, import_promises13.readFile)(file, "utf8");
|
|
4364
|
+
hash.update(`file:${(0, import_node_path15.relative)(cwd, file)}
|
|
4365
|
+
`);
|
|
4366
|
+
hash.update(contents);
|
|
4367
|
+
hash.update("\n");
|
|
4368
|
+
}
|
|
4369
|
+
return hash.digest("hex");
|
|
4370
|
+
}
|
|
4371
|
+
async function readManifest(outDir) {
|
|
4372
|
+
try {
|
|
4373
|
+
const raw = await (0, import_promises13.readFile)((0, import_node_path15.join)(outDir, MANIFEST_FILE), "utf8");
|
|
4374
|
+
const parsed = JSON.parse(raw);
|
|
4375
|
+
if (!isManifestShape(parsed)) return null;
|
|
4376
|
+
return { version: parsed.version, hash: parsed.hash, files: parsed.files };
|
|
4377
|
+
} catch {
|
|
4378
|
+
return null;
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
async function writeManifest(outDir, manifest) {
|
|
4382
|
+
await (0, import_promises13.writeFile)((0, import_node_path15.join)(outDir, MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
|
|
4383
|
+
`, "utf8");
|
|
4384
|
+
}
|
|
4385
|
+
async function listOutputFiles(outDir) {
|
|
4386
|
+
const found = [];
|
|
4387
|
+
async function walk(dir) {
|
|
4388
|
+
const entries = await (0, import_promises13.readdir)(dir, { withFileTypes: true }).catch(() => []);
|
|
4389
|
+
for (const entry of entries) {
|
|
4390
|
+
const abs = (0, import_node_path15.join)(dir, entry.name);
|
|
4391
|
+
if (entry.isDirectory()) {
|
|
4392
|
+
await walk(abs);
|
|
4393
|
+
} else if (entry.isFile()) {
|
|
4394
|
+
const rel = (0, import_node_path15.relative)(outDir, abs);
|
|
4395
|
+
if (rel === MANIFEST_FILE || rel === LOCK_FILE2) continue;
|
|
4396
|
+
found.push(rel);
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
}
|
|
4400
|
+
await walk(outDir);
|
|
4401
|
+
return found.sort();
|
|
4402
|
+
}
|
|
4403
|
+
async function allOutputsExist(outDir, files) {
|
|
4404
|
+
const present = new Set(await listOutputFiles(outDir));
|
|
4405
|
+
return files.every((file) => present.has(file));
|
|
4406
|
+
}
|
|
4407
|
+
async function isManifestFresh(outDir, manifest, inputsHash) {
|
|
4408
|
+
if (manifest === null) return false;
|
|
4409
|
+
if (manifest.version !== VERSION) return false;
|
|
4410
|
+
if (manifest.hash !== inputsHash) return false;
|
|
4411
|
+
if (manifest.files.length === 0) return false;
|
|
4412
|
+
return allOutputsExist(outDir, manifest.files);
|
|
4413
|
+
}
|
|
4414
|
+
|
|
4214
4415
|
// src/generate.ts
|
|
4215
4416
|
async function generate(config, inputRoutes = []) {
|
|
4216
4417
|
setCodegenDebug(config.debug);
|
|
4418
|
+
const inputsHash = await computeInputsHash(config);
|
|
4419
|
+
const manifest = await readManifest(config.codegen.outDir);
|
|
4420
|
+
if (await isManifestFresh(config.codegen.outDir, manifest, inputsHash)) {
|
|
4421
|
+
console.log(`[nestjs-codegen] ${config.codegen.outDir} up to date, skipped`);
|
|
4422
|
+
return;
|
|
4423
|
+
}
|
|
4217
4424
|
const extensions = config.extensions ?? [];
|
|
4218
4425
|
let routes = inputRoutes;
|
|
4219
4426
|
const ctx = createExtensionContext(config, () => routes);
|
|
@@ -4270,69 +4477,29 @@ async function generate(config, inputRoutes = []) {
|
|
|
4270
4477
|
if (extensions.length > 0) {
|
|
4271
4478
|
const extraFiles = await collectEmittedFiles(extensions, ctx);
|
|
4272
4479
|
for (const file of extraFiles) {
|
|
4273
|
-
const dest = (0,
|
|
4274
|
-
await (0,
|
|
4275
|
-
await (0,
|
|
4276
|
-
}
|
|
4277
|
-
}
|
|
4278
|
-
}
|
|
4279
|
-
|
|
4280
|
-
// src/watch/lock-file.ts
|
|
4281
|
-
var import_promises12 = require("fs/promises");
|
|
4282
|
-
var import_promises13 = require("fs/promises");
|
|
4283
|
-
var import_node_path15 = require("path");
|
|
4284
|
-
var LOCK_FILE = ".watcher.lock";
|
|
4285
|
-
function isProcessAlive(pid) {
|
|
4286
|
-
try {
|
|
4287
|
-
process.kill(pid, 0);
|
|
4288
|
-
return true;
|
|
4289
|
-
} catch {
|
|
4290
|
-
return false;
|
|
4291
|
-
}
|
|
4292
|
-
}
|
|
4293
|
-
async function acquireLock(outDir) {
|
|
4294
|
-
await (0, import_promises13.mkdir)(outDir, { recursive: true });
|
|
4295
|
-
const lockPath = (0, import_node_path15.join)(outDir, LOCK_FILE);
|
|
4296
|
-
const lockData = { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4297
|
-
try {
|
|
4298
|
-
const fd = await (0, import_promises12.open)(lockPath, "wx");
|
|
4299
|
-
await fd.writeFile(`${JSON.stringify(lockData, null, 2)}
|
|
4300
|
-
`, "utf8");
|
|
4301
|
-
await fd.close();
|
|
4302
|
-
} catch (err) {
|
|
4303
|
-
if (err.code === "EEXIST") {
|
|
4304
|
-
try {
|
|
4305
|
-
const raw = await (0, import_promises13.readFile)(lockPath, "utf8");
|
|
4306
|
-
const existing = JSON.parse(raw);
|
|
4307
|
-
if (isProcessAlive(existing.pid)) return null;
|
|
4308
|
-
await (0, import_promises13.unlink)(lockPath);
|
|
4309
|
-
return acquireLock(outDir);
|
|
4310
|
-
} catch {
|
|
4311
|
-
return null;
|
|
4312
|
-
}
|
|
4480
|
+
const dest = (0, import_node_path16.join)(config.codegen.outDir, file.path);
|
|
4481
|
+
await (0, import_promises14.mkdir)((0, import_node_path16.dirname)(dest), { recursive: true });
|
|
4482
|
+
await (0, import_promises14.writeFile)(dest, file.contents, "utf8");
|
|
4313
4483
|
}
|
|
4314
|
-
return null;
|
|
4315
4484
|
}
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
}
|
|
4323
|
-
};
|
|
4485
|
+
const outputFiles = await listOutputFiles(config.codegen.outDir);
|
|
4486
|
+
await writeManifest(config.codegen.outDir, {
|
|
4487
|
+
version: VERSION,
|
|
4488
|
+
hash: inputsHash,
|
|
4489
|
+
files: outputFiles
|
|
4490
|
+
});
|
|
4324
4491
|
}
|
|
4325
4492
|
|
|
4326
4493
|
// src/watch/watcher.ts
|
|
4327
4494
|
var PAGES_DEBOUNCE_MS = 150;
|
|
4328
4495
|
var NO_OP_WATCHER = { close: async () => {
|
|
4329
4496
|
} };
|
|
4330
|
-
async function watch(config, onChange) {
|
|
4497
|
+
async function watch(config, onChange, options = {}) {
|
|
4331
4498
|
const lock = await acquireLock(config.codegen.outDir);
|
|
4332
4499
|
if (lock === null) {
|
|
4333
4500
|
let holderPid = "unknown";
|
|
4334
4501
|
try {
|
|
4335
|
-
const raw = await (0,
|
|
4502
|
+
const raw = await (0, import_promises15.readFile)((0, import_node_path17.join)(config.codegen.outDir, ".watcher.lock"), "utf8");
|
|
4336
4503
|
const data = JSON.parse(raw);
|
|
4337
4504
|
if (data.pid !== void 0) holderPid = String(data.pid);
|
|
4338
4505
|
} catch {
|
|
@@ -4355,22 +4522,33 @@ async function watch(config, onChange) {
|
|
|
4355
4522
|
}
|
|
4356
4523
|
return discovery;
|
|
4357
4524
|
}
|
|
4358
|
-
|
|
4359
|
-
const initialRoutes = (await getDiscovery()).discover();
|
|
4360
|
-
lastRoutes = initialRoutes;
|
|
4361
|
-
await generate(config, initialRoutes);
|
|
4362
|
-
} catch (err) {
|
|
4363
|
-
console.warn(
|
|
4364
|
-
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
4365
|
-
);
|
|
4525
|
+
async function runInitialPass() {
|
|
4366
4526
|
try {
|
|
4367
|
-
await
|
|
4368
|
-
|
|
4527
|
+
const initialRoutes = (await getDiscovery()).discover();
|
|
4528
|
+
lastRoutes = initialRoutes;
|
|
4529
|
+
await generate(config, initialRoutes);
|
|
4530
|
+
} catch (err) {
|
|
4531
|
+
console.warn(
|
|
4532
|
+
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
4533
|
+
);
|
|
4534
|
+
try {
|
|
4535
|
+
await generate(config, lastRoutes);
|
|
4536
|
+
} catch {
|
|
4537
|
+
}
|
|
4369
4538
|
}
|
|
4370
4539
|
}
|
|
4540
|
+
if (options.deferInitialGenerate) {
|
|
4541
|
+
void runInitialPass().catch((err) => {
|
|
4542
|
+
console.warn(
|
|
4543
|
+
`[nestjs-codegen] Background initial generate failed: ${err instanceof Error ? err.message : String(err)}`
|
|
4544
|
+
);
|
|
4545
|
+
});
|
|
4546
|
+
} else {
|
|
4547
|
+
await runInitialPass();
|
|
4548
|
+
}
|
|
4371
4549
|
let pagesDebounceTimer;
|
|
4372
4550
|
const pagesGlob = config.pages?.glob ?? ".nestjs-codegen-no-pages";
|
|
4373
|
-
const pagesWatcher = import_chokidar.default.watch((0,
|
|
4551
|
+
const pagesWatcher = import_chokidar.default.watch((0, import_node_path17.join)(config.codegen.cwd, pagesGlob), {
|
|
4374
4552
|
ignoreInitial: true,
|
|
4375
4553
|
persistent: true,
|
|
4376
4554
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4397,7 +4575,7 @@ async function watch(config, onChange) {
|
|
|
4397
4575
|
pagesWatcher.on("unlink", schedulePagesRegenerate);
|
|
4398
4576
|
let contractsDebounceTimer;
|
|
4399
4577
|
const pendingChangedPaths = /* @__PURE__ */ new Set();
|
|
4400
|
-
const contractsWatcher = import_chokidar.default.watch((0,
|
|
4578
|
+
const contractsWatcher = import_chokidar.default.watch((0, import_node_path17.join)(config.codegen.cwd, config.contracts.glob), {
|
|
4401
4579
|
ignoreInitial: true,
|
|
4402
4580
|
persistent: true,
|
|
4403
4581
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4427,7 +4605,7 @@ async function watch(config, onChange) {
|
|
|
4427
4605
|
contractsWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
4428
4606
|
contractsWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
4429
4607
|
contractsWatcher.on("unlink", (p) => scheduleContractsRegenerate(p));
|
|
4430
|
-
const formsWatcher = import_chokidar.default.watch((0,
|
|
4608
|
+
const formsWatcher = import_chokidar.default.watch((0, import_node_path17.join)(config.codegen.cwd, config.forms.watch), {
|
|
4431
4609
|
ignoreInitial: true,
|
|
4432
4610
|
persistent: true,
|
|
4433
4611
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4455,9 +4633,13 @@ async function watch(config, onChange) {
|
|
|
4455
4633
|
|
|
4456
4634
|
// src/nest/module.ts
|
|
4457
4635
|
var CODEGEN_MODULE_OPTIONS = Symbol("NESTJS_CODEGEN_MODULE_OPTIONS");
|
|
4636
|
+
function isProductionEnv(env) {
|
|
4637
|
+
return (env ?? "").trim().toLowerCase() === "production";
|
|
4638
|
+
}
|
|
4458
4639
|
function shouldRun(options, env) {
|
|
4459
4640
|
if (options.enabled !== void 0) return options.enabled;
|
|
4460
|
-
|
|
4641
|
+
if (isProductionEnv(env)) return options.runInProduction === true;
|
|
4642
|
+
return true;
|
|
4461
4643
|
}
|
|
4462
4644
|
var NestjsCodegenService = class {
|
|
4463
4645
|
constructor(options) {
|
|
@@ -4466,11 +4648,21 @@ var NestjsCodegenService = class {
|
|
|
4466
4648
|
logger = new import_common.Logger("NestjsCodegen");
|
|
4467
4649
|
watcher = null;
|
|
4468
4650
|
async onApplicationBootstrap() {
|
|
4469
|
-
if (!shouldRun(this.options, process.env.NODE_ENV))
|
|
4470
|
-
|
|
4651
|
+
if (!shouldRun(this.options, process.env.NODE_ENV)) {
|
|
4652
|
+
if (this.options.enabled === void 0 && isProductionEnv(process.env.NODE_ENV)) {
|
|
4653
|
+
this.logger.log("Skipped in production (set runInProduction: true to override).");
|
|
4654
|
+
}
|
|
4655
|
+
return;
|
|
4656
|
+
}
|
|
4657
|
+
const {
|
|
4658
|
+
enabled: _enabled,
|
|
4659
|
+
runInProduction: _runInProduction,
|
|
4660
|
+
cwd,
|
|
4661
|
+
...userConfig
|
|
4662
|
+
} = this.options;
|
|
4471
4663
|
try {
|
|
4472
4664
|
const config = resolveConfig(userConfig, cwd ?? process.cwd());
|
|
4473
|
-
this.watcher = await watch(config);
|
|
4665
|
+
this.watcher = await watch(config, void 0, { deferInitialGenerate: true });
|
|
4474
4666
|
this.logger.log(`Watching ${config.contracts.glob} \u2192 ${config.codegen.outDir}`);
|
|
4475
4667
|
} catch (err) {
|
|
4476
4668
|
this.logger.warn(
|