diff --git a/.swift-version b/.swift-version index 5186d070..7d5c902e 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -4.0 +4.1 diff --git a/.travis.yml b/.travis.yml index 6576a483..611b6c5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ matrix: include: - os: osx env: JOB=SwiftPM_OSX - osx_image: xcode9 + osx_image: xcode9.3beta - os: linux env: JOB=SwiftPM_linux dist: trusty @@ -16,4 +16,6 @@ script: - swift build -c release - swift build - swift test - - eval "$(curl -sL https://raw.githubusercontent.com/lgaches/swifttravisci/master/codecov)" + - 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + eval "$(curl -sL https://raw.githubusercontent.com/lgaches/swifttravisci/master/codecov)"; + fi' diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 00000000..d4394b94 --- /dev/null +++ b/Package.resolved @@ -0,0 +1,25 @@ +{ + "object": { + "pins": [ + { + "package": "GraphQL", + "repositoryURL": "https://github.com/GraphQLSwift/GraphQL.git", + "state": { + "branch": null, + "revision": "faa869cdf0214cf25aa8df1081891b5e8647d6df", + "version": "0.5.0" + } + }, + { + "package": "Runtime", + "repositoryURL": "https://github.com/wickwirew/Runtime.git", + "state": { + "branch": null, + "revision": "9f9e3078fff093adbd8f43df1052ee5d68b05c2a", + "version": "0.6.0" + } + } + ] + }, + "version": 1 +} diff --git a/Package.swift b/Package.swift index 3e6ced57..96abb64b 100644 --- a/Package.swift +++ b/Package.swift @@ -1,8 +1,20 @@ +// swift-tools-version:4.0 import PackageDescription let package = Package( name: "Graphiti", + + products: [ + .library(name: "Graphiti", targets: ["Graphiti"]), + ], + dependencies: [ - .Package(url: "https://github.com/GraphQLSwift/GraphQL.git", majorVersion: 0, minor: 3), + .package(url: "https://github.com/GraphQLSwift/GraphQL.git", from: "0.5.0"), + ], + + targets: [ + .target(name: "Graphiti", dependencies: ["GraphQL"]), + + .testTarget(name: "GraphitiTests", dependencies: ["Graphiti"]), ] ) diff --git a/Sources/Graphiti/Graphiti.swift b/Sources/Graphiti/Graphiti.swift index f102fa1e..9470ffe0 100644 --- a/Sources/Graphiti/Graphiti.swift +++ b/Sources/Graphiti/Graphiti.swift @@ -19,7 +19,7 @@ final class AnyType : Hashable { } func isProtocol(type: Any.Type) -> Bool { - let description = String(describing: type(of: type)) + let description = String(describing: Swift.type(of: type)) return description.hasSuffix("Protocol") } @@ -29,11 +29,11 @@ func fixName(_ name: String) -> String { var workingString = name if name.hasPrefix("(") { - workingString = String(name.characters.dropFirst()) + workingString = String(name.dropFirst()) } var newName: [Character] = [] - for character in workingString.characters { + for character in workingString { if character != " " { newName.append(character) } else { diff --git a/Sources/Graphiti/Schema/Schema.swift b/Sources/Graphiti/Schema/Schema.swift index 16e063ce..69c1aef6 100644 --- a/Sources/Graphiti/Schema/Schema.swift +++ b/Sources/Graphiti/Schema/Schema.swift @@ -1,4 +1,5 @@ import GraphQL +import Runtime public final class SchemaBuilder { var graphQLTypeMap: [AnyType: GraphQLType] = [ @@ -261,7 +262,7 @@ public final class SchemaBuilder { } } -extension SchemaBuilder { +public extension SchemaBuilder { func map(_ type: Any.Type, to graphQLType: GraphQLType) { guard !(type is Void.Type) else { return @@ -339,7 +340,7 @@ extension SchemaBuilder { return outputType } - func getInputType(from type: Any.Type, field: String) throws -> GraphQLInputType { + public func getInputType(from type: Any.Type, field: String) throws -> GraphQLInputType { guard let graphQLType = getGraphQLType(from: type) else { throw GraphQLError( message: @@ -462,15 +463,16 @@ extension SchemaBuilder { return [:] } - for property in try properties(type) { + let info = try typeInfo(of: type) + for property in info.properties { if case let propertyType as MapInitializable.Type = property.type { let argument = GraphQLArgument( type: try getInputType(from: propertyType, field: field), - description: argumentsType.descriptions[property.key], - defaultValue: try argumentsType.defaultValues[property.key]?.asMap() + description: argumentsType.descriptions[property.name], + defaultValue: try argumentsType.defaultValues[property.name]?.asMap() ) - arguments[property.key] = argument + arguments[property.name] = argument } } diff --git a/Sources/Graphiti/Types/Field.swift b/Sources/Graphiti/Types/Field.swift index 6bba252e..00be722d 100644 --- a/Sources/Graphiti/Types/Field.swift +++ b/Sources/Graphiti/Types/Field.swift @@ -1,4 +1,5 @@ import GraphQL +import Runtime public protocol InputType : MapInitializable {} public protocol OutputType : MapFallibleRepresentable {} @@ -45,10 +46,12 @@ public class FieldBuilder { /// - Parameter excluding: properties excluded from the export /// - Throws: Reflection Errors public func exportFields(excluding: String...) throws { - for property in try properties(Type.self) { - if !excluding.contains(property.key) { - let field = GraphQLField(type: try schema.getOutputType(from: property.type, field: property.key)) - fields[property.key] = field + let info = try typeInfo(of: Type.self) + + for property in info.properties { + if !excluding.contains(property.name) { + let field = GraphQLField(type: try schema.getOutputType(from: property.type, field: property.name)) + fields[property.name] = field } } } @@ -65,11 +68,11 @@ public class FieldBuilder { if let resolve = resolve { r = { source, _, context, info in guard let s = source as? Type else { - throw GraphQLError(message: "Expected source type \(Type.self) but got \(type(of: source))") + throw GraphQLError(message: "Expected source type \(Type.self) but got \(Swift.type(of: source))") } guard let c = context as? Context else { - throw GraphQLError(message: "Expected context type \(Context.self) but got \(type(of: context))") + throw GraphQLError(message: "Expected context type \(Context.self) but got \(Swift.type(of: context))") } guard let output = try resolve(s, NoArguments(), c, info) else { @@ -103,11 +106,11 @@ public class FieldBuilder { if let resolve = resolve { r = { source, _, context, info in guard let s = source as? Type else { - throw GraphQLError(message: "Expected source type \(Type.self) but got \(type(of: source))") + throw GraphQLError(message: "Expected source type \(Type.self) but got \(Swift.type(of: source))") } guard let c = context as? Context else { - throw GraphQLError(message: "Expected context type \(Context.self) but got \(type(of: context))") + throw GraphQLError(message: "Expected context type \(Context.self) but got \(Swift.type(of: context))") } return try resolve(s, NoArguments(), c, info) @@ -137,11 +140,11 @@ public class FieldBuilder { if let resolve = resolve { r = { source, _, context, info in guard let s = source as? Type else { - throw GraphQLError(message: "Expected source type \(Type.self) but got \(type(of: source))") + throw GraphQLError(message: "Expected source type \(Type.self) but got \(Swift.type(of: source))") } guard let c = context as? Context else { - throw GraphQLError(message: "Expected context type \(Context.self) but got \(type(of: context))") + throw GraphQLError(message: "Expected context type \(Context.self) but got \(Swift.type(of: context))") } return try resolve(s, NoArguments(), c, info) @@ -186,11 +189,11 @@ public class FieldBuilder { if let resolve = resolve { r = { source, _, context, info in guard let s = source as? Type else { - throw GraphQLError(message: "Expected source type \(Type.self) but got \(type(of: source))") + throw GraphQLError(message: "Expected source type \(Type.self) but got \(Swift.type(of: source))") } guard let c = context as? Context else { - throw GraphQLError(message: "Expected context type \(Context.self) but got \(type(of: context))") + throw GraphQLError(message: "Expected context type \(Context.self) but got \(Swift.type(of: context))") } return try resolve(s, NoArguments(), c, info) @@ -225,13 +228,13 @@ public class FieldBuilder { resolve: resolve.map { resolve in return { source, args, context, info in guard let s = source as? Type else { - throw GraphQLError(message: "Expected source type \(Type.self) but got \(type(of: source))") + throw GraphQLError(message: "Expected source type \(Type.self) but got \(Swift.type(of: source))") } let a = try A(map: args) guard let c = context as? Context else { - throw GraphQLError(message: "Expected context type \(Context.self) but got \(type(of: context))") + throw GraphQLError(message: "Expected context type \(Context.self) but got \(Swift.type(of: context))") } guard let output = try resolve(s, a, c, info) else { @@ -263,13 +266,13 @@ public class FieldBuilder { resolve: resolve.map { resolve in return { source, args, context, info in guard let s = source as? Type else { - throw GraphQLError(message: "Expected type \(Type.self) but got \(type(of: source))") + throw GraphQLError(message: "Expected type \(Type.self) but got \(Swift.type(of: source))") } let a = try A(map: args) guard let c = context as? Context else { - throw GraphQLError(message: "Expected context type \(Context.self) but got \(type(of: context))") + throw GraphQLError(message: "Expected context type \(Context.self) but got \(Swift.type(of: context))") } return try resolve(s, a, c, info) diff --git a/Sources/Graphiti/Types/InputObjectType.swift b/Sources/Graphiti/Types/InputObjectType.swift index 5f613d2e..cf423bf1 100644 --- a/Sources/Graphiti/Types/InputObjectType.swift +++ b/Sources/Graphiti/Types/InputObjectType.swift @@ -1,4 +1,5 @@ import GraphQL +import Runtime public final class InputObjectTypeBuilder { var schema: SchemaBuilder @@ -14,11 +15,20 @@ public final class InputObjectTypeBuilder { /// Export all properties using reflection /// /// - Throws: Reflection Errors - public func exportFields() throws { - for property in try properties(Type.self) { - let field = InputObjectField(type: try schema.getInputType(from: property.type, field: property.key)) - fields[property.key] = field + public func exportFields(excluding: String...) throws { + + let info = try typeInfo(of: Type.self) + + for property in info.properties { + if !excluding.contains(property.name) { + let field = InputObjectField(type: try schema.getInputType(from: property.type, field: property.name)) + fields[property.name] = field + } } } + + public func addFieldMap(key: String, fieldMap: InputObjectField) { + fields[key] = fieldMap + } } diff --git a/Sources/Graphiti/Types/InterfaceType.swift b/Sources/Graphiti/Types/InterfaceType.swift index e25db07f..82ac25c8 100644 --- a/Sources/Graphiti/Types/InterfaceType.swift +++ b/Sources/Graphiti/Types/InterfaceType.swift @@ -13,11 +13,11 @@ public final class InterfaceTypeBuilder : FieldBuilder) { self.resolveType = { value, context, info in guard let v = value as? Type else { - throw GraphQLError(message: "Expected value type \(Type.self) but got \(type(of: value))") + throw GraphQLError(message: "Expected value type \(Type.self) but got \(Swift.type(of: value))") } guard let c = context as? Context else { - throw GraphQLError(message: "Expected context type \(Context.self) but got \(type(of: context))") + throw GraphQLError(message: "Expected context type \(Context.self) but got \(Swift.type(of: context))") } let type = try resolve(v, c, info) diff --git a/Tests/GraphitiTests/HelloWorldTests/HelloWorldTests.swift b/Tests/GraphitiTests/HelloWorldTests/HelloWorldTests.swift index 76355a38..aff31c83 100644 --- a/Tests/GraphitiTests/HelloWorldTests/HelloWorldTests.swift +++ b/Tests/GraphitiTests/HelloWorldTests/HelloWorldTests.swift @@ -15,7 +15,7 @@ extension Float : InputType, OutputType { class HelloWorldTests : XCTestCase { let schema = try! Schema { schema in try schema.query { query in - try query.field(name: "hello", type: String.self) { _ in + try query.field(name: "hello", type: String.self) { (_, _, _, _) -> String in "world" } } diff --git a/Tests/GraphitiTests/StarWarsTests/StarWarsQueryTests.swift b/Tests/GraphitiTests/StarWarsTests/StarWarsQueryTests.swift index c6d425db..a72c665f 100644 --- a/Tests/GraphitiTests/StarWarsTests/StarWarsQueryTests.swift +++ b/Tests/GraphitiTests/StarWarsTests/StarWarsQueryTests.swift @@ -443,9 +443,15 @@ class StarWarsQueryTests : XCTestCase { struct A : OutputType {} try schema.object(type: A.self) { a in - try a.field(name: "nullableA", type: (TypeReference?).self) { _ in A() } - try a.field(name: "nonNullA", type: TypeReference.self) { _ in A() } - try a.field(name: "throws", type: String.self) { _ in + try a.field(name: "nullableA", type: (TypeReference?).self) { (_, _, _, _) -> A? + in A() + } + + try a.field(name: "nonNullA", type: TypeReference.self) { (_, _, _, _) -> A + in A() + } + + try a.field(name: "throws", type: String.self) { (_, _, _, _) -> String in struct 🏃 : Error, CustomStringConvertible { let description: String } @@ -455,7 +461,9 @@ class StarWarsQueryTests : XCTestCase { } try schema.query { query in - try query.field(name: "nullableA", type: (A?).self) { _ in A() } + try query.field(name: "nullableA", type: (A?).self) { (_, _, _, _) -> A? in + A() + } } }