Skip to content

Commit 6f4bad0

Browse files
feat!: Namespaces generated types
They are placed inside a `GraphQLGenerated` enum. This avoids polluting the inheriting package's namespace, reducing type name conflicts.
1 parent c647919 commit 6f4bad0

5 files changed

Lines changed: 111 additions & 81 deletions

File tree

Examples/HelloWorldServer/Sources/HelloWorldServer/Resolvers.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,19 @@ public struct EmailAddress: Scalar {
6565
}
6666

6767
// Now create types that conform to the expected protocols
68-
struct Resolvers: ResolversProtocol {
68+
struct Resolvers: GraphQLGenerated.ResolversProtocol {
6969
typealias Query = HelloWorldServer.Query
7070
typealias Mutation = HelloWorldServer.Mutation
7171
typealias Subscription = HelloWorldServer.Subscription
7272
}
7373

74-
struct User: UserProtocol {
74+
struct User: GraphQLGenerated.UserProtocol {
7575
// User can choose structure
7676
let id: String
7777
let name: String
7878
let email: String
7979
let age: Int?
80-
let role: Role?
80+
let role: GraphQLGenerated.Role?
8181

8282
// Required implementations
8383
func id(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> String {
@@ -96,12 +96,12 @@ struct User: UserProtocol {
9696
return age
9797
}
9898

99-
func role(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> Role? {
99+
func role(context _: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> GraphQLGenerated.Role? {
100100
return role
101101
}
102102
}
103103

104-
struct Contact: ContactProtocol {
104+
struct Contact: GraphQLGenerated.ContactProtocol {
105105
// User can choose structure
106106
let email: String
107107

@@ -111,7 +111,7 @@ struct Contact: ContactProtocol {
111111
}
112112
}
113113

114-
struct Post: PostProtocol {
114+
struct Post: GraphQLGenerated.PostProtocol {
115115
// User can choose structure
116116
let id: String
117117
let title: String
@@ -131,37 +131,37 @@ struct Post: PostProtocol {
131131
return content
132132
}
133133

134-
func author(context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> any UserProtocol {
134+
func author(context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> any GraphQLGenerated.UserProtocol {
135135
return context.users[authorId]!
136136
}
137137
}
138138

139-
struct Query: QueryProtocol {
139+
struct Query: GraphQLGenerated.QueryProtocol {
140140
// Required implementations
141-
static func user(id: String, context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> (any UserProtocol)? {
141+
static func user(id: String, context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> (any GraphQLGenerated.UserProtocol)? {
142142
return context.users[id]
143143
}
144144

145-
static func users(context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> [any UserProtocol] {
146-
return context.users.values.map { $0 as any UserProtocol }
145+
static func users(context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> [any GraphQLGenerated.UserProtocol] {
146+
return context.users.values.map { $0 as any GraphQLGenerated.UserProtocol }
147147
}
148148

149-
static func post(id: String, context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> (any PostProtocol)? {
149+
static func post(id: String, context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> (any GraphQLGenerated.PostProtocol)? {
150150
return context.posts[id]
151151
}
152152

153-
static func posts(limit _: Int?, context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> [any PostProtocol] {
154-
return context.posts.values.map { $0 as any PostProtocol }
153+
static func posts(limit _: Int?, context: GraphQLContext, info _: GraphQL.GraphQLResolveInfo) async throws -> [any GraphQLGenerated.PostProtocol] {
154+
return context.posts.values.map { $0 as any GraphQLGenerated.PostProtocol }
155155
}
156156

157-
static func userOrPost(id: String, context: GraphQLContext, info _: GraphQLResolveInfo) async throws -> (any UserOrPostUnion)? {
157+
static func userOrPost(id: String, context: GraphQLContext, info _: GraphQLResolveInfo) async throws -> (any GraphQLGenerated.UserOrPostUnion)? {
158158
return context.users[id] ?? context.posts[id]
159159
}
160160
}
161161

162-
struct Mutation: MutationProtocol {
162+
struct Mutation: GraphQLGenerated.MutationProtocol {
163163
// Required implementations
164-
static func upsertUser(userInfo: UserInfoInput, context: GraphQLContext, info _: GraphQLResolveInfo) -> any UserProtocol {
164+
static func upsertUser(userInfo: GraphQLGenerated.UserInfoInput, context: GraphQLContext, info _: GraphQLResolveInfo) -> any GraphQLGenerated.UserProtocol {
165165
let user = User(
166166
id: userInfo.id,
167167
name: userInfo.name,
@@ -174,10 +174,10 @@ struct Mutation: MutationProtocol {
174174
}
175175
}
176176

177-
struct Subscription: SubscriptionProtocol {
177+
struct Subscription: GraphQLGenerated.SubscriptionProtocol {
178178
// Required implementations
179-
static func watchUser(id: String, context: GraphQLContext, info _: GraphQLResolveInfo) async throws -> AnyAsyncSequence<(any UserProtocol)?> {
180-
return AsyncStream<(any UserProtocol)?> { continuation in
179+
static func watchUser(id: String, context: GraphQLContext, info _: GraphQLResolveInfo) async throws -> AnyAsyncSequence<(any GraphQLGenerated.UserProtocol)?> {
180+
return AsyncStream<(any GraphQLGenerated.UserProtocol)?> { continuation in
181181
context.onTriggerWatch = { [weak context] in
182182
continuation.yield(context?.users[id])
183183
}

Sources/GraphQLGeneratorCore/Generator/SchemaGenerator.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ package struct SchemaGenerator {
1515
import GraphQLGeneratorRuntime
1616
1717
/// Build a GraphQL schema with the provided resolvers
18-
func buildGraphQLSchema<Resolvers: ResolversProtocol>(
18+
func buildGraphQLSchema<Resolvers: GraphQLGenerated.ResolversProtocol>(
1919
resolvers: Resolvers.Type,
2020
decoder: MapDecoder = .init()
2121
) throws -> GraphQLSchema {
@@ -712,7 +712,7 @@ package struct SchemaGenerator {
712712
// For nested resolvers, we decode and call the method on the parent instance
713713
// We use the type Declaration name, since this should always be a non-list, non-nullable instance,
714714
// and add 'any' because all intermediate types are represented as protocols
715-
let parentCastType = try swiftTypeDeclaration(for: parentType, nameGenerator: nameGenerator)
715+
let parentCastType = try swiftTypeDeclaration(for: parentType, includeNamespace: true, nameGenerator: nameGenerator)
716716
output += """
717717
718718
let parent = try cast(source, to: (any \(parentCastType)).self)
@@ -722,7 +722,7 @@ package struct SchemaGenerator {
722722
// Add field arguments
723723
for (argName, arg) in field.args {
724724
let safeArgName = nameGenerator.swiftMemberName(for: argName)
725-
let swiftType = try swiftTypeReference(for: arg.type, nameGenerator: nameGenerator)
725+
let swiftType = try swiftTypeReference(for: arg.type, includeNamespace: true, nameGenerator: nameGenerator)
726726
// Extract value from Map based on type
727727
var decodeStatement = "try decoder.decode((\(swiftType)).self, from: args[\"\(argName)\"])"
728728
if !(arg.type is GraphQLNonNull) {

Sources/GraphQLGeneratorCore/Generator/TypeGenerator.swift

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,30 @@ package struct TypeGenerator {
1919
// Generate ResolversProtocol
2020
output += """
2121
22-
protocol ResolversProtocol: Sendable {
22+
enum GraphQLGenerated {
23+
protocol ResolversProtocol: Sendable {
2324
"""
2425
if let queryType = schema.queryType {
2526
output += """
2627
27-
associatedtype Query: \(try swiftTypeDeclaration(for: queryType, nameGenerator: nameGenerator))
28+
associatedtype Query: \(try swiftTypeDeclaration(for: queryType, includeNamespace: false, nameGenerator: nameGenerator))
2829
"""
2930
}
3031
if let mutationType = schema.mutationType {
3132
output += """
3233
33-
associatedtype Mutation: \(try swiftTypeDeclaration(for: mutationType, nameGenerator: nameGenerator))
34+
associatedtype Mutation: \(try swiftTypeDeclaration(for: mutationType, includeNamespace: false, nameGenerator: nameGenerator))
3435
"""
3536
}
3637
if let subscriptionType = schema.subscriptionType {
3738
output += """
3839
39-
associatedtype Subscription: \(try swiftTypeDeclaration(for: subscriptionType, nameGenerator: nameGenerator))
40+
associatedtype Subscription: \(try swiftTypeDeclaration(for: subscriptionType, includeNamespace: false, nameGenerator: nameGenerator))
4041
"""
4142
}
4243
output += """
4344
44-
}
45+
}
4546
"""
4647

4748
// Ignore any internal types (which have prefix "__")
@@ -56,7 +57,7 @@ package struct TypeGenerator {
5657
for type in enumTypes {
5758
output += try"""
5859
59-
\(generateEnum(for: type))
60+
\(generateEnum(for: type).indent(1, includeFirst: true))
6061
"""
6162
}
6263

@@ -67,7 +68,7 @@ package struct TypeGenerator {
6768
for type in inputTypes {
6869
output += try"""
6970
70-
\(generateInputStruct(for: type))
71+
\(generateInputStruct(for: type).indent(1, includeFirst: true))
7172
"""
7273
}
7374

@@ -83,13 +84,13 @@ package struct TypeGenerator {
8384
if let description = type.description {
8485
output += """
8586
86-
\(description.docComment())
87+
\(description.docComment().indent(1, includeFirst: true))
8788
"""
8889
}
89-
let swiftTypeName = try swiftTypeDeclaration(for: type, nameGenerator: nameGenerator)
90+
let swiftTypeName = try swiftTypeDeclaration(for: type, includeNamespace: false, nameGenerator: nameGenerator)
9091
output += """
9192
92-
protocol \(swiftTypeName): Sendable {}
93+
protocol \(swiftTypeName): Sendable {}
9394
"""
9495

9596
// Record which types need to be conformed
@@ -109,7 +110,7 @@ package struct TypeGenerator {
109110
for type in interfaceTypes {
110111
output += try"""
111112
112-
\(generateInterfaceProtocol(for: type))
113+
\(generateInterfaceProtocol(for: type).indent(1, includeFirst: true))
113114
"""
114115
}
115116

@@ -125,33 +126,37 @@ package struct TypeGenerator {
125126
for type in objectTypes {
126127
output += try"""
127128
128-
\(generateTypeProtocol(for: type, unionTypeMap: unionTypeMap))
129+
\(generateTypeProtocol(for: type, unionTypeMap: unionTypeMap).indent(1, includeFirst: true))
129130
"""
130131
}
131132

132133
// Generate Query type
133134
if let queryType = schema.queryType {
134135
output += try"""
135136
136-
\(generateRootTypeProtocol(for: queryType))
137+
\(generateRootTypeProtocol(for: queryType).indent(1, includeFirst: true))
137138
"""
138139
}
139140

140141
// Generate Mutation type
141142
if let mutationType = schema.mutationType {
142143
output += try"""
143144
144-
\(generateRootTypeProtocol(for: mutationType))
145+
\(generateRootTypeProtocol(for: mutationType).indent(1, includeFirst: true))
145146
"""
146147
}
147148

148149
// Generate Mutation type
149150
if let subscriptionType = schema.subscriptionType {
150151
output += try"""
151152
152-
\(generateRootTypeProtocol(for: subscriptionType))
153+
\(generateRootTypeProtocol(for: subscriptionType).indent(1, includeFirst: true))
153154
"""
154155
}
156+
output += """
157+
158+
}
159+
"""
155160

156161
return output
157162
}
@@ -167,7 +172,7 @@ package struct TypeGenerator {
167172
"""
168173
}
169174

170-
let swiftTypeName = try swiftTypeDeclaration(for: type, nameGenerator: nameGenerator)
175+
let swiftTypeName = try swiftTypeDeclaration(for: type, includeNamespace: false, nameGenerator: nameGenerator)
171176
output += """
172177
173178
enum \(swiftTypeName): String, Codable, Sendable {
@@ -208,7 +213,7 @@ package struct TypeGenerator {
208213
"""
209214
}
210215

211-
let swiftTypeName = try swiftTypeDeclaration(for: type, nameGenerator: nameGenerator)
216+
let swiftTypeName = try swiftTypeDeclaration(for: type, includeNamespace: false, nameGenerator: nameGenerator)
212217
output += """
213218
214219
struct \(swiftTypeName): Codable, Sendable {
@@ -224,7 +229,7 @@ package struct TypeGenerator {
224229
"""
225230
}
226231

227-
let returnType = try swiftTypeReference(for: field.type, nameGenerator: nameGenerator)
232+
let returnType = try swiftTypeReference(for: field.type, includeNamespace: false, nameGenerator: nameGenerator)
228233

229234
output += """
230235
@@ -253,10 +258,10 @@ package struct TypeGenerator {
253258
}
254259

255260
let interfaces = try type.interfaces().map {
256-
try swiftTypeDeclaration(for: $0, nameGenerator: nameGenerator) + ", "
261+
try swiftTypeDeclaration(for: $0, includeNamespace: false, nameGenerator: nameGenerator) + ", "
257262
}.joined(separator: "")
258263

259-
let swiftTypeName = try swiftTypeDeclaration(for: type, nameGenerator: nameGenerator)
264+
let swiftTypeName = try swiftTypeDeclaration(for: type, includeNamespace: false, nameGenerator: nameGenerator)
260265
output += """
261266
262267
protocol \(swiftTypeName): \(interfaces)Sendable {
@@ -272,13 +277,13 @@ package struct TypeGenerator {
272277
"""
273278
}
274279

275-
let returnType = try swiftTypeReference(for: field.type, nameGenerator: nameGenerator)
280+
let returnType = try swiftTypeReference(for: field.type, includeNamespace: false, nameGenerator: nameGenerator)
276281

277282
var params: [String] = []
278283

279284
// Add arguments if any
280285
for (argName, arg) in field.args {
281-
let argType = try swiftTypeReference(for: arg.type, nameGenerator: nameGenerator)
286+
let argType = try swiftTypeReference(for: arg.type, includeNamespace: false, nameGenerator: nameGenerator)
282287
params.append("\(argName): \(argType)")
283288
}
284289

@@ -317,14 +322,14 @@ package struct TypeGenerator {
317322
}
318323

319324
let unions = try unionTypeMap[type.name]?.map {
320-
try swiftTypeDeclaration(for: $0, nameGenerator: nameGenerator) + ", "
325+
try swiftTypeDeclaration(for: $0, includeNamespace: false, nameGenerator: nameGenerator) + ", "
321326
}.joined(separator: "") ?? ""
322327

323328
let interfaces = try type.interfaces().map {
324-
try swiftTypeDeclaration(for: $0, nameGenerator: nameGenerator) + ", "
329+
try swiftTypeDeclaration(for: $0, includeNamespace: false, nameGenerator: nameGenerator) + ", "
325330
}.joined(separator: "")
326331

327-
let swiftTypeName = try swiftTypeDeclaration(for: type, nameGenerator: nameGenerator)
332+
let swiftTypeName = try swiftTypeDeclaration(for: type, includeNamespace: false, nameGenerator: nameGenerator)
328333
output += """
329334
330335
protocol \(swiftTypeName): \(unions)\(interfaces)Sendable {
@@ -340,13 +345,13 @@ package struct TypeGenerator {
340345
"""
341346
}
342347

343-
let returnType = try swiftTypeReference(for: field.type, nameGenerator: nameGenerator)
348+
let returnType = try swiftTypeReference(for: field.type, includeNamespace: false, nameGenerator: nameGenerator)
344349

345350
var params: [String] = []
346351

347352
// Add arguments if any
348353
for (argName, arg) in field.args {
349-
let argType = try swiftTypeReference(for: arg.type, nameGenerator: nameGenerator)
354+
let argType = try swiftTypeReference(for: arg.type, includeNamespace: false, nameGenerator: nameGenerator)
350355
params.append("\(argName): \(argType)")
351356
}
352357

@@ -386,7 +391,7 @@ package struct TypeGenerator {
386391
"""
387392
}
388393

389-
let swiftTypeName = try swiftTypeDeclaration(for: type, nameGenerator: nameGenerator)
394+
let swiftTypeName = try swiftTypeDeclaration(for: type, includeNamespace: false, nameGenerator: nameGenerator)
390395
output += """
391396
392397
protocol \(swiftTypeName): Sendable {
@@ -402,7 +407,7 @@ package struct TypeGenerator {
402407
"""
403408
}
404409

405-
var returnType = try swiftTypeReference(for: field.type, nameGenerator: nameGenerator)
410+
var returnType = try swiftTypeReference(for: field.type, includeNamespace: false, nameGenerator: nameGenerator)
406411
if type.name == "Subscription" {
407412
returnType = "AnyAsyncSequence<\(returnType)>"
408413
}
@@ -411,7 +416,7 @@ package struct TypeGenerator {
411416

412417
// Add arguments if any
413418
for (argName, arg) in field.args {
414-
let argType = try swiftTypeReference(for: arg.type, nameGenerator: nameGenerator)
419+
let argType = try swiftTypeReference(for: arg.type, includeNamespace: false, nameGenerator: nameGenerator)
415420
params.append("\(argName): \(argType)")
416421
}
417422

0 commit comments

Comments
 (0)