2727final class ExecutionContext {
2828 let schema : GraphQLSchema
2929 let fragments : [ String : FragmentDefinition ]
30- let rootValue : Map
31- let contextValue : Map
30+ let rootValue : MapRepresentable
31+ let contextValue : MapRepresentable
3232 let operation : OperationDefinition
3333 let variableValues : [ String : Map ]
3434 var errors : [ GraphQLError ]
3535
3636 init (
3737 schema: GraphQLSchema ,
3838 fragments: [ String : FragmentDefinition ] ,
39- rootValue: Map ,
40- contextValue: Map ,
39+ rootValue: MapRepresentable ,
40+ contextValue: MapRepresentable ,
4141 operation: OperationDefinition ,
4242 variableValues: [ String : Map ] ,
4343 errors: [ GraphQLError ]
@@ -64,8 +64,8 @@ final class ExecutionContext {
6464func execute(
6565 schema: GraphQLSchema ,
6666 documentAST: Document ,
67- rootValue: Map ,
68- contextValue: Map ,
67+ rootValue: MapRepresentable ,
68+ contextValue: MapRepresentable ,
6969 variableValues: [ String : Map ] = [ : ] ,
7070 operationName: String ? = nil
7171) throws -> Map {
@@ -88,7 +88,13 @@ func execute(
8888 rootValue: rootValue
8989 )
9090
91- var result : [ String : Map ] = [ " data " : data]
91+ var dataMap : Map = [ : ]
92+
93+ for (key, value) in data {
94+ dataMap [ key] = value. map
95+ }
96+
97+ var result : [ String : Map ] = [ " data " : dataMap]
9298
9399 if !context. errors. isEmpty {
94100 result [ " errors " ] = context. errors. map
@@ -109,8 +115,8 @@ func execute(
109115func buildExecutionContext(
110116 schema: GraphQLSchema ,
111117 documentAST: Document ,
112- rootValue: Map ,
113- contextValue: Map ,
118+ rootValue: MapRepresentable ,
119+ contextValue: MapRepresentable ,
114120 rawVariableValues: [ String : Map ] ,
115121 operationName: String ?
116122) throws -> ExecutionContext {
@@ -173,8 +179,8 @@ func buildExecutionContext(
173179func executeOperation(
174180 exeContext: ExecutionContext ,
175181 operation: OperationDefinition ,
176- rootValue: Map
177- ) throws -> Map {
182+ rootValue: MapRepresentable
183+ ) throws -> [ String : MapRepresentable ] {
178184 let type = try getOperationRootType ( schema: exeContext. schema, operation: operation)
179185
180186 var inputFields : [ String : [ Field ] ] = [ : ]
@@ -247,10 +253,10 @@ func getOperationRootType(
247253func executeFieldsSerially(
248254 exeContext: ExecutionContext ,
249255 parentType: GraphQLObjectType ,
250- sourceValue: Map ,
256+ sourceValue: MapRepresentable ,
251257 path: [ IndexPathElement ] ,
252258 fields: [ String : [ Field ] ]
253- ) throws -> Map {
259+ ) throws -> [ String : MapRepresentable ] {
254260 return try fields. reduce ( [ : ] ) { results, field in
255261 var results = results
256262 let fieldASTs = field. value
@@ -276,10 +282,10 @@ func executeFieldsSerially(
276282func executeFields(
277283 exeContext: ExecutionContext ,
278284 parentType: GraphQLObjectType ,
279- sourceValue: Map ,
285+ sourceValue: MapRepresentable ,
280286 path: [ IndexPathElement ] ,
281287 fields: [ String : [ Field ] ]
282- ) throws -> Map {
288+ ) throws -> [ String : MapRepresentable ] {
283289 return try executeFieldsSerially (
284290 exeContext: exeContext,
285291 parentType: parentType,
@@ -398,25 +404,25 @@ func collectFields(
398404 */
399405func shouldIncludeNode( exeContext: ExecutionContext , directives: [ Directive ] = [ ] ) throws -> Bool {
400406 if let skipAST = directives. find ( { $0. name. value == GraphQLSkipDirective . name } ) {
401- let skipIf = try getArgumentValues (
407+ let skip = try getArgumentValues (
402408 argDefs: GraphQLSkipDirective . args,
403409 argASTs: skipAST. arguments,
404410 variableValues: exeContext. variableValues
405- ) [ " if " ]
411+ )
406412
407- if let skipIf = skipIf , skipIf == . bool( true ) {
413+ if skip [ " if " ] == . bool( true ) {
408414 return false
409415 }
410416 }
411417
412418 if let includeAST = directives. find ( { $0. name. value == GraphQLIncludeDirective . name } ) {
413- let includeIf = try getArgumentValues (
419+ let include = try getArgumentValues (
414420 argDefs: GraphQLIncludeDirective . args,
415421 argASTs: includeAST. arguments,
416422 variableValues: exeContext. variableValues
417- ) [ " if " ]
423+ )
418424
419- if let includeIf = includeIf , includeIf == . bool( false ) {
425+ if include [ " if " ] == . bool( false ) {
420426 return false
421427 }
422428 }
@@ -467,10 +473,10 @@ func getFieldEntryKey(node: Field) -> String {
467473func resolveField(
468474 exeContext: ExecutionContext ,
469475 parentType: GraphQLObjectType ,
470- source: Map ,
476+ source: MapRepresentable ,
471477 fieldASTs: [ Field ] ,
472478 path: [ IndexPathElement ]
473- ) throws -> Map {
479+ ) throws -> MapRepresentable {
474480 let fieldAST = fieldASTs [ 0 ]
475481 let fieldName = fieldAST. name. value
476482
@@ -533,17 +539,17 @@ func resolveField(
533539}
534540
535541enum ResultOrError {
536- case result( Map )
542+ case result( MapRepresentable )
537543 case error( Error )
538544}
539545
540546// Isolates the "ReturnOrAbrupt" behavior to not de-opt the `resolveField`
541547// function. Returns the result of resolveFn or the abrupt-return Error object.
542548func resolveOrError(
543549 resolve: GraphQLFieldResolve ,
544- source: Map ,
545- args: [ String : Map ] ,
546- context: Map ,
550+ source: MapRepresentable ,
551+ args: Map ,
552+ context: MapRepresentable ,
547553 info: GraphQLResolveInfo
548554) -> ResultOrError {
549555 do {
@@ -562,7 +568,7 @@ func completeValueCatchingError(
562568 info: GraphQLResolveInfo ,
563569 path: [ IndexPathElement ] ,
564570 result: ResultOrError
565- ) throws -> Map {
571+ ) throws -> MapRepresentable {
566572 // If the field type is non-nullable, then it is resolved without any
567573 // protection from errors, however it still properly locates the error.
568574 if let returnType = returnType as? GraphQLNonNull {
@@ -593,7 +599,7 @@ func completeValueCatchingError(
593599 // If `completeValueWithLocatedError` returned abruptly (threw an error),
594600 // log the error and return null.
595601 exeContext. errors. append ( error)
596- return . null
602+ return Map . null
597603 } catch {
598604 fatalError ( )
599605 }
@@ -608,7 +614,7 @@ func completeValueWithLocatedError(
608614 info: GraphQLResolveInfo ,
609615 path: [ IndexPathElement ] ,
610616 result: ResultOrError
611- ) throws -> Map {
617+ ) throws -> MapRepresentable {
612618 do {
613619 let completed = try completeValue (
614620 exeContext: exeContext,
@@ -657,7 +663,7 @@ func completeValue(
657663 info: GraphQLResolveInfo ,
658664 path: [ IndexPathElement ] ,
659665 result: ResultOrError
660- ) throws -> Map {
666+ ) throws -> MapRepresentable {
661667 switch result {
662668 case . error( let error) :
663669 throw error
@@ -674,7 +680,7 @@ func completeValue(
674680 result: . result( result)
675681 )
676682
677- guard completed != . null else {
683+ guard !isNullish ( completed ) else {
678684 throw GraphQLError (
679685 message: " Cannot return null for non-nullable field \( info. parentType. name) . \( info. fieldName) . "
680686 )
@@ -685,7 +691,7 @@ func completeValue(
685691
686692 // If result value is null-ish (null, undefined, or NaN) then return null.
687693 if isNullish ( result) {
688- return . null
694+ return Map . null
689695 }
690696
691697 // If field type is List, complete each item in the list with the inner type
@@ -748,9 +754,9 @@ func completeListValue(
748754 fieldASTs: [ Field ] ,
749755 info: GraphQLResolveInfo ,
750756 path: [ IndexPathElement ] ,
751- result: Map
752- ) throws -> Map {
753- guard case . array ( let result) = result else {
757+ result: MapRepresentable
758+ ) throws -> MapRepresentable {
759+ guard let result = result as? [ MapRepresentable ] else {
754760 throw GraphQLError (
755761 message:
756762 " Expected Iterable, but did not find one for field " +
@@ -759,7 +765,7 @@ func completeListValue(
759765 }
760766
761767 let itemType = returnType. ofType
762- var completedResults : [ Map ] = [ ]
768+ var completedResults : [ MapRepresentable ] = [ ]
763769
764770 for (index, item) in result. enumerated ( ) {
765771 // No need to modify the info object containing the path,
@@ -778,14 +784,14 @@ func completeListValue(
778784 completedResults. append ( completedItem)
779785 }
780786
781- return . array ( completedResults)
787+ return completedResults
782788}
783789
784790/**
785791 * Complete a Scalar or Enum by serializing to a valid value, returning
786792 * null if serialization is not possible.
787793 */
788- func completeLeafValue( returnType: GraphQLLeafType , result: Map ) throws -> Map {
794+ func completeLeafValue( returnType: GraphQLLeafType , result: MapRepresentable ) throws -> Map {
789795 let serializedResult = try returnType. serialize ( value: result)
790796
791797 if isNullish ( serializedResult) {
@@ -809,8 +815,8 @@ func completeAbstractValue(
809815 fieldASTs: [ Field ] ,
810816 info: GraphQLResolveInfo ,
811817 path: [ IndexPathElement ] ,
812- result: Map
813- ) throws -> Map {
818+ result: MapRepresentable
819+ ) throws -> MapRepresentable {
814820 let resolveRes = try returnType. resolveType ? ( result, exeContext. contextValue, info) ??
815821 defaultResolveType ( value: result, context: exeContext. contextValue, info: info, abstractType: returnType) . map ( { . type( $0) } )
816822
@@ -869,8 +875,8 @@ func completeObjectValue(
869875 fieldASTs: [ Field ] ,
870876 info: GraphQLResolveInfo ,
871877 path: [ IndexPathElement ] ,
872- result: Map
873- ) throws -> Map {
878+ result: MapRepresentable
879+ ) throws -> MapRepresentable {
874880 // If there is an isTypeOf predicate func, call it with the
875881 // current result. If isTypeOf returns false, then raise an error rather
876882 // than continuing execution.
@@ -913,23 +919,46 @@ func completeObjectValue(
913919 * isTypeOf for the object being coerced, returning the first type that matches.
914920 */
915921func defaultResolveType(
916- value: Map ,
917- context: Map ,
922+ value: MapRepresentable ,
923+ context: MapRepresentable ,
918924 info: GraphQLResolveInfo ,
919925 abstractType: GraphQLAbstractType
920926) -> GraphQLObjectType ? {
921927 let possibleTypes = info. schema. getPossibleTypes ( abstractType: abstractType)
922928 return possibleTypes. find ( { $0. isTypeOf ? ( value, context, info) ?? false } )
923929}
924930
931+ func unwrap( _ value: MapRepresentable ) -> MapRepresentable ? {
932+ let mirror = Mirror ( reflecting: value)
933+
934+ if mirror. displayStyle != . optional {
935+ return value
936+ }
937+
938+ if mirror. children. isEmpty {
939+ return nil
940+ }
941+
942+ let child = mirror. children. first!
943+ return child. value as? MapRepresentable
944+ }
945+
925946/**
926947 * If a resolve func is not given, then a default resolve behavior is used
927948 * which takes the property of the source object of the same name as the field
928- * and returns it as the result, or if it's a func, returns the result
929- * of calling that func while passing along args and context.
949+ * and returns it as the result.
930950 */
931- func defaultResolve( source: Map , args: [ String : Map ] , context: Map , info: GraphQLResolveInfo ) -> Map {
932- return source [ info. fieldName]
951+ func defaultResolve( source: MapRepresentable , args: Map , context: MapRepresentable , info: GraphQLResolveInfo ) -> MapRepresentable {
952+ print ( type ( of: source) )
953+ guard let source = unwrap ( source) else {
954+ return Map . null
955+ }
956+ print ( type ( of: source) )
957+ guard let anyValue = try ? get ( info. fieldName, from: source) , let value = anyValue as? MapRepresentable else {
958+ return Map . null
959+ }
960+
961+ return value
933962}
934963
935964/**
0 commit comments