@@ -12,7 +12,7 @@ import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common
12
12
import { TsVisitor } from '@graphql-codegen/typescript' ;
13
13
import { buildApi , formatDirectiveConfig } from '../directive' ;
14
14
15
- const importZod = `import { z } from 'zod '` ;
15
+ const importZod = `import myzod from 'myzod '` ;
16
16
const anySchema = `definedNonNullAnySchema` ;
17
17
18
18
export const ZodSchemaVisitor = ( schema : GraphQLSchema , config : ValidationSchemaPluginConfig ) => {
@@ -27,13 +27,21 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
27
27
}
28
28
return [ importZod ] ;
29
29
} ,
30
+
30
31
initialEmit : ( ) : string =>
31
32
'\n' +
32
33
[
34
+ /*
35
+ * MyZod allows you to create typed objects with `myzod.Type<YourCustomType>`
36
+ * See https://www.npmjs.com/package/myzod#lazy
33
37
new DeclarationBlock({})
34
38
.asKind('type')
35
39
.withName('Properties<T>')
36
40
.withContent(['Required<{', ' [K in keyof T]: z.ZodType<T[K], any, T[K]>;', '}>'].join('\n')).string,
41
+ */
42
+ /*
43
+ * MyZod allows empty object hence no need for these hacks
44
+ * See https://www.npmjs.com/package/myzod#object
37
45
// Unfortunately, zod doesn’t provide non-null defined any schema.
38
46
// This is a temporary hack until it is fixed.
39
47
// see: https://github.com/colinhacks/zod/issues/884
@@ -48,54 +56,55 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
48
56
.asKind('const')
49
57
.withName(`${anySchema}`)
50
58
.withContent(`z.any().refine((v) => isDefinedNonNullAny(v))`).string,
59
+ */
51
60
] . join ( '\n' ) ,
52
61
InputObjectTypeDefinition : ( node : InputObjectTypeDefinitionNode ) => {
53
62
const name = tsVisitor . convertName ( node . name . value ) ;
54
63
importTypes . push ( name ) ;
55
64
56
65
const shape = node . fields
57
- ?. map ( field => generateInputObjectFieldZodSchema ( config , tsVisitor , schema , field , 2 ) )
66
+ ?. map ( field => generateInputObjectFieldMyZodSchema ( config , tsVisitor , schema , field , 2 ) )
58
67
. join ( ',\n' ) ;
59
68
60
69
return new DeclarationBlock ( { } )
61
70
. export ( )
62
- . asKind ( 'function ' )
63
- . withName ( `${ name } Schema(): z.ZodObject<Properties< ${ name } >>` )
64
- . withBlock ( [ indent ( `return z .object({` ) , shape , indent ( '})' ) ] . join ( '\n' ) ) . string ;
71
+ . asKind ( 'const ' )
72
+ . withName ( `${ name } Schema: myzod.Type< ${ name } >` ) //TODO: Test this
73
+ . withBlock ( [ indent ( `myzod .object({` ) , shape , indent ( '})' ) ] . join ( '\n' ) ) . string ;
65
74
} ,
66
75
EnumTypeDefinition : ( node : EnumTypeDefinitionNode ) => {
67
76
const enumname = tsVisitor . convertName ( node . name . value ) ;
68
77
importTypes . push ( enumname ) ;
69
-
78
+ /*
70
79
if (config.enumsAsTypes) {
71
80
return new DeclarationBlock({})
72
81
.export()
73
82
.asKind('const')
74
83
.withName(`${enumname}Schema`)
75
84
.withContent(`z.enum([${node.values?.map(enumOption => `'${enumOption.name.value}'`).join(', ')}])`).string;
76
85
}
77
-
86
+ */
78
87
return new DeclarationBlock ( { } )
79
88
. export ( )
80
89
. asKind ( 'const' )
81
90
. withName ( `${ enumname } Schema` )
82
- . withContent ( `z.nativeEnum (${ enumname } )` ) . string ;
91
+ . withContent ( `myzod.enum (${ enumname } )` ) . string ;
83
92
} ,
84
93
} ;
85
94
} ;
86
95
87
- const generateInputObjectFieldZodSchema = (
96
+ const generateInputObjectFieldMyZodSchema = (
88
97
config : ValidationSchemaPluginConfig ,
89
98
tsVisitor : TsVisitor ,
90
99
schema : GraphQLSchema ,
91
100
field : InputValueDefinitionNode ,
92
101
indentCount : number
93
102
) : string => {
94
- const gen = generateInputObjectFieldTypeZodSchema ( config , tsVisitor , schema , field , field . type ) ;
103
+ const gen = generateInputObjectFieldTypeMyZodSchema ( config , tsVisitor , schema , field , field . type ) ;
95
104
return indent ( `${ field . name . value } : ${ maybeLazy ( field . type , gen ) } ` , indentCount ) ;
96
105
} ;
97
106
98
- const generateInputObjectFieldTypeZodSchema = (
107
+ const generateInputObjectFieldTypeMyZodSchema = (
99
108
config : ValidationSchemaPluginConfig ,
100
109
tsVisitor : TsVisitor ,
101
110
schema : GraphQLSchema ,
@@ -104,22 +113,22 @@ const generateInputObjectFieldTypeZodSchema = (
104
113
parentType ?: TypeNode
105
114
) : string => {
106
115
if ( isListType ( type ) ) {
107
- const gen = generateInputObjectFieldTypeZodSchema ( config , tsVisitor , schema , field , type . type , type ) ;
116
+ const gen = generateInputObjectFieldTypeMyZodSchema ( config , tsVisitor , schema , field , type . type , type ) ;
108
117
if ( ! isNonNullType ( parentType ) ) {
109
- const arrayGen = `z .array(${ maybeLazy ( type . type , gen ) } )` ;
118
+ const arrayGen = `myzod .array(${ maybeLazy ( type . type , gen ) } )` ;
110
119
const maybeLazyGen = applyDirectives ( config , field , arrayGen ) ;
111
- return `${ maybeLazyGen } .nullish( )` ;
120
+ return `${ maybeLazyGen } .optional()` ; // to make it equivalent to nullish: `${maybeLazyGen}.optional().optional().or(nullable() )`;
112
121
}
113
- return `z .array(${ maybeLazy ( type . type , gen ) } )` ;
122
+ return `myzod .array(${ maybeLazy ( type . type , gen ) } )` ;
114
123
}
115
124
if ( isNonNullType ( type ) ) {
116
- const gen = generateInputObjectFieldTypeZodSchema ( config , tsVisitor , schema , field , type . type , type ) ;
125
+ const gen = generateInputObjectFieldTypeMyZodSchema ( config , tsVisitor , schema , field , type . type , type ) ;
117
126
return maybeLazy ( type . type , gen ) ;
118
127
}
119
128
if ( isNamedType ( type ) ) {
120
- const gen = generateNameNodeZodSchema ( config , tsVisitor , schema , type . name ) ;
129
+ const gen = generateNameNodeMyZodSchema ( config , tsVisitor , schema , type . name ) ;
121
130
if ( isListType ( parentType ) ) {
122
- return `${ gen } .nullable()` ;
131
+ return `${ gen } .nullable()` ; //TODO: Test this later
123
132
}
124
133
const appliedDirectivesGen = applyDirectives ( config , field , gen ) ;
125
134
if ( isNonNullType ( parentType ) ) {
@@ -130,14 +139,15 @@ const generateInputObjectFieldTypeZodSchema = (
130
139
return appliedDirectivesGen ;
131
140
}
132
141
if ( isListType ( parentType ) ) {
133
- return `${ appliedDirectivesGen } .nullable()` ;
142
+ return `${ appliedDirectivesGen } .nullable()` ; //TODO: Test this later
134
143
}
135
- return `${ appliedDirectivesGen } .nullish( )` ;
144
+ return `${ appliedDirectivesGen } .optional()` ; // to make it equivalent to nullish: `${appliedDirectivesGen}.optional().or(nullable() )`;
136
145
}
137
146
console . warn ( 'unhandled type:' , type ) ;
138
147
return '' ;
139
148
} ;
140
149
150
+ // TODO: Find out how it works and implement it
141
151
const applyDirectives = (
142
152
config : ValidationSchemaPluginConfig ,
143
153
field : InputValueDefinitionNode ,
@@ -150,7 +160,7 @@ const applyDirectives = (
150
160
return gen ;
151
161
} ;
152
162
153
- const generateNameNodeZodSchema = (
163
+ const generateNameNodeMyZodSchema = (
154
164
config : ValidationSchemaPluginConfig ,
155
165
tsVisitor : TsVisitor ,
156
166
schema : GraphQLSchema ,
@@ -173,7 +183,7 @@ const generateNameNodeZodSchema = (
173
183
174
184
const maybeLazy = ( type : TypeNode , schema : string ) : string => {
175
185
if ( isNamedType ( type ) && isInput ( type . name . value ) ) {
176
- return `z .lazy(() => ${ schema } )` ;
186
+ return `myzod .lazy(() => ${ schema } )` ;
177
187
}
178
188
return schema ;
179
189
} ;
@@ -185,11 +195,11 @@ const zod4Scalar = (config: ValidationSchemaPluginConfig, tsVisitor: TsVisitor,
185
195
const tsType = tsVisitor . scalars [ scalarName ] ;
186
196
switch ( tsType ) {
187
197
case 'string' :
188
- return `z .string()` ;
198
+ return `myzod .string()` ;
189
199
case 'number' :
190
- return `z .number()` ;
200
+ return `myzod .number()` ;
191
201
case 'boolean' :
192
- return `z .boolean()` ;
202
+ return `myzod .boolean()` ;
193
203
}
194
204
console . warn ( 'unhandled name:' , scalarName ) ;
195
205
return anySchema ;
0 commit comments