@@ -54,17 +54,16 @@ func VariableValues(schema *ast.Schema, op *ast.OperationDefinition, variables m
5454 rv = rv .Elem ()
5555 }
5656
57- if err := validator .validateVarType (v .Type , rv ); err != nil {
57+ rval , err := validator .validateVarType (v .Type , rv )
58+ if err != nil {
5859 return nil , err
5960 }
60-
61- coercedVars [v .Variable ] = val
61+ coercedVars [v .Variable ] = rval .Interface ()
6262 }
6363 }
6464
6565 validator .path = validator .path [0 : len (validator .path )- 1 ]
6666 }
67-
6867 return coercedVars , nil
6968}
7069
@@ -73,53 +72,52 @@ type varValidator struct {
7372 schema * ast.Schema
7473}
7574
76- func (v * varValidator ) validateVarType (typ * ast.Type , val reflect.Value ) * gqlerror.Error {
75+ func (v * varValidator ) validateVarType (typ * ast.Type , val reflect.Value ) (reflect. Value , * gqlerror.Error ) {
7776 currentPath := v .path
7877 resetPath := func () {
7978 v .path = currentPath
8079 }
8180 defer resetPath ()
82-
8381 if typ .Elem != nil {
8482 if val .Kind () != reflect .Slice {
85- return gqlerror .ErrorPathf (v .path , "must be an array" )
83+ // GraphQL spec says that non-null values should be coerced to an array when possible.
84+ // Hence if the value is not a slice, we create a slice and add val to it.
85+ slc := reflect .MakeSlice (reflect .SliceOf (val .Type ()), 0 , 0 )
86+ slc = reflect .Append (slc , val )
87+ val = slc
8688 }
87-
8889 for i := 0 ; i < val .Len (); i ++ {
8990 resetPath ()
9091 v .path = append (v .path , ast .PathIndex (i ))
9192 field := val .Index (i )
92-
9393 if field .Kind () == reflect .Ptr || field .Kind () == reflect .Interface {
9494 if typ .Elem .NonNull && field .IsNil () {
95- return gqlerror .ErrorPathf (v .path , "cannot be null" )
95+ return val , gqlerror .ErrorPathf (v .path , "cannot be null" )
9696 }
9797 field = field .Elem ()
9898 }
99-
100- if err := v . validateVarType ( typ . Elem , field ); err != nil {
101- return err
99+ _ , err := v . validateVarType ( typ . Elem , field )
100+ if err != nil {
101+ return val , err
102102 }
103103 }
104-
105- return nil
104+ return val , nil
106105 }
107-
108106 def := v .schema .Types [typ .NamedType ]
109107 if def == nil {
110108 panic (fmt .Errorf ("missing def for %s" , typ .NamedType ))
111109 }
112110
113111 if ! typ .NonNull && ! val .IsValid () {
114112 // If the type is not null and we got a invalid value namely null/nil, then it's valid
115- return nil
113+ return val , nil
116114 }
117115
118116 switch def .Kind {
119117 case ast .Enum :
120118 kind := val .Type ().Kind ()
121119 if kind != reflect .Int && kind != reflect .Int32 && kind != reflect .Int64 && kind != reflect .String {
122- return gqlerror .ErrorPathf (v .path , "enums must be ints or strings" )
120+ return val , gqlerror .ErrorPathf (v .path , "enums must be ints or strings" )
123121 }
124122 isValidEnum := false
125123 for _ , enumVal := range def .EnumValues {
@@ -128,42 +126,42 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) *gqlerr
128126 }
129127 }
130128 if ! isValidEnum {
131- return gqlerror .ErrorPathf (v .path , "%s is not a valid %s" , val .String (), def .Name )
129+ return val , gqlerror .ErrorPathf (v .path , "%s is not a valid %s" , val .String (), def .Name )
132130 }
133- return nil
131+ return val , nil
134132 case ast .Scalar :
135133 kind := val .Type ().Kind ()
136134 switch typ .NamedType {
137135 case "Int" :
138136 if kind == reflect .String || kind == reflect .Int || kind == reflect .Int32 || kind == reflect .Int64 {
139- return nil
137+ return val , nil
140138 }
141139 case "Float" :
142140 if kind == reflect .String || kind == reflect .Float32 || kind == reflect .Float64 || kind == reflect .Int || kind == reflect .Int32 || kind == reflect .Int64 {
143- return nil
141+ return val , nil
144142 }
145143 case "String" :
146144 if kind == reflect .String {
147- return nil
145+ return val , nil
148146 }
149147
150148 case "Boolean" :
151149 if kind == reflect .Bool {
152- return nil
150+ return val , nil
153151 }
154152
155153 case "ID" :
156154 if kind == reflect .Int || kind == reflect .Int32 || kind == reflect .Int64 || kind == reflect .String {
157- return nil
155+ return val , nil
158156 }
159157 default :
160158 // assume custom scalars are ok
161- return nil
159+ return val , nil
162160 }
163- return gqlerror .ErrorPathf (v .path , "cannot use %s as %s" , kind .String (), typ .NamedType )
161+ return val , gqlerror .ErrorPathf (v .path , "cannot use %s as %s" , kind .String (), typ .NamedType )
164162 case ast .InputObject :
165163 if val .Kind () != reflect .Map {
166- return gqlerror .ErrorPathf (v .path , "must be a %s" , def .Name )
164+ return val , gqlerror .ErrorPathf (v .path , "must be a %s" , def .Name )
167165 }
168166
169167 // check for unknown fields
@@ -174,7 +172,7 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) *gqlerr
174172 v .path = append (v .path , ast .PathName (name .String ()))
175173
176174 if fieldDef == nil {
177- return gqlerror .ErrorPathf (v .path , "unknown field" )
175+ return val , gqlerror .ErrorPathf (v .path , "unknown field" )
178176 }
179177 }
180178
@@ -192,30 +190,29 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) *gqlerr
192190 continue
193191 }
194192 }
195- return gqlerror .ErrorPathf (v .path , "must be defined" )
193+ return val , gqlerror .ErrorPathf (v .path , "must be defined" )
196194 }
197195 continue
198196 }
199197
200198 if field .Kind () == reflect .Ptr || field .Kind () == reflect .Interface {
201199 if fieldDef .Type .NonNull && field .IsNil () {
202- return gqlerror .ErrorPathf (v .path , "cannot be null" )
200+ return val , gqlerror .ErrorPathf (v .path , "cannot be null" )
203201 }
204202 //allow null object field and skip it
205203 if ! fieldDef .Type .NonNull && field .IsNil () {
206204 continue
207205 }
208206 field = field .Elem ()
209207 }
210-
211- err := v .validateVarType (fieldDef .Type , field )
208+ cval , err := v .validateVarType (fieldDef .Type , field )
212209 if err != nil {
213- return err
210+ return val , err
214211 }
212+ val .SetMapIndex (reflect .ValueOf (fieldDef .Name ), cval )
215213 }
216214 default :
217215 panic (fmt .Errorf ("unsupported type %s" , def .Kind ))
218216 }
219-
220- return nil
217+ return val , nil
221218}
0 commit comments