@dudousxd/nestjs-codegen 0.10.0 → 0.12.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 +47 -0
- package/dist/cli/main.cjs +209 -89
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +193 -73
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +167 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -3
- package/dist/index.d.ts +29 -3
- package/dist/index.js +154 -34
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +212 -73
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +15 -4
- package/dist/nest/index.d.ts +15 -4
- package/dist/nest/index.js +212 -73
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
package/dist/nest/index.d.cts
CHANGED
|
@@ -33,11 +33,21 @@ interface CodegenModuleOptions extends Omit<UserConfig, 'validation'> {
|
|
|
33
33
|
validation?: UserConfig['validation'];
|
|
34
34
|
/**
|
|
35
35
|
* Master switch for the boot-time watcher. When omitted, the watcher runs in every
|
|
36
|
-
* environment EXCEPT production
|
|
37
|
-
*
|
|
38
|
-
*
|
|
36
|
+
* environment EXCEPT production — codegen is a dev/CI build step, not a
|
|
37
|
+
* production-runtime concern. Set `false` to disable entirely, or `true` to force it
|
|
38
|
+
* on even in production (overrides {@link runInProduction}).
|
|
39
39
|
*/
|
|
40
40
|
enabled?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Run the boot-time watcher even when `NODE_ENV` is `production`. Codegen is a
|
|
43
|
+
* dev-time concern — in production the artifacts are already built by the CLI in the
|
|
44
|
+
* build pipeline — so this defaults to `false` (skip in production). Set `true` only
|
|
45
|
+
* if you genuinely need to regenerate at production runtime. Ignored when `enabled`
|
|
46
|
+
* is set explicitly.
|
|
47
|
+
*
|
|
48
|
+
* @default false
|
|
49
|
+
*/
|
|
50
|
+
runInProduction?: boolean;
|
|
41
51
|
/** Project root used to resolve globs / `outDir`. Defaults to `process.cwd()`. */
|
|
42
52
|
cwd?: string;
|
|
43
53
|
}
|
|
@@ -45,7 +55,8 @@ interface CodegenModuleOptions extends Omit<UserConfig, 'validation'> {
|
|
|
45
55
|
declare const CODEGEN_MODULE_OPTIONS: unique symbol;
|
|
46
56
|
/**
|
|
47
57
|
* Decide whether the boot-time watcher should start, given the module options and the
|
|
48
|
-
* current `NODE_ENV`. Explicit `enabled` always wins; otherwise default on
|
|
58
|
+
* current `NODE_ENV`. Explicit `enabled` always wins; otherwise default on everywhere
|
|
59
|
+
* except production, where it stays off unless `runInProduction` is set.
|
|
49
60
|
*/
|
|
50
61
|
declare function shouldRun(options: CodegenModuleOptions, env: string | undefined): boolean;
|
|
51
62
|
/**
|
package/dist/nest/index.d.ts
CHANGED
|
@@ -33,11 +33,21 @@ interface CodegenModuleOptions extends Omit<UserConfig, 'validation'> {
|
|
|
33
33
|
validation?: UserConfig['validation'];
|
|
34
34
|
/**
|
|
35
35
|
* Master switch for the boot-time watcher. When omitted, the watcher runs in every
|
|
36
|
-
* environment EXCEPT production
|
|
37
|
-
*
|
|
38
|
-
*
|
|
36
|
+
* environment EXCEPT production — codegen is a dev/CI build step, not a
|
|
37
|
+
* production-runtime concern. Set `false` to disable entirely, or `true` to force it
|
|
38
|
+
* on even in production (overrides {@link runInProduction}).
|
|
39
39
|
*/
|
|
40
40
|
enabled?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Run the boot-time watcher even when `NODE_ENV` is `production`. Codegen is a
|
|
43
|
+
* dev-time concern — in production the artifacts are already built by the CLI in the
|
|
44
|
+
* build pipeline — so this defaults to `false` (skip in production). Set `true` only
|
|
45
|
+
* if you genuinely need to regenerate at production runtime. Ignored when `enabled`
|
|
46
|
+
* is set explicitly.
|
|
47
|
+
*
|
|
48
|
+
* @default false
|
|
49
|
+
*/
|
|
50
|
+
runInProduction?: boolean;
|
|
41
51
|
/** Project root used to resolve globs / `outDir`. Defaults to `process.cwd()`. */
|
|
42
52
|
cwd?: string;
|
|
43
53
|
}
|
|
@@ -45,7 +55,8 @@ interface CodegenModuleOptions extends Omit<UserConfig, 'validation'> {
|
|
|
45
55
|
declare const CODEGEN_MODULE_OPTIONS: unique symbol;
|
|
46
56
|
/**
|
|
47
57
|
* Decide whether the boot-time watcher should start, given the module options and the
|
|
48
|
-
* current `NODE_ENV`. Explicit `enabled` always wins; otherwise default on
|
|
58
|
+
* current `NODE_ENV`. Explicit `enabled` always wins; otherwise default on everywhere
|
|
59
|
+
* except production, where it stays off unless `runInProduction` is set.
|
|
49
60
|
*/
|
|
50
61
|
declare function shouldRun(options: CodegenModuleOptions, env: string | undefined): boolean;
|
|
51
62
|
/**
|
package/dist/nest/index.js
CHANGED
|
@@ -138,8 +138,8 @@ function applyDefaults(userConfig, cwd) {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
// src/watch/watcher.ts
|
|
141
|
-
import { readFile as
|
|
142
|
-
import { join as
|
|
141
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
142
|
+
import { join as join16 } from "path";
|
|
143
143
|
import chokidar from "chokidar";
|
|
144
144
|
|
|
145
145
|
// src/discovery/contracts-fast.ts
|
|
@@ -2294,8 +2294,8 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
2294
2294
|
}
|
|
2295
2295
|
|
|
2296
2296
|
// src/generate.ts
|
|
2297
|
-
import { mkdir as
|
|
2298
|
-
import { dirname as dirname3, join as
|
|
2297
|
+
import { mkdir as mkdir10, writeFile as writeFile10 } from "fs/promises";
|
|
2298
|
+
import { dirname as dirname3, join as join15 } from "path";
|
|
2299
2299
|
|
|
2300
2300
|
// src/discovery/pages.ts
|
|
2301
2301
|
import { readFile } from "fs/promises";
|
|
@@ -2909,7 +2909,11 @@ function buildRequestModel(c) {
|
|
|
2909
2909
|
urlExpr,
|
|
2910
2910
|
optsExpr,
|
|
2911
2911
|
responseType: `${TA}['response']`,
|
|
2912
|
-
|
|
2912
|
+
// When no input is supplied the key omits the trailing element entirely
|
|
2913
|
+
// (`[name]` rather than `[name, undefined]`) so the bare `.queryKey()` is a
|
|
2914
|
+
// clean prefix that partial-matches every parametrized variant — making it
|
|
2915
|
+
// directly usable for `invalidateQueries`.
|
|
2916
|
+
queryKeyExpr: `(input === undefined ? [${flat}] as const : [${flat}, input] as const)`
|
|
2913
2917
|
};
|
|
2914
2918
|
}
|
|
2915
2919
|
function renderFetcherRequest(req) {
|
|
@@ -4186,9 +4190,159 @@ function buildEmpty() {
|
|
|
4186
4190
|
].join("\n");
|
|
4187
4191
|
}
|
|
4188
4192
|
|
|
4193
|
+
// src/generate-manifest.ts
|
|
4194
|
+
import { createHash } from "crypto";
|
|
4195
|
+
import { readFile as readFile3, readdir, writeFile as writeFile9 } from "fs/promises";
|
|
4196
|
+
import { join as join14, relative as relative6 } from "path";
|
|
4197
|
+
import fg3 from "fast-glob";
|
|
4198
|
+
|
|
4199
|
+
// src/watch/lock-file.ts
|
|
4200
|
+
import { open } from "fs/promises";
|
|
4201
|
+
import { mkdir as mkdir9, readFile as readFile2, unlink } from "fs/promises";
|
|
4202
|
+
import { join as join13 } from "path";
|
|
4203
|
+
var LOCK_FILE = ".watcher.lock";
|
|
4204
|
+
function isProcessAlive(pid) {
|
|
4205
|
+
try {
|
|
4206
|
+
process.kill(pid, 0);
|
|
4207
|
+
return true;
|
|
4208
|
+
} catch {
|
|
4209
|
+
return false;
|
|
4210
|
+
}
|
|
4211
|
+
}
|
|
4212
|
+
async function acquireLock(outDir) {
|
|
4213
|
+
await mkdir9(outDir, { recursive: true });
|
|
4214
|
+
const lockPath = join13(outDir, LOCK_FILE);
|
|
4215
|
+
const lockData = { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4216
|
+
try {
|
|
4217
|
+
const fd = await open(lockPath, "wx");
|
|
4218
|
+
await fd.writeFile(`${JSON.stringify(lockData, null, 2)}
|
|
4219
|
+
`, "utf8");
|
|
4220
|
+
await fd.close();
|
|
4221
|
+
} catch (err) {
|
|
4222
|
+
if (err.code === "EEXIST") {
|
|
4223
|
+
try {
|
|
4224
|
+
const raw = await readFile2(lockPath, "utf8");
|
|
4225
|
+
const existing = JSON.parse(raw);
|
|
4226
|
+
if (isProcessAlive(existing.pid)) return null;
|
|
4227
|
+
await unlink(lockPath);
|
|
4228
|
+
return acquireLock(outDir);
|
|
4229
|
+
} catch {
|
|
4230
|
+
return null;
|
|
4231
|
+
}
|
|
4232
|
+
}
|
|
4233
|
+
return null;
|
|
4234
|
+
}
|
|
4235
|
+
return {
|
|
4236
|
+
release: async () => {
|
|
4237
|
+
try {
|
|
4238
|
+
await unlink(lockPath);
|
|
4239
|
+
} catch {
|
|
4240
|
+
}
|
|
4241
|
+
}
|
|
4242
|
+
};
|
|
4243
|
+
}
|
|
4244
|
+
|
|
4245
|
+
// src/index.ts
|
|
4246
|
+
var VERSION = "0.12.0";
|
|
4247
|
+
|
|
4248
|
+
// src/generate-manifest.ts
|
|
4249
|
+
var MANIFEST_FILE = ".codegen-manifest.json";
|
|
4250
|
+
var LOCK_FILE2 = ".watcher.lock";
|
|
4251
|
+
function isManifestShape(value) {
|
|
4252
|
+
if (typeof value !== "object" || value === null) return false;
|
|
4253
|
+
const candidate = value;
|
|
4254
|
+
if (typeof candidate.version !== "string") return false;
|
|
4255
|
+
if (typeof candidate.hash !== "string") return false;
|
|
4256
|
+
if (!Array.isArray(candidate.files)) return false;
|
|
4257
|
+
return candidate.files.every((entry) => typeof entry === "string");
|
|
4258
|
+
}
|
|
4259
|
+
function serializeConfig(config) {
|
|
4260
|
+
try {
|
|
4261
|
+
return JSON.stringify(config, (_key, value) => {
|
|
4262
|
+
if (typeof value === "function") return `[fn:${value.name}]${value.toString()}`;
|
|
4263
|
+
return value;
|
|
4264
|
+
});
|
|
4265
|
+
} catch {
|
|
4266
|
+
return `unserializable:${config.codegen.outDir}:${config.contracts.glob}`;
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
async function discoverInputFiles(config) {
|
|
4270
|
+
const globs = [config.contracts.glob, config.forms.watch];
|
|
4271
|
+
if (config.pages) globs.push(config.pages.glob);
|
|
4272
|
+
const cwd = config.codegen.cwd;
|
|
4273
|
+
const matched = await fg3(globs, { cwd, absolute: true, onlyFiles: true });
|
|
4274
|
+
return [...new Set(matched)].sort();
|
|
4275
|
+
}
|
|
4276
|
+
async function computeInputsHash(config) {
|
|
4277
|
+
const hash = createHash("sha256");
|
|
4278
|
+
hash.update(`version:${VERSION}
|
|
4279
|
+
`);
|
|
4280
|
+
hash.update(`config:${serializeConfig(config)}
|
|
4281
|
+
`);
|
|
4282
|
+
const inputFiles = await discoverInputFiles(config);
|
|
4283
|
+
const cwd = config.codegen.cwd;
|
|
4284
|
+
for (const file of inputFiles) {
|
|
4285
|
+
const contents = await readFile3(file, "utf8");
|
|
4286
|
+
hash.update(`file:${relative6(cwd, file)}
|
|
4287
|
+
`);
|
|
4288
|
+
hash.update(contents);
|
|
4289
|
+
hash.update("\n");
|
|
4290
|
+
}
|
|
4291
|
+
return hash.digest("hex");
|
|
4292
|
+
}
|
|
4293
|
+
async function readManifest(outDir) {
|
|
4294
|
+
try {
|
|
4295
|
+
const raw = await readFile3(join14(outDir, MANIFEST_FILE), "utf8");
|
|
4296
|
+
const parsed = JSON.parse(raw);
|
|
4297
|
+
if (!isManifestShape(parsed)) return null;
|
|
4298
|
+
return { version: parsed.version, hash: parsed.hash, files: parsed.files };
|
|
4299
|
+
} catch {
|
|
4300
|
+
return null;
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4303
|
+
async function writeManifest(outDir, manifest) {
|
|
4304
|
+
await writeFile9(join14(outDir, MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
|
|
4305
|
+
`, "utf8");
|
|
4306
|
+
}
|
|
4307
|
+
async function listOutputFiles(outDir) {
|
|
4308
|
+
const found = [];
|
|
4309
|
+
async function walk(dir) {
|
|
4310
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
4311
|
+
for (const entry of entries) {
|
|
4312
|
+
const abs = join14(dir, entry.name);
|
|
4313
|
+
if (entry.isDirectory()) {
|
|
4314
|
+
await walk(abs);
|
|
4315
|
+
} else if (entry.isFile()) {
|
|
4316
|
+
const rel = relative6(outDir, abs);
|
|
4317
|
+
if (rel === MANIFEST_FILE || rel === LOCK_FILE2) continue;
|
|
4318
|
+
found.push(rel);
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
}
|
|
4322
|
+
await walk(outDir);
|
|
4323
|
+
return found.sort();
|
|
4324
|
+
}
|
|
4325
|
+
async function allOutputsExist(outDir, files) {
|
|
4326
|
+
const present = new Set(await listOutputFiles(outDir));
|
|
4327
|
+
return files.every((file) => present.has(file));
|
|
4328
|
+
}
|
|
4329
|
+
async function isManifestFresh(outDir, manifest, inputsHash) {
|
|
4330
|
+
if (manifest === null) return false;
|
|
4331
|
+
if (manifest.version !== VERSION) return false;
|
|
4332
|
+
if (manifest.hash !== inputsHash) return false;
|
|
4333
|
+
if (manifest.files.length === 0) return false;
|
|
4334
|
+
return allOutputsExist(outDir, manifest.files);
|
|
4335
|
+
}
|
|
4336
|
+
|
|
4189
4337
|
// src/generate.ts
|
|
4190
4338
|
async function generate(config, inputRoutes = []) {
|
|
4191
4339
|
setCodegenDebug(config.debug);
|
|
4340
|
+
const inputsHash = await computeInputsHash(config);
|
|
4341
|
+
const manifest = await readManifest(config.codegen.outDir);
|
|
4342
|
+
if (await isManifestFresh(config.codegen.outDir, manifest, inputsHash)) {
|
|
4343
|
+
console.log(`[nestjs-codegen] ${config.codegen.outDir} up to date, skipped`);
|
|
4344
|
+
return;
|
|
4345
|
+
}
|
|
4192
4346
|
const extensions = config.extensions ?? [];
|
|
4193
4347
|
let routes = inputRoutes;
|
|
4194
4348
|
const ctx = createExtensionContext(config, () => routes);
|
|
@@ -4245,69 +4399,29 @@ async function generate(config, inputRoutes = []) {
|
|
|
4245
4399
|
if (extensions.length > 0) {
|
|
4246
4400
|
const extraFiles = await collectEmittedFiles(extensions, ctx);
|
|
4247
4401
|
for (const file of extraFiles) {
|
|
4248
|
-
const dest =
|
|
4249
|
-
await
|
|
4250
|
-
await
|
|
4402
|
+
const dest = join15(config.codegen.outDir, file.path);
|
|
4403
|
+
await mkdir10(dirname3(dest), { recursive: true });
|
|
4404
|
+
await writeFile10(dest, file.contents, "utf8");
|
|
4251
4405
|
}
|
|
4252
4406
|
}
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
var LOCK_FILE = ".watcher.lock";
|
|
4260
|
-
function isProcessAlive(pid) {
|
|
4261
|
-
try {
|
|
4262
|
-
process.kill(pid, 0);
|
|
4263
|
-
return true;
|
|
4264
|
-
} catch {
|
|
4265
|
-
return false;
|
|
4266
|
-
}
|
|
4267
|
-
}
|
|
4268
|
-
async function acquireLock(outDir) {
|
|
4269
|
-
await mkdir10(outDir, { recursive: true });
|
|
4270
|
-
const lockPath = join14(outDir, LOCK_FILE);
|
|
4271
|
-
const lockData = { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4272
|
-
try {
|
|
4273
|
-
const fd = await open(lockPath, "wx");
|
|
4274
|
-
await fd.writeFile(`${JSON.stringify(lockData, null, 2)}
|
|
4275
|
-
`, "utf8");
|
|
4276
|
-
await fd.close();
|
|
4277
|
-
} catch (err) {
|
|
4278
|
-
if (err.code === "EEXIST") {
|
|
4279
|
-
try {
|
|
4280
|
-
const raw = await readFile2(lockPath, "utf8");
|
|
4281
|
-
const existing = JSON.parse(raw);
|
|
4282
|
-
if (isProcessAlive(existing.pid)) return null;
|
|
4283
|
-
await unlink(lockPath);
|
|
4284
|
-
return acquireLock(outDir);
|
|
4285
|
-
} catch {
|
|
4286
|
-
return null;
|
|
4287
|
-
}
|
|
4288
|
-
}
|
|
4289
|
-
return null;
|
|
4290
|
-
}
|
|
4291
|
-
return {
|
|
4292
|
-
release: async () => {
|
|
4293
|
-
try {
|
|
4294
|
-
await unlink(lockPath);
|
|
4295
|
-
} catch {
|
|
4296
|
-
}
|
|
4297
|
-
}
|
|
4298
|
-
};
|
|
4407
|
+
const outputFiles = await listOutputFiles(config.codegen.outDir);
|
|
4408
|
+
await writeManifest(config.codegen.outDir, {
|
|
4409
|
+
version: VERSION,
|
|
4410
|
+
hash: inputsHash,
|
|
4411
|
+
files: outputFiles
|
|
4412
|
+
});
|
|
4299
4413
|
}
|
|
4300
4414
|
|
|
4301
4415
|
// src/watch/watcher.ts
|
|
4302
4416
|
var PAGES_DEBOUNCE_MS = 150;
|
|
4303
4417
|
var NO_OP_WATCHER = { close: async () => {
|
|
4304
4418
|
} };
|
|
4305
|
-
async function watch(config, onChange) {
|
|
4419
|
+
async function watch(config, onChange, options = {}) {
|
|
4306
4420
|
const lock = await acquireLock(config.codegen.outDir);
|
|
4307
4421
|
if (lock === null) {
|
|
4308
4422
|
let holderPid = "unknown";
|
|
4309
4423
|
try {
|
|
4310
|
-
const raw = await
|
|
4424
|
+
const raw = await readFile4(join16(config.codegen.outDir, ".watcher.lock"), "utf8");
|
|
4311
4425
|
const data = JSON.parse(raw);
|
|
4312
4426
|
if (data.pid !== void 0) holderPid = String(data.pid);
|
|
4313
4427
|
} catch {
|
|
@@ -4330,22 +4444,33 @@ async function watch(config, onChange) {
|
|
|
4330
4444
|
}
|
|
4331
4445
|
return discovery;
|
|
4332
4446
|
}
|
|
4333
|
-
|
|
4334
|
-
const initialRoutes = (await getDiscovery()).discover();
|
|
4335
|
-
lastRoutes = initialRoutes;
|
|
4336
|
-
await generate(config, initialRoutes);
|
|
4337
|
-
} catch (err) {
|
|
4338
|
-
console.warn(
|
|
4339
|
-
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
4340
|
-
);
|
|
4447
|
+
async function runInitialPass() {
|
|
4341
4448
|
try {
|
|
4342
|
-
await
|
|
4343
|
-
|
|
4449
|
+
const initialRoutes = (await getDiscovery()).discover();
|
|
4450
|
+
lastRoutes = initialRoutes;
|
|
4451
|
+
await generate(config, initialRoutes);
|
|
4452
|
+
} catch (err) {
|
|
4453
|
+
console.warn(
|
|
4454
|
+
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
4455
|
+
);
|
|
4456
|
+
try {
|
|
4457
|
+
await generate(config, lastRoutes);
|
|
4458
|
+
} catch {
|
|
4459
|
+
}
|
|
4344
4460
|
}
|
|
4345
4461
|
}
|
|
4462
|
+
if (options.deferInitialGenerate) {
|
|
4463
|
+
void runInitialPass().catch((err) => {
|
|
4464
|
+
console.warn(
|
|
4465
|
+
`[nestjs-codegen] Background initial generate failed: ${err instanceof Error ? err.message : String(err)}`
|
|
4466
|
+
);
|
|
4467
|
+
});
|
|
4468
|
+
} else {
|
|
4469
|
+
await runInitialPass();
|
|
4470
|
+
}
|
|
4346
4471
|
let pagesDebounceTimer;
|
|
4347
4472
|
const pagesGlob = config.pages?.glob ?? ".nestjs-codegen-no-pages";
|
|
4348
|
-
const pagesWatcher = chokidar.watch(
|
|
4473
|
+
const pagesWatcher = chokidar.watch(join16(config.codegen.cwd, pagesGlob), {
|
|
4349
4474
|
ignoreInitial: true,
|
|
4350
4475
|
persistent: true,
|
|
4351
4476
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4372,7 +4497,7 @@ async function watch(config, onChange) {
|
|
|
4372
4497
|
pagesWatcher.on("unlink", schedulePagesRegenerate);
|
|
4373
4498
|
let contractsDebounceTimer;
|
|
4374
4499
|
const pendingChangedPaths = /* @__PURE__ */ new Set();
|
|
4375
|
-
const contractsWatcher = chokidar.watch(
|
|
4500
|
+
const contractsWatcher = chokidar.watch(join16(config.codegen.cwd, config.contracts.glob), {
|
|
4376
4501
|
ignoreInitial: true,
|
|
4377
4502
|
persistent: true,
|
|
4378
4503
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4402,7 +4527,7 @@ async function watch(config, onChange) {
|
|
|
4402
4527
|
contractsWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
4403
4528
|
contractsWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
4404
4529
|
contractsWatcher.on("unlink", (p) => scheduleContractsRegenerate(p));
|
|
4405
|
-
const formsWatcher = chokidar.watch(
|
|
4530
|
+
const formsWatcher = chokidar.watch(join16(config.codegen.cwd, config.forms.watch), {
|
|
4406
4531
|
ignoreInitial: true,
|
|
4407
4532
|
persistent: true,
|
|
4408
4533
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4430,9 +4555,13 @@ async function watch(config, onChange) {
|
|
|
4430
4555
|
|
|
4431
4556
|
// src/nest/module.ts
|
|
4432
4557
|
var CODEGEN_MODULE_OPTIONS = Symbol("NESTJS_CODEGEN_MODULE_OPTIONS");
|
|
4558
|
+
function isProductionEnv(env) {
|
|
4559
|
+
return (env ?? "").trim().toLowerCase() === "production";
|
|
4560
|
+
}
|
|
4433
4561
|
function shouldRun(options, env) {
|
|
4434
4562
|
if (options.enabled !== void 0) return options.enabled;
|
|
4435
|
-
|
|
4563
|
+
if (isProductionEnv(env)) return options.runInProduction === true;
|
|
4564
|
+
return true;
|
|
4436
4565
|
}
|
|
4437
4566
|
var NestjsCodegenService = class {
|
|
4438
4567
|
constructor(options) {
|
|
@@ -4441,11 +4570,21 @@ var NestjsCodegenService = class {
|
|
|
4441
4570
|
logger = new Logger("NestjsCodegen");
|
|
4442
4571
|
watcher = null;
|
|
4443
4572
|
async onApplicationBootstrap() {
|
|
4444
|
-
if (!shouldRun(this.options, process.env.NODE_ENV))
|
|
4445
|
-
|
|
4573
|
+
if (!shouldRun(this.options, process.env.NODE_ENV)) {
|
|
4574
|
+
if (this.options.enabled === void 0 && isProductionEnv(process.env.NODE_ENV)) {
|
|
4575
|
+
this.logger.log("Skipped in production (set runInProduction: true to override).");
|
|
4576
|
+
}
|
|
4577
|
+
return;
|
|
4578
|
+
}
|
|
4579
|
+
const {
|
|
4580
|
+
enabled: _enabled,
|
|
4581
|
+
runInProduction: _runInProduction,
|
|
4582
|
+
cwd,
|
|
4583
|
+
...userConfig
|
|
4584
|
+
} = this.options;
|
|
4446
4585
|
try {
|
|
4447
4586
|
const config = resolveConfig(userConfig, cwd ?? process.cwd());
|
|
4448
|
-
this.watcher = await watch(config);
|
|
4587
|
+
this.watcher = await watch(config, void 0, { deferInitialGenerate: true });
|
|
4449
4588
|
this.logger.log(`Watching ${config.contracts.glob} \u2192 ${config.codegen.outDir}`);
|
|
4450
4589
|
} catch (err) {
|
|
4451
4590
|
this.logger.warn(
|