From 92cc4508e8e2e4cae3f09d27829c8c561be723f3 Mon Sep 17 00:00:00 2001 From: Alexander Galabov Date: Fri, 6 Dec 2024 14:02:32 +0200 Subject: [PATCH 1/2] handle instance of and custom required fields --- spec/modifiers/custom.spec.ts | 44 +++++++++++++++++++++++++++++++ spec/modifiers/instanceof.spec.ts | 42 +++++++++++++++++++++++++++++ spec/modifiers/refine.spec.ts | 2 +- src/metadata.ts | 4 --- 4 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 spec/modifiers/custom.spec.ts create mode 100644 spec/modifiers/instanceof.spec.ts diff --git a/spec/modifiers/custom.spec.ts b/spec/modifiers/custom.spec.ts new file mode 100644 index 0000000..c27799c --- /dev/null +++ b/spec/modifiers/custom.spec.ts @@ -0,0 +1,44 @@ +import { z } from 'zod'; +import { expectSchema } from '../lib/helpers'; + +describe('custom', () => { + it('generates OpenAPI schema for custom type', () => { + const FileSchema = z + .custom(target => target instanceof File) + .openapi({ + type: 'string', + format: 'binary', + }) + .openapi('File'); + + expectSchema([FileSchema], { + File: { + type: 'string', + format: 'binary', + }, + }); + }); + + it('generates OpenAPI schema for custom type in object', () => { + const FileUploadSchema = z + .object({ + file: z + .custom(target => target instanceof File) + .openapi({ + type: 'string', + format: 'binary', + }), + }) + .openapi('FileUpload'); + + expectSchema([FileUploadSchema], { + FileUpload: { + type: 'object', + properties: { + file: { type: 'string', format: 'binary' }, + }, + required: ['file'], + }, + }); + }); +}); diff --git a/spec/modifiers/instanceof.spec.ts b/spec/modifiers/instanceof.spec.ts new file mode 100644 index 0000000..9c85f7d --- /dev/null +++ b/spec/modifiers/instanceof.spec.ts @@ -0,0 +1,42 @@ +import { z } from 'zod'; +import { expectSchema } from '../lib/helpers'; + +describe('instanceof', () => { + it('generates OpenAPI schema for instanceof type', () => { + const FileSchema = z + .instanceof(File) + .openapi({ + type: 'string', + format: 'binary', + }) + .openapi('File'); + + expectSchema([FileSchema], { + File: { + type: 'string', + format: 'binary', + }, + }); + }); + + it('generates OpenAPI schema for instanceof type in object', () => { + const FileUploadSchema = z + .object({ + file: z.instanceof(File).openapi({ + type: 'string', + format: 'binary', + }), + }) + .openapi('FileUpload'); + + expectSchema([FileUploadSchema], { + FileUpload: { + type: 'object', + properties: { + file: { type: 'string', format: 'binary' }, + }, + required: ['file'], + }, + }); + }); +}); diff --git a/spec/modifiers/refine.spec.ts b/spec/modifiers/refine.spec.ts index 739455c..b451200 100644 --- a/spec/modifiers/refine.spec.ts +++ b/spec/modifiers/refine.spec.ts @@ -64,7 +64,7 @@ describe('refine', () => { [ z .object({ - test: z.onumber().refine(num => num && num % 2 === 0), + test: z.onumber().refine(num => !num || num % 2 === 0), }) .openapi('ObjectWithRefinedString'), ], diff --git a/src/metadata.ts b/src/metadata.ts index 56f264c..05f1158 100644 --- a/src/metadata.ts +++ b/src/metadata.ts @@ -151,10 +151,6 @@ export class Metadata { } static isOptionalSchema(zodSchema: ZodTypeAny): boolean { - if (isZodType(zodSchema, 'ZodEffects')) { - return this.isOptionalSchema(zodSchema._def.schema); - } - return zodSchema.isOptional(); } } From 3713bd74a7238d0e3dee752705673062f93d1922 Mon Sep 17 00:00:00 2001 From: Alexander Galabov Date: Fri, 6 Dec 2024 14:07:58 +0200 Subject: [PATCH 2/2] fix tests --- spec/modifiers/custom.spec.ts | 4 ++++ spec/modifiers/instanceof.spec.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/spec/modifiers/custom.spec.ts b/spec/modifiers/custom.spec.ts index c27799c..59547ec 100644 --- a/spec/modifiers/custom.spec.ts +++ b/spec/modifiers/custom.spec.ts @@ -1,6 +1,10 @@ import { z } from 'zod'; import { expectSchema } from '../lib/helpers'; +// File as a class is not available on older node versions +// so I am defining this just for testing purposes +class File {} + describe('custom', () => { it('generates OpenAPI schema for custom type', () => { const FileSchema = z diff --git a/spec/modifiers/instanceof.spec.ts b/spec/modifiers/instanceof.spec.ts index 9c85f7d..7fb9763 100644 --- a/spec/modifiers/instanceof.spec.ts +++ b/spec/modifiers/instanceof.spec.ts @@ -1,6 +1,10 @@ import { z } from 'zod'; import { expectSchema } from '../lib/helpers'; +// File as a class is not available on older node versions +// so I am defining this just for testing purposes +class File {} + describe('instanceof', () => { it('generates OpenAPI schema for instanceof type', () => { const FileSchema = z