@@ -6,14 +6,17 @@ import type {
6
6
InputObjectTypeDefinitionNode ,
7
7
InputValueDefinitionNode ,
8
8
NameNode ,
9
+ ObjectTypeDefinitionNode ,
9
10
TypeNode ,
11
+ UnionTypeDefinitionNode ,
10
12
} from 'graphql' ;
11
13
12
14
import type { ValidationSchemaPluginConfig } from '../config' ;
13
15
import { BaseSchemaVisitor } from '../schema_visitor' ;
14
16
import type { Visitor } from '../visitor' ;
15
17
import { buildApiForValibot , formatDirectiveConfig } from '../directive' ;
16
18
import {
19
+ ObjectTypeDefinitionBuilder ,
17
20
isInput ,
18
21
isListType ,
19
22
isNamedType ,
@@ -48,6 +51,41 @@ export class ValibotSchemaVisitor extends BaseSchemaVisitor {
48
51
} ;
49
52
}
50
53
54
+ get ObjectTypeDefinition ( ) {
55
+ return {
56
+ leave : ObjectTypeDefinitionBuilder ( this . config . withObjectType , ( node : ObjectTypeDefinitionNode ) => {
57
+ const visitor = this . createVisitor ( 'output' ) ;
58
+ const name = visitor . convertName ( node . name . value ) ;
59
+ this . importTypes . push ( name ) ;
60
+
61
+ // Building schema for field arguments.
62
+ const argumentBlocks = this . buildTypeDefinitionArguments ( node , visitor ) ;
63
+ const appendArguments = argumentBlocks ? `\n${ argumentBlocks } ` : '' ;
64
+
65
+ // Building schema for fields.
66
+ const shape = node . fields ?. map ( field => generateFieldValibotSchema ( this . config , visitor , field , 2 ) ) . join ( ',\n' ) ;
67
+
68
+ switch ( this . config . validationSchemaExportType ) {
69
+ default :
70
+ return (
71
+ new DeclarationBlock ( { } )
72
+ . export ( )
73
+ . asKind ( 'function' )
74
+ . withName ( `${ name } Schema(): v.GenericSchema<${ name } >` )
75
+ . withBlock (
76
+ [
77
+ indent ( `return v.object({` ) ,
78
+ indent ( `__typename: v.optional(v.literal('${ node . name . value } ')),` , 2 ) ,
79
+ shape ,
80
+ indent ( '})' ) ,
81
+ ] . join ( '\n' ) ,
82
+ ) . string + appendArguments
83
+ ) ;
84
+ }
85
+ } ) ,
86
+ } ;
87
+ }
88
+
51
89
get EnumTypeDefinition ( ) {
52
90
return {
53
91
leave : ( node : EnumTypeDefinitionNode ) => {
@@ -74,6 +112,42 @@ export class ValibotSchemaVisitor extends BaseSchemaVisitor {
74
112
} ;
75
113
}
76
114
115
+ get UnionTypeDefinition ( ) {
116
+ return {
117
+ leave : ( node : UnionTypeDefinitionNode ) => {
118
+ if ( ! node . types || ! this . config . withObjectType )
119
+ return ;
120
+ const visitor = this . createVisitor ( 'output' ) ;
121
+ const unionName = visitor . convertName ( node . name . value ) ;
122
+ const unionElements = node . types
123
+ . map ( ( t ) => {
124
+ const element = visitor . convertName ( t . name . value ) ;
125
+ const typ = visitor . getType ( t . name . value ) ;
126
+ if ( typ ?. astNode ?. kind === 'EnumTypeDefinition' )
127
+ return `${ element } Schema` ;
128
+
129
+ switch ( this . config . validationSchemaExportType ) {
130
+ default :
131
+ return `${ element } Schema()` ;
132
+ }
133
+ } )
134
+ . join ( ', ' ) ;
135
+ const unionElementsCount = node . types . length ?? 0 ;
136
+
137
+ const union = unionElementsCount > 1 ? `v.union([${ unionElements } ])` : unionElements ;
138
+
139
+ switch ( this . config . validationSchemaExportType ) {
140
+ default :
141
+ return new DeclarationBlock ( { } )
142
+ . export ( )
143
+ . asKind ( 'function' )
144
+ . withName ( `${ unionName } Schema()` )
145
+ . withBlock ( indent ( `return ${ union } ` ) ) . string ;
146
+ }
147
+ } ,
148
+ } ;
149
+ }
150
+
77
151
protected buildInputFields (
78
152
fields : readonly ( FieldDefinitionNode | InputValueDefinitionNode ) [ ] ,
79
153
visitor : Visitor ,
@@ -147,13 +221,17 @@ function generateNameNodeValibotSchema(config: ValidationSchemaPluginConfig, vis
147
221
148
222
switch ( converter ?. targetKind ) {
149
223
case 'InputObjectTypeDefinition' :
224
+ case 'ObjectTypeDefinition' :
225
+ case 'UnionTypeDefinition' :
150
226
// using switch-case rather than if-else to allow for future expansion
151
227
switch ( config . validationSchemaExportType ) {
152
228
default :
153
229
return `${ converter . convertName ( ) } Schema()` ;
154
230
}
155
231
case 'EnumTypeDefinition' :
156
232
return `${ converter . convertName ( ) } Schema` ;
233
+ case 'ScalarTypeDefinition' :
234
+ return valibot4Scalar ( config , visitor , node . value ) ;
157
235
default :
158
236
if ( converter ?. targetKind )
159
237
console . warn ( 'Unknown targetKind' , converter ?. targetKind ) ;
0 commit comments