Skip to content

Commit e13ef31

Browse files
fix: TypeInfo ListValue walking bug
TypeInfo also matched to graphql-js
1 parent c2888ff commit e13ef31

File tree

2 files changed

+67
-20
lines changed

2 files changed

+67
-20
lines changed

Sources/GraphQL/Utilities/TypeInfo.swift

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,21 @@ final class TypeInfo {
99
var parentTypeStack: [GraphQLCompositeType?]
1010
var inputTypeStack: [GraphQLInputType?]
1111
var fieldDefStack: [GraphQLFieldDefinition?]
12+
var defaultValueStack: [Map]
1213
var directive: GraphQLDirective?
1314
var argument: GraphQLArgumentDefinition?
15+
var enumValue: GraphQLEnumValueDefinition?
1416

1517
init(schema: GraphQLSchema) {
1618
self.schema = schema
1719
typeStack = []
1820
parentTypeStack = []
1921
inputTypeStack = []
2022
fieldDefStack = []
23+
defaultValueStack = []
2124
directive = nil
2225
argument = nil
26+
enumValue = nil
2327
}
2428

2529
var type: GraphQLOutputType? {
@@ -50,6 +54,13 @@ final class TypeInfo {
5054
return nil
5155
}
5256

57+
var defaultValue: Map? {
58+
if !defaultValueStack.isEmpty {
59+
return defaultValueStack[defaultValueStack.count - 1]
60+
}
61+
return nil
62+
}
63+
5364
func enter(node: Node) {
5465
switch node {
5566
case is SelectionSet:
@@ -64,13 +75,17 @@ final class TypeInfo {
6475

6576
case let node as Field:
6677
var fieldDef: GraphQLFieldDefinition?
78+
var fieldType: GraphQLType?
6779

6880
if let parentType = parentType {
6981
fieldDef = getFieldDef(schema: schema, parentType: parentType, fieldAST: node)
82+
if let fieldDef = fieldDef {
83+
fieldType = fieldDef.type
84+
}
7085
}
7186

7287
fieldDefStack.append(fieldDef)
73-
typeStack.append(fieldDef?.type)
88+
typeStack.append(fieldType as? GraphQLOutputType)
7489

7590
case let node as Directive:
7691
directive = schema.getDirective(name: node.name.value)
@@ -94,7 +109,7 @@ final class TypeInfo {
94109
if let typeConditionAST = node.typeCondition {
95110
outputType = typeFromAST(schema: schema, inputTypeAST: typeConditionAST)
96111
} else {
97-
outputType = type
112+
outputType = getNamedType(type: type)
98113
}
99114
typeStack.append(outputType as? GraphQLOutputType)
100115

@@ -107,33 +122,59 @@ final class TypeInfo {
107122
inputTypeStack.append(inputType as? GraphQLInputType)
108123

109124
case let node as Argument:
110-
var argType: GraphQLInputType?
125+
var argDef: GraphQLArgumentDefinition?
111126

112127
if let directive = directive {
113-
if let argDef = directive.args.find({ $0.name == node.name.value }) {
114-
argType = argDef.type
115-
argument = argDef
128+
if let argDefinition = directive.args.find({ $0.name == node.name.value }) {
129+
argDef = argDefinition
116130
}
117131
} else if let fieldDef = fieldDef {
118-
if let argDef = fieldDef.args.find({ $0.name == node.name.value }) {
119-
argType = argDef.type
120-
argument = argDef
132+
if let argDefinition = fieldDef.args.find({ $0.name == node.name.value }) {
133+
argDef = argDefinition
121134
}
122135
}
123136

124-
inputTypeStack.append(argType)
137+
argument = argDef
138+
defaultValueStack.append(argDef?.defaultValue ?? .undefined)
139+
inputTypeStack.append(argDef?.type)
140+
141+
case is ListType, is ListValue:
142+
let listType = getNullableType(type: inputType)
143+
let itemType: GraphQLType?
125144

126-
case is ListType: // could be ListValue
127-
if let listType = getNullableType(type: inputType) as? GraphQLList {
128-
inputTypeStack.append(listType.ofType as? GraphQLInputType)
145+
if let listType = listType as? GraphQLList {
146+
itemType = listType.ofType
147+
} else {
148+
itemType = listType
129149
}
150+
defaultValueStack.append(.undefined)
130151

131-
inputTypeStack.append(nil)
152+
if let itemType = itemType as? GraphQLInputType {
153+
inputTypeStack.append(itemType)
154+
} else {
155+
inputTypeStack.append(nil)
156+
}
132157

133158
case let node as ObjectField:
134-
if let objectType = getNamedType(type: inputType) as? GraphQLInputObjectType {
135-
let inputField = objectType.fields[node.name.value]
136-
inputTypeStack.append(inputField?.type)
159+
let objectType = getNamedType(type: inputType)
160+
var inputFieldType: GraphQLInputType?
161+
var inputField: InputObjectFieldDefinition?
162+
163+
if let objectType = objectType as? GraphQLInputObjectType {
164+
inputField = objectType.fields[node.name.value]
165+
if let inputField = inputField {
166+
inputFieldType = inputField.type
167+
}
168+
}
169+
170+
defaultValueStack.append(inputField?.defaultValue ?? .undefined)
171+
inputTypeStack.append(inputFieldType)
172+
173+
case let node as EnumValue:
174+
if let enumType = getNamedType(type: inputType) as? GraphQLEnumType {
175+
enumValue = enumType.nameLookup[node.value]
176+
} else {
177+
enumValue = nil
137178
}
138179

139180
default:
@@ -161,11 +202,16 @@ final class TypeInfo {
161202

162203
case is Argument:
163204
argument = nil
205+
_ = defaultValueStack.popLast()
164206
_ = inputTypeStack.popLast()
165207

166-
case is ListType /* could be listValue */, is ObjectField:
208+
case is ListType, is ListValue, is ObjectField:
209+
_ = defaultValueStack.popLast()
167210
_ = inputTypeStack.popLast()
168211

212+
case is EnumValue:
213+
enumValue = nil
214+
169215
default:
170216
break
171217
}

Sources/GraphQL/Validation/Validate.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ extension HasSelectionSet: Hashable {
110110
}
111111
}
112112

113-
public typealias VariableUsage = (node: Variable, type: GraphQLInputType?)
113+
public typealias VariableUsage = (node: Variable, type: GraphQLInputType?, defaultValue: Map?)
114114

115115
/**
116116
* An instance of this class is passed as the "this" context to all validators,
@@ -242,7 +242,8 @@ public final class ValidationContext {
242242
if let variable = node as? Variable {
243243
usages.append(VariableUsage(
244244
node: variable,
245-
type: typeInfo.inputType
245+
type: typeInfo.inputType,
246+
defaultValue: typeInfo.defaultValue
246247
))
247248
}
248249

0 commit comments

Comments
 (0)