@voznov/zod-dto-nestjs 0.2.2 → 0.2.3
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 +30 -1
- package/dist/index.cjs +5 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,11 +19,16 @@ app.useGlobalPipes(new ZodValidationPipe());
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
|
-
import { Body, Controller, Post } from '@nestjs/common';
|
|
22
|
+
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
|
|
23
23
|
import { ZodDto } from '@voznov/zod-dto';
|
|
24
24
|
import { z } from 'zod';
|
|
25
25
|
|
|
26
26
|
class CreateUserDto extends ZodDto(z.object({ name: z.string(), email: z.email() })) {}
|
|
27
|
+
class UserIdParam extends ZodDto(z.object({ id: z.uuid() })) {}
|
|
28
|
+
class ListUsersQuery extends ZodDto(z.object({
|
|
29
|
+
page: z.coerce.number().int().min(1).default(1),
|
|
30
|
+
limit: z.coerce.number().int().min(1).max(100).default(20),
|
|
31
|
+
})) {}
|
|
27
32
|
|
|
28
33
|
@Controller('users')
|
|
29
34
|
export class UsersController {
|
|
@@ -31,6 +36,16 @@ export class UsersController {
|
|
|
31
36
|
create(@Body() body: CreateUserDto) {
|
|
32
37
|
// already validated; `body` is a CreateUserDto instance.
|
|
33
38
|
}
|
|
39
|
+
|
|
40
|
+
// `@Param() params: UserIdParam` — `id` validated as UUID, format: 'uuid' in the spec.
|
|
41
|
+
// (Cleaner than `@Param('id', ParseUUIDPipe) id: string`, and the spec carries the format.)
|
|
42
|
+
@Get(':id')
|
|
43
|
+
findOne(@Param() params: UserIdParam) { /* ... */ }
|
|
44
|
+
|
|
45
|
+
// `@Query() query: ListUsersQuery` — every Zod field becomes one OpenAPI query parameter,
|
|
46
|
+
// with per-field validation, defaults, and descriptions, no extra `@ApiQuery` decorators needed.
|
|
47
|
+
@Get()
|
|
48
|
+
list(@Query() query: ListUsersQuery) { /* ... */ }
|
|
34
49
|
}
|
|
35
50
|
```
|
|
36
51
|
|
|
@@ -52,6 +67,20 @@ Supported shapes: scalars, objects (nested), arrays, tuples, records, enums, lit
|
|
|
52
67
|
|
|
53
68
|
`.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.
|
|
54
69
|
|
|
70
|
+
> ⚠️ **`in` / `out` hooks are runtime-only.** The walker only reads the schema's structure, not the options passed to `ZodDto(schema, { in, out })`. A `out: ({ password, ...rest }) => rest` correctly strips `password` from the response *body*, but the OpenAPI schema still lists `password` as a property — the spec lies about a field that runtime drops. Same for `in`: snake_case→camelCase aliases applied via `in` are invisible in the spec, so docs show only the camelCase shape. If spec-correctness matters, either omit the field from the schema itself (`schema.omit({ password: true })`) or maintain a separate response DTO.
|
|
71
|
+
|
|
72
|
+
### Reference nested DTOs by class, not by raw schema
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
// ❌ Inlines NoteDto's full shape into items[]; codegen produces two separate types for the same data.
|
|
76
|
+
class PaginatedNotes extends ZodDto(z.object({ items: z.array(noteSchema) })) {}
|
|
77
|
+
|
|
78
|
+
// ✅ Emits `items: { type: 'array', items: { $ref: '#/components/schemas/NoteDto' } }`.
|
|
79
|
+
class PaginatedNotes extends ZodDto(z.object({ items: z.array(NoteDto) })) {}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Both forms parse identically, but only the second one keeps the spec DRY — `$ref` instead of an inlined copy. Use the DTO class itself in nested positions whenever you have one.
|
|
83
|
+
|
|
55
84
|
### Recursive schemas (`z.lazy` / `lazyDto`)
|
|
56
85
|
|
|
57
86
|
For self-referential shapes (comment trees, file trees, ...) wrap the recursion in a DTO and reference it back via `lazyDto` — the Swagger walker emits a proper `$ref` at the cycle, and `lazyDto` keeps TypeScript from tripping over the circular self-reference:
|
package/dist/index.cjs
CHANGED
|
@@ -160,7 +160,7 @@ var applyDecoratorsImpl = (schema) => {
|
|
|
160
160
|
const first = patterns ? [...patterns][0] : void 0;
|
|
161
161
|
if (first) so.pattern = first.source;
|
|
162
162
|
} else {
|
|
163
|
-
so.format = fmt;
|
|
163
|
+
so.format = fmt === "datetime" ? "date-time" : fmt;
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
return { so, selfRequired: true, innerSchemas: /* @__PURE__ */ new Set() };
|
|
@@ -233,14 +233,11 @@ var ZodValidationPipe = class {
|
|
|
233
233
|
if (!metatype || !(0, import_zod_dto2.isZodDtoClass)(metatype)) {
|
|
234
234
|
return value;
|
|
235
235
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (error instanceof import_zod_dto2.ZodDtoValidationError) {
|
|
240
|
-
throw this.createError(error.issues);
|
|
241
|
-
}
|
|
242
|
-
throw error;
|
|
236
|
+
const result = metatype.safeParse(value);
|
|
237
|
+
if (!result.success) {
|
|
238
|
+
throw this.createError((0, import_zod_dto2.formatZodIssues)(result.error.issues));
|
|
243
239
|
}
|
|
240
|
+
return result.data;
|
|
244
241
|
}
|
|
245
242
|
};
|
|
246
243
|
ZodValidationPipe = __decorateClass([
|
package/dist/index.cjs.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// Deferred to a microtask so self-referential DTOs (`lazyDto<X>(() => X)`) resolve past TDZ.\nregisterOnCreate((dto) => void Promise.resolve().then(() => applySwaggerDecorators(dto)));\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\n// `z.lazy(() => self)` is the only way to introduce a real cycle in a Zod schema graph.\n// Track each ZodLazy currently being walked so we can break re-entry without overflowing.\nconst lazyInProgress = new Set<z.ZodLazy>();\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.ZodLazy) {\n // `z.lazy(() => self)` is the only way Zod schemas can carry an actual cycle.\n // Track each ZodLazy instance currently being walked; on re-entry, emit a $ref\n // back to the DTO that the lazy resolves to (if any), or a permissive `{}` as a\n // last resort for anonymous self-referential trees.\n if (lazyInProgress.has(schema)) {\n const inner = schema.unwrap();\n if (isZodDtoClass(inner)) return { so: { oneOf: refs(inner) }, selfRequired: true, innerSchemas: new Set([inner]) };\n\n return leaf({});\n }\n lazyInProgress.add(schema);\n try {\n return applySwaggerDecorators(schema.unwrap());\n } finally {\n lazyInProgress.delete(schema);\n }\n }\n\n if (schema instanceof z.ZodReadonly || 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// Deferred to a microtask so self-referential DTOs (`lazyDto<X>(() => X)`) resolve past TDZ.\nregisterOnCreate((dto) => void Promise.resolve().then(() => applySwaggerDecorators(dto)));\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\n// `z.lazy(() => self)` is the only way to introduce a real cycle in a Zod schema graph.\n// Track each ZodLazy currently being walked so we can break re-entry without overflowing.\nconst lazyInProgress = new Set<z.ZodLazy>();\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.ZodLazy) {\n // `z.lazy(() => self)` is the only way Zod schemas can carry an actual cycle.\n // Track each ZodLazy instance currently being walked; on re-entry, emit a $ref\n // back to the DTO that the lazy resolves to (if any), or a permissive `{}` as a\n // last resort for anonymous self-referential trees.\n if (lazyInProgress.has(schema)) {\n const inner = schema.unwrap();\n if (isZodDtoClass(inner)) return { so: { oneOf: refs(inner) }, selfRequired: true, innerSchemas: new Set([inner]) };\n\n return leaf({});\n }\n lazyInProgress.add(schema);\n try {\n return applySwaggerDecorators(schema.unwrap());\n } finally {\n lazyInProgress.delete(schema);\n }\n }\n\n if (schema instanceof z.ZodReadonly || 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 // Zod's `iso.datetime()` reports `format: 'datetime'`; OpenAPI/JSON Schema spell it `date-time`.\n so.format = fmt === 'datetime' ? 'date-time' : 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 { formatZodIssues, isZodDtoClass } 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 const result = metatype.safeParse(value);\n if (!result.success) {\n throw this.createError(formatZodIssues(result.error.issues));\n }\n\n return result.data;\n }\n}\n"],"mappings":"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","names":["import_zod_dto","import_zod_dto"]}
|
package/dist/index.js
CHANGED
|
@@ -138,7 +138,7 @@ var applyDecoratorsImpl = (schema) => {
|
|
|
138
138
|
const first = patterns ? [...patterns][0] : void 0;
|
|
139
139
|
if (first) so.pattern = first.source;
|
|
140
140
|
} else {
|
|
141
|
-
so.format = fmt;
|
|
141
|
+
so.format = fmt === "datetime" ? "date-time" : fmt;
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
return { so, selfRequired: true, innerSchemas: /* @__PURE__ */ new Set() };
|
|
@@ -201,7 +201,7 @@ var applyDecoratorsImpl = (schema) => {
|
|
|
201
201
|
// src/pipe.ts
|
|
202
202
|
import { BadRequestException, Injectable } from "@nestjs/common";
|
|
203
203
|
import "@nestjs/common/interfaces";
|
|
204
|
-
import { isZodDtoClass as isZodDtoClass2
|
|
204
|
+
import { formatZodIssues, isZodDtoClass as isZodDtoClass2 } from "@voznov/zod-dto";
|
|
205
205
|
var ZodValidationPipe = class {
|
|
206
206
|
createError;
|
|
207
207
|
constructor(options) {
|
|
@@ -211,14 +211,11 @@ var ZodValidationPipe = class {
|
|
|
211
211
|
if (!metatype || !isZodDtoClass2(metatype)) {
|
|
212
212
|
return value;
|
|
213
213
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (error instanceof ZodDtoValidationError) {
|
|
218
|
-
throw this.createError(error.issues);
|
|
219
|
-
}
|
|
220
|
-
throw error;
|
|
214
|
+
const result = metatype.safeParse(value);
|
|
215
|
+
if (!result.success) {
|
|
216
|
+
throw this.createError(formatZodIssues(result.error.issues));
|
|
221
217
|
}
|
|
218
|
+
return result.data;
|
|
222
219
|
}
|
|
223
220
|
};
|
|
224
221
|
ZodValidationPipe = __decorateClass([
|
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// Deferred to a microtask so self-referential DTOs (`lazyDto<X>(() => X)`) resolve past TDZ.\nregisterOnCreate((dto) => void Promise.resolve().then(() => applySwaggerDecorators(dto)));\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\n// `z.lazy(() => self)` is the only way to introduce a real cycle in a Zod schema graph.\n// Track each ZodLazy currently being walked so we can break re-entry without overflowing.\nconst lazyInProgress = new Set<z.ZodLazy>();\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.ZodLazy) {\n // `z.lazy(() => self)` is the only way Zod schemas can carry an actual cycle.\n // Track each ZodLazy instance currently being walked; on re-entry, emit a $ref\n // back to the DTO that the lazy resolves to (if any), or a permissive `{}` as a\n // last resort for anonymous self-referential trees.\n if (lazyInProgress.has(schema)) {\n const inner = schema.unwrap();\n if (isZodDtoClass(inner)) return { so: { oneOf: refs(inner) }, selfRequired: true, innerSchemas: new Set([inner]) };\n\n return leaf({});\n }\n lazyInProgress.add(schema);\n try {\n return applySwaggerDecorators(schema.unwrap());\n } finally {\n lazyInProgress.delete(schema);\n }\n }\n\n if (schema instanceof z.ZodReadonly || 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// Deferred to a microtask so self-referential DTOs (`lazyDto<X>(() => X)`) resolve past TDZ.\nregisterOnCreate((dto) => void Promise.resolve().then(() => applySwaggerDecorators(dto)));\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\n// `z.lazy(() => self)` is the only way to introduce a real cycle in a Zod schema graph.\n// Track each ZodLazy currently being walked so we can break re-entry without overflowing.\nconst lazyInProgress = new Set<z.ZodLazy>();\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.ZodLazy) {\n // `z.lazy(() => self)` is the only way Zod schemas can carry an actual cycle.\n // Track each ZodLazy instance currently being walked; on re-entry, emit a $ref\n // back to the DTO that the lazy resolves to (if any), or a permissive `{}` as a\n // last resort for anonymous self-referential trees.\n if (lazyInProgress.has(schema)) {\n const inner = schema.unwrap();\n if (isZodDtoClass(inner)) return { so: { oneOf: refs(inner) }, selfRequired: true, innerSchemas: new Set([inner]) };\n\n return leaf({});\n }\n lazyInProgress.add(schema);\n try {\n return applySwaggerDecorators(schema.unwrap());\n } finally {\n lazyInProgress.delete(schema);\n }\n }\n\n if (schema instanceof z.ZodReadonly || 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 // Zod's `iso.datetime()` reports `format: 'datetime'`; OpenAPI/JSON Schema spell it `date-time`.\n so.format = fmt === 'datetime' ? 'date-time' : 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 { formatZodIssues, isZodDtoClass } 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 const result = metatype.safeParse(value);\n if (!result.success) {\n throw this.createError(formatZodIssues(result.error.issues));\n }\n\n return result.data;\n }\n}\n"],"mappings":"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","names":["isZodDtoClass","isZodDtoClass"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voznov/zod-dto-nestjs",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
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.2.
|
|
51
|
+
"@voznov/zod-dto": "^0.2.3"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public"
|