Skip to content

Commit d375bb2

Browse files
committed
fix star wars schema
1 parent f8706cc commit d375bb2

File tree

6 files changed

+241
-174
lines changed

6 files changed

+241
-174
lines changed

Sources/GraphQL/Execution/Execute.swift

Lines changed: 109 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -238,29 +238,29 @@ func executeFieldsSerially(exeContext: ExecutionContext, parentType: GraphQLObje
238238
* for "read" mode.
239239
*/
240240
func executeFields(exeContext: ExecutionContext, parentType: GraphQLObjectType, sourceValue: Map,
241-
path: [IndexPathElement], fields: [String: [Field]]) throws -> Map {
241+
path: [IndexPathElement], fields: [String: [Field]]) throws -> Map {
242242
let finalResults: [String: Map] = try fields.reduce([:]) { results, field in
243243
var results = results
244-
let fieldASTs = field.value
245-
let fieldPath = path + [field.key] as [IndexPathElement]
244+
let fieldASTs = field.value
245+
let fieldPath = path + [field.key] as [IndexPathElement]
246246

247-
let result = try resolveField(
248-
exeContext: exeContext,
249-
parentType: parentType,
250-
source: sourceValue,
251-
fieldASTs: fieldASTs,
252-
path: fieldPath
253-
)
247+
let result = try resolveField(
248+
exeContext: exeContext,
249+
parentType: parentType,
250+
source: sourceValue,
251+
fieldASTs: fieldASTs,
252+
path: fieldPath
253+
)
254254

255-
guard let r = result else {
256-
return results
257-
}
255+
guard let r = result else {
256+
return results
257+
}
258258

259259
results[field.key] = r
260-
261-
return results
260+
261+
return results
262262
}
263-
263+
264264
return .dictionary(finalResults)
265265
}
266266

@@ -537,79 +537,79 @@ func completeValueWithLocatedError(exeContext: ExecutionContext, returnType: Gra
537537
* value by evaluating all sub-selections.
538538
*/
539539
func completeValue(exeContext: ExecutionContext, returnType: GraphQLType, fieldASTs: [Field], info: GraphQLResolveInfo, path: [IndexPathElement], result: Map) throws -> Map? {
540-
// If field type is NonNull, complete for inner type, and throw field error
541-
// if result is null.
542-
if let returnType = returnType as? GraphQLNonNull {
543-
let completed = try completeValue(
544-
exeContext: exeContext,
545-
returnType: returnType.ofType,
546-
fieldASTs: fieldASTs,
547-
info: info,
548-
path: path,
549-
result: result
550-
)
540+
// If field type is NonNull, complete for inner type, and throw field error
541+
// if result is null.
542+
if let returnType = returnType as? GraphQLNonNull {
543+
let completed = try completeValue(
544+
exeContext: exeContext,
545+
returnType: returnType.ofType,
546+
fieldASTs: fieldASTs,
547+
info: info,
548+
path: path,
549+
result: result
550+
)
551551

552-
guard let c = completed else {
553-
throw GraphQLError(
554-
message: "Cannot return null for non-nullable field \(info.parentType.name).\(info.fieldName)."
555-
)
556-
}
552+
guard let c = completed else {
553+
throw GraphQLError(
554+
message: "Cannot return null for non-nullable field \(info.parentType.name).\(info.fieldName)."
555+
)
556+
}
557557

558-
return c
559-
}
558+
return c
559+
}
560560

561-
// If result value is null-ish (null, undefined, or NaN) then return null.
562-
if isNullish(result) {
563-
return nil
564-
}
561+
// If result value is null-ish (null, undefined, or NaN) then return null.
562+
if isNullish(result) {
563+
return nil
564+
}
565565

566-
// If field type is List, complete each item in the list with the inner type
567-
if let returnType = returnType as? GraphQLList {
568-
return try completeListValue(
569-
exeContext: exeContext,
570-
returnType: returnType,
571-
fieldASTs: fieldASTs,
572-
info: info,
573-
path: path,
574-
result: result
575-
)
576-
}
566+
// If field type is List, complete each item in the list with the inner type
567+
if let returnType = returnType as? GraphQLList {
568+
return try completeListValue(
569+
exeContext: exeContext,
570+
returnType: returnType,
571+
fieldASTs: fieldASTs,
572+
info: info,
573+
path: path,
574+
result: result
575+
)
576+
}
577577

578-
// If field type is a leaf type, Scalar or Enum, serialize to a valid value,
579-
// returning null if serialization is not possible.
580-
if let returnType = returnType as? GraphQLLeafType {
581-
return try completeLeafValue(returnType: returnType, result: result)
582-
}
578+
// If field type is a leaf type, Scalar or Enum, serialize to a valid value,
579+
// returning null if serialization is not possible.
580+
if let returnType = returnType as? GraphQLLeafType {
581+
return try completeLeafValue(returnType: returnType, result: result)
582+
}
583583

584-
// If field type is an abstract type, Interface or Union, determine the
585-
// runtime Object type and complete for that type.
586-
if let returnType = returnType as? GraphQLAbstractType {
587-
return try completeAbstractValue(
588-
exeContext: exeContext,
589-
returnType: returnType,
590-
fieldASTs: fieldASTs,
591-
info: info,
592-
path: path,
593-
result: result
594-
)
595-
}
584+
// If field type is an abstract type, Interface or Union, determine the
585+
// runtime Object type and complete for that type.
586+
if let returnType = returnType as? GraphQLAbstractType {
587+
return try completeAbstractValue(
588+
exeContext: exeContext,
589+
returnType: returnType,
590+
fieldASTs: fieldASTs,
591+
info: info,
592+
path: path,
593+
result: result
594+
)
595+
}
596596

597-
// If field type is Object, execute and complete all sub-selections.
598-
if let returnType = returnType as? GraphQLObjectType {
599-
return try completeObjectValue(
600-
exeContext: exeContext,
601-
returnType: returnType,
602-
fieldASTs: fieldASTs,
603-
info: info,
604-
path: path,
605-
result: result
597+
// If field type is Object, execute and complete all sub-selections.
598+
if let returnType = returnType as? GraphQLObjectType {
599+
return try completeObjectValue(
600+
exeContext: exeContext,
601+
returnType: returnType,
602+
fieldASTs: fieldASTs,
603+
info: info,
604+
path: path,
605+
result: result
606+
)
607+
}
608+
609+
// Not reachable. All possible output types have been considered.
610+
throw GraphQLError(
611+
message: "Cannot complete value of unexpected type \"\(returnType)\"."
606612
)
607-
}
608-
609-
// Not reachable. All possible output types have been considered.
610-
throw GraphQLError(
611-
message: "Cannot complete value of unexpected type \"\(returnType)\"."
612-
)
613613
}
614614

615615
/**
@@ -675,8 +675,8 @@ func completeLeafValue(returnType: GraphQLLeafType, result: Map) throws -> Map {
675675
* of that value, then complete the value for that type.
676676
*/
677677
func completeAbstractValue(exeContext: ExecutionContext, returnType: GraphQLAbstractType, fieldASTs: [Field], info: GraphQLResolveInfo, path: [IndexPathElement], result: Map) throws -> Map {
678-
let resolveRes = returnType.resolveType?(result, exeContext.contextValue, info) ??
679-
defaultResolveType(value: result, context: exeContext.contextValue, info: info, abstractType: returnType).map({ .type($0) })
678+
let resolveRes = try returnType.resolveType?(result, exeContext.contextValue, info) ??
679+
defaultResolveType(value: result, context: exeContext.contextValue, info: info, abstractType: returnType).map({ .type($0) })
680680

681681
guard let resolveResult = resolveRes else {
682682
throw GraphQLError(
@@ -685,7 +685,7 @@ func completeAbstractValue(exeContext: ExecutionContext, returnType: GraphQLAbst
685685
)
686686
}
687687

688-
// If resolveType returns a string, we assume it's a GraphQLObjectType name.
688+
// If resolveType returns a string, we assume it's a GraphQLObjectType name.
689689
var runtimeType: GraphQLType?
690690

691691
switch resolveResult {
@@ -695,33 +695,33 @@ func completeAbstractValue(exeContext: ExecutionContext, returnType: GraphQLAbst
695695
runtimeType = type
696696
}
697697

698-
guard let objectType = runtimeType as? GraphQLObjectType else {
699-
throw GraphQLError(
700-
message:
701-
"Abstract type \(returnType.name) must resolve to an Object type at " +
702-
"runtime for field \(info.parentType.name).\(info.fieldName) with " +
703-
"value \"\(resolveResult)\", received \"\(runtimeType)\".",
704-
nodes: fieldASTs
705-
)
706-
}
698+
guard let objectType = runtimeType as? GraphQLObjectType else {
699+
throw GraphQLError(
700+
message:
701+
"Abstract type \(returnType.name) must resolve to an Object type at " +
702+
"runtime for field \(info.parentType.name).\(info.fieldName) with " +
703+
"value \"\(resolveResult)\", received \"\(runtimeType)\".",
704+
nodes: fieldASTs
705+
)
706+
}
707707

708-
if !exeContext.schema.isPossibleType(abstractType: returnType, possibleType: objectType) {
709-
throw GraphQLError(
710-
message:
711-
"Runtime Object type \"\(objectType.name)\" is not a possible type " +
712-
"for \"\(returnType.name)\".",
713-
nodes: fieldASTs
714-
)
715-
}
708+
if !exeContext.schema.isPossibleType(abstractType: returnType, possibleType: objectType) {
709+
throw GraphQLError(
710+
message:
711+
"Runtime Object type \"\(objectType.name)\" is not a possible type " +
712+
"for \"\(returnType.name)\".",
713+
nodes: fieldASTs
714+
)
715+
}
716716

717-
return try completeObjectValue(
718-
exeContext: exeContext,
719-
returnType: objectType,
720-
fieldASTs: fieldASTs,
721-
info: info,
722-
path: path,
723-
result: result
724-
)
717+
return try completeObjectValue(
718+
exeContext: exeContext,
719+
returnType: objectType,
720+
fieldASTs: fieldASTs,
721+
info: info,
722+
path: path,
723+
result: result
724+
)
725725
}
726726

727727
/**

Sources/GraphQL/Type/Definition.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ public enum TypeResolveResult {
378378
case name(String)
379379
}
380380

381-
public typealias GraphQLTypeResolve = (_ value: Map, _ context: Map, _ info: GraphQLResolveInfo) -> TypeResolveResult
381+
public typealias GraphQLTypeResolve = (_ value: Map, _ context: Map, _ info: GraphQLResolveInfo) throws -> TypeResolveResult
382382

383383
public typealias GraphQLIsTypeOf = (_ source: Map, _ context: Map, _ info: GraphQLResolveInfo) -> Bool
384384

Sources/GraphQL/Type/Schema.swift

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -171,52 +171,67 @@ public final class GraphQLSchema {
171171

172172
public typealias TypeMap = [String: GraphQLNamedType]
173173

174-
public enum SchemaError : Error {
175-
// 'Schema must contain unique named types but contains multiple ' +
176-
// `types named "${type.name}".`
177-
case multipleTypesWithTheSameName
178-
}
174+
func typeMapReducer(map: TypeMap, type: GraphQLType) throws -> TypeMap {
175+
var map = map
179176

180-
func typeMapReducer(map: TypeMap, type: GraphQLNamedType) throws -> TypeMap {
181-
// if type is List || type is NonNull {
182-
// return typeMapReducer(map: map, type: type.ofType)
183-
// }
177+
if let type = type as? GraphQLWrapperType {
178+
return try typeMapReducer(map: map, type: type.wrappedType)
179+
}
184180

185-
// guard map[type.name] == nil else {
186-
// // check for identity
187-
// throw SchemaError.multipleTypesWithTheSameName
188-
// }
181+
guard let type = type as? GraphQLNamedType else {
182+
return map // Should never happen
183+
}
189184

190-
// map[type.name] = type
185+
// guard map[type.name] == nil else {
186+
// invariant(
187+
// map[type.name] === type,
188+
// 'Schema must contain unique named types but contains multiple ' +
189+
// `types named "${type.name}".`
190+
// );
191+
// }
192+
193+
map[type.name] = type
191194

192195
var reducedMap = map
193196

194-
// if let union = type as? UnionType {
195-
// reducedMap = type.getTypes().reduce(typeMapReducer, reducedMap)
196-
// }
197+
if let type = type as? GraphQLUnionType {
198+
reducedMap = try type.types.reduce(reducedMap, typeMapReducer)
199+
}
197200

198-
// if let object = type as? ObjectType {
199-
// reducedMap = object.interfaces.reduce(typeMapReducer, reducedMap)
200-
// }
201+
if let type = type as? GraphQLObjectType {
202+
reducedMap = try type.interfaces.reduce(reducedMap, typeMapReducer)
203+
}
201204

202-
// if type is ObjectType || type is InterfaceType {
203-
// for (_, field) in type.fields {
204-
//
205-
// if !field.args.isEmpty {
206-
// let fieldArgTypes = field.args.map($0.type)
207-
// reducedMap = fieldArgTypes.reduce(typeMapReducer, reducedMap)
208-
// }
209-
//
210-
// reducedMap = typeMapReducer(reducedMap, field.type)
211-
// }
212-
// }
213-
//
214-
// if type is InputObjectType {
215-
// for (_, field) in type.fields {
216-
// reducedMap = typeMapReducer(reducedMap, field.type)
217-
// }
218-
// }
205+
if let type = type as? GraphQLObjectType {
206+
for (_, field) in type.fields {
219207

208+
if !field.args.isEmpty {
209+
let fieldArgTypes = field.args.values.map({ $0.type })
210+
reducedMap = try fieldArgTypes.reduce(reducedMap, typeMapReducer)
211+
}
212+
213+
reducedMap = try typeMapReducer(map: reducedMap, type: field.type)
214+
}
215+
}
216+
217+
if let type = type as? GraphQLInterfaceType {
218+
for (_, field) in type.fields {
219+
220+
if !field.args.isEmpty {
221+
let fieldArgTypes = field.args.values.map({ $0.type })
222+
reducedMap = try fieldArgTypes.reduce(reducedMap, typeMapReducer)
223+
}
224+
225+
reducedMap = try typeMapReducer(map: reducedMap, type: field.type)
226+
}
227+
}
228+
229+
if let type = type as? GraphQLInputObjectType {
230+
for (_, field) in type.fields {
231+
reducedMap = try typeMapReducer(map: reducedMap, type: field.type)
232+
}
233+
}
234+
220235
return reducedMap
221236
}
222237

Tests/GraphQLTests/StarWarsTests/StarWarsData.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
*/
88

99
enum Episode : String {
10-
case newHope = "A New Hope"
11-
case empire = "The Empire Strikes Back"
12-
case jedi = "Return of the Jedi"
10+
case newHope = "NEWHOPE"
11+
case empire = "EMPIRE"
12+
case jedi = "JEDI"
1313
}
1414

1515
protocol Character {

0 commit comments

Comments
 (0)