Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render Selection Set Templates [3/X] #2117

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 100 additions & 17 deletions Apollo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

63 changes: 63 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/AllAnimalsQuery.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
public struct Data: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Object(API.Query.self) }
public static var selections: [Selection] { [
.field("allAnimals", [Animal].self),
] }

public var allAnimals: [AllAnimal] { data["allAnimals"] }

public struct AllAnimal: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Interface(API.Animal.self) }
public static var selections: [Selection] { [
.field("height", Height.self),
.field("species", String.self),
.field("skinCovering", GraphQLEnum<SkinCovering>?.self),
.field("predators", [Animal].self),
.typeCase(AsWarmBlooded.self),
.typeCase(AsPet.self),
.typeCase(AsCat.self),
.typeCase(AsClassroomPet.self),
.fragment(HeightInMeters.self),
] }

public var height: Height { data["height"] }
public var species: String { data["species"] }
public var skinCovering: GraphQLEnum<SkinCovering>? { data["skinCovering"] }
public var predators: [Predator] { data["predators"] }

public struct Height: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Object(API.Height.self) }
public static var selections: [Selection] { [
.field("feet", Int.self),
.field("inches", Int.self),
] }

public var feet: Int { data["feet"] }
public var inches: Int { data["inches"] }
public var meters: Int { data["meters"] }

}
public struct Predator: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Interface(API.Animal.self) }
public static var selections: [Selection] { [
.field("species", String.self),
.typeCase(AsWarmBlooded.self),
] }

public var species: String { data["species"] }

}
}
}
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/Animal.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public final class Animal: Interface { }
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/Bird.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public class Bird {}
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/Cat.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public class Cat {}
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/ClassroomPet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public enum ClassroomPet {}
16 changes: 16 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/ClassroomPetDetails.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
public struct ClassroomPetDetails: API.SelectionSet, Fragment {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Union(API.ClassroomPet.self) }
public static var selections: [Selection] { [
.typeCase(AsAnimal.self),
.typeCase(AsPet.self),
.typeCase(AsWarmBlooded.self),
.typeCase(AsCat.self),
.typeCase(AsBird.self),
.typeCase(AsPetRock.self),
] }


}
22 changes: 22 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/ClassroomPets.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
public struct Data: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Object(API.Query.self) }
public static var selections: [Selection] { [
.field("classroomPets", [ClassroomPet].self),
] }

public var classroomPets: [ClassroomPet] { data["classroomPets"] }

public struct ClassroomPet: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Union(API.ClassroomPet.self) }
public static var selections: [Selection] { [
.fragment(ClassroomPetDetails.self),
] }

}
}
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/Height.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public class Height {}
24 changes: 24 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/HeightInMeters.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
public struct HeightInMeters: API.SelectionSet, Fragment {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Interface(API.Animal.self) }
public static var selections: [Selection] { [
.field("height", Height.self),
] }

public var height: Height { data["height"] }

public struct Height: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Object(API.Height.self) }
public static var selections: [Selection] { [
.field("meters", Int.self),
] }

public var meters: Int { data["meters"] }

}
}
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/Human.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public class Human {}
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/Pet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public final class Pet: Interface { }
28 changes: 28 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/PetDetails.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
public struct PetDetails: API.SelectionSet, Fragment {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Interface(API.Pet.self) }
public static var selections: [Selection] { [
.field("humanName", String?.self),
.field("favoriteToy", String.self),
.field("owner", Human?.self),
] }

public var humanName: String? { data["humanName"] }
public var favoriteToy: String { data["favoriteToy"] }
public var owner: Owner? { data["owner"] }

public struct Owner: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Object(API.Human.self) }
public static var selections: [Selection] { [
.field("firstName", String.self),
] }

public var firstName: String { data["firstName"] }

}
}
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/PetRock.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public class PetRock {}
5 changes: 5 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/RelativeSize.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public enum RelativeSize: String, EnumType {
case LARGE
case AVERAGE
case SMALL
}
22 changes: 22 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/Schema.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import ApolloAPI

public typealias ID = String

public protocol SelectionSet: ApolloAPI.SelectionSet & ApolloAPI.RootSelectionSet
where Schema == API.Schema {}

public protocol TypeCase: ApolloAPI.SelectionSet & ApolloAPI.TypeCase
where Schema == API.Schema {}

public enum Schema: SchemaConfiguration {
public static func objectType(forTypename __typename: String) -> Object.Type? {
switch __typename {
case "Height": return API.Height.self
case "Human": return API.Human.self
case "Cat": return API.Cat.self
case "Bird": return API.Bird.self
case "PetRock": return API.PetRock.self
default: return nil
}
}
}
6 changes: 6 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/SkinCovering.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
public enum SkinCovering: String, EnumType {
case FUR
case HAIR
case FEATHERS
case SCALES
}
1 change: 1 addition & 0 deletions Sources/AnimalKingdomAPI/graphql/API/WarmBlooded.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public final class WarmBlooded: Interface { }
28 changes: 28 additions & 0 deletions Sources/AnimalKingdomAPI/graphql/API/WarmBloodedDetails.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
public struct WarmBloodedDetails: API.SelectionSet, Fragment {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Interface(API.WarmBlooded.self) }
public static var selections: [Selection] { [
.field("bodyTemperature", Int.self),
.field("height", Height.self),
] }

public var bodyTemperature: Int { data["bodyTemperature"] }
public var height: Height { data["height"] }

public struct Height: API.SelectionSet {
public let data: ResponseDict
public init(data: ResponseDict) { self.data = data }

public static var __parentType: ParentType { .Object(API.Height.self) }
public static var selections: [Selection] { [
.field("meters", Int.self),
.field("yards", Int.self),
] }

public var meters: Int { data["meters"] }
public var yards: Int { data["yards"] }

}
}
14 changes: 13 additions & 1 deletion Sources/ApolloCodegenLib/ApolloCodegen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,18 @@ public class ApolloCodegen {
directoryPath: modulePath
).generateFile()

#warning("TODO - generate operation/fragment files")
for fragment in compilationResult.fragments {
let irFragment = ir.build(fragment: fragment)
try FragmentFileGenerator(fragment: irFragment, schema: ir.schema, directoryPath: modulePath)
.generateFile()
}

for operation in compilationResult.operations {
let irOperation = ir.build(operation: operation)
try OperationFileGenerator(operation: irOperation, schema: ir.schema, directoryPath: modulePath)
.generateFile()
}

#warning("TODO - generate package manager manifest")
}

Expand Down Expand Up @@ -125,6 +136,7 @@ public class ApolloCodegen {
InputObjectFileGenerator(inputObjectType: graphqlInputObjectType, directoryPath: path)
})
}

}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Foundation

/// Generates a file containing the Swift representation of a GraphQL Fragment.
struct FragmentFileGenerator: FileGenerator {
/// The `IR.NamedFragment` object used to build the file content.
let fragment: IR.NamedFragment
let schema: IR.Schema
let path: String

var data: Data? {
SelectionSetTemplate(schema: schema)
.render(for: fragment)
.data(using: .utf8)
}

/// Designated initializer.
///
/// - Parameters:
/// - fragment: The `IR.NamedFragment` object used to build the file content.
/// - schema: The `IR.Schema` the fragment is belongs to.
/// - directoryPath: The **directory** path that the file should be written to, used to build the `path` property value.
init(fragment: IR.NamedFragment, schema: IR.Schema, directoryPath: String) {
self.fragment = fragment
self.schema = schema

self.path = URL(fileURLWithPath: directoryPath)
.appendingPathComponent("\(fragment.definition.name).swift").path
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Foundation

/// Generates a file containing the Swift representation of a GraphQL Operation.
struct OperationFileGenerator: FileGenerator {
/// The `IR.Operation` object used to build the file content.
let operation: IR.Operation
let schema: IR.Schema
let path: String

var data: Data? {
SelectionSetTemplate(schema: schema)
.render(for: operation)
.data(using: .utf8)
}

/// Designated initializer.
///
/// - Parameters:
/// - operation: The `IR.Operation` object used to build the file content.
/// - schema: The `IR.Schema` the operation is belongs to.
/// - directoryPath: The **directory** path that the file should be written to, used to build the `path` property value.
init(operation: IR.Operation, schema: IR.Schema, directoryPath: String) {
self.operation = operation
self.schema = schema

self.path = URL(fileURLWithPath: directoryPath)
.appendingPathComponent("\(operation.definition.name).swift").path
}
}
2 changes: 1 addition & 1 deletion Sources/ApolloCodegenLib/FileManager+Apollo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ApolloUtils

public typealias FileAttributes = [FileAttributeKey : Any]

/// Enables the `.apollo` etension namespace.
/// Enables the `.apollo` extension namespace.
extension FileManager: ApolloCompatible {}

extension ApolloExtension where Base: FileManager {
Expand Down
Loading