@@ -37,8 +37,9 @@ func ValuesOfCorrectTypeRule(context: ValidationContext) -> Visitor {
3737                    return  . break // Don't traverse further.
3838                } 
3939                // Ensure every required field exists.
40-                 let  fieldNodeMap  =  Dictionary ( grouping:  object. fields)  {  field in 
41-                     field. name. value
40+                 var  fieldNodeMap  =  [ String:  ObjectField] ( ) 
41+                 for  field  in  object. fields { 
42+                     fieldNodeMap [ field. name. value]  =  field
4243                } 
4344                for  (fieldName,  fieldDef)  in  type. fields { 
4445                    if  fieldNodeMap [ fieldName]  ==  nil ,  isRequiredInputField ( fieldDef)  { 
@@ -52,7 +53,15 @@ func ValuesOfCorrectTypeRule(context: ValidationContext) -> Visitor {
5253                    } 
5354                } 
5455
55-                 // TODO: Add oneOf support
56+                 if  type. isOneOf { 
57+                     validateOneOfInputObject ( 
58+                         context:  context, 
59+                         node:  object, 
60+                         type:  type, 
61+                         fieldNodeMap:  fieldNodeMap, 
62+                         variableDefinitions:  variableDefinitions
63+                     ) 
64+                 } 
5665                return  . continue
5766            } 
5867            if  let  field =  node as?  ObjectField  { 
@@ -172,3 +181,55 @@ func isValidValueNode(_ context: ValidationContext, _ node: Value) {
172181        } 
173182    } 
174183} 
184+ 
185+ func  validateOneOfInputObject( 
186+     context:  ValidationContext , 
187+     node:  ObjectValue , 
188+     type:  GraphQLInputObjectType , 
189+     fieldNodeMap:  [ String :  ObjectField ] , 
190+     variableDefinitions:  [ String :  VariableDefinition ] 
191+ )  { 
192+     let  keys  =  Array ( fieldNodeMap. keys) 
193+     let  isNotExactlyOneField  =  keys. count !=  1 
194+ 
195+     if  isNotExactlyOneField { 
196+         context. report ( 
197+             error:  GraphQLError ( 
198+                 message:  " OneOf Input Object  \" \( type. name) \"  must specify exactly one key. " , 
199+                 nodes:  [ node] 
200+             ) 
201+         ) 
202+         return 
203+     } 
204+ 
205+     let  value  =  fieldNodeMap [ keys [ 0 ] ] ? . value
206+     let  isNullLiteral  =  value ==  nil  || value? . kind ==  . nullValue
207+ 
208+     if  isNullLiteral { 
209+         context. report ( 
210+             error:  GraphQLError ( 
211+                 message:  " Field  \" \( type. name) . \( keys [ 0 ] ) \"  must be non-null. " , 
212+                 nodes:  [ node] 
213+             ) 
214+         ) 
215+         return 
216+     } 
217+ 
218+     if  let  value =  value,  value. kind ==  . variable { 
219+         let  variable  =  value as!  Variable  // Force unwrap is safe because of variable definition
220+         let  variableName  =  variable. name. value
221+ 
222+         if 
223+             let  definition =  variableDefinitions [ variableName] , 
224+             definition. type. kind !=  . nonNullType
225+         { 
226+             context. report ( 
227+                 error:  GraphQLError ( 
228+                     message:  " Variable  \" \( variableName) \"  must be non-nullable to be used for OneOf Input Object  \" \( type. name) \" . " , 
229+                     nodes:  [ node] 
230+                 ) 
231+             ) 
232+             return 
233+         } 
234+     } 
235+ } 
0 commit comments