Skip to content

Commit a026ce1

Browse files
authored
Merge pull request Code-Hex#453 from Code-Hex/add/variables
implement for variables
2 parents 5ed53b5 + 7646572 commit a026ce1

File tree

12 files changed

+349
-73
lines changed

12 files changed

+349
-73
lines changed

example/myzod/schemas.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as myzod from 'myzod'
2-
import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User } from '../types'
2+
import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, MyType, MyTypeFooArgs, PageInput, PageType, User } from '../types'
33

44
export const definedNonNullAnySchema = myzod.object({});
55

@@ -76,6 +76,22 @@ export function LayoutInputSchema(): myzod.Type<LayoutInput> {
7676
})
7777
}
7878

79+
export function MyTypeSchema(): myzod.Type<MyType> {
80+
return myzod.object({
81+
__typename: myzod.literal('MyType').optional(),
82+
foo: myzod.string().optional().nullable()
83+
})
84+
}
85+
86+
export function MyTypeFooArgsSchema(): myzod.Type<MyTypeFooArgs> {
87+
return myzod.object({
88+
a: myzod.string().optional().nullable(),
89+
b: myzod.number(),
90+
c: myzod.boolean().optional().nullable(),
91+
d: myzod.number()
92+
})
93+
}
94+
7995
export function PageInputSchema(): myzod.Type<PageInput> {
8096
return myzod.object({
8197
attributes: myzod.array(myzod.lazy(() => AttributeInputSchema())).optional().nullable(),

example/test.graphql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ enum HTTPMethod {
9494
scalar Date
9595
scalar URL
9696

97+
type MyType {
98+
foo(a: String, b: Int!, c: Boolean, d: Float!): String
99+
}
100+
97101
# https://github.com/confuser/graphql-constraint-directive
98102
directive @constraint(
99103
# String constraints

example/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,19 @@ export type LayoutInput = {
7878
dropdown?: InputMaybe<DropDownComponentInput>;
7979
};
8080

81+
export type MyType = {
82+
__typename?: 'MyType';
83+
foo?: Maybe<Scalars['String']['output']>;
84+
};
85+
86+
87+
export type MyTypeFooArgs = {
88+
a?: InputMaybe<Scalars['String']['input']>;
89+
b: Scalars['Int']['input'];
90+
c?: InputMaybe<Scalars['Boolean']['input']>;
91+
d: Scalars['Float']['input'];
92+
};
93+
8194
export type PageInput = {
8295
attributes?: InputMaybe<Array<AttributeInput>>;
8396
date?: InputMaybe<Scalars['Date']['input']>;

example/yup/schemas.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as yup from 'yup'
2-
import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User, UserKind } from '../types'
2+
import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, MyType, MyTypeFooArgs, PageInput, PageType, User, UserKind } from '../types'
33

44
export const ButtonComponentTypeSchema = yup.string<ButtonComponentType>().oneOf([ButtonComponentType.Button, ButtonComponentType.Submit]).defined();
55

@@ -80,6 +80,22 @@ export function LayoutInputSchema(): yup.ObjectSchema<LayoutInput> {
8080
})
8181
}
8282

83+
export function MyTypeSchema(): yup.ObjectSchema<MyType> {
84+
return yup.object({
85+
__typename: yup.string<'MyType'>().optional(),
86+
foo: yup.string().defined().nullable().optional()
87+
})
88+
}
89+
90+
export function MyTypeFooArgsSchema(): yup.ObjectSchema<MyTypeFooArgs> {
91+
return yup.object({
92+
a: yup.string().defined().nullable(),
93+
b: yup.number().defined().nonNullable(),
94+
c: yup.boolean().defined().nullable(),
95+
d: yup.number().defined().nonNullable()
96+
})
97+
}
98+
8399
export function PageInputSchema(): yup.ObjectSchema<PageInput> {
84100
return yup.object({
85101
attributes: yup.array(yup.lazy(() => AttributeInputSchema().nonNullable())).defined().nullable().optional(),

example/zod/schemas.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from 'zod'
2-
import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User } from '../types'
2+
import { Admin, AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, Guest, HttpInput, HttpMethod, LayoutInput, MyType, MyTypeFooArgs, PageInput, PageType, User } from '../types'
33

44
type Properties<T> = Required<{
55
[K in keyof T]: z.ZodType<T[K], any, T[K]>;
@@ -84,6 +84,22 @@ export function LayoutInputSchema(): z.ZodObject<Properties<LayoutInput>> {
8484
})
8585
}
8686

87+
export function MyTypeSchema(): z.ZodObject<Properties<MyType>> {
88+
return z.object({
89+
__typename: z.literal('MyType').optional(),
90+
foo: z.string().nullish()
91+
})
92+
}
93+
94+
export function MyTypeFooArgsSchema(): z.ZodObject<Properties<MyTypeFooArgs>> {
95+
return z.object({
96+
a: z.string().nullish(),
97+
b: z.number(),
98+
c: z.boolean().nullish(),
99+
d: z.number()
100+
})
101+
}
102+
87103
export function PageInputSchema(): z.ZodObject<Properties<PageInput>> {
88104
return z.object({
89105
attributes: z.array(z.lazy(() => AttributeInputSchema())).nullish(),

src/myzod/index.ts

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -73,37 +73,66 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
7373
const name = visitor.convertName(node.name.value);
7474
importTypes.push(name);
7575

76+
// Building schema for field arguments.
77+
const argumentBlocks = visitor.buildArgumentsSchemaBlock(node, (typeName, field) => {
78+
importTypes.push(typeName);
79+
const args = field.arguments ?? [];
80+
const shape = args.map(field => generateFieldMyZodSchema(config, visitor, field, 2)).join(',\n');
81+
switch (config.validationSchemaExportType) {
82+
case 'const':
83+
return new DeclarationBlock({})
84+
.export()
85+
.asKind('const')
86+
.withName(`${typeName}Schema: myzod.Type<${typeName}>`)
87+
.withContent([`myzod.object({`, shape, '})'].join('\n')).string;
88+
89+
case 'function':
90+
default:
91+
return new DeclarationBlock({})
92+
.export()
93+
.asKind('function')
94+
.withName(`${typeName}Schema(): myzod.Type<${typeName}>`)
95+
.withBlock([indent(`return myzod.object({`), shape, indent('})')].join('\n')).string;
96+
}
97+
});
98+
const appendArguments = argumentBlocks ? '\n' + argumentBlocks : '';
99+
100+
// Building schema for fields.
76101
const shape = node.fields?.map(field => generateFieldMyZodSchema(config, visitor, field, 2)).join(',\n');
77102

78103
switch (config.validationSchemaExportType) {
79104
case 'const':
80-
return new DeclarationBlock({})
81-
.export()
82-
.asKind('const')
83-
.withName(`${name}Schema: myzod.Type<${name}>`)
84-
.withContent(
85-
[
86-
`myzod.object({`,
87-
indent(`__typename: myzod.literal('${node.name.value}').optional(),`, 2),
88-
shape,
89-
'})',
90-
].join('\n')
91-
).string;
105+
return (
106+
new DeclarationBlock({})
107+
.export()
108+
.asKind('const')
109+
.withName(`${name}Schema: myzod.Type<${name}>`)
110+
.withContent(
111+
[
112+
`myzod.object({`,
113+
indent(`__typename: myzod.literal('${node.name.value}').optional(),`, 2),
114+
shape,
115+
'})',
116+
].join('\n')
117+
).string + appendArguments
118+
);
92119

93120
case 'function':
94121
default:
95-
return new DeclarationBlock({})
96-
.export()
97-
.asKind('function')
98-
.withName(`${name}Schema(): myzod.Type<${name}>`)
99-
.withBlock(
100-
[
101-
indent(`return myzod.object({`),
102-
indent(`__typename: myzod.literal('${node.name.value}').optional(),`, 2),
103-
shape,
104-
indent('})'),
105-
].join('\n')
106-
).string;
122+
return (
123+
new DeclarationBlock({})
124+
.export()
125+
.asKind('function')
126+
.withName(`${name}Schema(): myzod.Type<${name}>`)
127+
.withBlock(
128+
[
129+
indent(`return myzod.object({`),
130+
indent(`__typename: myzod.literal('${node.name.value}').optional(),`, 2),
131+
shape,
132+
indent('})'),
133+
].join('\n')
134+
).string + appendArguments
135+
);
107136
}
108137
}),
109138
},

src/visitor.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { TsVisitor } from '@graphql-codegen/typescript';
2-
import { GraphQLSchema, NameNode, specifiedScalarTypes } from 'graphql';
2+
import { FieldDefinitionNode, GraphQLSchema, NameNode, ObjectTypeDefinitionNode, specifiedScalarTypes } from 'graphql';
33

44
import { ValidationSchemaPluginConfig } from './config';
55

@@ -50,4 +50,28 @@ export class Visitor extends TsVisitor {
5050
const tsType = this.getScalarType(name);
5151
return tsType === 'string';
5252
}
53+
54+
public buildArgumentsSchemaBlock(
55+
node: ObjectTypeDefinitionNode,
56+
callback: (typeName: string, field: FieldDefinitionNode) => string
57+
) {
58+
const fieldsWithArguments = node.fields?.filter(field => field.arguments && field.arguments.length > 0) ?? [];
59+
if (fieldsWithArguments.length === 0) {
60+
return undefined;
61+
}
62+
return fieldsWithArguments
63+
.map(field => {
64+
const name =
65+
node.name.value +
66+
(this.config.addUnderscoreToArgsType ? '_' : '') +
67+
this.convertName(field, {
68+
useTypesPrefix: false,
69+
useTypesSuffix: false,
70+
}) +
71+
'Args';
72+
73+
return callback(name, field);
74+
})
75+
.join('\n');
76+
}
5377
}

src/yup/index.ts

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,32 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
8888
const name = visitor.convertName(node.name.value);
8989
importTypes.push(name);
9090

91+
// Building schema for field arguments.
92+
const argumentBlocks = visitor.buildArgumentsSchemaBlock(node, (typeName, field) => {
93+
importTypes.push(typeName);
94+
const args = field.arguments ?? [];
95+
const shape = args.map(field => generateFieldYupSchema(config, visitor, field, 2)).join(',\n');
96+
switch (config.validationSchemaExportType) {
97+
case 'const':
98+
return new DeclarationBlock({})
99+
.export()
100+
.asKind('const')
101+
.withName(`${typeName}Schema: yup.ObjectSchema<${typeName}>`)
102+
.withContent([`yup.object({`, shape, '})'].join('\n')).string;
103+
104+
case 'function':
105+
default:
106+
return new DeclarationBlock({})
107+
.export()
108+
.asKind('function')
109+
.withName(`${typeName}Schema(): yup.ObjectSchema<${typeName}>`)
110+
.withBlock([indent(`return yup.object({`), shape, indent('})')].join('\n')).string;
111+
}
112+
});
113+
const appendArguments = argumentBlocks ? '\n' + argumentBlocks : '';
114+
115+
// Building schema for fields.
116+
91117
const shape = node.fields
92118
?.map(field => {
93119
const fieldSchema = generateFieldYupSchema(config, visitor, field, 2);
@@ -97,33 +123,37 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
97123

98124
switch (config.validationSchemaExportType) {
99125
case 'const':
100-
return new DeclarationBlock({})
101-
.export()
102-
.asKind('const')
103-
.withName(`${name}Schema: yup.ObjectSchema<${name}>`)
104-
.withContent(
105-
[
106-
`yup.object({`,
107-
indent(`__typename: yup.string<'${node.name.value}'>().optional(),`, 2),
108-
shape,
109-
'})',
110-
].join('\n')
111-
).string;
126+
return (
127+
new DeclarationBlock({})
128+
.export()
129+
.asKind('const')
130+
.withName(`${name}Schema: yup.ObjectSchema<${name}>`)
131+
.withContent(
132+
[
133+
`yup.object({`,
134+
indent(`__typename: yup.string<'${node.name.value}'>().optional(),`, 2),
135+
shape,
136+
'})',
137+
].join('\n')
138+
).string + appendArguments
139+
);
112140

113141
case 'function':
114142
default:
115-
return new DeclarationBlock({})
116-
.export()
117-
.asKind('function')
118-
.withName(`${name}Schema(): yup.ObjectSchema<${name}>`)
119-
.withBlock(
120-
[
121-
indent(`return yup.object({`),
122-
indent(`__typename: yup.string<'${node.name.value}'>().optional(),`, 2),
123-
shape,
124-
indent('})'),
125-
].join('\n')
126-
).string;
143+
return (
144+
new DeclarationBlock({})
145+
.export()
146+
.asKind('function')
147+
.withName(`${name}Schema(): yup.ObjectSchema<${name}>`)
148+
.withBlock(
149+
[
150+
indent(`return yup.object({`),
151+
indent(`__typename: yup.string<'${node.name.value}'>().optional(),`, 2),
152+
shape,
153+
indent('})'),
154+
].join('\n')
155+
).string + appendArguments
156+
);
127157
}
128158
}),
129159
},

0 commit comments

Comments
 (0)