zod-nest 2.0.1 → 2.1.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.d.mts CHANGED
@@ -831,6 +831,18 @@ interface ApplyZodNestOptions {
831
831
  * `@ZodQuery({ ref })` override takes precedence over this preference.
832
832
  */
833
833
  queryParamStyle?: QueryParamStyle;
834
+ /**
835
+ * Copy each named component's `title` (when set via `.meta({ title })`) onto
836
+ * every `$ref` that targets it, as a sibling: `{ $ref, title }` (default
837
+ * `true`).
838
+ *
839
+ * OpenAPI 3.1 allows siblings next to `$ref`, and Swagger UI's 3.1 renderer
840
+ * inlines referenced schemas without showing their component name
841
+ * (swagger-api/swagger-ui#9540); the sibling `title` gives the renderer (and
842
+ * other 3.1-aware tools) a name to display. The annotation is semantically
843
+ * inert. Set `false` to emit bare `$ref`s.
844
+ */
845
+ refTitles?: boolean;
834
846
  }
835
847
  /**
836
848
  * Post-processor over the OpenAPI document emitted by
@@ -856,6 +868,9 @@ interface ApplyZodNestOptions {
856
868
  * transitive `$ref` deps, plus any `{ expose: true }` opt-ins) are kept —
857
869
  * unreferenced registered schemas are pruned. Exposure is document-scoped, so
858
870
  * several documents sharing one registry each carry only what they use.
871
+ * - Each named component's `title` is copied onto every `$ref` that targets it
872
+ * as a `{ $ref, title }` sibling (`applyRefTitles`, unless `refTitles: false`)
873
+ * so Swagger UI's 3.1 renderer surfaces the component name. Inert annotation.
859
874
  * - Every `$ref` whose target is missing throws `ZodNestDocumentError(DANGLING_REF)`.
860
875
  * - `doc.openapi` is set to `'3.1.0'` — zod-nest emits OpenAPI 3.1 only; this
861
876
  * guarantees the version string matches the emitted body regardless of the
package/dist/index.d.ts CHANGED
@@ -831,6 +831,18 @@ interface ApplyZodNestOptions {
831
831
  * `@ZodQuery({ ref })` override takes precedence over this preference.
832
832
  */
833
833
  queryParamStyle?: QueryParamStyle;
834
+ /**
835
+ * Copy each named component's `title` (when set via `.meta({ title })`) onto
836
+ * every `$ref` that targets it, as a sibling: `{ $ref, title }` (default
837
+ * `true`).
838
+ *
839
+ * OpenAPI 3.1 allows siblings next to `$ref`, and Swagger UI's 3.1 renderer
840
+ * inlines referenced schemas without showing their component name
841
+ * (swagger-api/swagger-ui#9540); the sibling `title` gives the renderer (and
842
+ * other 3.1-aware tools) a name to display. The annotation is semantically
843
+ * inert. Set `false` to emit bare `$ref`s.
844
+ */
845
+ refTitles?: boolean;
834
846
  }
835
847
  /**
836
848
  * Post-processor over the OpenAPI document emitted by
@@ -856,6 +868,9 @@ interface ApplyZodNestOptions {
856
868
  * transitive `$ref` deps, plus any `{ expose: true }` opt-ins) are kept —
857
869
  * unreferenced registered schemas are pruned. Exposure is document-scoped, so
858
870
  * several documents sharing one registry each carry only what they use.
871
+ * - Each named component's `title` is copied onto every `$ref` that targets it
872
+ * as a `{ $ref, title }` sibling (`applyRefTitles`, unless `refTitles: false`)
873
+ * so Swagger UI's 3.1 renderer surfaces the component name. Inert annotation.
859
874
  * - Every `$ref` whose target is missing throws `ZodNestDocumentError(DANGLING_REF)`.
860
875
  * - `doc.openapi` is set to `'3.1.0'` — zod-nest emits OpenAPI 3.1 only; this
861
876
  * guarantees the version string matches the emitted body regardless of the
package/dist/index.js CHANGED
@@ -1334,7 +1334,7 @@ var ZodResponse = /* @__PURE__ */ __name((opts) => {
1334
1334
  }, "ZodResponse");
1335
1335
 
1336
1336
  // src/decorators/internal/zod-schema-ref.ts
1337
- var resolveSchemaRef = /* @__PURE__ */ __name((schema, options) => {
1337
+ function resolveSchemaRef(schema, options) {
1338
1338
  const registry = options?.registry ?? defaultRegistry;
1339
1339
  const id = registerSchema(schema, registry, {
1340
1340
  id: options?.id
@@ -1371,7 +1371,8 @@ var resolveSchemaRef = /* @__PURE__ */ __name((schema, options) => {
1371
1371
  kind: "inline",
1372
1372
  schema: body
1373
1373
  };
1374
- }, "resolveSchemaRef");
1374
+ }
1375
+ __name(resolveSchemaRef, "resolveSchemaRef");
1375
1376
 
1376
1377
  // src/decorators/internal/zod-param-expand.ts
1377
1378
  var isZodObject = /* @__PURE__ */ __name((schema) => schema._zod.def.type === "object", "isZodObject");
@@ -1505,12 +1506,11 @@ var resolveBodySchema = /* @__PURE__ */ __name((schema, options) => {
1505
1506
  if (options?.flatten === true) {
1506
1507
  return flattenObjectIntersection(schema, options.registry ?? defaultRegistry, "@ZodBody");
1507
1508
  }
1508
- const resolution = resolveSchemaRef(schema, {
1509
+ return resolveSchemaRef(schema, {
1509
1510
  id: options?.id,
1510
1511
  registry: options?.registry,
1511
1512
  deferAnonInline: true
1512
- });
1513
- return resolution.kind === "ref" ? resolution.ref : resolution.schema;
1513
+ }).ref;
1514
1514
  }, "resolveBodySchema");
1515
1515
 
1516
1516
  // src/decorators/internal/query-marker.ts
@@ -2382,6 +2382,47 @@ var decorateIfPresent = /* @__PURE__ */ __name((schemas, key) => {
2382
2382
  };
2383
2383
  }, "decorateIfPresent");
2384
2384
 
2385
+ // src/document/ref-titles.ts
2386
+ var applyRefTitles = /* @__PURE__ */ __name((doc) => {
2387
+ const schemas = doc.components?.schemas;
2388
+ if (schemas === void 0) {
2389
+ return;
2390
+ }
2391
+ const titleById = /* @__PURE__ */ new Map();
2392
+ for (const [id, body] of Object.entries(schemas)) {
2393
+ if (isPlainRecord5(body) && typeof body.title === "string" && body.title !== "") {
2394
+ titleById.set(id, body.title);
2395
+ }
2396
+ }
2397
+ if (titleById.size === 0) {
2398
+ return;
2399
+ }
2400
+ addRefTitles(doc.paths, titleById);
2401
+ addRefTitles(schemas, titleById);
2402
+ }, "applyRefTitles");
2403
+ var isPlainRecord5 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isPlainRecord");
2404
+ var addRefTitles = /* @__PURE__ */ __name((node, titleById) => {
2405
+ if (Array.isArray(node)) {
2406
+ for (const item of node) {
2407
+ addRefTitles(item, titleById);
2408
+ }
2409
+ return;
2410
+ }
2411
+ if (!isPlainRecord5(node)) {
2412
+ return;
2413
+ }
2414
+ const ref = node.$ref;
2415
+ if (typeof ref === "string" && ref.startsWith(COMPONENTS_SCHEMAS_PREFIX) && node.title === void 0) {
2416
+ const title = titleById.get(ref.slice(COMPONENTS_SCHEMAS_PREFIX.length));
2417
+ if (title !== void 0) {
2418
+ node.title = title;
2419
+ }
2420
+ }
2421
+ for (const value of Object.values(node)) {
2422
+ addRefTitles(value, titleById);
2423
+ }
2424
+ }, "addRefTitles");
2425
+
2385
2426
  // src/document/rewrite-refs.ts
2386
2427
  var rewriteRefs2 = /* @__PURE__ */ __name((params) => {
2387
2428
  const { doc, renames, divergentOutputIds } = params;
@@ -2527,6 +2568,9 @@ var applyZodNest = /* @__PURE__ */ __name((doc, opts = {}) => {
2527
2568
  doc,
2528
2569
  registry
2529
2570
  });
2571
+ if (opts.refTitles !== false) {
2572
+ applyRefTitles(doc);
2573
+ }
2530
2574
  assertNoDanglingRefs({
2531
2575
  doc,
2532
2576
  collected: extended