Skip to content
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
11 changes: 10 additions & 1 deletion Examples/HelloWorldServer/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Examples/HelloWorldServer/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let package = Package(
name: "HelloWorldServer",
dependencies: [
.product(name: "GraphQL", package: "GraphQL"),
.product(name: "GraphQLGeneratorMacros", package: "graphql-generator"),
.product(name: "GraphQLGeneratorRuntime", package: "graphql-generator"),
],
plugins: [
Expand Down
59 changes: 19 additions & 40 deletions Examples/HelloWorldServer/Sources/HelloWorldServer/Resolvers.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation
import GraphQL
import GraphQLGeneratorMacros
import GraphQLGeneratorRuntime

/// Must be created by user and named `GraphQLContext`.
Expand Down Expand Up @@ -76,64 +77,42 @@ struct Resolvers: GraphQLGenerated.Resolvers {

struct User: GraphQLGenerated.User {
// User can choose structure
let id: String
let name: String
let email: String
let age: Int?
let role: GraphQLGenerated.Role?

/// Required implementations
func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return id
}
// Properties with auto-generated GraphQL resolvers.

func name(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return name
}
@graphQLResolver let id: String
@graphQLResolver let name: String
@graphQLResolver let age: Int?
@graphQLResolver let role: GraphQLGenerated.Role?

// Required implementations
// Can't use @graphQLResolver macro because we must convert from String to GraphQLScalars.EmailAddress

let email: String
func email(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> GraphQLScalars.EmailAddress {
return .init(email: email)
}

func age(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> Int? {
return age
}

func role(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> GraphQLGenerated.Role? {
return role
}
}

struct Contact: GraphQLGenerated.Contact {
/// User can choose structure
let email: String
// User can choose structure

/// Required implementations
let email: String
func email(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> GraphQLScalars.EmailAddress {
return .init(email: email)
}
}

struct Post: GraphQLGenerated.Post {
// User can choose structure
let id: String
let title: String
let content: String
let authorId: String

/// Required implementations
func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return id
}

func title(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return title
}

func content(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return content
}
@graphQLResolver let id: String
@graphQLResolver let title: String
@graphQLResolver let content: String

/// Required implementations
let authorId: String
func author(context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> any GraphQLGenerated.User {
return context.users[authorId]!
}
Expand Down Expand Up @@ -168,9 +147,9 @@ struct Mutation: GraphQLGenerated.Mutation {
let user = User(
id: userInfo.id,
name: userInfo.name,
email: userInfo.email.email,
age: userInfo.age,
role: userInfo.role
role: userInfo.role,
email: userInfo.email.email
)
context.users[userInfo.id] = user
return user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ union UserOrPost = User | Post
input UserInfo {
id: ID!
name: String!
email: EmailAddress!
age: Int
role: Role = USER
email: EmailAddress!
}

"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ struct HelloWorldServerTests {
@Test func query() async throws {
let schema = try buildGraphQLSchema(resolvers: Resolvers.self)
let context = GraphQLContext(
users: ["1": .init(id: "1", name: "John", email: "john@example.com", age: 18, role: .user)],
users: ["1": .init(id: "1", name: "John", age: 18, role: .user, email: "john@example.com")],
posts: ["1": .init(id: "1", title: "Foo", content: "bar", authorId: "1")]
)
let actual = try await graphql(
Expand Down Expand Up @@ -89,7 +89,7 @@ struct HelloWorldServerTests {
@Test func subscription() async throws {
let schema = try buildGraphQLSchema(resolvers: Resolvers.self)
let context = GraphQLContext(
users: ["1": .init(id: "1", name: "John", email: "john@example.com", age: 18, role: .user)],
users: ["1": .init(id: "1", name: "John", age: 18, role: .user, email: "john@example.com")],
posts: [:]
)
let stream = try await graphqlSubscribe(
Expand Down
11 changes: 10 additions & 1 deletion Examples/StarWars/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Examples/StarWars/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ let package = Package(
.product(name: "AsyncDataLoader", package: "DataLoader"),
.product(name: "AsyncHTTPClient", package: "async-http-client"),
.product(name: "GraphQL", package: "GraphQL"),
.product(name: "GraphQLGeneratorMacros", package: "graphql-generator"),
.product(name: "GraphQLGeneratorRuntime", package: "graphql-generator"),
],
plugins: [
Expand Down
49 changes: 9 additions & 40 deletions Examples/StarWars/Sources/StarWars/GraphQL/Relay.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation
import GraphQL
import GraphQLGeneratorMacros

/// Encodes a SWAPI type and ID into a Relay Node ID. This is the base64-encoded string `<type>:<id>`
/// - Parameters:
Expand All @@ -26,33 +27,17 @@ func urlToID(_ url: String) -> String {
}

struct PageInfo: GraphQLGenerated.PageInfo {
let hasNextPage: Bool
let hasPreviousPage: Bool
let startCursor: String?
let endCursor: String?

func hasNextPage(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> Bool {
return hasNextPage
}

func hasPreviousPage(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> Bool {
return hasPreviousPage
}

func startCursor(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String? {
return startCursor
}

func endCursor(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String? {
return endCursor
}
@graphQLResolver let hasNextPage: Bool
@graphQLResolver let hasPreviousPage: Bool
@graphQLResolver let startCursor: String?
@graphQLResolver let endCursor: String?
}

/// A generalized Relay connection.
struct Connection<T: GraphQLGenerated.Node>: Sendable {
let pageInfo: PageInfo
let edges: [Edge<T>]
let totalCount: Int
@graphQLResolver let pageInfo: any GraphQLGenerated.PageInfo
@graphQLResolver let edges: [Edge<T>]
@graphQLResolver let totalCount: Int?

/// Create a connection by passing a total list of the available IDs in order.
init(ids: [String], after: String?, first: Int?, before: String?, last: Int?) {
Expand Down Expand Up @@ -93,18 +78,6 @@ struct Connection<T: GraphQLGenerated.Node>: Sendable {
edges = pageIds.map { Edge<T>(cursor: $0) }
totalCount = ids.count
}

func pageInfo(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> any GraphQLGenerated.PageInfo {
return pageInfo
}

func edges(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> [Edge<T>]? {
return edges
}

func totalCount(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> Int? {
return totalCount
}
}

extension Connection:
Expand Down Expand Up @@ -338,11 +311,7 @@ extension Connection:
}

struct Edge<T: GraphQLGenerated.Node>: Sendable {
let cursor: String

func cursor(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return cursor
}
@graphQLResolver let cursor: String
}

extension Edge:
Expand Down
37 changes: 7 additions & 30 deletions Examples/StarWars/Sources/StarWars/GraphQL/Resolvers.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import AsyncHTTPClient
import Foundation
import GraphQL
import GraphQLGeneratorMacros
import GraphQLGeneratorRuntime

struct GraphQLContext {
Expand Down Expand Up @@ -130,7 +131,7 @@ struct Root: GraphQLGenerated.Root {
}

extension Film: GraphQLGenerated.Film {
var id: String {
@graphQLResolver var id: String {
return encodeID(type: Film.self, id: urlToID(url))
}

Expand Down Expand Up @@ -166,10 +167,6 @@ extension Film: GraphQLGenerated.Film {
return edited
}

func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return id
}

func speciesConnection(after: String?, first: Int?, before: String?, last: Int?, context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> (any GraphQLGenerated.FilmSpeciesConnection)? {
let filteredIDs = species.map { encodeID(type: Film.self, id: urlToID($0)) }
return Connection<Species>(ids: filteredIDs, after: after, first: first, before: before, last: last)
Expand Down Expand Up @@ -197,7 +194,7 @@ extension Film: GraphQLGenerated.Film {
}

extension Person: GraphQLGenerated.Person {
var id: String {
@graphQLResolver var id: String {
return encodeID(type: Person.self, id: urlToID(url))
}

Expand Down Expand Up @@ -266,14 +263,10 @@ extension Person: GraphQLGenerated.Person {
func edited(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String? {
return edited
}

func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return id
}
}

extension Planet: GraphQLGenerated.Planet {
var id: String {
@graphQLResolver var id: String {
return encodeID(type: Planet.self, id: urlToID(url))
}

Expand Down Expand Up @@ -330,14 +323,10 @@ extension Planet: GraphQLGenerated.Planet {
func edited(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String? {
return edited
}

func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return id
}
}

extension Species: GraphQLGenerated.Species {
var id: String {
@graphQLResolver var id: String {
return encodeID(type: Species.self, id: urlToID(url))
}

Expand Down Expand Up @@ -398,14 +387,10 @@ extension Species: GraphQLGenerated.Species {
func edited(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String? {
return edited
}

func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return id
}
}

extension Starship: GraphQLGenerated.Starship {
var id: String {
@graphQLResolver var id: String {
return encodeID(type: Starship.self, id: urlToID(url))
}

Expand Down Expand Up @@ -478,14 +463,10 @@ extension Starship: GraphQLGenerated.Starship {
func edited(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String? {
return edited
}

func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return id
}
}

extension Vehicle: GraphQLGenerated.Vehicle {
var id: String {
@graphQLResolver var id: String {
return encodeID(type: Vehicle.self, id: urlToID(url))
}

Expand Down Expand Up @@ -550,8 +531,4 @@ extension Vehicle: GraphQLGenerated.Vehicle {
func edited(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String? {
return edited
}

func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
return id
}
}
Loading