diff --git a/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/GraphQLObject+resolve.swift b/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/GraphQLObject+resolve.swift index e3eb298..1019363 100644 --- a/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/GraphQLObject+resolve.swift +++ b/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/GraphQLObject+resolve.swift @@ -7,7 +7,22 @@ import NIO extension GraphQLObject { static func resolveObject(using context: inout Resolution.Context) throws -> GraphQLObjectType { - let (typeProperties, typeMethods, inheritance) = try typeInfo(of: Self.self, .properties, .methods, .inheritance) + let inheritance = try typeInfo(of: Self.self, .inheritance) + let fieldsAndInterfaces = try self.fieldsAndInterfaces(using: &context) + + let interfaces = try inheritance + .compactMap { $0 as? GraphQLObject.Type } + .map { try context.resolveInterface(object: $0) } + fieldsAndInterfaces.interfaces + + let type = try GraphQLObjectType(name: concreteTypeName, + fields: fieldsAndInterfaces.fields, + interfaces: interfaces.distinct(by: \.name)) { value, _, _ in value is Self } + + return type + } + + static func fieldsAndInterfaces(using context: inout Resolution.Context) throws -> FieldsAndInterfaces { + let (typeProperties, typeMethods) = try typeInfo(of: Self.self, .properties, .methods) let isNode: Bool if let type = Self.self as? Node.Type { @@ -31,17 +46,16 @@ extension GraphQLObject { .merging(methods) { $1 } .merging(nodeFields) { $1 } - let interfaces = try inheritance - .compactMap { $0 as? GraphQLObject.Type } - .map { try context.resolveInterface(object: $0) } + propertyResults.flatMap(\.interfaces) + [isNode ? GraphQLNode : nil].compactMap { $0 } - - let type = try GraphQLObjectType(name: concreteTypeName, fields: fields, interfaces: interfaces.distinct(by: \.name)) { value, _, _ in value is Self } - - return type + return FieldsAndInterfaces(interfaces: propertyResults.flatMap(\.interfaces) + [isNode ? GraphQLNode : nil].compactMap { $0 }, fields: fields) } } +struct FieldsAndInterfaces { + let interfaces: [GraphQLInterfaceType] + let fields: GraphQLFieldMap +} + extension Sequence { fileprivate func distinct(by id: (Element) -> T) -> [Element] { diff --git a/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/PropertyWrappers/Inline.swift b/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/PropertyWrappers/Inline.swift index d8b9883..c5118df 100644 --- a/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/PropertyWrappers/Inline.swift +++ b/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/PropertyWrappers/Inline.swift @@ -18,19 +18,13 @@ extension Inline: CustomGraphQLProperty { for receiverType: GraphQLObject.Type, using context: inout Resolution.Context) throws -> PropertyResult { - let object = try Wrapped.resolveObject(using: &context) - - let fields = object.fields.mapValues { field in + let fields = try Wrapped.fieldsAndInterfaces(using: &context).fields.mapValues { field in return GraphQLField( type: field.type, description: field.description, deprecationReason: field.deprecationReason, - args: Dictionary( - uniqueKeysWithValues: field.args.map { ($0.name, $0.type) } - ) - .mapValues { GraphQLArgument(type: $0) } + args: field.args ) { source, arguments, context, eventLoop, info in - let object = receiverType.object(from: source) let result = try property.get(from: object) as! Self return try field.resolve!(result.wrappedValue, arguments, context, eventLoop, info) diff --git a/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/PropertyWrappers/LazyInline.swift b/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/PropertyWrappers/LazyInline.swift index 7127229..2a07817 100644 --- a/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/PropertyWrappers/LazyInline.swift +++ b/Sources/GraphZahl/Resolution/OutputResolvable/Implementations/Object/PropertyWrappers/LazyInline.swift @@ -26,17 +26,12 @@ extension LazyInline: CustomGraphQLProperty { for receiverType: GraphQLObject.Type, using context: inout Resolution.Context) throws -> PropertyResult { - let object = try Wrapped.resolveObject(using: &context) - - let fields = object.fields.mapValues { field in + let fields = try Wrapped.fieldsAndInterfaces(using: &context).fields.mapValues { field in return GraphQLField( type: field.type, description: field.description, deprecationReason: field.deprecationReason, - args: Dictionary( - uniqueKeysWithValues: field.args.map { ($0.name, $0.type) } - ) - .mapValues { GraphQLArgument(type: $0) } + args: field.args ) { source, arguments, context, eventLoop, info in let object = receiverType.object(from: source)