{"id":17644420,"url":"https://github.com/benlorantfy/nestjs-zod","last_synced_at":"2026-01-05T00:17:07.879Z","repository":{"id":40738054,"uuid":"492078768","full_name":"BenLorantfy/nestjs-zod","owner":"BenLorantfy","description":"All NestJS + Zod utilities you need","archived":false,"fork":false,"pushed_at":"2025-05-04T23:39:19.000Z","size":533,"stargazers_count":718,"open_issues_count":17,"forks_count":72,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-12T03:17:09.896Z","etag":null,"topics":["javascript","nest","nestjs","node","nodejs","openapi","typescript","zod"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BenLorantfy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-05-14T00:58:26.000Z","updated_at":"2025-05-11T18:16:05.000Z","dependencies_parsed_at":"2024-01-14T04:44:17.695Z","dependency_job_id":"118c9deb-c53b-4f9f-85f4-782894846847","html_url":"https://github.com/BenLorantfy/nestjs-zod","commit_stats":{"total_commits":112,"total_committers":17,"mean_commits":6.588235294117647,"dds":0.3125,"last_synced_commit":"8e8d515f61353dcfb92aae030c155d3ea30faa1f"},"previous_names":["risen228/nestjs-zod","risenforces/nestjs-zod","benlorantfy/nestjs-zod"],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenLorantfy%2Fnestjs-zod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenLorantfy%2Fnestjs-zod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenLorantfy%2Fnestjs-zod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenLorantfy%2Fnestjs-zod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BenLorantfy","download_url":"https://codeload.github.com/BenLorantfy/nestjs-zod/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254053306,"owners_count":22006717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","nest","nestjs","node","nodejs","openapi","typescript","zod"],"created_at":"2024-10-23T10:05:22.666Z","updated_at":"2026-01-05T00:17:07.872Z","avatar_url":"https://github.com/BenLorantfy.png","language":"TypeScript","funding_links":["https://github.com/sponsors/BenLorantfy"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.svg\" width=\"500px\" align=\"center\" alt=\"NestJS + Zod logo\" style=\"max-width: 100%;\" /\u003e\n  \u003ch1 align=\"center\"\u003enestjs-zod\u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    ✨ A seamless validation solution for your NestJS application ✨\n      \u003cbr/\u003e\n      by \u003ca href=\"https://x.com/benlorantfy\"\u003e@benlorantfy\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/BenLorantfy/nestjs-zod/actions?query=branch%3Amain\"\u003e\n    \u003cimg src=\"https://github.com/BenLorantfy/nestjs-zod/actions/workflows/test-and-build.yml/badge.svg?event=push\u0026branch=main\" alt=\"nestjs-zod CI Status\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\" rel=\"nofollow\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/BenLorantfy/nestjs-zod\" alt=\"License\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/nestjs-zod\" rel=\"nofollow\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dw/nestjs-zod.svg\" alt=\"npm\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/nestjs-zod\" rel=\"nofollow\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/stars/BenLorantfy/nestjs-zod\" alt=\"stars\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://x.com/benlorantfy\"\u003e\n    \u003cimg alt=\"X (formerly Twitter) Follow\" src=\"https://img.shields.io/twitter/follow/benlorantfy\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Core Library Features\n\n\u003cp\u003e\n✨ Create nestjs DTOs from zod schemas\n\u003c/p\u003e\n\u003cp\u003e\n✨ Validate / parse request body, query params, and url params using zod\n\u003c/p\u003e\n\u003cp\u003e\n✨ Serialize response bodies using zod\n\u003c/p\u003e\n\u003cp\u003e\n✨ Automatically generate OpenAPI documentation using zod\n\u003c/p\u003e\n\u003cp\u003e\n✨ Supports zod codecs\n\u003c/p\u003e\n\n\n\u003ch3 align=\"center\"\u003eSponsored by: \u003ca href=\"https://apisandbox.dev/\"\u003eapisandbox.dev\u003c/a\u003e\u003c/h3\u003e\n\n\u003ca href=\"https://apisandbox.dev/\"\u003e\n  \u003cimg alt=\"apisandbox.dev.  It's google docs for api design.  real-time collaboration.  shareable design links.  and more!.  Try It!\" src=\"./img/sponsor-p1.png\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/sponsors/BenLorantfy\"\u003e\n  \u003cimg alt=\"Psst! Sponsor nestjs-zod on GitHub Sponsors and get a free apisandbox.dev subscription!\" src=\"./img/sponsor-p2.png\" /\u003e\n\u003c/a\u003e\n\n\n## Getting Started\n\n### Automatic Setup\n`nestjs-zod` can be automatically setup by running the following command:\n```bash\nnpx nestjs-zod-cli /path/to/nestjs/project\n```\nThis command runs a codemod that adds the validation pipe, serialization interceptor, http exception filter, and swagger cleanup function\n\nAlternatively, you can follow the manual setup steps below\n\n### Manual Setup\n\n1. Install the package:\n    ```bash\n    npm install nestjs-zod # Note: zod ^3.25.0 || ^4.0.0 is also required\n    ```\n2. Add `ZodValidationPipe` to the `AppModule`\n    \u003cdetails\u003e\n      \u003csummary\u003e\n        Show me how\n      \u003c/summary\u003e\n\n    `ZodValidationPipe` is required in order to validate the request body, query, and params\n\n    ```diff\n    + import { APP_PIPE } from '@nestjs/core';\n    + import { ZodValidationPipe } from 'nestjs-zod';\n\n    @Module({\n      imports: [],\n      controllers: [AppController],\n      providers: [\n    +    {\n    +      provide: APP_PIPE,\n    +      useClass: ZodValidationPipe,\n    +    },\n      ]\n    })\n    export class AppModule {}\n    ```\n    \u003c/details\u003e\n\n3. Add `ZodSerializerInterceptor` to the `AppModule`\n    \u003cdetails\u003e\n      \u003csummary\u003e\n        Show me how\n      \u003c/summary\u003e\n\n    `ZodSerializerInterceptor` is required in order to validate the response bodies\n\n    ```diff\n    - import { APP_PIPE } from '@nestjs/core';\n    + import { APP_PIPE, APP_INTERCEPTOR } from '@nestjs/core';\n    - import { ZodValidationPipe } from 'nestjs-zod';\n    + import { ZodValidationPipe, ZodSerializerInterceptor } from 'nestjs-zod';\n\n    @Module({\n      imports: [],\n      controllers: [AppController],\n      providers: [\n        {\n          provide: APP_PIPE,\n          useClass: ZodValidationPipe,\n        },\n    +    {\n    +      provide: APP_INTERCEPTOR,\n    +      useClass: ZodSerializerInterceptor,\n    +    },\n      ]\n    })\n    export class AppModule {}\n    ```\n    \u003c/details\u003e\n\n4. [OPTIONAL] Add an `HttpExceptionFilter` \n    \u003cdetails\u003e\n      \u003csummary\u003e\n        Show me how\n      \u003c/summary\u003e\n\n    An `HttpExceptionFilter` is required in order to add custom handling for zod errors\n\n    ```diff\n    - import { APP_PIPE, APP_INTERCEPTOR } from '@nestjs/core';\n    + import { APP_PIPE, APP_INTERCEPTOR, APP_FILTER } from '@nestjs/core';\n    import { ZodValidationPipe, ZodSerializerInterceptor } from 'nestjs-zod';\n    + import { HttpExceptionFilter } from './http-exception.filter';\n\n    @Module({\n      imports: [],\n      controllers: [AppController],\n      providers: [\n        {\n          provide: APP_PIPE,\n          useClass: ZodValidationPipe,\n        },\n        {\n          provide: APP_INTERCEPTOR,\n          useClass: ZodSerializerInterceptor,\n        },\n        {\n          provide: APP_FILTER,\n          useClass: HttpExceptionFilter,\n        }\n      ]\n    })\n    export class AppModule {}\n\n    + // http-exception.filter\n    + @Catch(HttpException)\n    + export class HttpExceptionFilter extends BaseExceptionFilter {\n    +     private readonly logger = new Logger(HttpExceptionFilter.name);\n    + \n    +     catch(exception: HttpException, host: ArgumentsHost) {\n    +         if (exception instanceof ZodSerializationException) {\n    +             const zodError = exception.getZodError();\n    +             if (zodError instanceof ZodError) {\n    +                 this.logger.error(`ZodSerializationException: ${zodError.message}`);\n    +             }\n    +         }\n    + \n    +         super.catch(exception, host);\n    +     }\n    + }\n    ```\n    \u003c/details\u003e\n\n\n5. [OPTIONAL] Add `cleanupOpenApiDoc`\n\n    \u003e **Important**: This step is important if using `@nestjs/swagger`\n\n    \u003cdetails\u003e\n      \u003csummary\u003e\n        Show me how\n      \u003c/summary\u003e\n\n    `cleanupOpenApiDoc` is required if using `@nestjs/swagger` to properly post-process the OpenAPI doc\n\n    ```diff\n    - SwaggerModule.setup('api', app, openApiDoc);\n    + SwaggerModule.setup('api', app, cleanupOpenApiDoc(openApiDoc));\n    ```\n\n    \u003c/details\u003e\n\nCheck out the [example app](./packages/example/) for a full example of how to integrate `nestjs-zod` in your nestjs application\n\n## Documentation\n\n- [Request Validation](#request-validation)\n  - [`createZodDto` (Create a DTO from a Zod schema)](#createzoddto-create-a-dto-from-a-zod-schema)\n  - [`ZodValidationPipe` (Get nestjs to validate using zod)](#zodvalidationpipe-get-nestjs-to-validate-using-zod)\n  - [`createZodValidationPipe` (Creating custom validation pipe)](#createzodvalidationpipe-creating-custom-validation-pipe)\n  - [`ZodValidationException`](#zodvalidationexception)\n  - [`ZodSchemaDeclarationException`](#zodschemaDeclarationexception)\n- [Response Validation](#response-validation)  \n  - [`ZodSerializerDto` (Set zod DTO to serialize responses with)](#zodserializerdto-set-zod-dto-to-serialize-responses-with)\n  - [`ZodSerializerInterceptor` (Get nestjs to serialize responses with zod)](#zodserializerinterceptor-get-nestjs-to-serialize-responses-with-zod)\n  - [`createZodSerializerInterceptor` (Creating custom serializer interceptor)](#createzodserializerinterceptor-creating-custom-serializer-interceptor)\n  - [`ZodResponse` (Sync run-time, compile-time, and docs-time schemas)](#zodresponse-sync-run-time-compile-time-and-docs-time-schemas)\n  - [`ZodSerializationException`](#zodserializationexception)\n- [OpenAPI (Swagger) support](#openapi-swagger-support)\n  - [`cleanupOpenApiDoc` (Ensure proper OpenAPI output)](#cleanupopenapidoc-ensure-proper-openapi-output)\n  - [Output schemas](#output-schemas)\n  - [Codecs](#codecs)\n  - [Reusable schemas](#reusable-schemas)\n  - [`zodV3ToOpenAPI` (⚠️ DEPRECATED)](#zodv3toopenapi-deprecated)\n- [`validate` (⚠️ DEPRECATED)](#validate-deprecated)\n- [`ZodGuard` (⚠️ DEPRECATED)](#zodguard-deprecated)\n  - [`createZodGuard` (Creating custom guard)](#createzodguard-creating-custom-guard)\n- [`@nest-zod/z` (⚠️ DEPRECATED)](#nest-zodz-deprecated)\n  - [ZodDateString](#zoddatestring)\n  - [ZodPassword](#zodpassword)\n\n### Request Validation\n#### `createZodDto` (Create a DTO from a Zod schema)\n```ts\nfunction createZodDto\u003cTSchema extends UnknownSchema, TCodec extends boolean = false\u003e(schema: TSchema, options?: { codec: TCodec }): ZodDto\u003cTSchema, TCodec\u003e;\n```\nCreates a nestjs DTO from a zod schema.  These zod DTOs can be used in place of `class-validator` / `class-transformer` DTOs. Zod DTOs are responsible for three things:\n\n1. Providing a schema for `ZodValidationPipe` to validate incoming client data against\n2. Providing a compile-time typescript type from the Zod schema\n3. Providing an OpenAPI schema when using `nestjs/swagger`\n\n\u003e [!NOTE]\n\u003e For this feature to work, please ensure [`ZodValidationPipe`](#zodvalidationpipe-get-nestjs-to-validate-using-zod) is setup correctly\n\n##### Parameters\n- `schema` - A zod schema.  You can \"bring your own zod\", including zod v3 schemas, v4 schemas, zod mini schemas, etc.  The only requirement is that the schema has a method called `parse`\n- `options`\n  - `options.codec` - If set to `true`, then when serializing responses `nestjs-zod` will use `encode` instead of `parse`.  See more information about codecs in the [zod documentation](https://zod.dev/codecs)\n\n##### Examples\n###### Creating a zod DTO\n```ts\nimport { createZodDto } from 'nestjs-zod'\nimport { z } from 'zod'\n\nconst CredentialsSchema = z.object({\n  username: z.string(),\n  password: z.string(),\n})\n\n// class is required for using DTO as a type\nclass CredentialsDto extends createZodDto(CredentialsSchema) {}\n```\n###### Using a zod DTO\n```ts\n@Controller('auth')\nclass AuthController {\n  async signIn(@Body() credentials: CredentialsDto) {}\n}\n```\n\n#### `ZodValidationPipe` (Get nestjs to validate using zod)\n\n`ZodValidationPipe` is needed to ensure zod DTOs actually validate incoming request data when using `@Body()`, `@Params()`, or `@Query()` parameter decorators\n\nWhen the data is invalid it throws a [ZodValidationException](#zodvalidationexception).\n\n##### Example\n###### Globally (recommended)\n\n```ts\nimport { ZodValidationPipe } from 'nestjs-zod'\nimport { APP_PIPE } from '@nestjs/core'\n\n@Module({\n  providers: [\n    {\n      provide: APP_PIPE,\n      useClass: ZodValidationPipe,\n    },\n  ],\n})\nexport class AppModule {}\n```\n\n###### Locally\n```ts\nimport { ZodValidationPipe } from 'nestjs-zod'\n\n// controller-level\n@UsePipes(ZodValidationPipe)\nclass AuthController {}\n\nclass AuthController {\n  // route-level\n  @UsePipes(ZodValidationPipe)\n  async signIn() {}\n}\n```\n#### `createZodValidationPipe` (Creating custom validation pipe)\n```ts\nexport function createZodValidationPipe({ createValidationException, strictSchemaDeclaration }: ZodValidationPipeOptions = {}): ZodValidationPipeClass\n```\n\nCreates a custom zod validation pipe\n\n##### Example\n```ts\nimport { createZodValidationPipe } from 'nestjs-zod'\n\nconst MyZodValidationPipe = createZodValidationPipe({\n  // provide custom validation exception factory\n  createValidationException: (error: ZodError) =\u003e\n    new BadRequestException('Ooops'),\n})\n```\n\n##### Parameters\n- `params.createValidationException` - A callback that will be called with the zod error when a parsing error occurs.  Should return a new instance of `Error`\n- `params.strictSchemaDeclaration` - If `true`, throws a [`ZodSchemaDeclarationException`](#zodschemaDeclarationexception) when the pipe encounters a parameter that is not typed with a nestjs-zod DTO. It's recommended to set this to `true` to ensure all request data is properly validated\n\n#### `ZodValidationException`\n\nIf the zod request parsing fails, then `nestjs-zod` will throw a `ZodValidationException`, which will result in the following HTTP response:\n\n```json\n{\n  \"statusCode\": 400,\n  \"message\": \"Validation failed\",\n  \"errors\": [\n    {\n      \"code\": \"too_small\",\n      \"minimum\": 8,\n      \"type\": \"string\",\n      \"inclusive\": true,\n      \"message\": \"String must contain at least 8 character(s)\",\n      \"path\": [\"password\"]\n    }\n  ]\n}\n```\n\nYou can customize the exception and HTTP response by either `1)` creating a custom validation pipe using [`createZodValidationPipe`](#createzodvalidationpipe-creating-custom-validation-pipe) or `2)` handling `ZodValidationException` inside an [exception filter](https://docs.nestjs.com/exception-filters)\n\nHere is an example exception filter:\n\n```ts\n@Catch(ZodValidationException)\nexport class ZodValidationExceptionFilter implements ExceptionFilter {\n  catch(exception: ZodValidationException) {\n    exception.getZodError() // -\u003e ZodError\n  }\n}\n```\n\n#### `ZodSchemaDeclarationException`\n\nIf `strictSchemaDeclaration` is set to `true` in [`createZodValidationPipe`](#createzodvalidationpipe-creating-custom-validation-pipe) and a request parameter is not typed with a nestjs-zod DTO (e.g. using a primitive type like `string` or a class-validator DTO), then `nestjs-zod` will throw a `ZodSchemaDeclarationException`, which will result in the following HTTP response:\n\n```json\n{\n  \"statusCode\": 500,\n  \"message\": \"Internal Server Error\"\n}\n```\n\nThis is useful for catching cases during development where request data might not be properly validated. You can handle this exception in an [exception filter](https://docs.nestjs.com/exception-filters) if you want to customize the response:\n\n```ts\n@Catch(ZodSchemaDeclarationException)\nexport class ZodSchemaDeclarationExceptionFilter implements ExceptionFilter {\n  catch(exception: ZodSchemaDeclarationException, host: ArgumentsHost) {\n    const ctx = host.switchToHttp();\n    const response = ctx.getResponse();\n    response.status(500).json({\n      statusCode: 500,\n      message: 'Missing nestjs-zod schema declaration',\n    });\n  }\n}\n```\n\n### Response Validation\n\n#### `ZodSerializerDto` (Set zod DTO to serialize responses with)\n```ts\nfunction ZodSerializerDto(dto: ZodDto | UnknownSchema | [ZodDto] | [UnknownSchema])\n```\nParses / serializes the return value of a controller method using the provided zod schema.  This is especially useful to prevent accidental data leaks.\n\n\u003e [!NOTE]\n\u003e Instead of `ZodSerializerDto`, consider using [`ZodResponse`](#zodresponse-sync-run-time-compile-time-and-docs-time-schemas), which has some improvements over `ZodSerializerDto`\n\n\u003e [!NOTE]\n\u003e For this feature to work, please ensure [`ZodSerializerInterceptor`](#zodserializerinterceptor-get-nestjs-to-serialize-responses-with-zod) is setup correctly\n\n##### Parameters\n- `options.dto` - A ZodDto (or zod schema) to serialize the response with.  If passed with array syntax (`[MyDto]`) then it will parse as an array.  Note that the array syntax does not work with [`zod/mini`](https://zod.dev/packages/mini), because it requires the schema have an `.array()` method\n\n##### Example\n\n```ts\nconst UserSchema = z.object({ username: string() })\n\nclass UserDto extends createZodDto(UserSchema) {}\n\n@Controller('user')\nexport class UserController {\n  constructor(private readonly userService: UserService) {}\n\n  @ZodSerializerDto(UserDto)\n  getUser(id: number) {\n    return this.userService.findOne(id)\n  }\n}\n```\n\nIn the above example, if the `userService.findOne` method returns `password`, the `password` property will be stripped out thanks to the `@ZodSerializerDto` decorator.\n\nAlso note that arrays can be serialized using `[]` syntax like this:\n```ts\nclass BookDto extends createZodDto(z.object({ title: string() })) {}\n\n@Controller('books')\nexport class BooksController {\n  constructor() {}\n\n  @ZodSerializerDto([BookDto])\n  getBooks() {\n    return [{ title: 'The Martian' }, { title: 'Hail Marry' }];\n  }\n}\n```\n\nOr by using an array DTO:\n```ts\nclass BookListDto extends createZodDto(z.array(z.object({ title: string() }))) {}\n\n@Controller('books')\nexport class BooksController {\n  constructor() {}\n\n  @ZodSerializerDto(BookListDto)\n  getBooks() {\n    return [{ title: 'The Martian' }, { title: 'Hail Marry' }];\n  }\n}\n```\n\n\n#### `ZodSerializerInterceptor` (Get nestjs to serialize responses with zod)\n\nTo ensure `ZodSerializerDto` works correctly, `ZodSerializerInterceptor` needs to be added to the `AppModule`\n\n\u003e [!NOTE]\n\u003e Also see [`ZodSerializationException`](#zodserializationexception) for information about customizing the serialization error handling\n\n##### Example\n\nThis should be done in the `AppModule` like so:\n```ts\n@Module({\n  ...\n  providers: [\n    ...,\n    { provide: APP_INTERCEPTOR, useClass: ZodSerializerInterceptor },\n  ],\n})\nexport class AppModule {}\n```\n\n#### `createZodSerializerInterceptor` (Creating custom serializer interceptor)\n```ts\nexport function createZodSerializerInterceptor({ reportInput }: ZodSerializerInterceptorOptions = {}): ZodSerializerInterceptorClass\n```\n\nCreates a custom zod serializer interceptor\n\n##### Parameters\n- `params.reportInput` - When set to `true`, includes the input value in Zod error issues. This is useful for debugging serialization errors. Only supported in Zod v4.\n\n##### Example\n```ts\nimport { createZodSerializerInterceptor } from 'nestjs-zod'\nimport { APP_INTERCEPTOR } from '@nestjs/core'\n\nconst CustomZodSerializerInterceptor = createZodSerializerInterceptor({\n  reportInput: true,\n})\n\n@Module({\n  providers: [\n    {\n      provide: APP_INTERCEPTOR,\n      useClass: CustomZodSerializerInterceptor,\n    },\n  ],\n})\nexport class AppModule {}\n```\n\n#### `ZodResponse` (Sync run-time, compile-time, and docs-time schemas)\n\n```ts\nfunction ZodResponse\u003cTSchema extends UnknownSchema\u003e({ status, description, type }: { status?: number, description?: string, type: ZodDto\u003cTSchema\u003e \u0026 { io: \"input\" } }): (target: object, propertyKey?: string | symbol, descriptor?: Pick\u003cTypedPropertyDescriptor\u003c(...args: any[]) =\u003e input\u003cTSchema\u003e|Promise\u003cinput\u003cTSchema\u003e\u003e\u003e, 'value'\u003e) =\u003e void\nfunction ZodResponse\u003cTSchema extends RequiredBy\u003cUnknownSchema, 'array'\u003e\u003e({ status, description, type }: { status?: number, description?: string, type: [ZodDto\u003cTSchema\u003e \u0026 { io: \"input\" }] }): (target: object, propertyKey?: string | symbol, descriptor?: Pick\u003cTypedPropertyDescriptor\u003c(...args: any[]) =\u003e Array\u003cinput\u003cTSchema\u003e\u003e|Promise\u003cArray\u003cinput\u003cTSchema\u003e\u003e\u003e\u003e, 'value'\u003e) =\u003e void\n```\n\nConsolidation of multiple decorators that allows setting the run-time, compile-time, and docs-time schema all at once\n\n\u003e [!NOTE]\n\u003e For this feature to work, please ensure [`ZodSerializerInterceptor`](#zodserializerinterceptor-get-nestjs-to-serialize-responses-with-zod) and [`cleanupOpenApiDoc`](#cleanupopenapidoc-ensure-proper-openapi-output) are setup correctly\n\n##### Parameters\n- `params.status` - Optionally sets the \"happy-path\" `status` of the response.  If provided, sets the status code using `@HttpCode` from `nestjs/common` and using `@ApiResponse` from `nestjs/swagger`\n- `params.description` - Optionally sets a description of the response using `@ApiResponse`\n- `params.type` - Sets the run-time (via `@ZodSerializerDto`), compile-time (via TypeScript), and docs-time (via `@ApiResponse`) response type.  \n\n##### Example\nYou may find yourself duplicating type information:\n\n```tsx\n@ZodSerializer(BookDto)\n@ApiOkResponse({\n  status: 200,\n  type: BookDto\n})\ngetBook(): BookDto {\n  ...\n}\n```\nHere, `BookDto` is repeated 3 times:\n1. To set the DTO to use to serialize \n2. To set the DTO to use for the OpenAPI documentation\n3. To set the return type for the function\n\nIf these 3 spots get out of sync, this may cause bugs.  If you want to remove this duplication, you can consolidate using `ZodResponse`:\n```diff\n- @ZodSerializer(BookDto)\n- @ApiOkResponse({\n-  status: 200,\n-  type: BookDto.Output\n- })\n- getBook(): BookDto {\n+ @ZodResponse({ type: BookDto })\n+ getBook()\n  ...\n}\n```\n\n`@ZodResponse` will set all these things.  It will set the DTO to use to serialize, it will set the DTO to use for the OpenAPI documentation, and it will throw a compile-time typescript error if the method does not return data that matches the zod input schema \n\nThis is pretty powerful, because it ensures the run-time, compile-time, and docs-time representations of your response are all in sync.  For this reason, it's recommended to use `@ZodResponse` instead of repeating the DTO three times.\n\n\n#### `ZodSerializationException`\n\nIf the zod response serialization fails, then `nestjs-zod` will throw a `ZodSerializationException`, which will result in the following HTTP response:\n\n```json\n{\n  \"message\": \"Internal Server Error\",\n  \"statusCode\": 500,\n}\n```\n\nYou can customize the exception and HTTP response handling `ZodSerializationException` inside an [exception filter](https://docs.nestjs.com/exception-filters)\n\nSee the example app [here](/packages/example/src/http-exception.filter.ts) for more information.\n\n### OpenAPI (Swagger) support\n\n\u003e [!NOTE]\n\u003e For additional documentation, follow [Nest.js' Swagger Module Guide](https://docs.nestjs.com/openapi/introduction), or you can see the example application [here](/packages/example/)\n\nIf you have `@nestjs/swagger` setup, documentation will automatically be generated for:\n- Request bodies, if you use `@Body() body: MyDto`\n- Response bodies, if you use `@ApiOkResponse({ type: MyDto.Output })` (or [`@ZodResponse({ type: MyDto })`](#zodresponse-sync-run-time-compile-time-and-docs-time-schemas))\n- Query params, if you use `@Query() query: MyQueryParamsDto`\n\nTo generate the OpenAPI document, `nestjs-zod` uses [`z.toJSONSchema`](https://zod.dev/json-schema) for zod v4 schemas.  It's recommended to review the zod documentation itself for more information about how the OpenAPI document is generated\n\nFor zod v3 schemas, `nestjs-zod` uses a custom-built (deprecated) function called `zodV3ToOpenAPI` that generates the OpenAPI document by inspecting the zod schema directly.\n\nHowever, please ensure `cleanupOpenApiDoc` is setup correctly as detailed below\n\n#### `cleanupOpenApiDoc` (Ensure proper OpenAPI output)\n```ts\nfunction cleanupOpenApiDoc(doc: OpenAPIObject, options?: { version?: '3.1' | '3.0' | 'auto' }): OpenAPIObject\n```\nCleans up the generated OpenAPI doc by applying some post-processing\n\n\u003e [!NOTE]\n\u003e There used to be a function called `patchNestJsSwagger`.  This function has been replaced by `cleanupOpenApiDoc`\n\n##### Parameters\n- `doc` - The OpenAPI doc generated by `SwaggerModule.createDocument`\n- `options.version` - The OpenAPI version to use while cleaning up the document. \n  - `auto` (default) - Uses the version specified in the OpenAPI document (The version in the OpenAPI can be changed by using the `setOpenAPIVersion` method on the swagger document builder).\n  - `3.1` - Generates schemas that take advantage of OpenAPI 3.1 syntax.  See table below for more information\n  - `3.0` - Generates schemas that are compatible with OpenAPI 3.0.  See table below for more information\n\n|         | 3.0                                   | 3.1                                                |\n|---------|---------------------------------------|----------------------------------------------------|\n| null    | `{ type: 'string', nullable: true }`  | `{ anyOf: [{ type: 'string'}, { type: 'null' }] }` |\n| literal | `{ type: 'string', enum: ['hello'] }` | `{ type: 'string', const: 'hello' }`               |\n\n##### Example\nTo complete the swagger integration/setup, `cleanupOpenApiDoc` needs to be called with the generated open api doc, like so:\n\n```diff\n  const openApiDoc = SwaggerModule.createDocument(app, \n      new DocumentBuilder()\n        .setTitle('Example API')\n        .setDescription('Example API description')\n        .setVersion('1.0')\n        .build(),\n  );\n- SwaggerModule.setup('api', app, openApiDoc);\n+ SwaggerModule.setup('api', app, cleanupOpenApiDoc(openApiDoc));\n```\n\n#### Output schemas\n\nNote that `z.toJSONSchema` can generate two versions of any zod schema: \"input\" or \"output\".  This is what the [zod documentation](https://zod.dev/json-schema#io) says about this:\n\n\u003e Some schema types have different input and output types, e.g. ZodPipe, ZodDefault, and coerced primitives.\n\nNote that by default, when generating OpenAPI documentation, `nestjs-zod` uses the \"input\" version of a schema, except for [`@ZodResponse`](#zodresponse-sync-run-time-compile-time-and-docs-time-schemas) which always generates the \"output\" version of a schema.  If you want to explicitly use the \"output\" version of a schema when generating OpenAPI documentation, you can use the `.Output` property of a zod DTO.  For example, this makes sense when using `@ApiResponse`:\n\n```ts\n@ApiResponse({\n  type: MyDto.Output\n})\n```\n\nHowever, it's recommended to use [`@ZodResponse`](#zodresponse-sync-run-time-compile-time-and-docs-time-schemas) over `@ApiResponse`, which automatically handles this for you:\n\n```ts\n@ZodResponse({\n  type: MyDto // \u003c-- No need to do `.Output` here\n})\n```\n#### Codecs\nZod 4.1 introduced a new feature called \"codecs\".  There is more information about codecs in the [zod documentation](https://zod.dev/codecs)\n\n`nestjs-zod` supports `codecs`.  If the `codec: true` option is used when creating the zod DTO, then `parse` will be used for request bodies, and `encode` will be used when serializing response bodies.\n\n`codecs` can enable, in some cases, using _one_ zod schema, instead of two, for both the request and response\n\n```ts\nconst stringToDate = z.codec(\n  z.iso.datetime(),\n  z.date(),\n  {\n    decode: (isoString) =\u003e new Date(isoString),\n    encode: (date) =\u003e date.toISOString(),\n  }\n);\n\nclass BookDto extends createZodDto(z.object({\n  title: z.string(),\n  dateWritten: stringToDate\n}), {\n  codec: true\n}) { }\n\n@Controller('books')\nclass BookController {\n  constructor() { }\n  \n  @Post()\n  @ZodResponse({ \n    type: BookDto\n  })\n  createBook(@Body() book: BookDto) {\n    return book;\n  }\n}\n```\nSee the example app [here](/packages/example/src/people/people.dto.ts) for a full example.\n\n#### Reusable schemas\nYou can also externalize and reuse schemas across multiple DTOs.  If you add `.meta({ id: \"MySchema\" })` to any zod schema, then that schema will be added directly to `components.schemas` in the OpenAPI documentation.  For example, this code:\n```ts\nconst Author = z.object({ name: z.string() }).meta({ id: \"Author\" })\n\nclass BookDto extends createZodDto(z.object({ title: z.string(), author: Author })) { }\nclass BlogPostDto extends createZodDto(z.object({ title: z.string(), author: Author })) { }\n```\nWill result in this OpenAPI document:\n```jsonc\n{\n  \"components\": {\n    \"schemas\": {\n      \"Author\": {\n        // ...\n      },\n      \"BookDto\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"author\": {\n            \"$ref\": \"#/components/schemas/Author\"\n          },\n          \"required\": [\"author\"]\n        }\n      },\n      \"BlogPostDto\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"author\": {\n            \"$ref\": \"#/components/schemas/Author\"\n          },\n          \"required\": [\"author\"]\n        }\n      }\n    }\n  },\n  // ...\n}\n```\n\n##### Schema names\nNote that schemas are named / displayed in SwaggerUI according to the following logic:\n1. For input schemas, (e.g. schemas used in request bodies), SwaggerUI will display the `id` property in `.meta({ id: 'MySchema' })`\n2. For output schemas, (e.g. schemas used in `@ZodResponse()`), `nestjs-zod` suffixes the `id` set by `.meta({ id: 'MySchema' })` with `_Output`, so SwaggerUI displays, for example, `MySchema_Output`.  This is important to avoid collision with input schemas.\n3. However, if `title` is set by `.meta({ title: ... })`, then SwaggerUI will display `title`.  Note that unlike `id`s, there is no duplicate checking for titles, so it's the consumer's responsibility to avoid confusion when using `title`.\n\n#### `zodV3ToOpenAPI` _**(DEPRECATED)**_\n\n\u003e [!CAUTION]\n\u003e `zodV3ToOpenAPI` is deprecated and will not be supported soon, since zod v4 adds built-in support for generating OpenAPI schemas from zod schemas.  See [MIGRATION.md](./MIGRATION.md) for more information.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n    Show documentation for deprecated APIs\n  \u003c/summary\u003e\n\n  You can convert any Zod schema to an OpenAPI JSON object:\n\n  ```ts\n  import { zodToOpenAPI } from 'nestjs-zod'\n  import { z } from 'zod'\n\n  const SignUpSchema = z.object({\n    username: z.string().min(8).max(20),\n    password: z.string().min(8).max(20),\n    sex: z\n      .enum(['male', 'female', 'nonbinary'])\n      .describe('We respect your gender choice'),\n    social: z.record(z.string().url())\n  })\n\n  const openapi = zodV3ToOpenAPI(SignUpSchema)\n  ```\n\n  The output will be the following:\n\n  ```json\n  {\n    \"type\": \"object\",\n    \"properties\": {\n      \"username\": {\n        \"type\": \"string\",\n        \"minLength\": 8,\n        \"maxLength\": 20\n      },\n      \"password\": {\n        \"type\": \"string\",\n        \"minLength\": 8,\n        \"maxLength\": 20\n      },\n      \"sex\": {\n        \"description\": \"We respect your gender choice\",\n        \"type\": \"string\",\n        \"enum\": [\"male\", \"female\", \"nonbinary\"]\n      },\n      \"social\": {\n        \"type\": \"object\",\n        \"additionalProperties\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"birthDate\": {\n        \"type\": \"string\",\n        \"format\": \"date-time\"\n      }\n    },\n    \"required\": [\"username\", \"password\", \"sex\", \"social\", \"birthDate\"]\n  }\n  ```\n\u003c/details\u003e\n\n### `validate` _**(DEPRECATED)**_\n\n\u003e [!CAUTION]\n\u003e `validate` is deprecated and will not be supported soon.  It is recommended to use `.parse` directly. See [MIGRATION.md](./MIGRATION.md) for more information.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n    Show documentation for deprecated APIs\n  \u003c/summary\u003e\n\n  If you don't like `ZodGuard` and `ZodValidationPipe`, you can use `validate` function:\n\n  ```ts\n  import { validate } from 'nestjs-zod'\n\n  validate(wrongThing, UserDto, (zodError) =\u003e new MyException(zodError)) // throws MyException\n\n  const validatedUser = validate(\n    user,\n    UserDto,\n    (zodError) =\u003e new MyException(zodError)\n  ) // returns typed value when succeed\n  ```\n\n\u003c/details\u003e\n\n### `ZodGuard` _**(DEPRECATED)**_\n\n\u003e [!CAUTION]\n\u003e Guard-related functions are deprecated and will not be supported soon.  It is recommended to use guards for authorization, not validation. See [MIGRATION.md](./MIGRATION.md) for more information.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n    Show documentation for deprecated APIs\n  \u003c/summary\u003e\n\n  \u003e [!CAUTION]\n  \u003e `ZodGuard` is deprecated and will not be supported soon.  It is recommended to use guards for authorization, not validation. See [MIGRATION.md](./MIGRATION.md) for more information.\n\n  Sometimes, we need to validate user input before specific Guards. We can't use Validation Pipe since NestJS Pipes are always executed after Guards.\n\n  The solution is `ZodGuard`. It works just like `ZodValidationPipe`, except for that is doesn't transform the input.\n\n  It has 2 syntax forms:\n\n  - `@UseGuards(new ZodGuard('body', CredentialsSchema))`\n  - `@UseZodGuard('body', CredentialsSchema)`\n\n  Parameters:\n\n  1. The source - `'body' | 'query' | 'params'`\n  2. Zod Schema or DTO (just like `ZodValidationPipe`)\n\n  When the data is invalid - it throws [ZodValidationException](#validation-exceptions).\n\n  ```ts\n  import { ZodGuard } from 'nestjs-zod'\n\n  // controller-level\n  @UseZodGuard('body', CredentialsSchema)\n  @UseZodGuard('params', CredentialsDto)\n  class MyController {}\n\n  class MyController {\n    // route-level\n    @UseZodGuard('query', CredentialsSchema)\n    @UseZodGuard('body', CredentialsDto)\n    async signIn() {}\n  }\n  ```\n\n  #### `createZodGuard` (Creating custom guard)\n\n  \u003e [!CAUTION]\n  \u003e `createZodGuard` is deprecated and will not be supported soon.  It is recommended to use guards for authorization, not validation. See [MIGRATION.md](./MIGRATION.md) for more information.\n\n  ```ts\n  import { createZodGuard } from 'nestjs-zod'\n\n  const MyZodGuard = createZodGuard({\n    // provide custom validation exception factory\n    createValidationException: (error: ZodError) =\u003e\n      new BadRequestException('Ooops'),\n  })\n  ```\n\n\u003c/details\u003e\n\n### `@nest-zod/z` _**(DEPRECATED)**_\n\n\u003e [!CAUTION]\n\u003e `@nest-zod/z` is no longer supported and has no impact on the OpenAPI generation.  It is recommended to use `zod` directly.  See [MIGRATION.md](./MIGRATION.md) for more information.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n    Show documentation for deprecated package\n  \u003c/summary\u003e\n\n\n  `@nest-zod/z` provides a special version of Zod. It helps you to validate the user input more accurately by using our custom schemas and methods.\n\n  #### `ZodDateString`\n\n  \u003e [!CAUTION]\n  \u003e `@nest-zod/z` is no longer supported and has no impact on the OpenAPI generation.  It is recommended to use `zod` directly.  See [MIGRATION.md](./MIGRATION.md) for more information.\n\n  In HTTP, we always accept Dates as strings. But default Zod only has validations for full date-time strings. `ZodDateString` was created to address this issue.\n\n  ```ts\n  // 1. Expect user input to be a \"string\" type\n  // 2. Expect user input to be a valid date (by using new Date)\n  z.dateString()\n\n  // Cast to Date instance\n  // (use it on end of the chain, but before \"describe\")\n  z.dateString().cast()\n\n  // Expect string in \"full-date\" format from RFC3339\n  z.dateString().format('date')\n\n  // [default format]\n  // Expect string in \"date-time\" format from RFC3339\n  z.dateString().format('date-time')\n\n  // Expect date to be the past\n  z.dateString().past()\n\n  // Expect date to be the future\n  z.dateString().future()\n\n  // Expect year to be greater or equal to 2000\n  z.dateString().minYear(2000)\n\n  // Expect year to be less or equal to 2025\n  z.dateString().maxYear(2025)\n\n  // Expect day to be a week day\n  z.dateString().weekDay()\n\n  // Expect year to be a weekend\n  z.dateString().weekend()\n  ```\n\n  Valid `date` format examples:\n\n  - `2022-05-15`\n\n  Valid `date-time` format examples:\n\n  - `2022-05-02:08:33Z`\n  - `2022-05-02:08:33.000Z`\n  - `2022-05-02:08:33+00:00`\n  - `2022-05-02:08:33-00:00`\n  - `2022-05-02:08:33.000+00:00`\n\n  Errors:\n\n  - `invalid_date_string` - invalid date\n\n  - `invalid_date_string_format` - wrong format\n\n    Payload:\n\n    - `expected` - `'date' | 'date-time'`\n\n  - `invalid_date_string_direction` - not past/future\n\n    Payload:\n\n    - `expected` - `'past' | 'future'`\n\n  - `invalid_date_string_day` - not weekDay/weekend\n\n    Payload:\n\n    - `expected` - `'weekDay' | 'weekend'`\n\n  - `too_small` with `type === 'date_string_year'`\n  - `too_big` with `type === 'date_string_year'`\n\n  #### `ZodPassword`\n\n  \u003e [!CAUTION]\n  \u003e `@nest-zod/z` is no longer supported and has no impact on the OpenAPI generation.  It is recommended to use `zod` directly.  See [MIGRATION.md](./MIGRATION.md) for more information.\n\n  `ZodPassword` is a string-like type, just like the `ZodDateString`. As you might have guessed, it's intended to help you with password schemas definition.\n\n  Also, `ZodPassword` has a more accurate OpenAPI conversion, comparing to regular `.string()`: it has `password` format and generated RegExp string for `pattern`.\n\n  ```ts\n  // Expect user input to be a \"string\" type\n  z.password()\n\n  // Expect password length to be greater or equal to 8\n  z.password().min(8)\n\n  // Expect password length to be less or equal to 100\n  z.password().max(100)\n\n  // Expect password to have at least one digit\n  z.password().atLeastOne('digit')\n\n  // Expect password to have at least one lowercase letter\n  z.password().atLeastOne('lowercase')\n\n  // Expect password to have at least one uppercase letter\n  z.password().atLeastOne('uppercase')\n\n  // Expect password to have at least one special symbol\n  z.password().atLeastOne('special')\n  ```\n\n  Errors:\n\n  - `invalid_password_no_digit`\n  - `invalid_password_no_lowercase`\n  - `invalid_password_no_uppercase`\n  - `invalid_password_no_special`\n  - `too_small` with `type === 'password'`\n  - `too_big` with `type === 'password'`\n\n\u003c/details\u003e\n\n## Credits\n\nThis library was originally created by [risen228](https://github.com/risen228) and now maintained by [BenLorantfy](https://github.com/BenLorantfy/) (that's me!)\n\nI'm for hire!  Check out my resume [here](https://www.benlorantfy.com/resume).  You can email me at ben@lorantfy.com if you want to chat.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenlorantfy%2Fnestjs-zod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenlorantfy%2Fnestjs-zod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenlorantfy%2Fnestjs-zod/lists"}