@voznov/zod-dto-nestjs 0.1.2 → 0.2.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 CHANGED
@@ -23,7 +23,7 @@ import { Body, Controller, Post } from '@nestjs/common';
23
23
  import { ZodDto } from '@voznov/zod-dto';
24
24
  import { z } from 'zod';
25
25
 
26
- const CreateUserDto = ZodDto(z.object({ name: z.string(), email: z.email() }));
26
+ class CreateUserDto extends ZodDto(z.object({ name: z.string(), email: z.email() })) {}
27
27
 
28
28
  @Controller('users')
29
29
  export class UsersController {
@@ -44,6 +44,12 @@ Importing this package side-effect-registers an `onCreate` hook that decorates e
44
44
 
45
45
  Supported shapes: scalars, objects (nested), arrays, tuples, records, enums, literals, unions (including discriminated), intersections, optional/nullable/default wrappers, and nested DTO references (via `oneOf` + `ApiExtraModels`).
46
46
 
47
+ `.default(value)` is forwarded to the OpenAPI `default` keyword. For lazy defaults (`.default(() => ...)`), the thunk is invoked **once** at decoration time and the resolved value is frozen into the spec — use a stable thunk (don't put `Date.now()` / `randomUUID()` here unless you want the server-startup value baked into your docs).
48
+
49
+ `.describe(text)` is forwarded to the OpenAPI `description` keyword. Works on the wrapper or on the inner type — `z.string().describe('Login email').optional()` and `z.string().optional().describe('Login email')` both end up with `description: 'Login email'` in the spec.
50
+
51
+ `.refine(...)` validators run at request-validation time but are **not** reflected in the spec — JSON Schema can't express custom predicates, and a single `description` for a chain of refines (`.refine(...).refine(...).refine(...)`) would be ambiguous. Put human-readable docs in `.describe(...)` instead.
52
+
47
53
  ## Custom error response
48
54
 
49
55
  `ZodValidationPipe` accepts `{ createError }`. Default throws `BadRequestException` with the issues list as its response body.
package/dist/index.cjs CHANGED
@@ -56,7 +56,14 @@ var leaf = (so) => ({
56
56
  innerSchemas: /* @__PURE__ */ new Set()
57
57
  });
58
58
  var decoratedDtoClasses = /* @__PURE__ */ new Set();
59
+ var defaultValueCache = /* @__PURE__ */ new WeakMap();
59
60
  var applySwaggerDecorators = (schema) => {
61
+ const result = applyDecoratorsImpl(schema);
62
+ const description = schema.description;
63
+ if (description) result.so = { ...result.so, description };
64
+ return result;
65
+ };
66
+ var applyDecoratorsImpl = (schema) => {
60
67
  if (schema instanceof import_zod.z.ZodObject) {
61
68
  if ((0, import_zod_dto.isZodDtoClass)(schema) && decoratedDtoClasses.has(schema)) {
62
69
  return { so: { oneOf: (0, import_swagger.refs)(schema) }, selfRequired: true, innerSchemas: /* @__PURE__ */ new Set([schema]) };
@@ -90,7 +97,9 @@ var applySwaggerDecorators = (schema) => {
90
97
  return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };
91
98
  }
92
99
  if (schema instanceof import_zod.z.ZodDefault) {
93
- return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };
100
+ const inner = applySwaggerDecorators(schema.unwrap());
101
+ if (!defaultValueCache.has(schema)) defaultValueCache.set(schema, schema._zod.def.defaultValue);
102
+ return { ...inner, so: { ...inner.so, default: defaultValueCache.get(schema) }, selfRequired: false };
94
103
  }
95
104
  if (schema instanceof import_zod.z.ZodReadonly || schema instanceof import_zod.z.ZodLazy || schema instanceof import_zod.z.ZodCatch) {
96
105
  return applySwaggerDecorators(schema.unwrap());
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/swagger.ts","../src/utils.ts","../src/pipe.ts"],"sourcesContent":["import { registerOnCreate } from '@voznov/zod-dto';\nimport { applySwaggerDecorators } from './swagger';\n\n// Auto-register swagger decoration on every ZodDto() creation when this package is imported.\nregisterOnCreate(applySwaggerDecorators);\n\nexport { ZodValidationPipe } from './pipe';\nexport type { ZodValidationPipeOptions } from './pipe';\nexport { applySwaggerDecorators } from './swagger';\n","import { ApiExtraModels, ApiProperty, type ApiPropertyOptions, refs } from '@nestjs/swagger';\nimport { type SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';\nimport { isZodDtoClass, type ZodDtoClass } from '@voznov/zod-dto';\nimport { z } from 'zod';\nimport { mapValues } from './utils';\n\nconst schemaObjectToApiPropertyOptions = (so: SchemaObject, selfRequired: boolean): ApiPropertyOptions => {\n if ('oneOf' in so || 'anyOf' in so || 'allOf' in so) {\n return { ...so, type: Array, required: selfRequired };\n }\n\n return { ...so, required: selfRequired } as ApiPropertyOptions;\n};\n\nconst leaf = (so: SchemaObject): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => ({\n so,\n selfRequired: true,\n innerSchemas: new Set(),\n});\n\nconst decoratedDtoClasses = new Set<ZodDtoClass>();\n\nexport const applySwaggerDecorators = (schema: z.core.$ZodType): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => {\n // --- Objects ---\n\n if (schema instanceof z.ZodObject) {\n if (isZodDtoClass(schema) && decoratedDtoClasses.has(schema)) {\n return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: new Set([schema]) };\n }\n\n const properties: Record<string, SchemaObject> = {};\n const required: string[] = [];\n const innerSchemas = new Set<ZodDtoClass>();\n Object.entries(schema.shape).forEach(([key, fieldSchema]) => {\n const { so, selfRequired, innerSchemas: innerSchemas_ } = applySwaggerDecorators(fieldSchema as z.ZodType);\n properties[key] = so;\n innerSchemas_.forEach((innerSchema) => innerSchemas.add(innerSchema));\n if (selfRequired) {\n required.push(key);\n }\n });\n\n if (isZodDtoClass(schema)) {\n decoratedDtoClasses.add(schema);\n for (const [key, propertySo] of Object.entries(properties)) {\n ApiProperty(schemaObjectToApiPropertyOptions(propertySo, required.includes(key)))(schema.prototype, key);\n }\n ApiExtraModels(...[...innerSchemas.values()].filter((innerSchema) => innerSchema !== schema))(schema);\n\n return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: new Set([schema]) };\n }\n\n return { so: { type: 'object', properties: mapValues(properties, (so) => (so.oneOf?.length === 1 ? so.oneOf[0] : so)), required }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodRecord) {\n const { so } = applySwaggerDecorators(schema._zod.def.valueType as z.ZodType);\n\n return leaf({ type: 'object', additionalProperties: so.oneOf?.length === 1 ? so.oneOf[0] : so });\n }\n\n // --- Wrappers (unwrap to inner type) ---\n\n if (schema instanceof z.ZodOptional || schema instanceof z.ZodExactOptional) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };\n }\n\n if (schema instanceof z.ZodDefault) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };\n }\n\n if (schema instanceof z.ZodReadonly || schema instanceof z.ZodLazy || schema instanceof z.ZodCatch) {\n return applySwaggerDecorators(schema.unwrap());\n }\n\n if (schema instanceof z.ZodNonOptional) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: true };\n }\n\n if (schema instanceof z.ZodNullable) {\n const result = applySwaggerDecorators(schema.unwrap());\n\n return { ...result, so: { ...result.so, nullable: true } };\n }\n\n if (schema instanceof z.ZodPipe) {\n // z.preprocess() creates a Pipe(in: ZodTransform, out: schema).\n // For swagger, skip the transform and process the output schema directly.\n const inner = schema.in instanceof z.ZodTransform ? schema.out : schema.in;\n\n return applySwaggerDecorators(inner);\n }\n\n if (schema instanceof z.ZodTransform) {\n return leaf({});\n }\n\n // --- Arrays & tuples ---\n\n if (schema instanceof z.ZodArray) {\n const element = schema.unwrap();\n const { so, selfRequired: selfRequiredElement, innerSchemas } = applySwaggerDecorators(element);\n if (!selfRequiredElement) {\n throw new Error('Not required array item is not supported in Swagger. Use nullable instead.');\n }\n\n return { so: { type: 'array', items: so.oneOf?.length === 1 ? so.oneOf[0] : so }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodTuple) {\n const itemSchemas = schema._zod.def.items.map((item) => {\n const { so } = applySwaggerDecorators(item);\n\n return so.oneOf?.length === 1 ? so.oneOf[0] : so;\n });\n\n // Deduplicate by JSON representation to collapse identical types\n const unique = [...new Map(itemSchemas.map((s) => [JSON.stringify(s), s])).values()];\n const items = unique.length === 1 ? unique[0] : { oneOf: unique };\n\n return leaf({ type: 'array', items, minItems: itemSchemas.length, maxItems: itemSchemas.length });\n }\n\n // --- Scalars ---\n\n // ZodString: plain z.string(). ZodStringFormat: z.email(), z.uuid(), z.url(), z.ipv4(), etc.\n // Both share the same properties (minLength, maxLength, format).\n if (schema instanceof z.ZodString || schema instanceof z.ZodStringFormat) {\n const so: SchemaObject = { type: 'string' };\n if (schema.minLength !== null) so.minLength = schema.minLength;\n if (schema.maxLength !== null) so.maxLength = schema.maxLength;\n const fmt = schema.format;\n if (fmt !== null) {\n if (fmt === 'regex') {\n // Grab the first regex pattern from the internal bag.\n const patterns = schema._zod.bag.patterns;\n const first = patterns ? [...patterns][0] : undefined;\n if (first) so.pattern = first.source;\n } else {\n so.format = fmt;\n }\n }\n\n return { so, selfRequired: true, innerSchemas: new Set() };\n }\n\n // Number and integer subtypes (ZodInt, ZodNumberFormat, etc.) — all instanceof ZodNumber.\n if (schema instanceof z.ZodNumber) {\n const fmt = schema.format;\n const isInt = fmt === 'int32' || fmt === 'uint32' || fmt === 'safeint';\n const so: SchemaObject = { type: isInt ? 'integer' : 'number' };\n if (schema.minValue !== null && schema.minValue !== Number.MIN_SAFE_INTEGER && Number.isFinite(schema.minValue)) so.minimum = schema.minValue;\n if (schema.maxValue !== null && schema.maxValue !== Number.MAX_SAFE_INTEGER && Number.isFinite(schema.maxValue)) so.maximum = schema.maxValue;\n\n return { so, selfRequired: true, innerSchemas: new Set() };\n }\n\n if (schema instanceof z.ZodBigInt) {\n return leaf({ type: 'integer', format: 'int64' });\n }\n\n if (schema instanceof z.ZodBoolean) {\n return leaf({ type: 'boolean' });\n }\n\n if (schema instanceof z.ZodDate) {\n return leaf({ type: 'string', format: 'date-time' });\n }\n\n if (schema instanceof z.ZodNull) {\n return { so: { nullable: true }, selfRequired: true, innerSchemas: new Set() };\n }\n\n // --- Enums & literals ---\n\n if (schema instanceof z.ZodEnum) {\n return leaf({ enum: schema.options });\n }\n\n if (schema instanceof z.ZodLiteral) {\n return leaf({ enum: [...schema.values] });\n }\n\n // --- Unions & intersections ---\n\n if (schema instanceof z.ZodUnion || schema instanceof z.ZodDiscriminatedUnion) {\n const innerSchemas = new Set<ZodDtoClass>();\n const oneOf = schema.options.map((option) => {\n const { so, selfRequired, innerSchemas: innerSchemas_ } = applySwaggerDecorators(option);\n\n if (!selfRequired) {\n throw new Error('Not required option in oneOf is not supported in Swagger. Use nullable instead.');\n }\n\n innerSchemas_.forEach((innerSchema) => innerSchemas.add(innerSchema));\n\n // Flatten { oneOf: [single_ref] } → just the ref, so union of DTO refs stays clean.\n return so.oneOf?.length === 1 ? so.oneOf[0] : so;\n });\n\n return { so: { oneOf }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodIntersection) {\n const left = applySwaggerDecorators(schema._zod.def.left as z.ZodType);\n const right = applySwaggerDecorators(schema._zod.def.right as z.ZodType);\n const innerSchemas = new Set([...left.innerSchemas, ...right.innerSchemas]);\n const leftSo = left.so.oneOf?.length === 1 ? left.so.oneOf[0] : left.so;\n const rightSo = right.so.oneOf?.length === 1 ? right.so.oneOf[0] : right.so;\n\n return { so: { allOf: [leftSo, rightSo] }, selfRequired: true, innerSchemas };\n }\n\n // --- Catch-all ---\n\n if (schema instanceof z.ZodAny || schema instanceof z.ZodUnknown) {\n return leaf({});\n }\n\n if (schema instanceof z.ZodUndefined || schema instanceof z.ZodVoid || schema instanceof z.ZodNever) {\n throw new Error(`applySwaggerDecorators: ${(schema as z.ZodType).def.type} cannot be represented in JSON`);\n }\n\n throw new Error(`applySwaggerDecorators: unsupported Zod type \"${(schema as z.ZodType).def.type}\"`);\n};\n","export const mapValues = <K extends string, V, R>(obj: Record<K, V>, fn: (value: V, key: K) => R): Record<K, R> =>\n Object.fromEntries(Object.entries<V>(obj).map(([key, value]) => [key, fn(value, key as K)])) as Record<K, R>;\n","import { BadRequestException, Injectable, type PipeTransform } from '@nestjs/common';\nimport { type ArgumentMetadata } from '@nestjs/common/interfaces';\nimport { isZodDtoClass, toDto, ZodDtoValidationError } from '@voznov/zod-dto';\n\nexport interface ZodValidationPipeOptions {\n createError?: (issues: string[]) => Error;\n}\n\n@Injectable()\nexport class ZodValidationPipe implements PipeTransform {\n private readonly createError: (issues: string[]) => Error;\n\n constructor(options?: ZodValidationPipeOptions) {\n this.createError = options?.createError ?? ((issues) => new BadRequestException(issues));\n }\n\n transform(value: unknown, { metatype }: ArgumentMetadata): unknown {\n if (!metatype || !isZodDtoClass(metatype)) {\n return value;\n }\n\n try {\n return toDto(metatype, value);\n } catch (error) {\n if (error instanceof ZodDtoValidationError) {\n throw this.createError(error.issues);\n }\n throw error;\n }\n }\n}\n"],"mappings":"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","names":["import_zod_dto","import_zod_dto"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/swagger.ts","../src/utils.ts","../src/pipe.ts"],"sourcesContent":["import { registerOnCreate } from '@voznov/zod-dto';\nimport { applySwaggerDecorators } from './swagger';\n\n// Auto-register swagger decoration on every ZodDto() creation when this package is imported.\nregisterOnCreate(applySwaggerDecorators);\n\nexport { ZodValidationPipe } from './pipe';\nexport type { ZodValidationPipeOptions } from './pipe';\nexport { applySwaggerDecorators } from './swagger';\n","import { ApiExtraModels, ApiProperty, type ApiPropertyOptions, refs } from '@nestjs/swagger';\nimport { type SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';\nimport { isZodDtoClass, type ZodDtoClass } from '@voznov/zod-dto';\nimport { z } from 'zod';\nimport { mapValues } from './utils';\n\nconst schemaObjectToApiPropertyOptions = (so: SchemaObject, selfRequired: boolean): ApiPropertyOptions => {\n if ('oneOf' in so || 'anyOf' in so || 'allOf' in so) {\n return { ...so, type: Array, required: selfRequired };\n }\n\n return { ...so, required: selfRequired } as ApiPropertyOptions;\n};\n\nconst leaf = (so: SchemaObject): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => ({\n so,\n selfRequired: true,\n innerSchemas: new Set(),\n});\n\nconst decoratedDtoClasses = new Set<ZodDtoClass>();\n\n// Snapshot resolved default per schema instance — Zod's `defaultValue` is a getter that\n// re-invokes the thunk on every access. Without this cache, the same `ZodDefault` schema\n// surfaced through two paths (JS subclass, `.extend/.pick/.omit`, shared field reuse, ...)\n// would emit a different value into each occurrence in the spec.\nconst defaultValueCache = new WeakMap<z.ZodDefault, unknown>();\n\nexport const applySwaggerDecorators = (schema: z.core.$ZodType): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => {\n const result = applyDecoratorsImpl(schema);\n // `.describe(text)` → OpenAPI `description`. Read at every recursion level so the text\n // lands in the spec whether it's set on a wrapper (`.optional().describe(...)`) or on\n // the inner type (`.describe(...).optional()`).\n const description = (schema as z.ZodType).description;\n if (description) result.so = { ...result.so, description };\n\n return result;\n};\n\nconst applyDecoratorsImpl = (schema: z.core.$ZodType): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => {\n // --- Objects ---\n\n if (schema instanceof z.ZodObject) {\n if (isZodDtoClass(schema) && decoratedDtoClasses.has(schema)) {\n return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: new Set([schema]) };\n }\n\n const properties: Record<string, SchemaObject> = {};\n const required: string[] = [];\n const innerSchemas = new Set<ZodDtoClass>();\n Object.entries<z.core.$ZodType>(schema.shape).forEach(([key, fieldSchema]) => {\n const { so, selfRequired, innerSchemas: innerSchemas_ } = applySwaggerDecorators(fieldSchema);\n properties[key] = so;\n innerSchemas_.forEach((innerSchema) => innerSchemas.add(innerSchema));\n if (selfRequired) {\n required.push(key);\n }\n });\n\n if (isZodDtoClass(schema)) {\n decoratedDtoClasses.add(schema);\n for (const [key, propertySo] of Object.entries(properties)) {\n ApiProperty(schemaObjectToApiPropertyOptions(propertySo, required.includes(key)))(schema.prototype, key);\n }\n ApiExtraModels(...[...innerSchemas.values()].filter((innerSchema) => innerSchema !== schema))(schema);\n\n return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: new Set([schema]) };\n }\n\n return { so: { type: 'object', properties: mapValues(properties, (so) => (so.oneOf?.length === 1 ? so.oneOf[0] : so)), required }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodRecord) {\n const { so } = applySwaggerDecorators(schema._zod.def.valueType);\n\n return leaf({ type: 'object', additionalProperties: so.oneOf?.length === 1 ? so.oneOf[0] : so });\n }\n\n // --- Wrappers (unwrap to inner type) ---\n\n if (schema instanceof z.ZodOptional || schema instanceof z.ZodExactOptional) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };\n }\n\n if (schema instanceof z.ZodDefault) {\n const inner = applySwaggerDecorators(schema.unwrap());\n if (!defaultValueCache.has(schema)) defaultValueCache.set(schema, schema._zod.def.defaultValue);\n\n return { ...inner, so: { ...inner.so, default: defaultValueCache.get(schema) }, selfRequired: false };\n }\n\n if (schema instanceof z.ZodReadonly || schema instanceof z.ZodLazy || schema instanceof z.ZodCatch) {\n return applySwaggerDecorators(schema.unwrap());\n }\n\n if (schema instanceof z.ZodNonOptional) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: true };\n }\n\n if (schema instanceof z.ZodNullable) {\n const result = applySwaggerDecorators(schema.unwrap());\n\n return { ...result, so: { ...result.so, nullable: true } };\n }\n\n if (schema instanceof z.ZodPipe) {\n // z.preprocess() creates a Pipe(in: ZodTransform, out: schema).\n // For swagger, skip the transform and process the output schema directly.\n const inner = schema.in instanceof z.ZodTransform ? schema.out : schema.in;\n\n return applySwaggerDecorators(inner);\n }\n\n if (schema instanceof z.ZodTransform) {\n return leaf({});\n }\n\n // --- Arrays & tuples ---\n\n if (schema instanceof z.ZodArray) {\n const element = schema.unwrap();\n const { so, selfRequired: selfRequiredElement, innerSchemas } = applySwaggerDecorators(element);\n if (!selfRequiredElement) {\n throw new Error('Not required array item is not supported in Swagger. Use nullable instead.');\n }\n\n return { so: { type: 'array', items: so.oneOf?.length === 1 ? so.oneOf[0] : so }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodTuple) {\n const itemSchemas = schema._zod.def.items.map((item) => {\n const { so } = applySwaggerDecorators(item);\n\n return so.oneOf?.length === 1 ? so.oneOf[0] : so;\n });\n\n // Deduplicate by JSON representation to collapse identical types\n const unique = [...new Map(itemSchemas.map((s) => [JSON.stringify(s), s])).values()];\n const items = unique.length === 1 ? unique[0] : { oneOf: unique };\n\n return leaf({ type: 'array', items, minItems: itemSchemas.length, maxItems: itemSchemas.length });\n }\n\n // --- Scalars ---\n\n // ZodString: plain z.string(). ZodStringFormat: z.email(), z.uuid(), z.url(), z.ipv4(), etc.\n // Both share the same properties (minLength, maxLength, format).\n if (schema instanceof z.ZodString || schema instanceof z.ZodStringFormat) {\n const so: SchemaObject = { type: 'string' };\n if (schema.minLength !== null) so.minLength = schema.minLength;\n if (schema.maxLength !== null) so.maxLength = schema.maxLength;\n const fmt = schema.format;\n if (fmt !== null) {\n if (fmt === 'regex') {\n // Grab the first regex pattern from the internal bag.\n const patterns = schema._zod.bag.patterns;\n const first = patterns ? [...patterns][0] : undefined;\n if (first) so.pattern = first.source;\n } else {\n so.format = fmt;\n }\n }\n\n return { so, selfRequired: true, innerSchemas: new Set() };\n }\n\n // Number and integer subtypes (ZodInt, ZodNumberFormat, etc.) — all instanceof ZodNumber.\n if (schema instanceof z.ZodNumber) {\n const fmt = schema.format;\n const isInt = fmt === 'int32' || fmt === 'uint32' || fmt === 'safeint';\n const so: SchemaObject = { type: isInt ? 'integer' : 'number' };\n if (schema.minValue !== null && schema.minValue !== Number.MIN_SAFE_INTEGER && Number.isFinite(schema.minValue)) so.minimum = schema.minValue;\n if (schema.maxValue !== null && schema.maxValue !== Number.MAX_SAFE_INTEGER && Number.isFinite(schema.maxValue)) so.maximum = schema.maxValue;\n\n return { so, selfRequired: true, innerSchemas: new Set() };\n }\n\n if (schema instanceof z.ZodBigInt) {\n return leaf({ type: 'integer', format: 'int64' });\n }\n\n if (schema instanceof z.ZodBoolean) {\n return leaf({ type: 'boolean' });\n }\n\n if (schema instanceof z.ZodDate) {\n return leaf({ type: 'string', format: 'date-time' });\n }\n\n if (schema instanceof z.ZodNull) {\n return { so: { nullable: true }, selfRequired: true, innerSchemas: new Set() };\n }\n\n // --- Enums & literals ---\n\n if (schema instanceof z.ZodEnum) {\n return leaf({ enum: schema.options });\n }\n\n if (schema instanceof z.ZodLiteral) {\n return leaf({ enum: [...schema.values] });\n }\n\n // --- Unions & intersections ---\n\n if (schema instanceof z.ZodUnion || schema instanceof z.ZodDiscriminatedUnion) {\n const innerSchemas = new Set<ZodDtoClass>();\n const oneOf = schema.options.map((option) => {\n const { so, selfRequired, innerSchemas: innerSchemas_ } = applySwaggerDecorators(option);\n\n if (!selfRequired) {\n throw new Error('Not required option in oneOf is not supported in Swagger. Use nullable instead.');\n }\n\n innerSchemas_.forEach((innerSchema) => innerSchemas.add(innerSchema));\n\n // Flatten { oneOf: [single_ref] } → just the ref, so union of DTO refs stays clean.\n return so.oneOf?.length === 1 ? so.oneOf[0] : so;\n });\n\n return { so: { oneOf }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodIntersection) {\n const left = applySwaggerDecorators(schema._zod.def.left as z.ZodType);\n const right = applySwaggerDecorators(schema._zod.def.right as z.ZodType);\n const innerSchemas = new Set([...left.innerSchemas, ...right.innerSchemas]);\n const leftSo = left.so.oneOf?.length === 1 ? left.so.oneOf[0] : left.so;\n const rightSo = right.so.oneOf?.length === 1 ? right.so.oneOf[0] : right.so;\n\n return { so: { allOf: [leftSo, rightSo] }, selfRequired: true, innerSchemas };\n }\n\n // --- Catch-all ---\n\n if (schema instanceof z.ZodAny || schema instanceof z.ZodUnknown) {\n return leaf({});\n }\n\n if (schema instanceof z.ZodUndefined || schema instanceof z.ZodVoid || schema instanceof z.ZodNever) {\n throw new Error(`applySwaggerDecorators: ${(schema as z.ZodType).def.type} cannot be represented in JSON`);\n }\n\n throw new Error(`applySwaggerDecorators: unsupported Zod type \"${(schema as z.ZodType).def.type}\"`);\n};\n","export const mapValues = <K extends string, V, R>(obj: Record<K, V>, fn: (value: V, key: K) => R): Record<K, R> =>\n Object.fromEntries(Object.entries<V>(obj).map(([key, value]) => [key, fn(value, key as K)])) as Record<K, R>;\n","import { BadRequestException, Injectable, type PipeTransform } from '@nestjs/common';\nimport { type ArgumentMetadata } from '@nestjs/common/interfaces';\nimport { isZodDtoClass, toDto, ZodDtoValidationError } from '@voznov/zod-dto';\n\nexport interface ZodValidationPipeOptions {\n createError?: (issues: string[]) => Error;\n}\n\n@Injectable()\nexport class ZodValidationPipe implements PipeTransform {\n private readonly createError: (issues: string[]) => Error;\n\n constructor(options?: ZodValidationPipeOptions) {\n this.createError = options?.createError ?? ((issues) => new BadRequestException(issues));\n }\n\n transform(value: unknown, { metatype }: ArgumentMetadata): unknown {\n if (!metatype || !isZodDtoClass(metatype)) {\n return value;\n }\n\n try {\n return toDto(metatype, value);\n } catch (error) {\n if (error instanceof ZodDtoValidationError) {\n throw this.createError(error.issues);\n }\n throw error;\n }\n }\n}\n"],"mappings":"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","names":["import_zod_dto","import_zod_dto"]}
package/dist/index.js CHANGED
@@ -34,7 +34,14 @@ var leaf = (so) => ({
34
34
  innerSchemas: /* @__PURE__ */ new Set()
35
35
  });
36
36
  var decoratedDtoClasses = /* @__PURE__ */ new Set();
37
+ var defaultValueCache = /* @__PURE__ */ new WeakMap();
37
38
  var applySwaggerDecorators = (schema) => {
39
+ const result = applyDecoratorsImpl(schema);
40
+ const description = schema.description;
41
+ if (description) result.so = { ...result.so, description };
42
+ return result;
43
+ };
44
+ var applyDecoratorsImpl = (schema) => {
38
45
  if (schema instanceof z.ZodObject) {
39
46
  if (isZodDtoClass(schema) && decoratedDtoClasses.has(schema)) {
40
47
  return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: /* @__PURE__ */ new Set([schema]) };
@@ -68,7 +75,9 @@ var applySwaggerDecorators = (schema) => {
68
75
  return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };
69
76
  }
70
77
  if (schema instanceof z.ZodDefault) {
71
- return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };
78
+ const inner = applySwaggerDecorators(schema.unwrap());
79
+ if (!defaultValueCache.has(schema)) defaultValueCache.set(schema, schema._zod.def.defaultValue);
80
+ return { ...inner, so: { ...inner.so, default: defaultValueCache.get(schema) }, selfRequired: false };
72
81
  }
73
82
  if (schema instanceof z.ZodReadonly || schema instanceof z.ZodLazy || schema instanceof z.ZodCatch) {
74
83
  return applySwaggerDecorators(schema.unwrap());
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/swagger.ts","../src/utils.ts","../src/pipe.ts"],"sourcesContent":["import { registerOnCreate } from '@voznov/zod-dto';\nimport { applySwaggerDecorators } from './swagger';\n\n// Auto-register swagger decoration on every ZodDto() creation when this package is imported.\nregisterOnCreate(applySwaggerDecorators);\n\nexport { ZodValidationPipe } from './pipe';\nexport type { ZodValidationPipeOptions } from './pipe';\nexport { applySwaggerDecorators } from './swagger';\n","import { ApiExtraModels, ApiProperty, type ApiPropertyOptions, refs } from '@nestjs/swagger';\nimport { type SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';\nimport { isZodDtoClass, type ZodDtoClass } from '@voznov/zod-dto';\nimport { z } from 'zod';\nimport { mapValues } from './utils';\n\nconst schemaObjectToApiPropertyOptions = (so: SchemaObject, selfRequired: boolean): ApiPropertyOptions => {\n if ('oneOf' in so || 'anyOf' in so || 'allOf' in so) {\n return { ...so, type: Array, required: selfRequired };\n }\n\n return { ...so, required: selfRequired } as ApiPropertyOptions;\n};\n\nconst leaf = (so: SchemaObject): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => ({\n so,\n selfRequired: true,\n innerSchemas: new Set(),\n});\n\nconst decoratedDtoClasses = new Set<ZodDtoClass>();\n\nexport const applySwaggerDecorators = (schema: z.core.$ZodType): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => {\n // --- Objects ---\n\n if (schema instanceof z.ZodObject) {\n if (isZodDtoClass(schema) && decoratedDtoClasses.has(schema)) {\n return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: new Set([schema]) };\n }\n\n const properties: Record<string, SchemaObject> = {};\n const required: string[] = [];\n const innerSchemas = new Set<ZodDtoClass>();\n Object.entries(schema.shape).forEach(([key, fieldSchema]) => {\n const { so, selfRequired, innerSchemas: innerSchemas_ } = applySwaggerDecorators(fieldSchema as z.ZodType);\n properties[key] = so;\n innerSchemas_.forEach((innerSchema) => innerSchemas.add(innerSchema));\n if (selfRequired) {\n required.push(key);\n }\n });\n\n if (isZodDtoClass(schema)) {\n decoratedDtoClasses.add(schema);\n for (const [key, propertySo] of Object.entries(properties)) {\n ApiProperty(schemaObjectToApiPropertyOptions(propertySo, required.includes(key)))(schema.prototype, key);\n }\n ApiExtraModels(...[...innerSchemas.values()].filter((innerSchema) => innerSchema !== schema))(schema);\n\n return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: new Set([schema]) };\n }\n\n return { so: { type: 'object', properties: mapValues(properties, (so) => (so.oneOf?.length === 1 ? so.oneOf[0] : so)), required }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodRecord) {\n const { so } = applySwaggerDecorators(schema._zod.def.valueType as z.ZodType);\n\n return leaf({ type: 'object', additionalProperties: so.oneOf?.length === 1 ? so.oneOf[0] : so });\n }\n\n // --- Wrappers (unwrap to inner type) ---\n\n if (schema instanceof z.ZodOptional || schema instanceof z.ZodExactOptional) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };\n }\n\n if (schema instanceof z.ZodDefault) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };\n }\n\n if (schema instanceof z.ZodReadonly || schema instanceof z.ZodLazy || schema instanceof z.ZodCatch) {\n return applySwaggerDecorators(schema.unwrap());\n }\n\n if (schema instanceof z.ZodNonOptional) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: true };\n }\n\n if (schema instanceof z.ZodNullable) {\n const result = applySwaggerDecorators(schema.unwrap());\n\n return { ...result, so: { ...result.so, nullable: true } };\n }\n\n if (schema instanceof z.ZodPipe) {\n // z.preprocess() creates a Pipe(in: ZodTransform, out: schema).\n // For swagger, skip the transform and process the output schema directly.\n const inner = schema.in instanceof z.ZodTransform ? schema.out : schema.in;\n\n return applySwaggerDecorators(inner);\n }\n\n if (schema instanceof z.ZodTransform) {\n return leaf({});\n }\n\n // --- Arrays & tuples ---\n\n if (schema instanceof z.ZodArray) {\n const element = schema.unwrap();\n const { so, selfRequired: selfRequiredElement, innerSchemas } = applySwaggerDecorators(element);\n if (!selfRequiredElement) {\n throw new Error('Not required array item is not supported in Swagger. Use nullable instead.');\n }\n\n return { so: { type: 'array', items: so.oneOf?.length === 1 ? so.oneOf[0] : so }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodTuple) {\n const itemSchemas = schema._zod.def.items.map((item) => {\n const { so } = applySwaggerDecorators(item);\n\n return so.oneOf?.length === 1 ? so.oneOf[0] : so;\n });\n\n // Deduplicate by JSON representation to collapse identical types\n const unique = [...new Map(itemSchemas.map((s) => [JSON.stringify(s), s])).values()];\n const items = unique.length === 1 ? unique[0] : { oneOf: unique };\n\n return leaf({ type: 'array', items, minItems: itemSchemas.length, maxItems: itemSchemas.length });\n }\n\n // --- Scalars ---\n\n // ZodString: plain z.string(). ZodStringFormat: z.email(), z.uuid(), z.url(), z.ipv4(), etc.\n // Both share the same properties (minLength, maxLength, format).\n if (schema instanceof z.ZodString || schema instanceof z.ZodStringFormat) {\n const so: SchemaObject = { type: 'string' };\n if (schema.minLength !== null) so.minLength = schema.minLength;\n if (schema.maxLength !== null) so.maxLength = schema.maxLength;\n const fmt = schema.format;\n if (fmt !== null) {\n if (fmt === 'regex') {\n // Grab the first regex pattern from the internal bag.\n const patterns = schema._zod.bag.patterns;\n const first = patterns ? [...patterns][0] : undefined;\n if (first) so.pattern = first.source;\n } else {\n so.format = fmt;\n }\n }\n\n return { so, selfRequired: true, innerSchemas: new Set() };\n }\n\n // Number and integer subtypes (ZodInt, ZodNumberFormat, etc.) — all instanceof ZodNumber.\n if (schema instanceof z.ZodNumber) {\n const fmt = schema.format;\n const isInt = fmt === 'int32' || fmt === 'uint32' || fmt === 'safeint';\n const so: SchemaObject = { type: isInt ? 'integer' : 'number' };\n if (schema.minValue !== null && schema.minValue !== Number.MIN_SAFE_INTEGER && Number.isFinite(schema.minValue)) so.minimum = schema.minValue;\n if (schema.maxValue !== null && schema.maxValue !== Number.MAX_SAFE_INTEGER && Number.isFinite(schema.maxValue)) so.maximum = schema.maxValue;\n\n return { so, selfRequired: true, innerSchemas: new Set() };\n }\n\n if (schema instanceof z.ZodBigInt) {\n return leaf({ type: 'integer', format: 'int64' });\n }\n\n if (schema instanceof z.ZodBoolean) {\n return leaf({ type: 'boolean' });\n }\n\n if (schema instanceof z.ZodDate) {\n return leaf({ type: 'string', format: 'date-time' });\n }\n\n if (schema instanceof z.ZodNull) {\n return { so: { nullable: true }, selfRequired: true, innerSchemas: new Set() };\n }\n\n // --- Enums & literals ---\n\n if (schema instanceof z.ZodEnum) {\n return leaf({ enum: schema.options });\n }\n\n if (schema instanceof z.ZodLiteral) {\n return leaf({ enum: [...schema.values] });\n }\n\n // --- Unions & intersections ---\n\n if (schema instanceof z.ZodUnion || schema instanceof z.ZodDiscriminatedUnion) {\n const innerSchemas = new Set<ZodDtoClass>();\n const oneOf = schema.options.map((option) => {\n const { so, selfRequired, innerSchemas: innerSchemas_ } = applySwaggerDecorators(option);\n\n if (!selfRequired) {\n throw new Error('Not required option in oneOf is not supported in Swagger. Use nullable instead.');\n }\n\n innerSchemas_.forEach((innerSchema) => innerSchemas.add(innerSchema));\n\n // Flatten { oneOf: [single_ref] } → just the ref, so union of DTO refs stays clean.\n return so.oneOf?.length === 1 ? so.oneOf[0] : so;\n });\n\n return { so: { oneOf }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodIntersection) {\n const left = applySwaggerDecorators(schema._zod.def.left as z.ZodType);\n const right = applySwaggerDecorators(schema._zod.def.right as z.ZodType);\n const innerSchemas = new Set([...left.innerSchemas, ...right.innerSchemas]);\n const leftSo = left.so.oneOf?.length === 1 ? left.so.oneOf[0] : left.so;\n const rightSo = right.so.oneOf?.length === 1 ? right.so.oneOf[0] : right.so;\n\n return { so: { allOf: [leftSo, rightSo] }, selfRequired: true, innerSchemas };\n }\n\n // --- Catch-all ---\n\n if (schema instanceof z.ZodAny || schema instanceof z.ZodUnknown) {\n return leaf({});\n }\n\n if (schema instanceof z.ZodUndefined || schema instanceof z.ZodVoid || schema instanceof z.ZodNever) {\n throw new Error(`applySwaggerDecorators: ${(schema as z.ZodType).def.type} cannot be represented in JSON`);\n }\n\n throw new Error(`applySwaggerDecorators: unsupported Zod type \"${(schema as z.ZodType).def.type}\"`);\n};\n","export const mapValues = <K extends string, V, R>(obj: Record<K, V>, fn: (value: V, key: K) => R): Record<K, R> =>\n Object.fromEntries(Object.entries<V>(obj).map(([key, value]) => [key, fn(value, key as K)])) as Record<K, R>;\n","import { BadRequestException, Injectable, type PipeTransform } from '@nestjs/common';\nimport { type ArgumentMetadata } from '@nestjs/common/interfaces';\nimport { isZodDtoClass, toDto, ZodDtoValidationError } from '@voznov/zod-dto';\n\nexport interface ZodValidationPipeOptions {\n createError?: (issues: string[]) => Error;\n}\n\n@Injectable()\nexport class ZodValidationPipe implements PipeTransform {\n private readonly createError: (issues: string[]) => Error;\n\n constructor(options?: ZodValidationPipeOptions) {\n this.createError = options?.createError ?? ((issues) => new BadRequestException(issues));\n }\n\n transform(value: unknown, { metatype }: ArgumentMetadata): unknown {\n if (!metatype || !isZodDtoClass(metatype)) {\n return value;\n }\n\n try {\n return toDto(metatype, value);\n } catch (error) {\n if (error instanceof ZodDtoValidationError) {\n throw this.createError(error.issues);\n }\n throw error;\n }\n }\n}\n"],"mappings":"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","names":["isZodDtoClass","isZodDtoClass"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/swagger.ts","../src/utils.ts","../src/pipe.ts"],"sourcesContent":["import { registerOnCreate } from '@voznov/zod-dto';\nimport { applySwaggerDecorators } from './swagger';\n\n// Auto-register swagger decoration on every ZodDto() creation when this package is imported.\nregisterOnCreate(applySwaggerDecorators);\n\nexport { ZodValidationPipe } from './pipe';\nexport type { ZodValidationPipeOptions } from './pipe';\nexport { applySwaggerDecorators } from './swagger';\n","import { ApiExtraModels, ApiProperty, type ApiPropertyOptions, refs } from '@nestjs/swagger';\nimport { type SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';\nimport { isZodDtoClass, type ZodDtoClass } from '@voznov/zod-dto';\nimport { z } from 'zod';\nimport { mapValues } from './utils';\n\nconst schemaObjectToApiPropertyOptions = (so: SchemaObject, selfRequired: boolean): ApiPropertyOptions => {\n if ('oneOf' in so || 'anyOf' in so || 'allOf' in so) {\n return { ...so, type: Array, required: selfRequired };\n }\n\n return { ...so, required: selfRequired } as ApiPropertyOptions;\n};\n\nconst leaf = (so: SchemaObject): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => ({\n so,\n selfRequired: true,\n innerSchemas: new Set(),\n});\n\nconst decoratedDtoClasses = new Set<ZodDtoClass>();\n\n// Snapshot resolved default per schema instance — Zod's `defaultValue` is a getter that\n// re-invokes the thunk on every access. Without this cache, the same `ZodDefault` schema\n// surfaced through two paths (JS subclass, `.extend/.pick/.omit`, shared field reuse, ...)\n// would emit a different value into each occurrence in the spec.\nconst defaultValueCache = new WeakMap<z.ZodDefault, unknown>();\n\nexport const applySwaggerDecorators = (schema: z.core.$ZodType): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => {\n const result = applyDecoratorsImpl(schema);\n // `.describe(text)` → OpenAPI `description`. Read at every recursion level so the text\n // lands in the spec whether it's set on a wrapper (`.optional().describe(...)`) or on\n // the inner type (`.describe(...).optional()`).\n const description = (schema as z.ZodType).description;\n if (description) result.so = { ...result.so, description };\n\n return result;\n};\n\nconst applyDecoratorsImpl = (schema: z.core.$ZodType): { so: SchemaObject; selfRequired: boolean; innerSchemas: Set<ZodDtoClass> } => {\n // --- Objects ---\n\n if (schema instanceof z.ZodObject) {\n if (isZodDtoClass(schema) && decoratedDtoClasses.has(schema)) {\n return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: new Set([schema]) };\n }\n\n const properties: Record<string, SchemaObject> = {};\n const required: string[] = [];\n const innerSchemas = new Set<ZodDtoClass>();\n Object.entries<z.core.$ZodType>(schema.shape).forEach(([key, fieldSchema]) => {\n const { so, selfRequired, innerSchemas: innerSchemas_ } = applySwaggerDecorators(fieldSchema);\n properties[key] = so;\n innerSchemas_.forEach((innerSchema) => innerSchemas.add(innerSchema));\n if (selfRequired) {\n required.push(key);\n }\n });\n\n if (isZodDtoClass(schema)) {\n decoratedDtoClasses.add(schema);\n for (const [key, propertySo] of Object.entries(properties)) {\n ApiProperty(schemaObjectToApiPropertyOptions(propertySo, required.includes(key)))(schema.prototype, key);\n }\n ApiExtraModels(...[...innerSchemas.values()].filter((innerSchema) => innerSchema !== schema))(schema);\n\n return { so: { oneOf: refs(schema) }, selfRequired: true, innerSchemas: new Set([schema]) };\n }\n\n return { so: { type: 'object', properties: mapValues(properties, (so) => (so.oneOf?.length === 1 ? so.oneOf[0] : so)), required }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodRecord) {\n const { so } = applySwaggerDecorators(schema._zod.def.valueType);\n\n return leaf({ type: 'object', additionalProperties: so.oneOf?.length === 1 ? so.oneOf[0] : so });\n }\n\n // --- Wrappers (unwrap to inner type) ---\n\n if (schema instanceof z.ZodOptional || schema instanceof z.ZodExactOptional) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: false };\n }\n\n if (schema instanceof z.ZodDefault) {\n const inner = applySwaggerDecorators(schema.unwrap());\n if (!defaultValueCache.has(schema)) defaultValueCache.set(schema, schema._zod.def.defaultValue);\n\n return { ...inner, so: { ...inner.so, default: defaultValueCache.get(schema) }, selfRequired: false };\n }\n\n if (schema instanceof z.ZodReadonly || schema instanceof z.ZodLazy || schema instanceof z.ZodCatch) {\n return applySwaggerDecorators(schema.unwrap());\n }\n\n if (schema instanceof z.ZodNonOptional) {\n return { ...applySwaggerDecorators(schema.unwrap()), selfRequired: true };\n }\n\n if (schema instanceof z.ZodNullable) {\n const result = applySwaggerDecorators(schema.unwrap());\n\n return { ...result, so: { ...result.so, nullable: true } };\n }\n\n if (schema instanceof z.ZodPipe) {\n // z.preprocess() creates a Pipe(in: ZodTransform, out: schema).\n // For swagger, skip the transform and process the output schema directly.\n const inner = schema.in instanceof z.ZodTransform ? schema.out : schema.in;\n\n return applySwaggerDecorators(inner);\n }\n\n if (schema instanceof z.ZodTransform) {\n return leaf({});\n }\n\n // --- Arrays & tuples ---\n\n if (schema instanceof z.ZodArray) {\n const element = schema.unwrap();\n const { so, selfRequired: selfRequiredElement, innerSchemas } = applySwaggerDecorators(element);\n if (!selfRequiredElement) {\n throw new Error('Not required array item is not supported in Swagger. Use nullable instead.');\n }\n\n return { so: { type: 'array', items: so.oneOf?.length === 1 ? so.oneOf[0] : so }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodTuple) {\n const itemSchemas = schema._zod.def.items.map((item) => {\n const { so } = applySwaggerDecorators(item);\n\n return so.oneOf?.length === 1 ? so.oneOf[0] : so;\n });\n\n // Deduplicate by JSON representation to collapse identical types\n const unique = [...new Map(itemSchemas.map((s) => [JSON.stringify(s), s])).values()];\n const items = unique.length === 1 ? unique[0] : { oneOf: unique };\n\n return leaf({ type: 'array', items, minItems: itemSchemas.length, maxItems: itemSchemas.length });\n }\n\n // --- Scalars ---\n\n // ZodString: plain z.string(). ZodStringFormat: z.email(), z.uuid(), z.url(), z.ipv4(), etc.\n // Both share the same properties (minLength, maxLength, format).\n if (schema instanceof z.ZodString || schema instanceof z.ZodStringFormat) {\n const so: SchemaObject = { type: 'string' };\n if (schema.minLength !== null) so.minLength = schema.minLength;\n if (schema.maxLength !== null) so.maxLength = schema.maxLength;\n const fmt = schema.format;\n if (fmt !== null) {\n if (fmt === 'regex') {\n // Grab the first regex pattern from the internal bag.\n const patterns = schema._zod.bag.patterns;\n const first = patterns ? [...patterns][0] : undefined;\n if (first) so.pattern = first.source;\n } else {\n so.format = fmt;\n }\n }\n\n return { so, selfRequired: true, innerSchemas: new Set() };\n }\n\n // Number and integer subtypes (ZodInt, ZodNumberFormat, etc.) — all instanceof ZodNumber.\n if (schema instanceof z.ZodNumber) {\n const fmt = schema.format;\n const isInt = fmt === 'int32' || fmt === 'uint32' || fmt === 'safeint';\n const so: SchemaObject = { type: isInt ? 'integer' : 'number' };\n if (schema.minValue !== null && schema.minValue !== Number.MIN_SAFE_INTEGER && Number.isFinite(schema.minValue)) so.minimum = schema.minValue;\n if (schema.maxValue !== null && schema.maxValue !== Number.MAX_SAFE_INTEGER && Number.isFinite(schema.maxValue)) so.maximum = schema.maxValue;\n\n return { so, selfRequired: true, innerSchemas: new Set() };\n }\n\n if (schema instanceof z.ZodBigInt) {\n return leaf({ type: 'integer', format: 'int64' });\n }\n\n if (schema instanceof z.ZodBoolean) {\n return leaf({ type: 'boolean' });\n }\n\n if (schema instanceof z.ZodDate) {\n return leaf({ type: 'string', format: 'date-time' });\n }\n\n if (schema instanceof z.ZodNull) {\n return { so: { nullable: true }, selfRequired: true, innerSchemas: new Set() };\n }\n\n // --- Enums & literals ---\n\n if (schema instanceof z.ZodEnum) {\n return leaf({ enum: schema.options });\n }\n\n if (schema instanceof z.ZodLiteral) {\n return leaf({ enum: [...schema.values] });\n }\n\n // --- Unions & intersections ---\n\n if (schema instanceof z.ZodUnion || schema instanceof z.ZodDiscriminatedUnion) {\n const innerSchemas = new Set<ZodDtoClass>();\n const oneOf = schema.options.map((option) => {\n const { so, selfRequired, innerSchemas: innerSchemas_ } = applySwaggerDecorators(option);\n\n if (!selfRequired) {\n throw new Error('Not required option in oneOf is not supported in Swagger. Use nullable instead.');\n }\n\n innerSchemas_.forEach((innerSchema) => innerSchemas.add(innerSchema));\n\n // Flatten { oneOf: [single_ref] } → just the ref, so union of DTO refs stays clean.\n return so.oneOf?.length === 1 ? so.oneOf[0] : so;\n });\n\n return { so: { oneOf }, selfRequired: true, innerSchemas };\n }\n\n if (schema instanceof z.ZodIntersection) {\n const left = applySwaggerDecorators(schema._zod.def.left as z.ZodType);\n const right = applySwaggerDecorators(schema._zod.def.right as z.ZodType);\n const innerSchemas = new Set([...left.innerSchemas, ...right.innerSchemas]);\n const leftSo = left.so.oneOf?.length === 1 ? left.so.oneOf[0] : left.so;\n const rightSo = right.so.oneOf?.length === 1 ? right.so.oneOf[0] : right.so;\n\n return { so: { allOf: [leftSo, rightSo] }, selfRequired: true, innerSchemas };\n }\n\n // --- Catch-all ---\n\n if (schema instanceof z.ZodAny || schema instanceof z.ZodUnknown) {\n return leaf({});\n }\n\n if (schema instanceof z.ZodUndefined || schema instanceof z.ZodVoid || schema instanceof z.ZodNever) {\n throw new Error(`applySwaggerDecorators: ${(schema as z.ZodType).def.type} cannot be represented in JSON`);\n }\n\n throw new Error(`applySwaggerDecorators: unsupported Zod type \"${(schema as z.ZodType).def.type}\"`);\n};\n","export const mapValues = <K extends string, V, R>(obj: Record<K, V>, fn: (value: V, key: K) => R): Record<K, R> =>\n Object.fromEntries(Object.entries<V>(obj).map(([key, value]) => [key, fn(value, key as K)])) as Record<K, R>;\n","import { BadRequestException, Injectable, type PipeTransform } from '@nestjs/common';\nimport { type ArgumentMetadata } from '@nestjs/common/interfaces';\nimport { isZodDtoClass, toDto, ZodDtoValidationError } from '@voznov/zod-dto';\n\nexport interface ZodValidationPipeOptions {\n createError?: (issues: string[]) => Error;\n}\n\n@Injectable()\nexport class ZodValidationPipe implements PipeTransform {\n private readonly createError: (issues: string[]) => Error;\n\n constructor(options?: ZodValidationPipeOptions) {\n this.createError = options?.createError ?? ((issues) => new BadRequestException(issues));\n }\n\n transform(value: unknown, { metatype }: ArgumentMetadata): unknown {\n if (!metatype || !isZodDtoClass(metatype)) {\n return value;\n }\n\n try {\n return toDto(metatype, value);\n } catch (error) {\n if (error instanceof ZodDtoValidationError) {\n throw this.createError(error.issues);\n }\n throw error;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,wBAAwB;;;ACAjC,SAAS,gBAAgB,aAAsC,YAAY;AAC3E,OAAkC;AAClC,SAAS,qBAAuC;AAChD,SAAS,SAAS;;;ACHX,IAAM,YAAY,CAAyB,KAAmB,OACnE,OAAO,YAAY,OAAO,QAAW,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,GAAG,OAAO,GAAQ,CAAC,CAAC,CAAC;;;ADK7F,IAAM,mCAAmC,CAAC,IAAkB,iBAA8C;AACxG,MAAI,WAAW,MAAM,WAAW,MAAM,WAAW,IAAI;AACnD,WAAO,EAAE,GAAG,IAAI,MAAM,OAAO,UAAU,aAAa;AAAA,EACtD;AAEA,SAAO,EAAE,GAAG,IAAI,UAAU,aAAa;AACzC;AAEA,IAAM,OAAO,CAAC,QAAmG;AAAA,EAC/G;AAAA,EACA,cAAc;AAAA,EACd,cAAc,oBAAI,IAAI;AACxB;AAEA,IAAM,sBAAsB,oBAAI,IAAiB;AAMjD,IAAM,oBAAoB,oBAAI,QAA+B;AAEtD,IAAM,yBAAyB,CAAC,WAAyG;AAC9I,QAAM,SAAS,oBAAoB,MAAM;AAIzC,QAAM,cAAe,OAAqB;AAC1C,MAAI,YAAa,QAAO,KAAK,EAAE,GAAG,OAAO,IAAI,YAAY;AAEzD,SAAO;AACT;AAEA,IAAM,sBAAsB,CAAC,WAAyG;AAGpI,MAAI,kBAAkB,EAAE,WAAW;AACjC,QAAI,cAAc,MAAM,KAAK,oBAAoB,IAAI,MAAM,GAAG;AAC5D,aAAO,EAAE,IAAI,EAAE,OAAO,KAAK,MAAM,EAAE,GAAG,cAAc,MAAM,cAAc,oBAAI,IAAI,CAAC,MAAM,CAAC,EAAE;AAAA,IAC5F;AAEA,UAAM,aAA2C,CAAC;AAClD,UAAM,WAAqB,CAAC;AAC5B,UAAM,eAAe,oBAAI,IAAiB;AAC1C,WAAO,QAAyB,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,KAAK,WAAW,MAAM;AAC5E,YAAM,EAAE,IAAI,cAAc,cAAc,cAAc,IAAI,uBAAuB,WAAW;AAC5F,iBAAW,GAAG,IAAI;AAClB,oBAAc,QAAQ,CAAC,gBAAgB,aAAa,IAAI,WAAW,CAAC;AACpE,UAAI,cAAc;AAChB,iBAAS,KAAK,GAAG;AAAA,MACnB;AAAA,IACF,CAAC;AAED,QAAI,cAAc,MAAM,GAAG;AACzB,0BAAoB,IAAI,MAAM;AAC9B,iBAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,UAAU,GAAG;AAC1D,oBAAY,iCAAiC,YAAY,SAAS,SAAS,GAAG,CAAC,CAAC,EAAE,OAAO,WAAW,GAAG;AAAA,MACzG;AACA,qBAAe,GAAG,CAAC,GAAG,aAAa,OAAO,CAAC,EAAE,OAAO,CAAC,gBAAgB,gBAAgB,MAAM,CAAC,EAAE,MAAM;AAEpG,aAAO,EAAE,IAAI,EAAE,OAAO,KAAK,MAAM,EAAE,GAAG,cAAc,MAAM,cAAc,oBAAI,IAAI,CAAC,MAAM,CAAC,EAAE;AAAA,IAC5F;AAEA,WAAO,EAAE,IAAI,EAAE,MAAM,UAAU,YAAY,UAAU,YAAY,CAAC,OAAQ,GAAG,OAAO,WAAW,IAAI,GAAG,MAAM,CAAC,IAAI,EAAG,GAAG,SAAS,GAAG,cAAc,MAAM,aAAa;AAAA,EACtK;AAEA,MAAI,kBAAkB,EAAE,WAAW;AACjC,UAAM,EAAE,GAAG,IAAI,uBAAuB,OAAO,KAAK,IAAI,SAAS;AAE/D,WAAO,KAAK,EAAE,MAAM,UAAU,sBAAsB,GAAG,OAAO,WAAW,IAAI,GAAG,MAAM,CAAC,IAAI,GAAG,CAAC;AAAA,EACjG;AAIA,MAAI,kBAAkB,EAAE,eAAe,kBAAkB,EAAE,kBAAkB;AAC3E,WAAO,EAAE,GAAG,uBAAuB,OAAO,OAAO,CAAC,GAAG,cAAc,MAAM;AAAA,EAC3E;AAEA,MAAI,kBAAkB,EAAE,YAAY;AAClC,UAAM,QAAQ,uBAAuB,OAAO,OAAO,CAAC;AACpD,QAAI,CAAC,kBAAkB,IAAI,MAAM,EAAG,mBAAkB,IAAI,QAAQ,OAAO,KAAK,IAAI,YAAY;AAE9F,WAAO,EAAE,GAAG,OAAO,IAAI,EAAE,GAAG,MAAM,IAAI,SAAS,kBAAkB,IAAI,MAAM,EAAE,GAAG,cAAc,MAAM;AAAA,EACtG;AAEA,MAAI,kBAAkB,EAAE,eAAe,kBAAkB,EAAE,WAAW,kBAAkB,EAAE,UAAU;AAClG,WAAO,uBAAuB,OAAO,OAAO,CAAC;AAAA,EAC/C;AAEA,MAAI,kBAAkB,EAAE,gBAAgB;AACtC,WAAO,EAAE,GAAG,uBAAuB,OAAO,OAAO,CAAC,GAAG,cAAc,KAAK;AAAA,EAC1E;AAEA,MAAI,kBAAkB,EAAE,aAAa;AACnC,UAAM,SAAS,uBAAuB,OAAO,OAAO,CAAC;AAErD,WAAO,EAAE,GAAG,QAAQ,IAAI,EAAE,GAAG,OAAO,IAAI,UAAU,KAAK,EAAE;AAAA,EAC3D;AAEA,MAAI,kBAAkB,EAAE,SAAS;AAG/B,UAAM,QAAQ,OAAO,cAAc,EAAE,eAAe,OAAO,MAAM,OAAO;AAExE,WAAO,uBAAuB,KAAK;AAAA,EACrC;AAEA,MAAI,kBAAkB,EAAE,cAAc;AACpC,WAAO,KAAK,CAAC,CAAC;AAAA,EAChB;AAIA,MAAI,kBAAkB,EAAE,UAAU;AAChC,UAAM,UAAU,OAAO,OAAO;AAC9B,UAAM,EAAE,IAAI,cAAc,qBAAqB,aAAa,IAAI,uBAAuB,OAAO;AAC9F,QAAI,CAAC,qBAAqB;AACxB,YAAM,IAAI,MAAM,4EAA4E;AAAA,IAC9F;AAEA,WAAO,EAAE,IAAI,EAAE,MAAM,SAAS,OAAO,GAAG,OAAO,WAAW,IAAI,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,cAAc,MAAM,aAAa;AAAA,EACrH;AAEA,MAAI,kBAAkB,EAAE,UAAU;AAChC,UAAM,cAAc,OAAO,KAAK,IAAI,MAAM,IAAI,CAAC,SAAS;AACtD,YAAM,EAAE,GAAG,IAAI,uBAAuB,IAAI;AAE1C,aAAO,GAAG,OAAO,WAAW,IAAI,GAAG,MAAM,CAAC,IAAI;AAAA,IAChD,CAAC;AAGD,UAAM,SAAS,CAAC,GAAG,IAAI,IAAI,YAAY,IAAI,CAAC,MAAM,CAAC,KAAK,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;AACnF,UAAM,QAAQ,OAAO,WAAW,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,OAAO;AAEhE,WAAO,KAAK,EAAE,MAAM,SAAS,OAAO,UAAU,YAAY,QAAQ,UAAU,YAAY,OAAO,CAAC;AAAA,EAClG;AAMA,MAAI,kBAAkB,EAAE,aAAa,kBAAkB,EAAE,iBAAiB;AACxE,UAAM,KAAmB,EAAE,MAAM,SAAS;AAC1C,QAAI,OAAO,cAAc,KAAM,IAAG,YAAY,OAAO;AACrD,QAAI,OAAO,cAAc,KAAM,IAAG,YAAY,OAAO;AACrD,UAAM,MAAM,OAAO;AACnB,QAAI,QAAQ,MAAM;AAChB,UAAI,QAAQ,SAAS;AAEnB,cAAM,WAAW,OAAO,KAAK,IAAI;AACjC,cAAM,QAAQ,WAAW,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI;AAC5C,YAAI,MAAO,IAAG,UAAU,MAAM;AAAA,MAChC,OAAO;AACL,WAAG,SAAS;AAAA,MACd;AAAA,IACF;AAEA,WAAO,EAAE,IAAI,cAAc,MAAM,cAAc,oBAAI,IAAI,EAAE;AAAA,EAC3D;AAGA,MAAI,kBAAkB,EAAE,WAAW;AACjC,UAAM,MAAM,OAAO;AACnB,UAAM,QAAQ,QAAQ,WAAW,QAAQ,YAAY,QAAQ;AAC7D,UAAM,KAAmB,EAAE,MAAM,QAAQ,YAAY,SAAS;AAC9D,QAAI,OAAO,aAAa,QAAQ,OAAO,aAAa,OAAO,oBAAoB,OAAO,SAAS,OAAO,QAAQ,EAAG,IAAG,UAAU,OAAO;AACrI,QAAI,OAAO,aAAa,QAAQ,OAAO,aAAa,OAAO,oBAAoB,OAAO,SAAS,OAAO,QAAQ,EAAG,IAAG,UAAU,OAAO;AAErI,WAAO,EAAE,IAAI,cAAc,MAAM,cAAc,oBAAI,IAAI,EAAE;AAAA,EAC3D;AAEA,MAAI,kBAAkB,EAAE,WAAW;AACjC,WAAO,KAAK,EAAE,MAAM,WAAW,QAAQ,QAAQ,CAAC;AAAA,EAClD;AAEA,MAAI,kBAAkB,EAAE,YAAY;AAClC,WAAO,KAAK,EAAE,MAAM,UAAU,CAAC;AAAA,EACjC;AAEA,MAAI,kBAAkB,EAAE,SAAS;AAC/B,WAAO,KAAK,EAAE,MAAM,UAAU,QAAQ,YAAY,CAAC;AAAA,EACrD;AAEA,MAAI,kBAAkB,EAAE,SAAS;AAC/B,WAAO,EAAE,IAAI,EAAE,UAAU,KAAK,GAAG,cAAc,MAAM,cAAc,oBAAI,IAAI,EAAE;AAAA,EAC/E;AAIA,MAAI,kBAAkB,EAAE,SAAS;AAC/B,WAAO,KAAK,EAAE,MAAM,OAAO,QAAQ,CAAC;AAAA,EACtC;AAEA,MAAI,kBAAkB,EAAE,YAAY;AAClC,WAAO,KAAK,EAAE,MAAM,CAAC,GAAG,OAAO,MAAM,EAAE,CAAC;AAAA,EAC1C;AAIA,MAAI,kBAAkB,EAAE,YAAY,kBAAkB,EAAE,uBAAuB;AAC7E,UAAM,eAAe,oBAAI,IAAiB;AAC1C,UAAM,QAAQ,OAAO,QAAQ,IAAI,CAAC,WAAW;AAC3C,YAAM,EAAE,IAAI,cAAc,cAAc,cAAc,IAAI,uBAAuB,MAAM;AAEvF,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,MAAM,iFAAiF;AAAA,MACnG;AAEA,oBAAc,QAAQ,CAAC,gBAAgB,aAAa,IAAI,WAAW,CAAC;AAGpE,aAAO,GAAG,OAAO,WAAW,IAAI,GAAG,MAAM,CAAC,IAAI;AAAA,IAChD,CAAC;AAED,WAAO,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,MAAM,aAAa;AAAA,EAC3D;AAEA,MAAI,kBAAkB,EAAE,iBAAiB;AACvC,UAAM,OAAO,uBAAuB,OAAO,KAAK,IAAI,IAAiB;AACrE,UAAM,QAAQ,uBAAuB,OAAO,KAAK,IAAI,KAAkB;AACvE,UAAM,eAAe,oBAAI,IAAI,CAAC,GAAG,KAAK,cAAc,GAAG,MAAM,YAAY,CAAC;AAC1E,UAAM,SAAS,KAAK,GAAG,OAAO,WAAW,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,KAAK;AACrE,UAAM,UAAU,MAAM,GAAG,OAAO,WAAW,IAAI,MAAM,GAAG,MAAM,CAAC,IAAI,MAAM;AAEzE,WAAO,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,OAAO,EAAE,GAAG,cAAc,MAAM,aAAa;AAAA,EAC9E;AAIA,MAAI,kBAAkB,EAAE,UAAU,kBAAkB,EAAE,YAAY;AAChE,WAAO,KAAK,CAAC,CAAC;AAAA,EAChB;AAEA,MAAI,kBAAkB,EAAE,gBAAgB,kBAAkB,EAAE,WAAW,kBAAkB,EAAE,UAAU;AACnG,UAAM,IAAI,MAAM,2BAA4B,OAAqB,IAAI,IAAI,gCAAgC;AAAA,EAC3G;AAEA,QAAM,IAAI,MAAM,iDAAkD,OAAqB,IAAI,IAAI,GAAG;AACpG;;;AEpPA,SAAS,qBAAqB,kBAAsC;AACpE,OAAsC;AACtC,SAAS,iBAAAA,gBAAe,OAAO,6BAA6B;AAOrD,IAAM,oBAAN,MAAiD;AAAA,EACrC;AAAA,EAEjB,YAAY,SAAoC;AAC9C,SAAK,cAAc,SAAS,gBAAgB,CAAC,WAAW,IAAI,oBAAoB,MAAM;AAAA,EACxF;AAAA,EAEA,UAAU,OAAgB,EAAE,SAAS,GAA8B;AACjE,QAAI,CAAC,YAAY,CAACC,eAAc,QAAQ,GAAG;AACzC,aAAO;AAAA,IACT;AAEA,QAAI;AACF,aAAO,MAAM,UAAU,KAAK;AAAA,IAC9B,SAAS,OAAO;AACd,UAAI,iBAAiB,uBAAuB;AAC1C,cAAM,KAAK,YAAY,MAAM,MAAM;AAAA,MACrC;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;AArBa,oBAAN;AAAA,EADN,WAAW;AAAA,GACC;;;AHLb,iBAAiB,sBAAsB;","names":["isZodDtoClass","isZodDtoClass"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voznov/zod-dto-nestjs",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "NestJS adapter for @voznov/zod-dto — validation pipe, Swagger generation",
5
5
  "keywords": [
6
6
  "zod",
@@ -48,7 +48,7 @@
48
48
  "@nestjs/common": ">=10.0.0",
49
49
  "@nestjs/swagger": ">=7.0.0",
50
50
  "zod": ">=4.0.0",
51
- "@voznov/zod-dto": "^0.1.2"
51
+ "@voznov/zod-dto": "^0.2.0"
52
52
  },
53
53
  "publishConfig": {
54
54
  "access": "public"