From f642aff07df820b788bbed19c63c5b401c803dbe Mon Sep 17 00:00:00 2001 From: Dylan Lundy <4567380+diesal11@users.noreply.github.com> Date: Thu, 13 Mar 2025 22:47:45 +1030 Subject: [PATCH] fix(zod): Required fields with a default value should be optional --- .../schema/src/plugins/zod/transformer.ts | 12 ++++++---- tests/integration/tests/plugins/zod.test.ts | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/packages/schema/src/plugins/zod/transformer.ts b/packages/schema/src/plugins/zod/transformer.ts index 899c6c473..b8669e8e2 100644 --- a/packages/schema/src/plugins/zod/transformer.ts +++ b/packages/schema/src/plugins/zod/transformer.ts @@ -282,22 +282,24 @@ export default class Transformer { const fieldName = alternatives.some((alt) => alt.includes(':')) ? '' : ` ${field.name}:`; - const opt = !field.isRequired ? '.optional()' : ''; - let resString: string; if (alternatives.length === 1) { - resString = alternatives.join(',\r\n'); + resString = alternatives[0]; } else { if (alternatives.some((alt) => alt.includes('Unchecked'))) { // if the union is for combining checked and unchecked input types, use `smartUnion` // to parse with the best candidate at runtime - resString = this.wrapWithSmartUnion(...alternatives) + `${opt}`; + resString = this.wrapWithSmartUnion(...alternatives); } else { - resString = `z.union([${alternatives.join(',\r\n')}])${opt}`; + resString = `z.union([${alternatives.join(',\r\n')}])`; } } + if (!field.isRequired) { + resString += '.optional()'; + } + if (field.isNullable) { resString += '.nullable()'; } diff --git a/tests/integration/tests/plugins/zod.test.ts b/tests/integration/tests/plugins/zod.test.ts index 226da18f7..154101c31 100644 --- a/tests/integration/tests/plugins/zod.test.ts +++ b/tests/integration/tests/plugins/zod.test.ts @@ -1097,4 +1097,28 @@ describe('Zod plugin tests', () => { expect(schemas.UserSchema.safeParse({ id: 1, email: 'a@b.com' }).success).toBeTruthy(); expect(schemas.UserPrismaCreateSchema.safeParse({ email: 'a@b.com' }).success).toBeTruthy(); }); + + it('@json fields with @default should be optional', async () => { + const { zodSchemas } = await loadSchema( + ` + type Foo { + a String + } + + model Bar { + id Int @id @default(autoincrement()) + foo Foo @json @default("{ \\"a\\": \\"a\\" }") + fooList Foo[] @json @default("[]") + } + `, + { + fullZod: true, + provider: 'postgresql', + pushDb: false, + } + ); + + // Ensure Zod Schemas correctly mark @default fields as optional + expect(zodSchemas.objects.BarCreateInputObjectSchema.safeParse({}).success).toBeTruthy(); + }); });