Skip to content

Commit 7aa6430

Browse files
Merge pull request #78 from NeedleInAJayStack/fix/recursiveInputs
Adds support for reference types on Input fields
2 parents 82081d1 + c15895b commit 7aa6430

File tree

2 files changed

+54
-23
lines changed

2 files changed

+54
-23
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
runs-on: ${{ matrix.os }}
1414
strategy:
1515
matrix:
16-
os: [macos-10.15, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
16+
os: [macos-10.15, macos-latest, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
1717
steps:
1818
- uses: actions/checkout@v2
1919
- name: Set code coverage path

Sources/GraphQL/Type/Definition.swift

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ protocol GraphQLTypeReferenceContainer : GraphQLNamedType {
7777
func replaceTypeReferences(typeMap: TypeMap) throws
7878
}
7979

80-
extension GraphQLObjectType : GraphQLTypeReferenceContainer {}
81-
extension GraphQLInterfaceType : GraphQLTypeReferenceContainer {}
80+
extension GraphQLObjectType : GraphQLTypeReferenceContainer {}
81+
extension GraphQLInterfaceType : GraphQLTypeReferenceContainer {}
82+
extension GraphQLInputObjectType : GraphQLTypeReferenceContainer {}
8283

8384
/**
8485
* These types may describe the parent context of a selection set.
@@ -1171,13 +1172,13 @@ extension GraphQLEnumValueDefinition : KeySubscriptable {
11711172
public final class GraphQLInputObjectType {
11721173
public let name: String
11731174
public let description: String?
1174-
public let fields: InputObjectFieldMap
1175+
public let fields: InputObjectFieldDefinitionMap
11751176
public let kind: TypeKind = .inputObject
11761177

11771178
public init(
11781179
name: String,
11791180
description: String? = nil,
1180-
fields: InputObjectConfigFieldMap
1181+
fields: InputObjectFieldMap = [:]
11811182
) throws {
11821183
try assertValid(name: name)
11831184
self.name = name
@@ -1187,6 +1188,12 @@ public final class GraphQLInputObjectType {
11871188
fields: fields
11881189
)
11891190
}
1191+
1192+
func replaceTypeReferences(typeMap: TypeMap) throws {
1193+
for field in fields {
1194+
try field.value.replaceTypeReferences(typeMap: typeMap)
1195+
}
1196+
}
11901197
}
11911198

11921199
extension GraphQLInputObjectType : Encodable {
@@ -1233,32 +1240,32 @@ extension GraphQLInputObjectType : Hashable {
12331240

12341241
func defineInputObjectFieldMap(
12351242
name: String,
1236-
fields: InputObjectConfigFieldMap
1237-
) throws -> InputObjectFieldMap {
1243+
fields: InputObjectFieldMap
1244+
) throws -> InputObjectFieldDefinitionMap {
12381245
guard !fields.isEmpty else {
12391246
throw GraphQLError(
12401247
message:
1241-
"\(name) fields must be an object with field names as keys or a " +
1242-
"function which returns such an object."
1248+
"\(name) fields must be an object with field names as " +
1249+
"keys or a function which returns such an object."
12431250
)
12441251
}
12451252

1246-
var resultFieldMap = InputObjectFieldMap()
1253+
var definitionMap = InputObjectFieldDefinitionMap()
12471254

1248-
for (fieldName, field) in fields {
1249-
try assertValid(name: fieldName)
1255+
for (name, field) in fields {
1256+
try assertValid(name: name)
12501257

1251-
let newField = InputObjectFieldDefinition(
1252-
name: fieldName,
1253-
description: field.description,
1258+
let definition = InputObjectFieldDefinition(
1259+
name: name,
12541260
type: field.type,
1261+
description: field.description,
12551262
defaultValue: field.defaultValue
12561263
)
12571264

1258-
resultFieldMap[fieldName] = newField
1265+
definitionMap[name] = definition
12591266
}
12601267

1261-
return resultFieldMap
1268+
return definitionMap
12621269
}
12631270

12641271
public struct InputObjectField {
@@ -1273,13 +1280,37 @@ public struct InputObjectField {
12731280
}
12741281
}
12751282

1276-
public typealias InputObjectConfigFieldMap = [String: InputObjectField]
1283+
public typealias InputObjectFieldMap = [String: InputObjectField]
12771284

1278-
public struct InputObjectFieldDefinition {
1285+
public final class InputObjectFieldDefinition {
12791286
public let name: String
1287+
public internal(set) var type: GraphQLInputType
12801288
public let description: String?
1281-
public let type: GraphQLInputType
12821289
public let defaultValue: String?
1290+
1291+
init(
1292+
name: String,
1293+
type: GraphQLInputType,
1294+
description: String? = nil,
1295+
defaultValue: String? = nil
1296+
) {
1297+
self.name = name
1298+
self.type = type
1299+
self.description = description
1300+
self.defaultValue = defaultValue
1301+
}
1302+
1303+
func replaceTypeReferences(typeMap: TypeMap) throws {
1304+
let resolvedType = try resolveTypeReference(type: type, typeMap: typeMap)
1305+
1306+
guard let inputType = resolvedType as? GraphQLInputType else {
1307+
throw GraphQLError(
1308+
message: "Resolved type \"\(resolvedType)\" is not a valid input type."
1309+
)
1310+
}
1311+
1312+
self.type = inputType
1313+
}
12831314
}
12841315

12851316
extension InputObjectFieldDefinition : Encodable {
@@ -1316,7 +1347,7 @@ extension InputObjectFieldDefinition : KeySubscriptable {
13161347
}
13171348
}
13181349

1319-
public typealias InputObjectFieldMap = [String: InputObjectFieldDefinition]
1350+
public typealias InputObjectFieldDefinitionMap = [String: InputObjectFieldDefinition]
13201351

13211352
/**
13221353
* List Modifier
@@ -1492,10 +1523,10 @@ extension GraphQLNonNull : Hashable {
14921523
}
14931524

14941525
/**
1495-
* A special type to allow object/interface types to reference itself. It's replaced with the real type
1526+
* A special type to allow object/interface/input types to reference itself. It's replaced with the real type
14961527
* object when the schema is built.
14971528
*/
1498-
public final class GraphQLTypeReference : GraphQLType, GraphQLOutputType, GraphQLNullableType, GraphQLNamedType {
1529+
public final class GraphQLTypeReference : GraphQLType, GraphQLOutputType, GraphQLInputType, GraphQLNullableType, GraphQLNamedType {
14991530
public let name: String
15001531
public let kind: TypeKind = .typeReference
15011532

0 commit comments

Comments
 (0)