zod-nest 2.1.4 → 3.0.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/dist/index.mjs CHANGED
@@ -2351,11 +2351,24 @@ var inlineAnonymousBodies = /* @__PURE__ */ __name(({ doc, registry }) => {
2351
2351
  if (bodyByRef.size === 0) {
2352
2352
  return;
2353
2353
  }
2354
+ for (const ref of refsWithin(schemas, bodyByRef)) {
2355
+ bodyByRef.delete(ref);
2356
+ }
2354
2357
  inlineRefs(doc.paths, bodyByRef);
2355
2358
  for (const ref of bodyByRef.keys()) {
2356
2359
  delete schemas[ref.slice(COMPONENTS_SCHEMAS_PREFIX.length)];
2357
2360
  }
2358
2361
  }, "inlineAnonymousBodies");
2362
+ var refsWithin = /* @__PURE__ */ __name((schemas, bodyByRef) => {
2363
+ const found = /* @__PURE__ */ new Set();
2364
+ walkRefs(schemas, (ref) => {
2365
+ if (bodyByRef.has(ref)) {
2366
+ found.add(ref);
2367
+ }
2368
+ return void 0;
2369
+ });
2370
+ return found;
2371
+ }, "refsWithin");
2359
2372
  var isPlainRecord4 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isPlainRecord");
2360
2373
  var inlineRefs = /* @__PURE__ */ __name((node, bodyByRef) => {
2361
2374
  if (Array.isArray(node)) {
@@ -2391,8 +2404,18 @@ var mergeSchemas = /* @__PURE__ */ __name((params) => {
2391
2404
  ...collected.inputExposedIds,
2392
2405
  ...collected.outputExposedIds
2393
2406
  ]);
2407
+ const foreignKeys = collectForeignKeys(schemas);
2394
2408
  for (const id of exposedIds) {
2395
- applyTruthTable(schemas, id, collected.inputExposedIds.has(id), collected.outputExposedIds.has(id), inputSchemas.get(id), outputSchemas.get(id), divergentOutputIds);
2409
+ applyTruthTable({
2410
+ schemas,
2411
+ id,
2412
+ inputExposed: collected.inputExposedIds.has(id),
2413
+ outputExposed: collected.outputExposedIds.has(id),
2414
+ inputBody: inputSchemas.get(id),
2415
+ outputBody: outputSchemas.get(id),
2416
+ divergentOutputIds,
2417
+ foreignKeys
2418
+ });
2396
2419
  }
2397
2420
  for (const [className, dtoId] of collected.classToDtoId) {
2398
2421
  if (className === dtoId) {
@@ -2414,24 +2437,35 @@ var ensureComponentsSchemas = /* @__PURE__ */ __name((doc) => {
2414
2437
  components.schemas = schemas;
2415
2438
  return schemas;
2416
2439
  }, "ensureComponentsSchemas");
2417
- var applyTruthTable = /* @__PURE__ */ __name((schemas, id, inputExposed, outputExposed, inputBody, outputBody, divergentOutputIds) => {
2440
+ var applyTruthTable = /* @__PURE__ */ __name((params) => {
2441
+ const { schemas, id, inputExposed, outputExposed, inputBody, outputBody } = params;
2442
+ const { divergentOutputIds, foreignKeys } = params;
2418
2443
  if (inputExposed && !outputExposed) {
2419
- writeOrThrowAmbiguous(schemas, id, inputBody);
2444
+ writeOrThrowAmbiguous(schemas, id, inputBody, foreignKeys);
2420
2445
  return;
2421
2446
  }
2422
2447
  if (!inputExposed && outputExposed) {
2423
- writeOrThrowAmbiguous(schemas, id, outputBody);
2448
+ writeOrThrowAmbiguous(schemas, id, outputBody, foreignKeys);
2424
2449
  return;
2425
2450
  }
2426
2451
  if (canonicalEqual(inputBody, outputBody)) {
2427
- writeOrThrowAmbiguous(schemas, id, inputBody);
2452
+ writeOrThrowAmbiguous(schemas, id, inputBody, foreignKeys);
2428
2453
  return;
2429
2454
  }
2430
- writeOrThrowAmbiguous(schemas, id, inputBody);
2431
- writeOrThrowAmbiguous(schemas, `${id}${OUTPUT_SUFFIX}`, outputBody);
2455
+ writeOrThrowAmbiguous(schemas, id, inputBody, foreignKeys);
2456
+ writeOrThrowAmbiguous(schemas, `${id}${OUTPUT_SUFFIX}`, outputBody, foreignKeys);
2432
2457
  divergentOutputIds.add(id);
2433
2458
  }, "applyTruthTable");
2434
- var writeOrThrowAmbiguous = /* @__PURE__ */ __name((schemas, key, body) => {
2459
+ var collectForeignKeys = /* @__PURE__ */ __name((schemas) => {
2460
+ const foreign = /* @__PURE__ */ new Set();
2461
+ for (const [key, body] of Object.entries(schemas)) {
2462
+ if (!isMarkerPlaceholder(body)) {
2463
+ foreign.add(key);
2464
+ }
2465
+ }
2466
+ return foreign;
2467
+ }, "collectForeignKeys");
2468
+ var writeOrThrowAmbiguous = /* @__PURE__ */ __name((schemas, key, body, foreignKeys) => {
2435
2469
  if (body === void 0) {
2436
2470
  return;
2437
2471
  }
@@ -2440,10 +2474,18 @@ var writeOrThrowAmbiguous = /* @__PURE__ */ __name((schemas, key, body) => {
2440
2474
  schemas[key] = body;
2441
2475
  return;
2442
2476
  }
2443
- throw new ZodNestDocumentError("AMBIGUOUS_RENAME", `Two distinct schemas target \`components.schemas[${key}]\` with differing bodies \u2014 multiple createZodDto classes likely share the same dtoId. Set distinct \`options.id\` values, or align the class names so renames are unambiguous.`, {
2444
- key
2477
+ const preexisting = foreignKeys.has(key);
2478
+ throw new ZodNestDocumentError("AMBIGUOUS_RENAME", `Two distinct schemas target \`components.schemas[${key}]\` with differing bodies \u2014 ` + ambiguousRenameHint(key, preexisting), {
2479
+ key,
2480
+ preexisting
2445
2481
  });
2446
2482
  }, "writeOrThrowAmbiguous");
2483
+ var ambiguousRenameHint = /* @__PURE__ */ __name((key, preexisting) => {
2484
+ if (preexisting) {
2485
+ return `\`${key}\` was already populated before zod-nest emitted anything. On NestJS 12+ the usual cause is the native Standard Schema path \u2014 \`@Body({ schema })\`, \`@Query({ schema })\` or \`@ApiResponse({ standardSchema })\` \u2014 which makes @nestjs/swagger emit the component itself, in its OpenAPI 3.0 shape. Route the schema through \`createZodDto\` / \`@ZodBody\` / \`@ZodResponse\` instead, or drop \`applyZodNest\` and let Nest own the whole document. A hand-authored component or a doc pre-pass under the same name does this too.`;
2486
+ }
2487
+ return "Two registered ids resolved to the same key \u2014 most often an `<Id>Output` sibling from a diverging input/output schema colliding with a DTO explicitly registered as `<Id>Output`. Rename one of them, or set a distinct `options.id`.";
2488
+ }, "ambiguousRenameHint");
2447
2489
  var isMarkerPlaceholder = /* @__PURE__ */ __name((value) => {
2448
2490
  if (value === null || typeof value !== "object") {
2449
2491
  return false;