@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.
package/dist/index.d.cts CHANGED
@@ -73,6 +73,12 @@ interface CodegenManifest {
73
73
  * unrelated source-file changes. Absent on pre-drift-guard manifests.
74
74
  */
75
75
  configHash?: string;
76
+ /**
77
+ * Per-top-level-key hashes of the serialized resolved config, so a drift-guard
78
+ * failure can NAME the keys that differ instead of asking the consumer to
79
+ * eyeball two whole configs. Absent on manifests written before this field.
80
+ */
81
+ configKeyHashes?: Record<string, string>;
76
82
  /** Generated output files, relative to `outDir`, recorded after the last run. */
77
83
  files: string[];
78
84
  }
@@ -367,6 +373,6 @@ interface FastDiscoveryOptions {
367
373
  }
368
374
  declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
369
375
 
370
- declare const VERSION = "0.14.1";
376
+ declare const VERSION = "0.14.2";
371
377
 
372
378
  export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
package/dist/index.d.ts CHANGED
@@ -73,6 +73,12 @@ interface CodegenManifest {
73
73
  * unrelated source-file changes. Absent on pre-drift-guard manifests.
74
74
  */
75
75
  configHash?: string;
76
+ /**
77
+ * Per-top-level-key hashes of the serialized resolved config, so a drift-guard
78
+ * failure can NAME the keys that differ instead of asking the consumer to
79
+ * eyeball two whole configs. Absent on manifests written before this field.
80
+ */
81
+ configKeyHashes?: Record<string, string>;
76
82
  /** Generated output files, relative to `outDir`, recorded after the last run. */
77
83
  files: string[];
78
84
  }
@@ -367,6 +373,6 @@ interface FastDiscoveryOptions {
367
373
  }
368
374
  declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
369
375
 
370
- declare const VERSION = "0.14.1";
376
+ declare const VERSION = "0.14.2";
371
377
 
372
378
  export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
package/dist/index.js CHANGED
@@ -2159,19 +2159,41 @@ function isManifestShape(value) {
2159
2159
  if (typeof candidate.hash !== "string") return false;
2160
2160
  if (candidate.entryPoint !== void 0 && !isEntryPoint(candidate.entryPoint)) return false;
2161
2161
  if (candidate.configHash !== void 0 && typeof candidate.configHash !== "string") return false;
2162
+ if (candidate.configKeyHashes !== void 0 && !isStringRecord(candidate.configKeyHashes)) {
2163
+ return false;
2164
+ }
2162
2165
  if (!Array.isArray(candidate.files)) return false;
2163
2166
  return candidate.files.every((entry) => typeof entry === "string");
2164
2167
  }
2168
+ function isStringRecord(value) {
2169
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2170
+ return Object.values(value).every((entry) => typeof entry === "string");
2171
+ }
2165
2172
  function serializeConfig(config) {
2173
+ return serializeConfigValue(config, `unserializable:${config.codegen.outDir}`);
2174
+ }
2175
+ function serializeConfigValue(value, unserializableMarker) {
2166
2176
  try {
2167
- return JSON.stringify(config, (_key, value) => {
2168
- if (typeof value === "function") return `[fn:${value.name}]${value.toString()}`;
2169
- return value;
2177
+ return JSON.stringify(value, (_key, entry) => {
2178
+ if (typeof entry === "function") return `[fn:${entry.name}]`;
2179
+ return entry;
2170
2180
  });
2171
2181
  } catch {
2172
- return `unserializable:${config.codegen.outDir}:${config.contracts.glob}`;
2182
+ return unserializableMarker;
2173
2183
  }
2174
2184
  }
2185
+ function computeConfigKeyHashes(config) {
2186
+ const hashes = {};
2187
+ for (const [key, value] of Object.entries(config)) {
2188
+ if (value === void 0) continue;
2189
+ hashes[key] = createHash("sha256").update(serializeConfigValue(value, `unserializable:${key}`)).digest("hex");
2190
+ }
2191
+ return hashes;
2192
+ }
2193
+ function diffConfigKeyHashes(previous, current) {
2194
+ const keys = /* @__PURE__ */ new Set([...Object.keys(previous), ...Object.keys(current)]);
2195
+ return [...keys].filter((key) => previous[key] !== current[key]).sort();
2196
+ }
2175
2197
  async function discoverInputFiles(config) {
2176
2198
  const globs = [config.contracts.glob, config.forms.watch];
2177
2199
  if (config.pages) globs.push(config.pages.glob);
@@ -2206,6 +2228,7 @@ async function readManifest(outDir) {
2206
2228
  hash: parsed.hash,
2207
2229
  ...parsed.entryPoint ? { entryPoint: parsed.entryPoint } : {},
2208
2230
  ...parsed.configHash ? { configHash: parsed.configHash } : {},
2231
+ ...parsed.configKeyHashes ? { configKeyHashes: parsed.configKeyHashes } : {},
2209
2232
  files: parsed.files
2210
2233
  };
2211
2234
  } catch {
@@ -2259,8 +2282,9 @@ function debugWarn(message) {
2259
2282
  }
2260
2283
 
2261
2284
  // src/generate.ts
2262
- function driftGuardMessage(outDir, previousEntryPoint, currentEntryPoint) {
2263
- 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.`;
2285
+ function driftGuardMessage(outDir, previousEntryPoint, currentEntryPoint, differingKeys) {
2286
+ 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)";
2287
+ 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.`;
2264
2288
  }
2265
2289
  async function generate(config, inputRoutes = [], entryPoint = "cli") {
2266
2290
  setCodegenDebug(config.debug);
@@ -2271,9 +2295,17 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
2271
2295
  return;
2272
2296
  }
2273
2297
  const configHash = computeConfigHash(config);
2298
+ const configKeyHashes = computeConfigKeyHashes(config);
2274
2299
  if (config.driftGuard && manifest?.entryPoint && manifest.entryPoint !== entryPoint && manifest.configHash && manifest.configHash !== configHash) {
2275
2300
  throw new DriftGuardError(
2276
- driftGuardMessage(config.codegen.outDir, manifest.entryPoint, entryPoint)
2301
+ driftGuardMessage(
2302
+ config.codegen.outDir,
2303
+ manifest.entryPoint,
2304
+ entryPoint,
2305
+ // A pre-key-hash manifest can't tell us WHICH keys differ — pass none
2306
+ // rather than diffing against {} (which would name every key).
2307
+ manifest.configKeyHashes ? diffConfigKeyHashes(manifest.configKeyHashes, configKeyHashes) : []
2308
+ )
2277
2309
  );
2278
2310
  }
2279
2311
  const extensions = config.extensions ?? [];
@@ -2343,6 +2375,7 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
2343
2375
  hash: inputsHash,
2344
2376
  entryPoint,
2345
2377
  configHash,
2378
+ configKeyHashes,
2346
2379
  files: outputFiles
2347
2380
  });
2348
2381
  }
@@ -4873,7 +4906,7 @@ function createChainModuleRenderer(opts) {
4873
4906
  }
4874
4907
 
4875
4908
  // src/index.ts
4876
- var VERSION = "0.14.1";
4909
+ var VERSION = "0.14.2";
4877
4910
  export {
4878
4911
  CodegenError,
4879
4912
  ConfigError,