From 3d7cd833c73068dbad7501c8424296e3c6272b9f Mon Sep 17 00:00:00 2001 From: Nick DeGroot <1966472+nickthegroot@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:39:05 -0700 Subject: [PATCH] :bug: Fix #599: add lazy support for potential self-referential types also include unit tests --- example/myzod/schemas.ts | 2 +- example/valibot/schemas.ts | 2 +- example/yup/schemas.ts | 2 +- example/zod/schemas.ts | 2 +- src/myzod/index.ts | 22 +++++++++++++--------- src/valibot/index.ts | 19 +++++++++++-------- src/yup/index.ts | 23 +++++++++++++---------- src/zod/index.ts | 22 +++++++++++++--------- tests/myzod.spec.ts | 20 ++++++++++---------- tests/valibot.spec.ts | 18 +++++++++--------- tests/yup.spec.ts | 24 ++++++++++++------------ tests/zod.spec.ts | 20 ++++++++++---------- 12 files changed, 95 insertions(+), 81 deletions(-) diff --git a/example/myzod/schemas.ts b/example/myzod/schemas.ts index 68c8623d..3a47f823 100644 --- a/example/myzod/schemas.ts +++ b/example/myzod/schemas.ts @@ -120,7 +120,7 @@ export function UserSchema(): myzod.Type { createdAt: definedNonNullAnySchema.optional().nullable(), email: myzod.string().optional().nullable(), id: myzod.string().optional().nullable(), - kind: UserKindSchema().optional().nullable(), + kind: myzod.lazy(() => UserKindSchema().optional().nullable()), name: myzod.string().optional().nullable(), password: myzod.string().optional().nullable(), updatedAt: definedNonNullAnySchema.optional().nullable() diff --git a/example/valibot/schemas.ts b/example/valibot/schemas.ts index 14c8bac1..dbc09340 100644 --- a/example/valibot/schemas.ts +++ b/example/valibot/schemas.ts @@ -118,7 +118,7 @@ export function UserSchema(): v.GenericSchema { createdAt: v.nullish(v.any()), email: v.nullish(v.string()), id: v.nullish(v.string()), - kind: v.nullish(UserKindSchema()), + kind: v.lazy(() => v.nullish(UserKindSchema())), name: v.nullish(v.string()), password: v.nullish(v.string()), updatedAt: v.nullish(v.any()) diff --git a/example/yup/schemas.ts b/example/yup/schemas.ts index abc049aa..d78a3abd 100644 --- a/example/yup/schemas.ts +++ b/example/yup/schemas.ts @@ -124,7 +124,7 @@ export function UserSchema(): yup.ObjectSchema { createdAt: yup.mixed().nullable().optional(), email: yup.string().defined().nullable().optional(), id: yup.string().defined().nullable().optional(), - kind: UserKindSchema().nullable().optional(), + kind: yup.lazy(() => UserKindSchema().nullable()).optional(), name: yup.string().defined().nullable().optional(), password: yup.string().defined().nullable().optional(), updatedAt: yup.mixed().nullable().optional() diff --git a/example/zod/schemas.ts b/example/zod/schemas.ts index 407e3895..7bd0aef7 100644 --- a/example/zod/schemas.ts +++ b/example/zod/schemas.ts @@ -128,7 +128,7 @@ export function UserSchema(): z.ZodObject> { createdAt: definedNonNullAnySchema.nullish(), email: z.string().nullish(), id: z.string().nullish(), - kind: UserKindSchema().nullish(), + kind: z.lazy(() => UserKindSchema().nullish()), name: z.string().nullish(), password: z.string().nullish(), updatedAt: definedNonNullAnySchema.nullish() diff --git a/src/myzod/index.ts b/src/myzod/index.ts index 4a9e5778..bfbb706a 100644 --- a/src/myzod/index.ts +++ b/src/myzod/index.ts @@ -16,13 +16,14 @@ import type { Visitor } from '../visitor.js'; import { resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers'; import { convertNameParts, DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common'; import { + isEnumType, + isScalarType, Kind, } from 'graphql'; import { buildApi, formatDirectiveConfig } from '../directive.js'; import { escapeGraphQLCharacters, InterfaceTypeDefinitionBuilder, - isInput, isListType, isNamedType, isNonNullType, @@ -262,22 +263,22 @@ export class MyZodSchemaVisitor extends BaseSchemaVisitor { function generateFieldMyZodSchema(config: ValidationSchemaPluginConfig, visitor: Visitor, field: InputValueDefinitionNode | FieldDefinitionNode, indentCount: number): string { const gen = generateFieldTypeMyZodSchema(config, visitor, field, field.type); - return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount); + return indent(`${field.name.value}: ${maybeLazy(visitor, field.type, gen)}`, indentCount); } function generateFieldTypeMyZodSchema(config: ValidationSchemaPluginConfig, visitor: Visitor, field: InputValueDefinitionNode | FieldDefinitionNode, type: TypeNode, parentType?: TypeNode): string { if (isListType(type)) { const gen = generateFieldTypeMyZodSchema(config, visitor, field, type.type, type); if (!isNonNullType(parentType)) { - const arrayGen = `myzod.array(${maybeLazy(type.type, gen)})`; + const arrayGen = `myzod.array(${maybeLazy(visitor, type.type, gen)})`; const maybeLazyGen = applyDirectives(config, field, arrayGen); return `${maybeLazyGen}.optional().nullable()`; } - return `myzod.array(${maybeLazy(type.type, gen)})`; + return `myzod.array(${maybeLazy(visitor, type.type, gen)})`; } if (isNonNullType(type)) { const gen = generateFieldTypeMyZodSchema(config, visitor, field, type.type, type); - return maybeLazy(type.type, gen); + return maybeLazy(visitor, type.type, gen); } if (isNamedType(type)) { const gen = generateNameNodeMyZodSchema(config, visitor, type.name); @@ -358,11 +359,14 @@ function generateNameNodeMyZodSchema(config: ValidationSchemaPluginConfig, visit } } -function maybeLazy(type: TypeNode, schema: string): string { - if (isNamedType(type) && isInput(type.name.value)) - return `myzod.lazy(() => ${schema})`; +function maybeLazy(visitor: Visitor, type: TypeNode, schema: string): string { + if (!isNamedType(type)) { + return schema; + } - return schema; + const schemaType = visitor.getType(type.name.value); + const isComplexType = !isScalarType(schemaType) && !isEnumType(schemaType); + return isComplexType ? `myzod.lazy(() => ${schema})` : schema; } function myzod4Scalar(config: ValidationSchemaPluginConfig, visitor: Visitor, scalarName: string): string { diff --git a/src/valibot/index.ts b/src/valibot/index.ts index 7b9671ba..76408d17 100644 --- a/src/valibot/index.ts +++ b/src/valibot/index.ts @@ -10,6 +10,7 @@ import type { TypeNode, UnionTypeDefinitionNode, } from 'graphql'; +import { isEnumType, isScalarType } from 'graphql'; import type { ValidationSchemaPluginConfig } from '../config.js'; import type { Visitor } from '../visitor.js'; @@ -17,7 +18,6 @@ import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common import { buildApiForValibot, formatDirectiveConfig } from '../directive.js'; import { InterfaceTypeDefinitionBuilder, - isInput, isListType, isNamedType, isNonNullType, @@ -205,13 +205,13 @@ export class ValibotSchemaVisitor extends BaseSchemaVisitor { function generateFieldValibotSchema(config: ValidationSchemaPluginConfig, visitor: Visitor, field: InputValueDefinitionNode | FieldDefinitionNode, indentCount: number): string { const gen = generateFieldTypeValibotSchema(config, visitor, field, field.type); - return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount); + return indent(`${field.name.value}: ${maybeLazy(visitor, field.type, gen)}`, indentCount); } function generateFieldTypeValibotSchema(config: ValidationSchemaPluginConfig, visitor: Visitor, field: InputValueDefinitionNode | FieldDefinitionNode, type: TypeNode, parentType?: TypeNode): string { if (isListType(type)) { const gen = generateFieldTypeValibotSchema(config, visitor, field, type.type, type); - const arrayGen = `v.array(${maybeLazy(type.type, gen)})`; + const arrayGen = `v.array(${maybeLazy(visitor, type.type, gen)})`; if (!isNonNullType(parentType)) return `v.nullish(${arrayGen})`; @@ -219,7 +219,7 @@ function generateFieldTypeValibotSchema(config: ValidationSchemaPluginConfig, vi } if (isNonNullType(type)) { const gen = generateFieldTypeValibotSchema(config, visitor, field, type.type, type); - return maybeLazy(type.type, gen); + return maybeLazy(visitor, type.type, gen); } if (isNamedType(type)) { const gen = generateNameNodeValibotSchema(config, visitor, type.name); @@ -283,11 +283,14 @@ function generateNameNodeValibotSchema(config: ValidationSchemaPluginConfig, vis } } -function maybeLazy(type: TypeNode, schema: string): string { - if (isNamedType(type) && isInput(type.name.value)) - return `v.lazy(() => ${schema})`; +function maybeLazy(visitor: Visitor, type: TypeNode, schema: string): string { + if (!isNamedType(type)) { + return schema; + } - return schema; + const schemaType = visitor.getType(type.name.value); + const isComplexType = !isScalarType(schemaType) && !isEnumType(schemaType); + return isComplexType ? `v.lazy(() => ${schema})` : schema; } function valibot4Scalar(config: ValidationSchemaPluginConfig, visitor: Visitor, scalarName: string): string { diff --git a/src/yup/index.ts b/src/yup/index.ts index 7370e9ea..46aa9482 100644 --- a/src/yup/index.ts +++ b/src/yup/index.ts @@ -16,13 +16,14 @@ import type { Visitor } from '../visitor.js'; import { resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers'; import { convertNameParts, DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common'; import { + isEnumType, + isScalarType, Kind, } from 'graphql'; import { buildApi, formatDirectiveConfig } from '../directive.js'; import { escapeGraphQLCharacters, InterfaceTypeDefinitionBuilder, - isInput, isListType, isNamedType, isNonNullType, @@ -324,20 +325,20 @@ function generateFieldYupSchema(config: ValidationSchemaPluginConfig, visitor: V const formatted = formatDirectiveConfig(config.directives); gen += buildApi(formatted, field.directives); } - return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount); + return indent(`${field.name.value}: ${maybeLazy(visitor, field.type, gen)}`, indentCount); } function generateFieldTypeYupSchema(config: ValidationSchemaPluginConfig, visitor: Visitor, type: TypeNode, parentType?: TypeNode): string { if (isListType(type)) { const gen = generateFieldTypeYupSchema(config, visitor, type.type, type); if (!isNonNullType(parentType)) - return `yup.array(${maybeLazy(type.type, gen)}).defined().nullable()`; + return `yup.array(${maybeLazy(visitor, type.type, gen)}).defined().nullable()`; - return `yup.array(${maybeLazy(type.type, gen)}).defined()`; + return `yup.array(${maybeLazy(visitor, type.type, gen)}).defined()`; } if (isNonNullType(type)) { const gen = generateFieldTypeYupSchema(config, visitor, type.type, type); - return maybeLazy(type.type, gen); + return maybeLazy(visitor, type.type, gen); } if (isNamedType(type)) { const gen = generateNameNodeYupSchema(config, visitor, type.name); @@ -380,12 +381,14 @@ function generateNameNodeYupSchema(config: ValidationSchemaPluginConfig, visitor } } -function maybeLazy(type: TypeNode, schema: string): string { - if (isNamedType(type) && isInput(type.name.value)) { - // https://github.com/jquense/yup/issues/1283#issuecomment-786559444 - return `yup.lazy(() => ${schema})`; +function maybeLazy(visitor: Visitor, type: TypeNode, schema: string): string { + if (!isNamedType(type)) { + return schema; } - return schema; + + const schemaType = visitor.getType(type.name.value); + const isComplexType = !isScalarType(schemaType) && !isEnumType(schemaType); + return isComplexType ? `yup.lazy(() => ${schema})` : schema; } function yup4Scalar(config: ValidationSchemaPluginConfig, visitor: Visitor, scalarName: string): string { diff --git a/src/zod/index.ts b/src/zod/index.ts index fc77e16d..ecc85eb8 100644 --- a/src/zod/index.ts +++ b/src/zod/index.ts @@ -16,13 +16,14 @@ import type { Visitor } from '../visitor.js'; import { resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers'; import { convertNameParts, DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common'; import { + isEnumType, + isScalarType, Kind, } from 'graphql'; import { buildApi, formatDirectiveConfig } from '../directive.js'; import { escapeGraphQLCharacters, InterfaceTypeDefinitionBuilder, - isInput, isListType, isNamedType, isNonNullType, @@ -278,22 +279,22 @@ export class ZodSchemaVisitor extends BaseSchemaVisitor { function generateFieldZodSchema(config: ValidationSchemaPluginConfig, visitor: Visitor, field: InputValueDefinitionNode | FieldDefinitionNode, indentCount: number): string { const gen = generateFieldTypeZodSchema(config, visitor, field, field.type); - return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount); + return indent(`${field.name.value}: ${maybeLazy(visitor, field.type, gen)}`, indentCount); } function generateFieldTypeZodSchema(config: ValidationSchemaPluginConfig, visitor: Visitor, field: InputValueDefinitionNode | FieldDefinitionNode, type: TypeNode, parentType?: TypeNode): string { if (isListType(type)) { const gen = generateFieldTypeZodSchema(config, visitor, field, type.type, type); if (!isNonNullType(parentType)) { - const arrayGen = `z.array(${maybeLazy(type.type, gen)})`; + const arrayGen = `z.array(${maybeLazy(visitor, type.type, gen)})`; const maybeLazyGen = applyDirectives(config, field, arrayGen); return `${maybeLazyGen}.nullish()`; } - return `z.array(${maybeLazy(type.type, gen)})`; + return `z.array(${maybeLazy(visitor, type.type, gen)})`; } if (isNonNullType(type)) { const gen = generateFieldTypeZodSchema(config, visitor, field, type.type, type); - return maybeLazy(type.type, gen); + return maybeLazy(visitor, type.type, gen); } if (isNamedType(type)) { const gen = generateNameNodeZodSchema(config, visitor, type.name); @@ -374,11 +375,14 @@ function generateNameNodeZodSchema(config: ValidationSchemaPluginConfig, visitor } } -function maybeLazy(type: TypeNode, schema: string): string { - if (isNamedType(type) && isInput(type.name.value)) - return `z.lazy(() => ${schema})`; +function maybeLazy(visitor: Visitor, type: TypeNode, schema: string): string { + if (!isNamedType(type)) { + return schema; + } - return schema; + const schemaType = visitor.getType(type.name.value); + const isComplexType = !isScalarType(schemaType) && !isEnumType(schemaType); + return isComplexType ? `z.lazy(() => ${schema})` : schema; } function zod4Scalar(config: ValidationSchemaPluginConfig, visitor: Visitor, scalarName: string): string { diff --git a/tests/myzod.spec.ts b/tests/myzod.spec.ts index 56b003e2..c3cae26e 100644 --- a/tests/myzod.spec.ts +++ b/tests/myzod.spec.ts @@ -830,7 +830,7 @@ describe('myzod', () => { export function BookSchema(): myzod.Type { return myzod.object({ __typename: myzod.literal('Book').optional(), - author: AuthorSchema().optional().nullable(), + author: myzod.lazy(() => AuthorSchema().optional().nullable()), title: myzod.string().optional().nullable() }) } @@ -838,7 +838,7 @@ describe('myzod', () => { export function AuthorSchema(): myzod.Type { return myzod.object({ __typename: myzod.literal('Author').optional(), - books: myzod.array(BookSchema().nullable()).optional().nullable(), + books: myzod.array(myzod.lazy(() => BookSchema().nullable())).optional().nullable(), name: myzod.string().optional().nullable() }) } @@ -1075,7 +1075,7 @@ describe('myzod', () => { export function GeometrySchema(): myzod.Type { return myzod.object({ __typename: myzod.literal('Geometry').optional(), - shape: ShapeSchema().optional().nullable() + shape: myzod.lazy(() => ShapeSchema().optional().nullable()) }) } " @@ -1196,7 +1196,7 @@ describe('myzod', () => { export const GeometrySchema: myzod.Type = myzod.object({ __typename: myzod.literal('Geometry').optional(), - shape: ShapeSchema.optional().nullable() + shape: myzod.lazy(() => ShapeSchema.optional().nullable()) }); " `) @@ -1317,14 +1317,14 @@ describe('myzod', () => { " export function BookSchema(): myzod.Type { return myzod.object({ - author: AuthorSchema().optional().nullable(), + author: myzod.lazy(() => AuthorSchema().optional().nullable()), title: myzod.string().optional().nullable() }) } export function AuthorSchema(): myzod.Type { return myzod.object({ - books: myzod.array(BookSchema().nullable()).optional().nullable(), + books: myzod.array(myzod.lazy(() => BookSchema().nullable())).optional().nullable(), name: myzod.string().optional().nullable() }) } @@ -1369,7 +1369,7 @@ describe('myzod', () => { export function BookSchema(): myzod.Type { return myzod.object({ title: myzod.string(), - author: AuthorSchema() + author: myzod.lazy(() => AuthorSchema()) }) } @@ -1377,7 +1377,7 @@ describe('myzod', () => { return myzod.object({ __typename: myzod.literal('Textbook').optional(), title: myzod.string(), - author: AuthorSchema(), + author: myzod.lazy(() => AuthorSchema()), courses: myzod.array(myzod.string()) }) } @@ -1386,7 +1386,7 @@ describe('myzod', () => { return myzod.object({ __typename: myzod.literal('ColoringBook').optional(), title: myzod.string(), - author: AuthorSchema(), + author: myzod.lazy(() => AuthorSchema()), colors: myzod.array(myzod.string()) }) } @@ -1394,7 +1394,7 @@ describe('myzod', () => { export function AuthorSchema(): myzod.Type { return myzod.object({ __typename: myzod.literal('Author').optional(), - books: myzod.array(BookSchema()).optional().nullable(), + books: myzod.array(myzod.lazy(() => BookSchema())).optional().nullable(), name: myzod.string().optional().nullable() }) } diff --git a/tests/valibot.spec.ts b/tests/valibot.spec.ts index 3a7eadaa..70f3af3e 100644 --- a/tests/valibot.spec.ts +++ b/tests/valibot.spec.ts @@ -772,7 +772,7 @@ describe('valibot', () => { export function BookSchema(): v.GenericSchema { return v.object({ __typename: v.optional(v.literal('Book')), - author: v.nullish(AuthorSchema()), + author: v.lazy(() => v.nullish(AuthorSchema())), title: v.nullish(v.string()) }) } @@ -780,7 +780,7 @@ describe('valibot', () => { export function AuthorSchema(): v.GenericSchema { return v.object({ __typename: v.optional(v.literal('Author')), - books: v.nullish(v.array(v.nullable(BookSchema()))), + books: v.nullish(v.array(v.lazy(() => v.nullable(BookSchema())))), name: v.nullish(v.string()) }) } @@ -1019,7 +1019,7 @@ describe('valibot', () => { export function GeometrySchema(): v.GenericSchema { return v.object({ __typename: v.optional(v.literal('Geometry')), - shape: v.nullish(ShapeSchema()) + shape: v.lazy(() => v.nullish(ShapeSchema())) }) } " @@ -1209,14 +1209,14 @@ describe('valibot', () => { export function BookSchema(): v.GenericSchema { return v.object({ - author: v.nullish(AuthorSchema()), + author: v.lazy(() => v.nullish(AuthorSchema())), title: v.nullish(v.string()) }) } export function AuthorSchema(): v.GenericSchema { return v.object({ - books: v.nullish(v.array(v.nullable(BookSchema()))), + books: v.nullish(v.array(v.lazy(() => v.nullable(BookSchema())))), name: v.nullish(v.string()) }) } @@ -1262,7 +1262,7 @@ describe('valibot', () => { export function BookSchema(): v.GenericSchema { return v.object({ title: v.string(), - author: AuthorSchema() + author: v.lazy(() => AuthorSchema()) }) } @@ -1270,7 +1270,7 @@ describe('valibot', () => { return v.object({ __typename: v.optional(v.literal('Textbook')), title: v.string(), - author: AuthorSchema(), + author: v.lazy(() => AuthorSchema()), courses: v.array(v.string()) }) } @@ -1279,7 +1279,7 @@ describe('valibot', () => { return v.object({ __typename: v.optional(v.literal('ColoringBook')), title: v.string(), - author: AuthorSchema(), + author: v.lazy(() => AuthorSchema()), colors: v.array(v.string()) }) } @@ -1287,7 +1287,7 @@ describe('valibot', () => { export function AuthorSchema(): v.GenericSchema { return v.object({ __typename: v.optional(v.literal('Author')), - books: v.nullish(v.array(BookSchema())), + books: v.nullish(v.array(v.lazy(() => BookSchema()))), name: v.nullish(v.string()) }) } diff --git a/tests/yup.spec.ts b/tests/yup.spec.ts index 982d7407..38aea731 100644 --- a/tests/yup.spec.ts +++ b/tests/yup.spec.ts @@ -760,7 +760,7 @@ describe('yup', () => { export function BookSchema(): yup.ObjectSchema { return yup.object({ __typename: yup.string<'Book'>().optional(), - author: AuthorSchema().nullable().optional(), + author: yup.lazy(() => AuthorSchema().nullable()).optional(), title: yup.string().defined().nullable().optional() }) } @@ -768,7 +768,7 @@ describe('yup', () => { export function Book2Schema(): yup.ObjectSchema { return yup.object({ __typename: yup.string<'Book2'>().optional(), - author: AuthorSchema().nonNullable(), + author: yup.lazy(() => AuthorSchema().nonNullable()), title: yup.string().defined().nonNullable() }) } @@ -776,7 +776,7 @@ describe('yup', () => { export function AuthorSchema(): yup.ObjectSchema { return yup.object({ __typename: yup.string<'Author'>().optional(), - books: yup.array(BookSchema().nullable()).defined().nullable().optional(), + books: yup.array(yup.lazy(() => BookSchema().nullable())).defined().nullable().optional(), name: yup.string().defined().nullable().optional() }) } @@ -991,7 +991,7 @@ describe('yup', () => { export function GeometrySchema(): yup.ObjectSchema { return yup.object({ __typename: yup.string<'Geometry'>().optional(), - shape: ShapeSchema().nullable().optional() + shape: yup.lazy(() => ShapeSchema().nullable()).optional() }) } " @@ -1132,7 +1132,7 @@ describe('yup', () => { export const GeometrySchema: yup.ObjectSchema = yup.object({ __typename: yup.string<'Geometry'>().optional(), - shape: ShapeSchema.nullable().optional() + shape: yup.lazy(() => ShapeSchema.nullable()).optional() }); " `) @@ -1280,21 +1280,21 @@ describe('yup', () => { export function BookSchema(): yup.ObjectSchema { return yup.object({ - author: AuthorSchema().nullable().optional(), + author: yup.lazy(() => AuthorSchema().nullable()).optional(), title: yup.string().defined().nullable().optional() }) } export function Book2Schema(): yup.ObjectSchema { return yup.object({ - author: AuthorSchema().nonNullable(), + author: yup.lazy(() => AuthorSchema().nonNullable()), title: yup.string().defined().nonNullable() }) } export function AuthorSchema(): yup.ObjectSchema { return yup.object({ - books: yup.array(BookSchema().nullable()).defined().nullable().optional(), + books: yup.array(yup.lazy(() => BookSchema().nullable())).defined().nullable().optional(), name: yup.string().defined().nullable().optional() }) } @@ -1349,7 +1349,7 @@ describe('yup', () => { export function BookSchema(): yup.ObjectSchema { return yup.object({ title: yup.string().defined().nonNullable(), - author: AuthorSchema().nonNullable() + author: yup.lazy(() => AuthorSchema().nonNullable()) }) } @@ -1357,7 +1357,7 @@ describe('yup', () => { return yup.object({ __typename: yup.string<'Textbook'>().optional(), title: yup.string().defined().nonNullable(), - author: AuthorSchema().nonNullable(), + author: yup.lazy(() => AuthorSchema().nonNullable()), courses: yup.array(yup.string().defined().nonNullable()).defined() }) } @@ -1366,7 +1366,7 @@ describe('yup', () => { return yup.object({ __typename: yup.string<'ColoringBook'>().optional(), title: yup.string().defined().nonNullable(), - author: AuthorSchema().nonNullable(), + author: yup.lazy(() => AuthorSchema().nonNullable()), colors: yup.array(yup.string().defined().nonNullable()).defined() }) } @@ -1374,7 +1374,7 @@ describe('yup', () => { export function AuthorSchema(): yup.ObjectSchema { return yup.object({ __typename: yup.string<'Author'>().optional(), - books: yup.array(BookSchema().nonNullable()).defined().nullable().optional(), + books: yup.array(yup.lazy(() => BookSchema().nonNullable())).defined().nullable().optional(), name: yup.string().defined().nullable().optional() }) } diff --git a/tests/zod.spec.ts b/tests/zod.spec.ts index 53e451ed..cb75e13a 100644 --- a/tests/zod.spec.ts +++ b/tests/zod.spec.ts @@ -1056,7 +1056,7 @@ describe('zod', () => { export function BookSchema(): z.ZodObject> { return z.object({ __typename: z.literal('Book').optional(), - author: AuthorSchema().nullish(), + author: z.lazy(() => AuthorSchema().nullish()), title: z.string().nullish() }) } @@ -1064,7 +1064,7 @@ describe('zod', () => { export function AuthorSchema(): z.ZodObject> { return z.object({ __typename: z.literal('Author').optional(), - books: z.array(BookSchema().nullable()).nullish(), + books: z.array(z.lazy(() => BookSchema().nullable())).nullish(), name: z.string().nullish() }) } @@ -1301,7 +1301,7 @@ describe('zod', () => { export function GeometrySchema(): z.ZodObject> { return z.object({ __typename: z.literal('Geometry').optional(), - shape: ShapeSchema().nullish() + shape: z.lazy(() => ShapeSchema().nullish()) }) } " @@ -1422,7 +1422,7 @@ describe('zod', () => { export const GeometrySchema: z.ZodObject> = z.object({ __typename: z.literal('Geometry').optional(), - shape: ShapeSchema.nullish() + shape: z.lazy(() => ShapeSchema.nullish()) }); " `) @@ -1544,14 +1544,14 @@ describe('zod', () => { " export function BookSchema(): z.ZodObject> { return z.object({ - author: AuthorSchema().nullish(), + author: z.lazy(() => AuthorSchema().nullish()), title: z.string().nullish() }) } export function AuthorSchema(): z.ZodObject> { return z.object({ - books: z.array(BookSchema().nullable()).nullish(), + books: z.array(z.lazy(() => BookSchema().nullable())).nullish(), name: z.string().nullish() }) } @@ -1597,7 +1597,7 @@ describe('zod', () => { export function BookSchema(): z.ZodObject> { return z.object({ title: z.string(), - author: AuthorSchema() + author: z.lazy(() => AuthorSchema()) }) } @@ -1605,7 +1605,7 @@ describe('zod', () => { return z.object({ __typename: z.literal('Textbook').optional(), title: z.string(), - author: AuthorSchema(), + author: z.lazy(() => AuthorSchema()), courses: z.array(z.string()) }) } @@ -1614,7 +1614,7 @@ describe('zod', () => { return z.object({ __typename: z.literal('ColoringBook').optional(), title: z.string(), - author: AuthorSchema(), + author: z.lazy(() => AuthorSchema()), colors: z.array(z.string()) }) } @@ -1622,7 +1622,7 @@ describe('zod', () => { export function AuthorSchema(): z.ZodObject> { return z.object({ __typename: z.literal('Author').optional(), - books: z.array(BookSchema()).nullish(), + books: z.array(z.lazy(() => BookSchema())).nullish(), name: z.string().nullish() }) }