@dudousxd/nestjs-codegen 0.14.1 → 0.14.2

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.
@@ -2099,8 +2099,9 @@ function debugWarn(message) {
2099
2099
  }
2100
2100
 
2101
2101
  // src/generate.ts
2102
- function driftGuardMessage(outDir, previousEntryPoint, currentEntryPoint) {
2103
- return `[nestjs-codegen] Config drift detected in "${outDir}": the last generate ran from the "${previousEntryPoint}" entry point, this run is from the "${currentEntryPoint}" entry point, and their resolved configs differ (e.g. \`serialization: "json"\` vs \`"superjson"\`). Both entry points must read the SAME config \u2014 export a shared config object (e.g. codegen.config.ts) and import it from BOTH nestjs-codegen.config.ts (CLI) and NestjsCodegenModule.forRoot() (Nest module), or set \`driftGuard: false\` on either config to opt out of this check.`;
2102
+ function driftGuardMessage(outDir, previousEntryPoint, currentEntryPoint, differingKeys) {
2103
+ const differ = differingKeys.length > 0 ? `their resolved configs differ at: ${differingKeys.map((key) => `\`${key}\``).join(", ")}` : "their resolved configs differ (re-run after this generate records per-key hashes to see which keys)";
2104
+ return `[nestjs-codegen] Config drift detected in "${outDir}": the last generate ran from the "${previousEntryPoint}" entry point, this run is from the "${currentEntryPoint}" entry point, and ${differ}. Both entry points must read the SAME config \u2014 export a shared config object (e.g. codegen.config.ts) and import it from BOTH nestjs-codegen.config.ts (CLI) and NestjsCodegenModule.forRoot() (Nest module), or set \`driftGuard: false\` on either config to opt out of this check.`;
2104
2105
  }
2105
2106
  async function generate(config, inputRoutes = [], entryPoint = "cli") {
2106
2107
  setCodegenDebug(config.debug);
@@ -2111,9 +2112,17 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
2111
2112
  return;
2112
2113
  }
2113
2114
  const configHash = computeConfigHash(config);
2115
+ const configKeyHashes = computeConfigKeyHashes(config);
2114
2116
  if (config.driftGuard && manifest?.entryPoint && manifest.entryPoint !== entryPoint && manifest.configHash && manifest.configHash !== configHash) {
2115
2117
  throw new DriftGuardError(
2116
- driftGuardMessage(config.codegen.outDir, manifest.entryPoint, entryPoint)
2118
+ driftGuardMessage(
2119
+ config.codegen.outDir,
2120
+ manifest.entryPoint,
2121
+ entryPoint,
2122
+ // A pre-key-hash manifest can't tell us WHICH keys differ — pass none
2123
+ // rather than diffing against {} (which would name every key).
2124
+ manifest.configKeyHashes ? diffConfigKeyHashes(manifest.configKeyHashes, configKeyHashes) : []
2125
+ )
2117
2126
  );
2118
2127
  }
2119
2128
  const extensions = config.extensions ?? [];
@@ -2183,6 +2192,7 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
2183
2192
  hash: inputsHash,
2184
2193
  entryPoint,
2185
2194
  configHash,
2195
+ configKeyHashes,
2186
2196
  files: outputFiles
2187
2197
  });
2188
2198
  }
@@ -4612,7 +4622,7 @@ async function watch(config, onChange, options = {}) {
4612
4622
  }
4613
4623
 
4614
4624
  // src/index.ts
4615
- var VERSION = "0.14.1";
4625
+ var VERSION = "0.14.2";
4616
4626
 
4617
4627
  // src/generate-manifest.ts
4618
4628
  var MANIFEST_FILE = ".codegen-manifest.json";
@@ -4633,19 +4643,41 @@ function isManifestShape(value) {
4633
4643
  if (typeof candidate.hash !== "string") return false;
4634
4644
  if (candidate.entryPoint !== void 0 && !isEntryPoint(candidate.entryPoint)) return false;
4635
4645
  if (candidate.configHash !== void 0 && typeof candidate.configHash !== "string") return false;
4646
+ if (candidate.configKeyHashes !== void 0 && !isStringRecord(candidate.configKeyHashes)) {
4647
+ return false;
4648
+ }
4636
4649
  if (!Array.isArray(candidate.files)) return false;
4637
4650
  return candidate.files.every((entry) => typeof entry === "string");
4638
4651
  }
4652
+ function isStringRecord(value) {
4653
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
4654
+ return Object.values(value).every((entry) => typeof entry === "string");
4655
+ }
4639
4656
  function serializeConfig(config) {
4657
+ return serializeConfigValue(config, `unserializable:${config.codegen.outDir}`);
4658
+ }
4659
+ function serializeConfigValue(value, unserializableMarker) {
4640
4660
  try {
4641
- return JSON.stringify(config, (_key, value) => {
4642
- if (typeof value === "function") return `[fn:${value.name}]${value.toString()}`;
4643
- return value;
4661
+ return JSON.stringify(value, (_key, entry) => {
4662
+ if (typeof entry === "function") return `[fn:${entry.name}]`;
4663
+ return entry;
4644
4664
  });
4645
4665
  } catch {
4646
- return `unserializable:${config.codegen.outDir}:${config.contracts.glob}`;
4666
+ return unserializableMarker;
4647
4667
  }
4648
4668
  }
4669
+ function computeConfigKeyHashes(config) {
4670
+ const hashes = {};
4671
+ for (const [key, value] of Object.entries(config)) {
4672
+ if (value === void 0) continue;
4673
+ hashes[key] = createHash("sha256").update(serializeConfigValue(value, `unserializable:${key}`)).digest("hex");
4674
+ }
4675
+ return hashes;
4676
+ }
4677
+ function diffConfigKeyHashes(previous, current) {
4678
+ const keys = /* @__PURE__ */ new Set([...Object.keys(previous), ...Object.keys(current)]);
4679
+ return [...keys].filter((key) => previous[key] !== current[key]).sort();
4680
+ }
4649
4681
  async function discoverInputFiles(config) {
4650
4682
  const globs = [config.contracts.glob, config.forms.watch];
4651
4683
  if (config.pages) globs.push(config.pages.glob);
@@ -4680,6 +4712,7 @@ async function readManifest(outDir) {
4680
4712
  hash: parsed.hash,
4681
4713
  ...parsed.entryPoint ? { entryPoint: parsed.entryPoint } : {},
4682
4714
  ...parsed.configHash ? { configHash: parsed.configHash } : {},
4715
+ ...parsed.configKeyHashes ? { configKeyHashes: parsed.configKeyHashes } : {},
4683
4716
  files: parsed.files
4684
4717
  };
4685
4718
  } catch {