Skip to content

Commit ba0eee0

Browse files
committed
added own visitor and fixed build error for #373
1 parent 4b80770 commit ba0eee0

File tree

4 files changed

+150
-133
lines changed

4 files changed

+150
-133
lines changed

src/myzod/index.ts

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,14 @@ import {
1212
UnionTypeDefinitionNode,
1313
} from 'graphql';
1414
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
15-
import { TsVisitor } from '@graphql-codegen/typescript';
15+
import { Visitor } from '../visitor';
1616
import { buildApi, formatDirectiveConfig } from '../directive';
1717
import { SchemaVisitor } from '../types';
1818

1919
const importZod = `import * as myzod from 'myzod'`;
2020
const anySchema = `definedNonNullAnySchema`;
2121

2222
export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchemaPluginConfig): SchemaVisitor => {
23-
const tsVisitor = new TsVisitor(schema, config);
24-
2523
const importTypes: string[] = [];
2624

2725
return {
@@ -39,12 +37,11 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
3937
].join('\n'),
4038
InputObjectTypeDefinition: {
4139
leave: (node: InputObjectTypeDefinitionNode) => {
42-
const name = tsVisitor.convertName(node.name.value);
40+
const visitor = new Visitor('input', schema, config);
41+
const name = visitor.convertName(node.name.value);
4342
importTypes.push(name);
4443

45-
const shape = node.fields
46-
?.map(field => generateFieldMyZodSchema(config, tsVisitor, schema, field, 2))
47-
.join(',\n');
44+
const shape = node.fields?.map(field => generateFieldMyZodSchema(config, visitor, field, 2)).join(',\n');
4845

4946
return new DeclarationBlock({})
5047
.export()
@@ -55,12 +52,11 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
5552
},
5653
ObjectTypeDefinition: {
5754
leave: ObjectTypeDefinitionBuilder(config.withObjectType, (node: ObjectTypeDefinitionNode) => {
58-
const name = tsVisitor.convertName(node.name.value);
55+
const visitor = new Visitor('output', schema, config);
56+
const name = visitor.convertName(node.name.value);
5957
importTypes.push(name);
6058

61-
const shape = node.fields
62-
?.map(field => generateFieldMyZodSchema(config, tsVisitor, schema, field, 2))
63-
.join(',\n');
59+
const shape = node.fields?.map(field => generateFieldMyZodSchema(config, visitor, field, 2)).join(',\n');
6460

6561
return new DeclarationBlock({})
6662
.export()
@@ -78,7 +74,8 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
7874
},
7975
EnumTypeDefinition: {
8076
leave: (node: EnumTypeDefinitionNode) => {
81-
const enumname = tsVisitor.convertName(node.name.value);
77+
const visitor = new Visitor('both', schema, config);
78+
const enumname = visitor.convertName(node.name.value);
8279
importTypes.push(enumname);
8380
// z.enum are basically myzod.literals
8481
if (config.enumsAsTypes) {
@@ -101,11 +98,13 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
10198
leave: (node: UnionTypeDefinitionNode) => {
10299
if (!node.types || !config.withObjectType) return;
103100

104-
const unionName = tsVisitor.convertName(node.name.value);
101+
const visitor = new Visitor('output', schema, config);
102+
103+
const unionName = visitor.convertName(node.name.value);
105104
const unionElements = node.types
106105
?.map(t => {
107-
const element = tsVisitor.convertName(t.name.value);
108-
const typ = schema.getType(t.name.value);
106+
const element = visitor.convertName(t.name.value);
107+
const typ = visitor.getType(t.name.value);
109108
if (typ?.astNode?.kind === 'EnumTypeDefinition') {
110109
return `${element}Schema`;
111110
}
@@ -126,25 +125,23 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
126125

127126
const generateFieldMyZodSchema = (
128127
config: ValidationSchemaPluginConfig,
129-
tsVisitor: TsVisitor,
130-
schema: GraphQLSchema,
128+
visitor: Visitor,
131129
field: InputValueDefinitionNode | FieldDefinitionNode,
132130
indentCount: number
133131
): string => {
134-
const gen = generateFieldTypeMyZodSchema(config, tsVisitor, schema, field, field.type);
132+
const gen = generateFieldTypeMyZodSchema(config, visitor, field, field.type);
135133
return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount);
136134
};
137135

138136
const generateFieldTypeMyZodSchema = (
139137
config: ValidationSchemaPluginConfig,
140-
tsVisitor: TsVisitor,
141-
schema: GraphQLSchema,
138+
visitor: Visitor,
142139
field: InputValueDefinitionNode | FieldDefinitionNode,
143140
type: TypeNode,
144141
parentType?: TypeNode
145142
): string => {
146143
if (isListType(type)) {
147-
const gen = generateFieldTypeMyZodSchema(config, tsVisitor, schema, field, type.type, type);
144+
const gen = generateFieldTypeMyZodSchema(config, visitor, field, type.type, type);
148145
if (!isNonNullType(parentType)) {
149146
const arrayGen = `myzod.array(${maybeLazy(type.type, gen)})`;
150147
const maybeLazyGen = applyDirectives(config, field, arrayGen);
@@ -153,18 +150,18 @@ const generateFieldTypeMyZodSchema = (
153150
return `myzod.array(${maybeLazy(type.type, gen)})`;
154151
}
155152
if (isNonNullType(type)) {
156-
const gen = generateFieldTypeMyZodSchema(config, tsVisitor, schema, field, type.type, type);
153+
const gen = generateFieldTypeMyZodSchema(config, visitor, field, type.type, type);
157154
return maybeLazy(type.type, gen);
158155
}
159156
if (isNamedType(type)) {
160-
const gen = generateNameNodeMyZodSchema(config, tsVisitor, schema, type.name);
157+
const gen = generateNameNodeMyZodSchema(config, visitor, type.name);
161158
if (isListType(parentType)) {
162159
return `${gen}.nullable()`;
163160
}
164161
const appliedDirectivesGen = applyDirectives(config, field, gen);
165162
if (isNonNullType(parentType)) {
166163
if (config.notAllowEmptyString === true) {
167-
const tsType = tsVisitor.scalars[type.name.value];
164+
const tsType = visitor.getScalarType(type.name.value);
168165
if (tsType === 'string') return `${gen}.min(1)`;
169166
}
170167
return appliedDirectivesGen;
@@ -192,33 +189,32 @@ const applyDirectives = (
192189

193190
const generateNameNodeMyZodSchema = (
194191
config: ValidationSchemaPluginConfig,
195-
tsVisitor: TsVisitor,
196-
schema: GraphQLSchema,
192+
visitor: Visitor,
197193
node: NameNode
198194
): string => {
199-
const typ = schema.getType(node.value);
195+
const converter = visitor.getNameNodeConverter(node);
200196

201-
if (typ?.astNode?.kind === 'InputObjectTypeDefinition') {
202-
const enumName = tsVisitor.convertName(typ.astNode.name.value);
203-
return `${enumName}Schema()`;
197+
if (converter?.targetKind === 'InputObjectTypeDefinition') {
198+
const name = converter.convertName();
199+
return `${name}Schema()`;
204200
}
205201

206-
if (typ?.astNode?.kind === 'ObjectTypeDefinition') {
207-
const enumName = tsVisitor.convertName(typ.astNode.name.value);
208-
return `${enumName}Schema()`;
202+
if (converter?.targetKind === 'ObjectTypeDefinition') {
203+
const name = converter.convertName();
204+
return `${name}Schema()`;
209205
}
210206

211-
if (typ?.astNode?.kind === 'EnumTypeDefinition') {
212-
const enumName = tsVisitor.convertName(typ.astNode.name.value);
213-
return `${enumName}Schema`;
207+
if (converter?.targetKind === 'EnumTypeDefinition') {
208+
const name = converter.convertName();
209+
return `${name}Schema`;
214210
}
215211

216-
if (typ?.astNode?.kind === 'UnionTypeDefinition') {
217-
const enumName = tsVisitor.convertName(typ.astNode.name.value);
218-
return `${enumName}Schema()`;
212+
if (converter?.targetKind === 'UnionTypeDefinition') {
213+
const name = converter.convertName();
214+
return `${name}Schema()`;
219215
}
220216

221-
return myzod4Scalar(config, tsVisitor, node.value);
217+
return myzod4Scalar(config, visitor, node.value);
222218
};
223219

224220
const maybeLazy = (type: TypeNode, schema: string): string => {
@@ -228,11 +224,11 @@ const maybeLazy = (type: TypeNode, schema: string): string => {
228224
return schema;
229225
};
230226

231-
const myzod4Scalar = (config: ValidationSchemaPluginConfig, tsVisitor: TsVisitor, scalarName: string): string => {
227+
const myzod4Scalar = (config: ValidationSchemaPluginConfig, visitor: Visitor, scalarName: string): string => {
232228
if (config.scalarSchemas?.[scalarName]) {
233229
return config.scalarSchemas[scalarName];
234230
}
235-
const tsType = tsVisitor.scalars[scalarName];
231+
const tsType = visitor.getScalarType(scalarName);
236232
switch (tsType) {
237233
case 'string':
238234
return `myzod.string()`;

src/visitor.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { ValidationSchemaPluginConfig } from './config';
2+
import { TsVisitor } from '@graphql-codegen/typescript';
3+
import { NameNode, GraphQLSchema } from 'graphql';
4+
5+
export class Visitor extends TsVisitor {
6+
constructor(
7+
private scalarDirection: 'input' | 'output' | 'both',
8+
private schema: GraphQLSchema,
9+
config: ValidationSchemaPluginConfig
10+
) {
11+
super(schema, config);
12+
}
13+
14+
public getType(name: string) {
15+
return this.schema.getType(name);
16+
}
17+
18+
public getNameNodeConverter(node: NameNode) {
19+
const typ = this.schema.getType(node.value);
20+
const astNode = typ?.astNode;
21+
if (astNode === undefined || astNode === null) {
22+
return undefined;
23+
}
24+
return {
25+
targetKind: astNode.kind,
26+
convertName: () => this.convertName(astNode.name.value),
27+
};
28+
}
29+
30+
public getScalarType(scalarName: string): string | null {
31+
if (this.scalarDirection === 'both') {
32+
return null;
33+
}
34+
return this.scalars[scalarName][this.scalarDirection];
35+
}
36+
}

0 commit comments

Comments
 (0)