zod-nest 1.10.0 → 1.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/README.md +5 -3
- package/dist/index.d.mts +87 -14
- package/dist/index.d.ts +87 -14
- package/dist/index.js +146 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +146 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ For the long-form motivation, see [`docs/why-this-exists.md`](docs/why-this-exis
|
|
|
23
23
|
- **OpenAPI 3.1 emission** — no post-processing, no spec downgrade, no leftover internal extension keys.
|
|
24
24
|
- **`createZodDto`** — class wrapper around a Zod schema with introspectable `schema`, `id`, `io`, and a sibling `Output` class when input/output diverge.
|
|
25
25
|
- **`ZodValidationPipe`** — auto-detects DTO from handler-arg metatype, accepts an explicit DTO or raw Zod schema, customizable exception factory.
|
|
26
|
-
- **`@ZodResponse`** — stackable per status code
|
|
26
|
+
- **`@ZodResponse`** — stackable per status code; each entry is a DTO **or a raw Zod schema** (single, array `[Entry]`, or tuple `[A, B, …]`, mixable). A raw schema is normalised to an output DTO internally, so a `z.discriminatedUnion` / `z.union` / `z.intersection` that can't be wrapped in `createZodDto` (TS2509) drops straight into a response. No internal `@HttpCode` — caller controls status.
|
|
27
27
|
- **`@ZodBody` / `@ZodQuery` / `@ZodHeaders` / `@ZodCookies`** — method-level decorators that wire OpenAPI docs for schemas whose `z.infer<>` is a union (intersection-of-union, discriminated unions, etc.) — the ones that can't be wrapped in `createZodDto` because TS refuses unions as class bases (TS2509). Schema validation stays via `@Body(new ZodValidationPipe(schema))`; the type at the handler arg stays `z.infer<>`.
|
|
28
28
|
- **`ZodSerializerInterceptor`** — response validation with a `passthroughOnError` escape hatch for untrusted upstream shapes.
|
|
29
29
|
- **`applyZodNest`** — one call after `SwaggerModule.createDocument(...)` replaces the entire `cleanupOpenApiDoc` ritual.
|
|
@@ -186,6 +186,8 @@ The decorator set: `@ZodBody`, `@ZodQuery`, `@ZodHeaders`, `@ZodCookies`. All ar
|
|
|
186
186
|
|
|
187
187
|
See [`docs/recipes/intersection-with-union.md`](docs/recipes/intersection-with-union.md) for the full pattern.
|
|
188
188
|
|
|
189
|
+
Named query objects (both `@Query() dto` and `@ZodQuery`) expand to one parameter per field by default. Pass `applyZodNest(raw, { app, queryParamStyle: 'ref' })` — or `@ZodQuery(schema, { ref: true })` per handler — to instead emit a single schema-based query parameter that `$ref`s the shared component. Same wire format; see [`docs/swagger-integration.md → Query parameter style`](docs/swagger-integration.md#query-parameter-style).
|
|
190
|
+
|
|
189
191
|
### I/O suffix rules
|
|
190
192
|
|
|
191
193
|
If a schema's input and output JSON Schemas are byte-equal (the common case), the OpenAPI doc emits a single `components.schemas[Id]`. If they differ (e.g. a `transform`, a `pipe`, an `.optional().default(x)` field), the doc emits two: `Id` for input, `IdOutput` for output. Response refs are rewritten to `IdOutput` automatically.
|
|
@@ -471,7 +473,7 @@ A compact, link-out index. Type signatures and detailed semantics live in the co
|
|
|
471
473
|
|
|
472
474
|
**DTO** — [`docs/dto.md`](docs/dto.md)
|
|
473
475
|
|
|
474
|
-
- `createZodDto(schema, options?)`, `isZodDto(value)`, `ZodDto<TSchema>`, `Io`
|
|
476
|
+
- `createZodDto(schema, options?)`, `isZodDto(value)`, `isZodSchema(value)`, `ZodDto<TSchema>`, `Io`
|
|
475
477
|
|
|
476
478
|
**Validation** — [`docs/validation-pipe.md`](docs/validation-pipe.md)
|
|
477
479
|
|
|
@@ -479,7 +481,7 @@ A compact, link-out index. Type signatures and detailed semantics live in the co
|
|
|
479
481
|
|
|
480
482
|
**Response** — [`docs/responses.md`](docs/responses.md)
|
|
481
483
|
|
|
482
|
-
- `@ZodResponse({ status?, type, description?, passthroughOnError? })
|
|
484
|
+
- `@ZodResponse({ status?, type, description?, passthroughOnError?, contentType?, stream? })` (`type` is a DTO or raw schema, or an array/tuple of either), `ZodSerializerInterceptor`, `ZodSerializationException`, `defaultStatusFor`, `resolveEffectiveStatus`, `ResponseStatusInput`, `ResponseStatusWildcard`, `ResponseVariant`, `ZodResponseEntry`, `ZodResponseType`, `ZOD_RESPONSES_METADATA_KEY`
|
|
483
485
|
|
|
484
486
|
**Parameter decorators for raw schemas** — [`docs/recipes/intersection-with-union.md`](docs/recipes/intersection-with-union.md)
|
|
485
487
|
|
package/dist/index.d.mts
CHANGED
|
@@ -225,6 +225,16 @@ declare const isZodDtoMarker: (value: unknown) => value is ZodDtoMarker;
|
|
|
225
225
|
* NestJS exposes via `ArgumentMetadata`.
|
|
226
226
|
*/
|
|
227
227
|
declare const isZodDto: (value: unknown) => value is ZodDto;
|
|
228
|
+
/**
|
|
229
|
+
* Runtime guard: is `value` a Zod schema (any `z.*` type)?
|
|
230
|
+
*
|
|
231
|
+
* Used by `@ZodResponse` to accept a raw schema in place of a DTO — including
|
|
232
|
+
* `z.discriminatedUnion` / `z.union` / `z.intersection`, which can't be wrapped
|
|
233
|
+
* with `createZodDto` (their `z.infer` is a union, so `class … extends
|
|
234
|
+
* createZodDto(schema)` fails to typecheck with TS2509). `instanceof z.ZodType`
|
|
235
|
+
* holds for every schema built through the same `zod` module instance.
|
|
236
|
+
*/
|
|
237
|
+
declare const isZodSchema: (value: unknown) => value is z.ZodType;
|
|
228
238
|
|
|
229
239
|
/**
|
|
230
240
|
* Default exception thrown by `ZodSerializerInterceptor` in strict mode
|
|
@@ -477,18 +487,28 @@ declare class ZodValidationPipe implements PipeTransform {
|
|
|
477
487
|
}
|
|
478
488
|
|
|
479
489
|
/**
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
490
|
+
* One entry in `@ZodResponse({ type })` — either a zod-nest DTO or a raw Zod
|
|
491
|
+
* schema. A raw schema is normalised internally to `createZodDto(schema).Output`
|
|
492
|
+
* (output IO, since a response body is output-only), so schemas that can't be
|
|
493
|
+
* wrapped with `createZodDto` — `z.discriminatedUnion` / `z.union` /
|
|
494
|
+
* `z.intersection`, whose `z.infer` is a union and so trip TS2509 in an
|
|
495
|
+
* `extends` clause — can be passed straight to a response. See `toResponseDto`.
|
|
496
|
+
*/
|
|
497
|
+
type ZodResponseEntry = ZodDto | z.ZodType;
|
|
498
|
+
/**
|
|
499
|
+
* Accepted shapes for `@ZodResponse({ type })`. Each slot is a `ZodResponseEntry`
|
|
500
|
+
* (DTO or raw schema), and the two may be mixed within an array:
|
|
501
|
+
* - `Dto` / `Schema` → validates as the entry's schema (single response).
|
|
502
|
+
* - `[Entry]` (length 1) → validates as `z.array(entry.schema)`; matches Nest's
|
|
483
503
|
* `@ApiResponse({ isArray: true })` convention without minting a separate
|
|
484
504
|
* `*sDto` id.
|
|
485
505
|
* - `[A, B, ...]` (length ≥ 2) → validates as `z.tuple([A.schema, B.schema, ...])`;
|
|
486
506
|
* surfaces as an OpenAPI 3.1 `prefixItems` tuple via `applyZodNest`.
|
|
487
507
|
*
|
|
488
|
-
* Empty arrays and
|
|
489
|
-
* so typos surface at module load, not the first request.
|
|
508
|
+
* Empty arrays and entries that are neither a DTO nor a schema throw `TypeError`
|
|
509
|
+
* at decoration time so typos surface at module load, not the first request.
|
|
490
510
|
*/
|
|
491
|
-
type ZodResponseType =
|
|
511
|
+
type ZodResponseType = ZodResponseEntry | readonly [ZodResponseEntry, ...ZodResponseEntry[]];
|
|
492
512
|
/**
|
|
493
513
|
* Accepted shapes for `@ZodResponse({ status })`:
|
|
494
514
|
* - `number` — exact match against `response.statusCode` (most common case).
|
|
@@ -596,12 +616,34 @@ interface ZodQueryOptions {
|
|
|
596
616
|
readonly id?: string;
|
|
597
617
|
/** Registry to register into. Defaults to `defaultRegistry`. */
|
|
598
618
|
readonly registry?: ZodNestRegistry;
|
|
619
|
+
/**
|
|
620
|
+
* Override how this query DTO is represented in the OpenAPI doc, taking
|
|
621
|
+
* precedence over `applyZodNest`'s `queryParamStyle`:
|
|
622
|
+
*
|
|
623
|
+
* - `true` — one single schema-based query parameter that `$ref`s the DTO's
|
|
624
|
+
* `components.schemas` entry (`style: 'form'`, `explode: true`).
|
|
625
|
+
* - `false` — one parameter per top-level property.
|
|
626
|
+
* - unset — follow the global `queryParamStyle` preference (default `'expand'`).
|
|
627
|
+
*
|
|
628
|
+
* Ref mode needs a named schema to reference: `ref: true` on an anonymous
|
|
629
|
+
* schema (no `.meta({ id })` and no `id` option) throws `ZodNestError`.
|
|
630
|
+
*/
|
|
631
|
+
readonly ref?: boolean;
|
|
599
632
|
}
|
|
600
633
|
/**
|
|
601
|
-
* Method-level decorator
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
634
|
+
* Method-level decorator describing a `@Query()` object schema as OpenAPI
|
|
635
|
+
* query parameters.
|
|
636
|
+
*
|
|
637
|
+
* When the schema is named (`.meta({ id })` or the `id` option), the decorator
|
|
638
|
+
* registers it and emits a single deferred marker, leaving the expand-vs-`$ref`
|
|
639
|
+
* decision to `applyZodNest` — so an unset `ref` follows the global
|
|
640
|
+
* `queryParamStyle` preference, `ref: true` collapses to one `$ref` query
|
|
641
|
+
* parameter, and `ref: false` expands per property. This mirrors the
|
|
642
|
+
* `@Query() dto` (`createZodDto`) path, which flows through the same marker.
|
|
643
|
+
*
|
|
644
|
+
* When the schema is anonymous, there is no component to reference, so the
|
|
645
|
+
* decorator expands one `@ApiQuery` per property immediately (and rejects
|
|
646
|
+
* `ref: true`).
|
|
605
647
|
*
|
|
606
648
|
* The user remains responsible for binding the actual query values to the
|
|
607
649
|
* handler, typically via `@Query(new ZodValidationPipe(schema)) q: z.infer<typeof schema>`.
|
|
@@ -700,6 +742,21 @@ declare class ZodNestModule {
|
|
|
700
742
|
static forRoot(options?: ZodNestModuleOptions): DynamicModule;
|
|
701
743
|
}
|
|
702
744
|
|
|
745
|
+
/**
|
|
746
|
+
* How a named `@Query()` / `@ZodQuery` DTO is represented in the OpenAPI doc:
|
|
747
|
+
*
|
|
748
|
+
* - `'expand'` (default) — one parameter per top-level property of the DTO
|
|
749
|
+
* schema, each inlined or `$ref`'d independently.
|
|
750
|
+
* - `'ref'` — a single schema-based query parameter that references the DTO's
|
|
751
|
+
* `components.schemas` entry (`style: 'form'`, `explode: true`,
|
|
752
|
+
* `schema: { $ref }`). The wire format is identical to `'expand'`; only the
|
|
753
|
+
* document representation collapses to the shared component.
|
|
754
|
+
*
|
|
755
|
+
* Query-only: path / header / cookie markers always expand regardless of this
|
|
756
|
+
* setting, since the form-exploded-object pattern is a query serialization.
|
|
757
|
+
*/
|
|
758
|
+
type QueryParamStyle = 'expand' | 'ref';
|
|
759
|
+
|
|
703
760
|
interface ApplyZodNestOptions {
|
|
704
761
|
/**
|
|
705
762
|
* The NestJS app instance. Required so `applyZodNest` can walk controllers
|
|
@@ -721,6 +778,20 @@ interface ApplyZodNestOptions {
|
|
|
721
778
|
* Set to `false` to emit `{}` for those instead.
|
|
722
779
|
*/
|
|
723
780
|
strict?: boolean;
|
|
781
|
+
/**
|
|
782
|
+
* How named `@Query()` / `@ZodQuery` DTOs are represented in the document
|
|
783
|
+
* (default `'expand'`):
|
|
784
|
+
*
|
|
785
|
+
* - `'expand'` — one query parameter per top-level property of the DTO.
|
|
786
|
+
* - `'ref'` — a single schema-based query parameter referencing the DTO's
|
|
787
|
+
* `components.schemas` entry (`style: 'form'`, `explode: true`). The wire
|
|
788
|
+
* format is unchanged; only the spec representation collapses to the
|
|
789
|
+
* shared component. Note: Swagger UI renders the two forms differently.
|
|
790
|
+
*
|
|
791
|
+
* Query-only — path / header / cookie DTOs always expand. A per-handler
|
|
792
|
+
* `@ZodQuery({ ref })` override takes precedence over this preference.
|
|
793
|
+
*/
|
|
794
|
+
queryParamStyle?: QueryParamStyle;
|
|
724
795
|
}
|
|
725
796
|
/**
|
|
726
797
|
* Post-processor over the OpenAPI document emitted by
|
|
@@ -732,9 +803,11 @@ interface ApplyZodNestOptions {
|
|
|
732
803
|
* keyed by the marker's `dtoId` (renaming as needed).
|
|
733
804
|
* - Every `@Query()` / `@Param()` / `@Headers()` / `@Cookie()` marker
|
|
734
805
|
* parameter is expanded into one parameter per top-level property of the
|
|
735
|
-
* DTO's schema (`expandParamMarkers`)
|
|
736
|
-
*
|
|
737
|
-
*
|
|
806
|
+
* DTO's schema (`expandParamMarkers`) — except `@Query()` DTOs under
|
|
807
|
+
* `queryParamStyle: 'ref'` (or a `@ZodQuery({ ref: true })` override), which
|
|
808
|
+
* collapse to a single `$ref` schema-based query parameter. The synthetic
|
|
809
|
+
* `components.schemas.Object` that `@nestjs/swagger` materialises for the
|
|
810
|
+
* marker placeholder is pruned when it has no remaining referrers.
|
|
738
811
|
* - The I/O suffix truth table is applied — equal input/output bodies collapse
|
|
739
812
|
* to one `components.schemas[id]`; divergent bodies split as
|
|
740
813
|
* `id` (input) + `idOutput` (output), with response-side refs rewritten.
|
|
@@ -775,4 +848,4 @@ declare class ZodNestDocumentError extends ZodNestError {
|
|
|
775
848
|
constructor(code: ZodNestDocumentErrorCode, message: string, details?: Record<string, unknown>);
|
|
776
849
|
}
|
|
777
850
|
|
|
778
|
-
export { type ApplyZodNestOptions, COMPONENTS_SCHEMAS_PREFIX, type CreateSerializationException, type CreateValidationException, type CreateZodDtoOptions, DEFAULT_MAX_LOGGED_VALUE_BYTES, DEFAULT_REDACT_KEYS, DEFAULT_STREAM_CONTENT_TYPES, type Io, type LineageEntry, type NormalizedZodNestOptions, type Override, type OverrideContext, type OverrideJSONSchemaArg, type RegisterSchemaOptions, type ResponseStatusInput, type ResponseStatusWildcard, type ResponseVariant, type ResponseVariantKind, SchemaObject, type ToOpenApiOptions, type ToOpenApiResult, ZOD_DTO_SYMBOL, ZOD_NEST_DTO_EXTENSION, ZOD_NEST_ERROR_DUPLICATE_ID, ZOD_NEST_ERROR_EXTENSION, ZOD_NEST_OPTIONS, ZOD_RESPONSES_METADATA_KEY, ZodBody, type ZodBodyOptions, ZodCookies, type ZodCookiesOptions, type ZodDto, type ZodDtoMarker, ZodHeaders, type ZodHeadersOptions, ZodNestDocumentError, type ZodNestDocumentErrorCode, ZodNestError, ZodNestModule, type ZodNestModuleOptions, type ZodNestRegistry, ZodNestUnrepresentableError, ZodQuery, type ZodQueryOptions, ZodResponse, type ZodResponseDescription, type ZodResponseOptions, type ZodResponseType, ZodSerializationException, ZodSerializerInterceptor, ZodValidationException, ZodValidationPipe, type ZodValidationPipeArg, type ZodValidationPipeOptions, applyZodNest, createRegistry, createZodDto, defaultRegistry, defaultStatusFor, extend, getLineage, isZodDto, isZodDtoMarker, makeZodDtoMarker, overrideJSONSchema, registerSchema, resolveEffectiveStatus, toOpenApi };
|
|
851
|
+
export { type ApplyZodNestOptions, COMPONENTS_SCHEMAS_PREFIX, type CreateSerializationException, type CreateValidationException, type CreateZodDtoOptions, DEFAULT_MAX_LOGGED_VALUE_BYTES, DEFAULT_REDACT_KEYS, DEFAULT_STREAM_CONTENT_TYPES, type Io, type LineageEntry, type NormalizedZodNestOptions, type Override, type OverrideContext, type OverrideJSONSchemaArg, type RegisterSchemaOptions, type ResponseStatusInput, type ResponseStatusWildcard, type ResponseVariant, type ResponseVariantKind, SchemaObject, type ToOpenApiOptions, type ToOpenApiResult, ZOD_DTO_SYMBOL, ZOD_NEST_DTO_EXTENSION, ZOD_NEST_ERROR_DUPLICATE_ID, ZOD_NEST_ERROR_EXTENSION, ZOD_NEST_OPTIONS, ZOD_RESPONSES_METADATA_KEY, ZodBody, type ZodBodyOptions, ZodCookies, type ZodCookiesOptions, type ZodDto, type ZodDtoMarker, ZodHeaders, type ZodHeadersOptions, ZodNestDocumentError, type ZodNestDocumentErrorCode, ZodNestError, ZodNestModule, type ZodNestModuleOptions, type ZodNestRegistry, ZodNestUnrepresentableError, ZodQuery, type ZodQueryOptions, ZodResponse, type ZodResponseDescription, type ZodResponseEntry, type ZodResponseOptions, type ZodResponseType, ZodSerializationException, ZodSerializerInterceptor, ZodValidationException, ZodValidationPipe, type ZodValidationPipeArg, type ZodValidationPipeOptions, applyZodNest, createRegistry, createZodDto, defaultRegistry, defaultStatusFor, extend, getLineage, isZodDto, isZodDtoMarker, isZodSchema, makeZodDtoMarker, overrideJSONSchema, registerSchema, resolveEffectiveStatus, toOpenApi };
|
package/dist/index.d.ts
CHANGED
|
@@ -225,6 +225,16 @@ declare const isZodDtoMarker: (value: unknown) => value is ZodDtoMarker;
|
|
|
225
225
|
* NestJS exposes via `ArgumentMetadata`.
|
|
226
226
|
*/
|
|
227
227
|
declare const isZodDto: (value: unknown) => value is ZodDto;
|
|
228
|
+
/**
|
|
229
|
+
* Runtime guard: is `value` a Zod schema (any `z.*` type)?
|
|
230
|
+
*
|
|
231
|
+
* Used by `@ZodResponse` to accept a raw schema in place of a DTO — including
|
|
232
|
+
* `z.discriminatedUnion` / `z.union` / `z.intersection`, which can't be wrapped
|
|
233
|
+
* with `createZodDto` (their `z.infer` is a union, so `class … extends
|
|
234
|
+
* createZodDto(schema)` fails to typecheck with TS2509). `instanceof z.ZodType`
|
|
235
|
+
* holds for every schema built through the same `zod` module instance.
|
|
236
|
+
*/
|
|
237
|
+
declare const isZodSchema: (value: unknown) => value is z.ZodType;
|
|
228
238
|
|
|
229
239
|
/**
|
|
230
240
|
* Default exception thrown by `ZodSerializerInterceptor` in strict mode
|
|
@@ -477,18 +487,28 @@ declare class ZodValidationPipe implements PipeTransform {
|
|
|
477
487
|
}
|
|
478
488
|
|
|
479
489
|
/**
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
490
|
+
* One entry in `@ZodResponse({ type })` — either a zod-nest DTO or a raw Zod
|
|
491
|
+
* schema. A raw schema is normalised internally to `createZodDto(schema).Output`
|
|
492
|
+
* (output IO, since a response body is output-only), so schemas that can't be
|
|
493
|
+
* wrapped with `createZodDto` — `z.discriminatedUnion` / `z.union` /
|
|
494
|
+
* `z.intersection`, whose `z.infer` is a union and so trip TS2509 in an
|
|
495
|
+
* `extends` clause — can be passed straight to a response. See `toResponseDto`.
|
|
496
|
+
*/
|
|
497
|
+
type ZodResponseEntry = ZodDto | z.ZodType;
|
|
498
|
+
/**
|
|
499
|
+
* Accepted shapes for `@ZodResponse({ type })`. Each slot is a `ZodResponseEntry`
|
|
500
|
+
* (DTO or raw schema), and the two may be mixed within an array:
|
|
501
|
+
* - `Dto` / `Schema` → validates as the entry's schema (single response).
|
|
502
|
+
* - `[Entry]` (length 1) → validates as `z.array(entry.schema)`; matches Nest's
|
|
483
503
|
* `@ApiResponse({ isArray: true })` convention without minting a separate
|
|
484
504
|
* `*sDto` id.
|
|
485
505
|
* - `[A, B, ...]` (length ≥ 2) → validates as `z.tuple([A.schema, B.schema, ...])`;
|
|
486
506
|
* surfaces as an OpenAPI 3.1 `prefixItems` tuple via `applyZodNest`.
|
|
487
507
|
*
|
|
488
|
-
* Empty arrays and
|
|
489
|
-
* so typos surface at module load, not the first request.
|
|
508
|
+
* Empty arrays and entries that are neither a DTO nor a schema throw `TypeError`
|
|
509
|
+
* at decoration time so typos surface at module load, not the first request.
|
|
490
510
|
*/
|
|
491
|
-
type ZodResponseType =
|
|
511
|
+
type ZodResponseType = ZodResponseEntry | readonly [ZodResponseEntry, ...ZodResponseEntry[]];
|
|
492
512
|
/**
|
|
493
513
|
* Accepted shapes for `@ZodResponse({ status })`:
|
|
494
514
|
* - `number` — exact match against `response.statusCode` (most common case).
|
|
@@ -596,12 +616,34 @@ interface ZodQueryOptions {
|
|
|
596
616
|
readonly id?: string;
|
|
597
617
|
/** Registry to register into. Defaults to `defaultRegistry`. */
|
|
598
618
|
readonly registry?: ZodNestRegistry;
|
|
619
|
+
/**
|
|
620
|
+
* Override how this query DTO is represented in the OpenAPI doc, taking
|
|
621
|
+
* precedence over `applyZodNest`'s `queryParamStyle`:
|
|
622
|
+
*
|
|
623
|
+
* - `true` — one single schema-based query parameter that `$ref`s the DTO's
|
|
624
|
+
* `components.schemas` entry (`style: 'form'`, `explode: true`).
|
|
625
|
+
* - `false` — one parameter per top-level property.
|
|
626
|
+
* - unset — follow the global `queryParamStyle` preference (default `'expand'`).
|
|
627
|
+
*
|
|
628
|
+
* Ref mode needs a named schema to reference: `ref: true` on an anonymous
|
|
629
|
+
* schema (no `.meta({ id })` and no `id` option) throws `ZodNestError`.
|
|
630
|
+
*/
|
|
631
|
+
readonly ref?: boolean;
|
|
599
632
|
}
|
|
600
633
|
/**
|
|
601
|
-
* Method-level decorator
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
634
|
+
* Method-level decorator describing a `@Query()` object schema as OpenAPI
|
|
635
|
+
* query parameters.
|
|
636
|
+
*
|
|
637
|
+
* When the schema is named (`.meta({ id })` or the `id` option), the decorator
|
|
638
|
+
* registers it and emits a single deferred marker, leaving the expand-vs-`$ref`
|
|
639
|
+
* decision to `applyZodNest` — so an unset `ref` follows the global
|
|
640
|
+
* `queryParamStyle` preference, `ref: true` collapses to one `$ref` query
|
|
641
|
+
* parameter, and `ref: false` expands per property. This mirrors the
|
|
642
|
+
* `@Query() dto` (`createZodDto`) path, which flows through the same marker.
|
|
643
|
+
*
|
|
644
|
+
* When the schema is anonymous, there is no component to reference, so the
|
|
645
|
+
* decorator expands one `@ApiQuery` per property immediately (and rejects
|
|
646
|
+
* `ref: true`).
|
|
605
647
|
*
|
|
606
648
|
* The user remains responsible for binding the actual query values to the
|
|
607
649
|
* handler, typically via `@Query(new ZodValidationPipe(schema)) q: z.infer<typeof schema>`.
|
|
@@ -700,6 +742,21 @@ declare class ZodNestModule {
|
|
|
700
742
|
static forRoot(options?: ZodNestModuleOptions): DynamicModule;
|
|
701
743
|
}
|
|
702
744
|
|
|
745
|
+
/**
|
|
746
|
+
* How a named `@Query()` / `@ZodQuery` DTO is represented in the OpenAPI doc:
|
|
747
|
+
*
|
|
748
|
+
* - `'expand'` (default) — one parameter per top-level property of the DTO
|
|
749
|
+
* schema, each inlined or `$ref`'d independently.
|
|
750
|
+
* - `'ref'` — a single schema-based query parameter that references the DTO's
|
|
751
|
+
* `components.schemas` entry (`style: 'form'`, `explode: true`,
|
|
752
|
+
* `schema: { $ref }`). The wire format is identical to `'expand'`; only the
|
|
753
|
+
* document representation collapses to the shared component.
|
|
754
|
+
*
|
|
755
|
+
* Query-only: path / header / cookie markers always expand regardless of this
|
|
756
|
+
* setting, since the form-exploded-object pattern is a query serialization.
|
|
757
|
+
*/
|
|
758
|
+
type QueryParamStyle = 'expand' | 'ref';
|
|
759
|
+
|
|
703
760
|
interface ApplyZodNestOptions {
|
|
704
761
|
/**
|
|
705
762
|
* The NestJS app instance. Required so `applyZodNest` can walk controllers
|
|
@@ -721,6 +778,20 @@ interface ApplyZodNestOptions {
|
|
|
721
778
|
* Set to `false` to emit `{}` for those instead.
|
|
722
779
|
*/
|
|
723
780
|
strict?: boolean;
|
|
781
|
+
/**
|
|
782
|
+
* How named `@Query()` / `@ZodQuery` DTOs are represented in the document
|
|
783
|
+
* (default `'expand'`):
|
|
784
|
+
*
|
|
785
|
+
* - `'expand'` — one query parameter per top-level property of the DTO.
|
|
786
|
+
* - `'ref'` — a single schema-based query parameter referencing the DTO's
|
|
787
|
+
* `components.schemas` entry (`style: 'form'`, `explode: true`). The wire
|
|
788
|
+
* format is unchanged; only the spec representation collapses to the
|
|
789
|
+
* shared component. Note: Swagger UI renders the two forms differently.
|
|
790
|
+
*
|
|
791
|
+
* Query-only — path / header / cookie DTOs always expand. A per-handler
|
|
792
|
+
* `@ZodQuery({ ref })` override takes precedence over this preference.
|
|
793
|
+
*/
|
|
794
|
+
queryParamStyle?: QueryParamStyle;
|
|
724
795
|
}
|
|
725
796
|
/**
|
|
726
797
|
* Post-processor over the OpenAPI document emitted by
|
|
@@ -732,9 +803,11 @@ interface ApplyZodNestOptions {
|
|
|
732
803
|
* keyed by the marker's `dtoId` (renaming as needed).
|
|
733
804
|
* - Every `@Query()` / `@Param()` / `@Headers()` / `@Cookie()` marker
|
|
734
805
|
* parameter is expanded into one parameter per top-level property of the
|
|
735
|
-
* DTO's schema (`expandParamMarkers`)
|
|
736
|
-
*
|
|
737
|
-
*
|
|
806
|
+
* DTO's schema (`expandParamMarkers`) — except `@Query()` DTOs under
|
|
807
|
+
* `queryParamStyle: 'ref'` (or a `@ZodQuery({ ref: true })` override), which
|
|
808
|
+
* collapse to a single `$ref` schema-based query parameter. The synthetic
|
|
809
|
+
* `components.schemas.Object` that `@nestjs/swagger` materialises for the
|
|
810
|
+
* marker placeholder is pruned when it has no remaining referrers.
|
|
738
811
|
* - The I/O suffix truth table is applied — equal input/output bodies collapse
|
|
739
812
|
* to one `components.schemas[id]`; divergent bodies split as
|
|
740
813
|
* `id` (input) + `idOutput` (output), with response-side refs rewritten.
|
|
@@ -775,4 +848,4 @@ declare class ZodNestDocumentError extends ZodNestError {
|
|
|
775
848
|
constructor(code: ZodNestDocumentErrorCode, message: string, details?: Record<string, unknown>);
|
|
776
849
|
}
|
|
777
850
|
|
|
778
|
-
export { type ApplyZodNestOptions, COMPONENTS_SCHEMAS_PREFIX, type CreateSerializationException, type CreateValidationException, type CreateZodDtoOptions, DEFAULT_MAX_LOGGED_VALUE_BYTES, DEFAULT_REDACT_KEYS, DEFAULT_STREAM_CONTENT_TYPES, type Io, type LineageEntry, type NormalizedZodNestOptions, type Override, type OverrideContext, type OverrideJSONSchemaArg, type RegisterSchemaOptions, type ResponseStatusInput, type ResponseStatusWildcard, type ResponseVariant, type ResponseVariantKind, SchemaObject, type ToOpenApiOptions, type ToOpenApiResult, ZOD_DTO_SYMBOL, ZOD_NEST_DTO_EXTENSION, ZOD_NEST_ERROR_DUPLICATE_ID, ZOD_NEST_ERROR_EXTENSION, ZOD_NEST_OPTIONS, ZOD_RESPONSES_METADATA_KEY, ZodBody, type ZodBodyOptions, ZodCookies, type ZodCookiesOptions, type ZodDto, type ZodDtoMarker, ZodHeaders, type ZodHeadersOptions, ZodNestDocumentError, type ZodNestDocumentErrorCode, ZodNestError, ZodNestModule, type ZodNestModuleOptions, type ZodNestRegistry, ZodNestUnrepresentableError, ZodQuery, type ZodQueryOptions, ZodResponse, type ZodResponseDescription, type ZodResponseOptions, type ZodResponseType, ZodSerializationException, ZodSerializerInterceptor, ZodValidationException, ZodValidationPipe, type ZodValidationPipeArg, type ZodValidationPipeOptions, applyZodNest, createRegistry, createZodDto, defaultRegistry, defaultStatusFor, extend, getLineage, isZodDto, isZodDtoMarker, makeZodDtoMarker, overrideJSONSchema, registerSchema, resolveEffectiveStatus, toOpenApi };
|
|
851
|
+
export { type ApplyZodNestOptions, COMPONENTS_SCHEMAS_PREFIX, type CreateSerializationException, type CreateValidationException, type CreateZodDtoOptions, DEFAULT_MAX_LOGGED_VALUE_BYTES, DEFAULT_REDACT_KEYS, DEFAULT_STREAM_CONTENT_TYPES, type Io, type LineageEntry, type NormalizedZodNestOptions, type Override, type OverrideContext, type OverrideJSONSchemaArg, type RegisterSchemaOptions, type ResponseStatusInput, type ResponseStatusWildcard, type ResponseVariant, type ResponseVariantKind, SchemaObject, type ToOpenApiOptions, type ToOpenApiResult, ZOD_DTO_SYMBOL, ZOD_NEST_DTO_EXTENSION, ZOD_NEST_ERROR_DUPLICATE_ID, ZOD_NEST_ERROR_EXTENSION, ZOD_NEST_OPTIONS, ZOD_RESPONSES_METADATA_KEY, ZodBody, type ZodBodyOptions, ZodCookies, type ZodCookiesOptions, type ZodDto, type ZodDtoMarker, ZodHeaders, type ZodHeadersOptions, ZodNestDocumentError, type ZodNestDocumentErrorCode, ZodNestError, ZodNestModule, type ZodNestModuleOptions, type ZodNestRegistry, ZodNestUnrepresentableError, ZodQuery, type ZodQueryOptions, ZodResponse, type ZodResponseDescription, type ZodResponseEntry, type ZodResponseOptions, type ZodResponseType, ZodSerializationException, ZodSerializerInterceptor, ZodValidationException, ZodValidationPipe, type ZodValidationPipeArg, type ZodValidationPipeOptions, applyZodNest, createRegistry, createZodDto, defaultRegistry, defaultStatusFor, extend, getLineage, isZodDto, isZodDtoMarker, isZodSchema, makeZodDtoMarker, overrideJSONSchema, registerSchema, resolveEffectiveStatus, toOpenApi };
|
package/dist/index.js
CHANGED
|
@@ -585,6 +585,10 @@ var buildSiblingClass = /* @__PURE__ */ __name((parent, schema) => {
|
|
|
585
585
|
};
|
|
586
586
|
}
|
|
587
587
|
};
|
|
588
|
+
Object.defineProperty(SiblingClass, "name", {
|
|
589
|
+
get: /* @__PURE__ */ __name(() => parent.id, "get"),
|
|
590
|
+
configurable: true
|
|
591
|
+
});
|
|
588
592
|
return SiblingClass;
|
|
589
593
|
}, "buildSiblingClass");
|
|
590
594
|
var resolveOutput = /* @__PURE__ */ __name((parent, schema) => {
|
|
@@ -658,9 +662,8 @@ var createZodDto = /* @__PURE__ */ __name((schema, options) => {
|
|
|
658
662
|
};
|
|
659
663
|
return ZodDtoBase;
|
|
660
664
|
}, "createZodDto");
|
|
661
|
-
|
|
662
|
-
// src/dto/predicates.ts
|
|
663
665
|
var isZodDto = /* @__PURE__ */ __name((value) => typeof value === "function" && value[ZOD_DTO_SYMBOL] === true, "isZodDto");
|
|
666
|
+
var isZodSchema = /* @__PURE__ */ __name((value) => value instanceof zod.z.ZodType, "isZodSchema");
|
|
664
667
|
var ZodSerializationException = class extends common.InternalServerErrorException {
|
|
665
668
|
static {
|
|
666
669
|
__name(this, "ZodSerializationException");
|
|
@@ -948,8 +951,8 @@ function _ts_param(paramIndex, decorator) {
|
|
|
948
951
|
};
|
|
949
952
|
}
|
|
950
953
|
__name(_ts_param, "_ts_param");
|
|
951
|
-
var
|
|
952
|
-
var isOptionsObject = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !
|
|
954
|
+
var isZodSchema2 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && "_zod" in value, "isZodSchema");
|
|
955
|
+
var isOptionsObject = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !isZodSchema2(value), "isOptionsObject");
|
|
953
956
|
var defaultExceptionFactory = /* @__PURE__ */ __name((zodError, argMetadata) => new ZodValidationException(zodError, argMetadata), "defaultExceptionFactory");
|
|
954
957
|
exports.ZodValidationPipe = class _ZodValidationPipe {
|
|
955
958
|
static {
|
|
@@ -1018,7 +1021,7 @@ exports.ZodValidationPipe = class _ZodValidationPipe {
|
|
|
1018
1021
|
dtoName: arg.name
|
|
1019
1022
|
};
|
|
1020
1023
|
}
|
|
1021
|
-
if (
|
|
1024
|
+
if (isZodSchema2(arg)) {
|
|
1022
1025
|
return {
|
|
1023
1026
|
schema: arg,
|
|
1024
1027
|
factory: void 0,
|
|
@@ -1086,6 +1089,48 @@ var appendResponseVariant = /* @__PURE__ */ __name((handler, variant) => {
|
|
|
1086
1089
|
...existing
|
|
1087
1090
|
], handler);
|
|
1088
1091
|
}, "appendResponseVariant");
|
|
1092
|
+
|
|
1093
|
+
// src/response/normalize-type.ts
|
|
1094
|
+
var responseDtoCache = /* @__PURE__ */ new WeakMap();
|
|
1095
|
+
var anonResponseSchemaCounter = 0;
|
|
1096
|
+
var warnedOnAnonymousResponseSchema = false;
|
|
1097
|
+
var warnAnonymousOnce = /* @__PURE__ */ __name((fallbackId) => {
|
|
1098
|
+
if (warnedOnAnonymousResponseSchema) {
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
warnedOnAnonymousResponseSchema = true;
|
|
1102
|
+
console.warn(`[zod-nest] @ZodResponse received a raw Zod schema with no \`.meta({ id })\`. It will appear in components.schemas as "${fallbackId}". Add \`schema.meta({ id: 'Foo' })\` to control the OpenAPI component name.`);
|
|
1103
|
+
}, "warnAnonymousOnce");
|
|
1104
|
+
var schemaToOutputDto = /* @__PURE__ */ __name((schema) => {
|
|
1105
|
+
const cached = responseDtoCache.get(schema);
|
|
1106
|
+
if (cached !== void 0) {
|
|
1107
|
+
return cached;
|
|
1108
|
+
}
|
|
1109
|
+
const namedId = registerSchema(schema);
|
|
1110
|
+
if (namedId !== void 0) {
|
|
1111
|
+
const dto2 = createZodDto(schema).Output;
|
|
1112
|
+
responseDtoCache.set(schema, dto2);
|
|
1113
|
+
return dto2;
|
|
1114
|
+
}
|
|
1115
|
+
anonResponseSchemaCounter += 1;
|
|
1116
|
+
const fallbackId = `_AnonZodResponseSchema_${anonResponseSchemaCounter}`;
|
|
1117
|
+
warnAnonymousOnce(fallbackId);
|
|
1118
|
+
const dto = createZodDto(schema, {
|
|
1119
|
+
id: fallbackId
|
|
1120
|
+
}).Output;
|
|
1121
|
+
responseDtoCache.set(schema, dto);
|
|
1122
|
+
return dto;
|
|
1123
|
+
}, "schemaToOutputDto");
|
|
1124
|
+
var toResponseDto = /* @__PURE__ */ __name((entry, index) => {
|
|
1125
|
+
if (isZodDto(entry)) {
|
|
1126
|
+
return entry;
|
|
1127
|
+
}
|
|
1128
|
+
if (isZodSchema(entry)) {
|
|
1129
|
+
return schemaToOutputDto(entry);
|
|
1130
|
+
}
|
|
1131
|
+
const where = index === void 0 ? "@ZodResponse({ type })" : `@ZodResponse({ type }) element [${index}]`;
|
|
1132
|
+
throw new TypeError(`[zod-nest] ${where} must be a zod-nest DTO class (from createZodDto), a Zod schema, or a non-empty array of those.`);
|
|
1133
|
+
}, "toResponseDto");
|
|
1089
1134
|
var extractDescriptionFields = /* @__PURE__ */ __name((desc) => {
|
|
1090
1135
|
if (desc === void 0) {
|
|
1091
1136
|
return {};
|
|
@@ -1188,13 +1233,10 @@ var applySwaggerResponseDecorator = /* @__PURE__ */ __name((variant, effectiveSt
|
|
|
1188
1233
|
}, "applySwaggerResponseDecorator");
|
|
1189
1234
|
|
|
1190
1235
|
// src/decorators/zod-response.decorator.ts
|
|
1191
|
-
var buildArrayKind = /* @__PURE__ */ __name((
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
const [head, ...rest] = dtos;
|
|
1236
|
+
var buildArrayKind = /* @__PURE__ */ __name((entries) => {
|
|
1237
|
+
const [headEntry, ...restEntries] = entries;
|
|
1238
|
+
const head = toResponseDto(headEntry, 0);
|
|
1239
|
+
const rest = restEntries.map((entry, index) => toResponseDto(entry, index + 1));
|
|
1198
1240
|
if (rest.length === 0) {
|
|
1199
1241
|
return {
|
|
1200
1242
|
kind: "array",
|
|
@@ -1210,24 +1252,25 @@ var buildArrayKind = /* @__PURE__ */ __name((dtos) => {
|
|
|
1210
1252
|
];
|
|
1211
1253
|
return {
|
|
1212
1254
|
kind: "tuple",
|
|
1213
|
-
dto:
|
|
1255
|
+
dto: [
|
|
1256
|
+
head,
|
|
1257
|
+
...rest
|
|
1258
|
+
],
|
|
1214
1259
|
validationSchema: zod.z.tuple(tupleSchemas)
|
|
1215
1260
|
};
|
|
1216
1261
|
}, "buildArrayKind");
|
|
1217
1262
|
var buildKind = /* @__PURE__ */ __name((type) => {
|
|
1218
1263
|
if (Array.isArray(type)) {
|
|
1219
1264
|
if (type.length === 0) {
|
|
1220
|
-
throw new TypeError("[zod-nest] @ZodResponse({ type: [] }) is invalid \u2014 provide at least one DTO.");
|
|
1265
|
+
throw new TypeError("[zod-nest] @ZodResponse({ type: [] }) is invalid \u2014 provide at least one DTO or schema.");
|
|
1221
1266
|
}
|
|
1222
1267
|
return buildArrayKind(type);
|
|
1223
1268
|
}
|
|
1224
|
-
|
|
1225
|
-
throw new TypeError("[zod-nest] @ZodResponse({ type }) must be a zod-nest DTO class (from createZodDto) or an array of such classes.");
|
|
1226
|
-
}
|
|
1269
|
+
const dto = toResponseDto(type);
|
|
1227
1270
|
return {
|
|
1228
1271
|
kind: "single",
|
|
1229
|
-
dto
|
|
1230
|
-
validationSchema:
|
|
1272
|
+
dto,
|
|
1273
|
+
validationSchema: dto.schema
|
|
1231
1274
|
};
|
|
1232
1275
|
}, "buildKind");
|
|
1233
1276
|
var normaliseStatus = /* @__PURE__ */ __name((status) => {
|
|
@@ -1429,10 +1472,51 @@ var resolveBodySchema = /* @__PURE__ */ __name((schema, options) => {
|
|
|
1429
1472
|
});
|
|
1430
1473
|
return resolution.kind === "ref" ? resolution.ref : resolution.schema;
|
|
1431
1474
|
}, "resolveBodySchema");
|
|
1475
|
+
|
|
1476
|
+
// src/decorators/internal/query-marker.ts
|
|
1477
|
+
var API_PARAMETERS_METADATA_KEY = "swagger/apiParameters";
|
|
1478
|
+
var appendQueryMarker = /* @__PURE__ */ __name((dtoId, ref) => (_target, _propertyKey, descriptor) => {
|
|
1479
|
+
const method = descriptor.value;
|
|
1480
|
+
if (typeof method !== "function") {
|
|
1481
|
+
return descriptor;
|
|
1482
|
+
}
|
|
1483
|
+
const marker = {
|
|
1484
|
+
name: dtoId,
|
|
1485
|
+
in: "query",
|
|
1486
|
+
__zodNestDto: true,
|
|
1487
|
+
dtoId,
|
|
1488
|
+
io: "input"
|
|
1489
|
+
};
|
|
1490
|
+
if (ref !== void 0) {
|
|
1491
|
+
marker.ref = ref;
|
|
1492
|
+
}
|
|
1493
|
+
const existing = Reflect.getMetadata(API_PARAMETERS_METADATA_KEY, method);
|
|
1494
|
+
const params = Array.isArray(existing) ? existing : [];
|
|
1495
|
+
Reflect.defineMetadata(API_PARAMETERS_METADATA_KEY, [
|
|
1496
|
+
...params,
|
|
1497
|
+
marker
|
|
1498
|
+
], method);
|
|
1499
|
+
return descriptor;
|
|
1500
|
+
}, "appendQueryMarker");
|
|
1501
|
+
|
|
1502
|
+
// src/decorators/zod-query.decorator.ts
|
|
1432
1503
|
var ZodQuery = /* @__PURE__ */ __name((schema, options) => {
|
|
1504
|
+
if (!isZodObject(schema)) {
|
|
1505
|
+
throw new ZodNestError(`@ZodQuery requires a \`z.object({...})\` schema (got \`${schema._zod.def.type}\`). Each property of the object becomes one OpenAPI parameter. For non-object body shapes (intersections, unions, primitives), use \`@ZodBody\` instead.`);
|
|
1506
|
+
}
|
|
1507
|
+
const registry = options?.registry ?? defaultRegistry;
|
|
1508
|
+
const id = registerSchema(schema, registry, {
|
|
1509
|
+
id: options?.id
|
|
1510
|
+
});
|
|
1511
|
+
if (id !== void 0) {
|
|
1512
|
+
return appendQueryMarker(id, options?.ref);
|
|
1513
|
+
}
|
|
1514
|
+
if (options?.ref === true) {
|
|
1515
|
+
throw new ZodNestError(`@ZodQuery({ ref: true }) requires a named schema \u2014 there is no component to \`$ref\`. Name the schema via \`.meta({ id: 'Foo' })\` or pass the \`id\` option, or drop \`ref\` to expand per property.`);
|
|
1516
|
+
}
|
|
1433
1517
|
const expanded = expandObjectSchema(schema, {
|
|
1434
1518
|
id: options?.id,
|
|
1435
|
-
registry
|
|
1519
|
+
registry,
|
|
1436
1520
|
decoratorName: "@ZodQuery"
|
|
1437
1521
|
});
|
|
1438
1522
|
return common.applyDecorators(...expanded.map(({ name, required, resolution }) => swagger.ApiQuery({
|
|
@@ -1516,10 +1600,10 @@ __name(_ts_param2, "_ts_param");
|
|
|
1516
1600
|
var defaultSerializationFactory = /* @__PURE__ */ __name((err, ctx) => new ZodSerializationException(err, ctx), "defaultSerializationFactory");
|
|
1517
1601
|
var formatDtoLabel = /* @__PURE__ */ __name((variant) => {
|
|
1518
1602
|
if (variant.kind === "single") {
|
|
1519
|
-
return variant.dto.
|
|
1603
|
+
return variant.dto.id;
|
|
1520
1604
|
}
|
|
1521
1605
|
const dtos = variant.dto;
|
|
1522
|
-
return `[${dtos.map((d) => d.
|
|
1606
|
+
return `[${dtos.map((d) => d.id).join(", ")}]`;
|
|
1523
1607
|
}, "formatDtoLabel");
|
|
1524
1608
|
var formatHandlerLabel = /* @__PURE__ */ __name((context) => `${context.getClass().name}.${context.getHandler().name}`, "formatHandlerLabel");
|
|
1525
1609
|
var matchesWildcard = /* @__PURE__ */ __name((wildcard, status) => wildcard.charCodeAt(0) - 48 === Math.floor(status / 100), "matchesWildcard");
|
|
@@ -1938,13 +2022,21 @@ var hintFor = /* @__PURE__ */ __name((ref, collected) => {
|
|
|
1938
2022
|
var isPlainRecord3 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isPlainRecord");
|
|
1939
2023
|
var expandParamMarkers = /* @__PURE__ */ __name((params) => {
|
|
1940
2024
|
const { doc, inputSchemas, outputSchemas } = params;
|
|
2025
|
+
const queryParamStyle = params.queryParamStyle ?? "expand";
|
|
2026
|
+
const schemas = doc.components?.schemas;
|
|
2027
|
+
const componentIds = schemas !== null && typeof schemas === "object" ? new Set(Object.keys(schemas)) : /* @__PURE__ */ new Set();
|
|
1941
2028
|
let expandedAny = false;
|
|
1942
2029
|
forEachOperation(doc, (op) => {
|
|
1943
2030
|
const parameters = op.parameters;
|
|
1944
2031
|
if (!Array.isArray(parameters)) {
|
|
1945
2032
|
return;
|
|
1946
2033
|
}
|
|
1947
|
-
const next = expandParameterList(parameters,
|
|
2034
|
+
const next = expandParameterList(parameters, {
|
|
2035
|
+
inputSchemas,
|
|
2036
|
+
outputSchemas,
|
|
2037
|
+
queryParamStyle,
|
|
2038
|
+
componentIds
|
|
2039
|
+
});
|
|
1948
2040
|
if (next !== parameters) {
|
|
1949
2041
|
op.parameters = next;
|
|
1950
2042
|
expandedAny = true;
|
|
@@ -1954,7 +2046,7 @@ var expandParamMarkers = /* @__PURE__ */ __name((params) => {
|
|
|
1954
2046
|
pruneOrphanObjectSchema(doc);
|
|
1955
2047
|
}
|
|
1956
2048
|
}, "expandParamMarkers");
|
|
1957
|
-
var expandParameterList = /* @__PURE__ */ __name((parameters,
|
|
2049
|
+
var expandParameterList = /* @__PURE__ */ __name((parameters, context) => {
|
|
1958
2050
|
let result;
|
|
1959
2051
|
for (let i = 0; i < parameters.length; i++) {
|
|
1960
2052
|
const param = parameters[i];
|
|
@@ -1966,12 +2058,34 @@ var expandParameterList = /* @__PURE__ */ __name((parameters, inputSchemas, outp
|
|
|
1966
2058
|
if (result === void 0) {
|
|
1967
2059
|
result = parameters.slice(0, i);
|
|
1968
2060
|
}
|
|
1969
|
-
const map = marker.io === "output" ? outputSchemas : inputSchemas;
|
|
2061
|
+
const map = marker.io === "output" ? context.outputSchemas : context.inputSchemas;
|
|
1970
2062
|
const body = map.get(marker.dtoId);
|
|
1971
|
-
result.push(...
|
|
2063
|
+
result.push(...resolveMarker(marker, body, context));
|
|
1972
2064
|
}
|
|
1973
2065
|
return result ?? parameters;
|
|
1974
2066
|
}, "expandParameterList");
|
|
2067
|
+
var resolveMarker = /* @__PURE__ */ __name((marker, body, context) => {
|
|
2068
|
+
const useRef = marker.ref ?? context.queryParamStyle === "ref";
|
|
2069
|
+
if (marker.in === "query" && useRef && context.componentIds.has(marker.dtoId)) {
|
|
2070
|
+
return [
|
|
2071
|
+
buildRefQueryParam(marker, body)
|
|
2072
|
+
];
|
|
2073
|
+
}
|
|
2074
|
+
return expandOne(marker, body);
|
|
2075
|
+
}, "resolveMarker");
|
|
2076
|
+
var buildRefQueryParam = /* @__PURE__ */ __name((marker, body) => {
|
|
2077
|
+
const required = isPlainRecord3(body) && Array.isArray(body.required) && body.required.length > 0;
|
|
2078
|
+
return {
|
|
2079
|
+
name: marker.dtoId,
|
|
2080
|
+
in: "query",
|
|
2081
|
+
required,
|
|
2082
|
+
style: "form",
|
|
2083
|
+
explode: true,
|
|
2084
|
+
schema: {
|
|
2085
|
+
$ref: `${COMPONENTS_SCHEMAS_PREFIX}${marker.dtoId}`
|
|
2086
|
+
}
|
|
2087
|
+
};
|
|
2088
|
+
}, "buildRefQueryParam");
|
|
1975
2089
|
var readMarker2 = /* @__PURE__ */ __name((value) => {
|
|
1976
2090
|
if (!isPlainRecord3(value)) {
|
|
1977
2091
|
return void 0;
|
|
@@ -1988,6 +2102,9 @@ var readMarker2 = /* @__PURE__ */ __name((value) => {
|
|
|
1988
2102
|
if (typeof value.in !== "string" || value.in === "") {
|
|
1989
2103
|
return void 0;
|
|
1990
2104
|
}
|
|
2105
|
+
if (value.ref !== void 0 && typeof value.ref !== "boolean") {
|
|
2106
|
+
return void 0;
|
|
2107
|
+
}
|
|
1991
2108
|
return value;
|
|
1992
2109
|
}, "readMarker");
|
|
1993
2110
|
var expandOne = /* @__PURE__ */ __name((marker, body) => {
|
|
@@ -2326,7 +2443,8 @@ var applyZodNest = /* @__PURE__ */ __name((doc, opts) => {
|
|
|
2326
2443
|
expandParamMarkers({
|
|
2327
2444
|
doc,
|
|
2328
2445
|
inputSchemas,
|
|
2329
|
-
outputSchemas
|
|
2446
|
+
outputSchemas,
|
|
2447
|
+
queryParamStyle: opts.queryParamStyle
|
|
2330
2448
|
});
|
|
2331
2449
|
rewriteRefs2({
|
|
2332
2450
|
doc,
|
|
@@ -2372,6 +2490,7 @@ exports.extend = extend;
|
|
|
2372
2490
|
exports.getLineage = getLineage;
|
|
2373
2491
|
exports.isZodDto = isZodDto;
|
|
2374
2492
|
exports.isZodDtoMarker = isZodDtoMarker;
|
|
2493
|
+
exports.isZodSchema = isZodSchema;
|
|
2375
2494
|
exports.makeZodDtoMarker = makeZodDtoMarker;
|
|
2376
2495
|
exports.overrideJSONSchema = overrideJSONSchema;
|
|
2377
2496
|
exports.registerSchema = registerSchema;
|