diff --git a/example/myzod/schemas.ts b/example/myzod/schemas.ts index 36b9d2b7..2690d0ea 100644 --- a/example/myzod/schemas.ts +++ b/example/myzod/schemas.ts @@ -1,5 +1,5 @@ import * as myzod from 'myzod' -import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User } from '../types' +import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, InnerType, LayoutInput, OuterType, PageInput, PageType, User } from '../types' export const definedNonNullAnySchema = myzod.object({}); @@ -68,12 +68,26 @@ export function HttpInputSchema(): myzod.Type { export const HttpMethodSchema = myzod.enum(HttpMethod); +export function InnerTypeSchema(): myzod.Type { + return myzod.object({ + __typename: myzod.literal('InnerType').optional(), + testScalar: definedNonNullAnySchema + }) +} + export function LayoutInputSchema(): myzod.Type { return myzod.object({ dropdown: myzod.lazy(() => DropDownComponentInputSchema().optional().nullable()) }) } +export function OuterTypeSchema(): myzod.Type { + return myzod.object({ + __typename: myzod.literal('OuterType').optional(), + inner: InnerTypeSchema().optional().nullable() + }) +} + export function PageInputSchema(): myzod.Type { return myzod.object({ attributes: myzod.array(myzod.lazy(() => AttributeInputSchema())).optional().nullable(), diff --git a/example/test.graphql b/example/test.graphql index 62450491..622f772f 100644 --- a/example/test.graphql +++ b/example/test.graphql @@ -15,6 +15,16 @@ type Guest { union UserKind = Admin | Guest +type InnerType { + testScalar: MyScalar! +} + +type OuterType { + inner: InnerType +} + +scalar MyScalar + type User { id: ID name: String diff --git a/example/types.ts b/example/types.ts index f8f3f610..fe9e83a7 100644 --- a/example/types.ts +++ b/example/types.ts @@ -13,6 +13,7 @@ export type Scalars = { Int: { input: number; output: number; } Float: { input: number; output: number; } Date: { input: any; output: any; } + MyScalar: { input: any; output: any; } URL: { input: any; output: any; } }; @@ -74,10 +75,20 @@ export enum HttpMethod { Post = 'POST' } +export type InnerType = { + __typename?: 'InnerType'; + testScalar: Scalars['MyScalar']['output']; +}; + export type LayoutInput = { dropdown?: InputMaybe; }; +export type OuterType = { + __typename?: 'OuterType'; + inner?: Maybe; +}; + export type PageInput = { attributes?: InputMaybe>; date?: InputMaybe; diff --git a/example/yup/schemas.ts b/example/yup/schemas.ts index 240f426c..2e8bd6dd 100644 --- a/example/yup/schemas.ts +++ b/example/yup/schemas.ts @@ -1,5 +1,5 @@ import * as yup from 'yup' -import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User, UserKind } from '../types' +import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, InnerType, LayoutInput, OuterType, PageInput, PageType, User, UserKind } from '../types' function union(...schemas: ReadonlyArray>): yup.MixedSchema { return yup.mixed().test({ @@ -7,11 +7,11 @@ function union(...schemas: ReadonlyArray>): yup.Mixe }).defined() } -export function AdminSchema(): yup.ObjectSchema { +export function AdminSchema(): yup.Schema { return yup.object({ __typename: yup.string<'Admin'>().optional(), lastModifiedAt: yup.mixed().nullable().optional() - }) + }) satisfies yup.ObjectSchema } export function AttributeInputSchema(): yup.ObjectSchema { @@ -56,11 +56,11 @@ export function EventInputSchema(): yup.ObjectSchema { export const EventOptionTypeSchema = yup.string().oneOf([EventOptionType.Reload, EventOptionType.Retry]).defined(); -export function GuestSchema(): yup.ObjectSchema { +export function GuestSchema(): yup.Schema { return yup.object({ __typename: yup.string<'Guest'>().optional(), lastLoggedIn: yup.mixed().nullable().optional() - }) + }) satisfies yup.ObjectSchema } export function HttpInputSchema(): yup.ObjectSchema { @@ -72,12 +72,26 @@ export function HttpInputSchema(): yup.ObjectSchema { export const HttpMethodSchema = yup.string().oneOf([HttpMethod.Get, HttpMethod.Post]).defined(); +export function InnerTypeSchema(): yup.Schema { + return yup.object({ + __typename: yup.string<'InnerType'>().optional(), + testScalar: yup.mixed().nonNullable() + }) satisfies yup.ObjectSchema +} + export function LayoutInputSchema(): yup.ObjectSchema { return yup.object({ dropdown: yup.lazy(() => DropDownComponentInputSchema()).optional() }) } +export function OuterTypeSchema(): yup.Schema { + return yup.object({ + __typename: yup.string<'OuterType'>().optional(), + inner: InnerTypeSchema().nullable().optional() + }) satisfies yup.ObjectSchema +} + export function PageInputSchema(): yup.ObjectSchema { return yup.object({ attributes: yup.array(yup.lazy(() => AttributeInputSchema().nonNullable())).defined().nullable().optional(), @@ -96,7 +110,7 @@ export function PageInputSchema(): yup.ObjectSchema { export const PageTypeSchema = yup.string().oneOf([PageType.BasicAuth, PageType.Lp, PageType.Restricted, PageType.Service]).defined(); -export function UserSchema(): yup.ObjectSchema { +export function UserSchema(): yup.Schema { return yup.object({ __typename: yup.string<'User'>().optional(), createdAt: yup.mixed().nullable().optional(), @@ -106,7 +120,7 @@ export function UserSchema(): yup.ObjectSchema { name: yup.string().defined().nullable().optional(), password: yup.string().defined().nullable().optional(), updatedAt: yup.mixed().nullable().optional() - }) + }) satisfies yup.ObjectSchema } export function UserKindSchema(): yup.MixedSchema { diff --git a/example/zod/schemas.ts b/example/zod/schemas.ts index 3b294d28..1877a1f2 100644 --- a/example/zod/schemas.ts +++ b/example/zod/schemas.ts @@ -1,5 +1,5 @@ import { z } from 'zod' -import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User } from '../types' +import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, InnerType, LayoutInput, OuterType, PageInput, PageType, User } from '../types' type Properties = Required<{ [K in keyof T]: z.ZodType; @@ -76,12 +76,26 @@ export function HttpInputSchema(): z.ZodObject> { export const HttpMethodSchema = z.nativeEnum(HttpMethod); +export function InnerTypeSchema(): z.ZodObject> { + return z.object>({ + __typename: z.literal('InnerType').optional(), + testScalar: definedNonNullAnySchema + }) +} + export function LayoutInputSchema(): z.ZodObject> { return z.object>({ dropdown: z.lazy(() => DropDownComponentInputSchema().nullish()) }) } +export function OuterTypeSchema(): z.ZodObject> { + return z.object>({ + __typename: z.literal('OuterType').optional(), + inner: InnerTypeSchema().nullish() + }) +} + export function PageInputSchema(): z.ZodObject> { return z.object>({ attributes: z.array(z.lazy(() => AttributeInputSchema())).nullish(), diff --git a/src/yup/index.ts b/src/yup/index.ts index fa319151..cb8c19d1 100644 --- a/src/yup/index.ts +++ b/src/yup/index.ts @@ -83,13 +83,13 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema return new DeclarationBlock({}) .export() .asKind('function') - .withName(`${name}Schema(): yup.ObjectSchema<${name}>`) + .withName(`${name}Schema(): yup.Schema`) .withBlock( [ indent(`return yup.object({`), indent(`__typename: yup.string<'${node.name.value}'>().optional(),`, 2), shape, - indent('})'), + indent(`}) satisfies yup.ObjectSchema<${name}>`), ].join('\n') ).string; }), diff --git a/tests/yup.spec.ts b/tests/yup.spec.ts index 4670fb76..125fc216 100644 --- a/tests/yup.spec.ts +++ b/tests/yup.spec.ts @@ -408,20 +408,23 @@ describe('yup', () => { {} ); const wantContains = [ - 'export function AuthorSchema(): yup.ObjectSchema {', + 'export function AuthorSchema(): yup.Schema {', "__typename: yup.string<'Author'>().optional(),", 'books: yup.array(BookSchema().nullable()).defined().nullable().optional(),', 'name: yup.string().defined().nullable().optional()', + '}) satisfies yup.ObjectSchema', - 'export function BookSchema(): yup.ObjectSchema {', + 'export function BookSchema(): yup.Schema {', "__typename: yup.string<'Book'>().optional(),", 'author: AuthorSchema().nullable().optional(),', 'title: yup.string().defined().nonNullable()', + '}) satisfies yup.ObjectSchema', - 'export function Book2Schema(): yup.ObjectSchema {', + 'export function Book2Schema(): yup.Schema {', "__typename: yup.string<'Book2'>().optional(),", 'author: AuthorSchema().nonNullable(),', 'title: yup.string().defined().nullable().optional()', + '}) satisfies yup.ObjectSchema', ]; for (const wantContain of wantContains) { expect(result.content).toContain(wantContain); @@ -497,7 +500,7 @@ describe('yup', () => { 'updateInputId: yup.number().defined().nonNullable(),', 'updateName: yup.string().defined().nonNullable()', // User - 'export function UserSchema(): yup.ObjectSchema {', + 'export function UserSchema(): yup.Schema {', "__typename: yup.string<'User'>().optional(),", 'id: yup.string().defined().nonNullable(),', 'name: yup.string().defined().nullable().optional(),', @@ -505,6 +508,7 @@ describe('yup', () => { 'isMember: yup.boolean().defined().nullable().optional(),', 'email: yup.string().email().defined().nullable().optional(),', 'createdAt: yup.date().defined().nonNullable()', + '}) satisfies yup.ObjectSchema', ]; for (const wantContain of wantContains) { expect(result.content).toContain(wantContain); @@ -573,11 +577,11 @@ describe('yup', () => { ); const wantContains = [ - 'export function GeometrySchema(): yup.ObjectSchema {', + 'export function GeometrySchema(): yup.Schema {', 'return yup.object({', "__typename: yup.string<'Geometry'>().optional(),", 'shape: ShapeSchema().nullable().optional()', - '})', + '}) satisfies yup.ObjectSchema', ]; for (const wantContain of wantContains) { expect(result.content).toContain(wantContain);