@@ -6,14 +6,17 @@ import type {
66 InputObjectTypeDefinitionNode ,
77 InputValueDefinitionNode ,
88 NameNode ,
9+ ObjectTypeDefinitionNode ,
910 TypeNode ,
11+ UnionTypeDefinitionNode ,
1012} from 'graphql' ;
1113
1214import type { ValidationSchemaPluginConfig } from '../config' ;
1315import { BaseSchemaVisitor } from '../schema_visitor' ;
1416import type { Visitor } from '../visitor' ;
1517import { buildApiForValibot , formatDirectiveConfig } from '../directive' ;
1618import {
19+ ObjectTypeDefinitionBuilder ,
1720 isInput ,
1821 isListType ,
1922 isNamedType ,
@@ -48,6 +51,41 @@ export class ValibotSchemaVisitor extends BaseSchemaVisitor {
4851 } ;
4952 }
5053
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+
5189 get EnumTypeDefinition ( ) {
5290 return {
5391 leave : ( node : EnumTypeDefinitionNode ) => {
@@ -74,6 +112,42 @@ export class ValibotSchemaVisitor extends BaseSchemaVisitor {
74112 } ;
75113 }
76114
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+
77151 protected buildInputFields (
78152 fields : readonly ( FieldDefinitionNode | InputValueDefinitionNode ) [ ] ,
79153 visitor : Visitor ,
@@ -147,13 +221,17 @@ function generateNameNodeValibotSchema(config: ValidationSchemaPluginConfig, vis
147221
148222 switch ( converter ?. targetKind ) {
149223 case 'InputObjectTypeDefinition' :
224+ case 'ObjectTypeDefinition' :
225+ case 'UnionTypeDefinition' :
150226 // using switch-case rather than if-else to allow for future expansion
151227 switch ( config . validationSchemaExportType ) {
152228 default :
153229 return `${ converter . convertName ( ) } Schema()` ;
154230 }
155231 case 'EnumTypeDefinition' :
156232 return `${ converter . convertName ( ) } Schema` ;
233+ case 'ScalarTypeDefinition' :
234+ return valibot4Scalar ( config , visitor , node . value ) ;
157235 default :
158236 if ( converter ?. targetKind )
159237 console . warn ( 'Unknown targetKind' , converter ?. targetKind ) ;
0 commit comments