1
1
package graphql.kickstart.tools
2
2
3
- import graphql.Scalars
4
3
import graphql.introspection.Introspection
5
- import graphql.kickstart.tools.directive.SchemaGeneratorDirectiveHelper
4
+ import graphql.kickstart.tools.directive.DirectiveWiringHelper
6
5
import graphql.kickstart.tools.util.getDocumentation
7
6
import graphql.kickstart.tools.util.getExtendedFieldDefinitions
8
7
import graphql.kickstart.tools.util.unwrap
@@ -57,9 +56,7 @@ class SchemaParser internal constructor(
57
56
(inputObjectDefinitions.map { it.name } + enumDefinitions.map { it.name }).toSet()
58
57
59
58
private val codeRegistryBuilder = GraphQLCodeRegistry .newCodeRegistry()
60
-
61
- private val schemaGeneratorDirectiveHelper = SchemaGeneratorDirectiveHelper ()
62
- private val schemaDirectiveParameters = SchemaGeneratorDirectiveHelper .Parameters (null , runtimeWiring, null , codeRegistryBuilder)
59
+ private val directiveWiringHelper = DirectiveWiringHelper (options, runtimeWiring, codeRegistryBuilder)
63
60
64
61
/* *
65
62
* Parses the given schema with respect to the given dictionary and returns GraphQL objects.
@@ -124,9 +121,7 @@ class SchemaParser internal constructor(
124
121
.name(name)
125
122
.definition(objectDefinition)
126
123
.description(getDocumentation(objectDefinition, options))
127
-
128
- builder.withDirectives(* buildDirectives(objectDefinition.directives, Introspection .DirectiveLocation .OBJECT ))
129
- builder.withAppliedDirectives(* buildAppliedDirectives(objectDefinition.directives))
124
+ .withAppliedDirectives(* buildAppliedDirectives(objectDefinition.directives))
130
125
131
126
objectDefinition.implements.forEach { implementsDefinition ->
132
127
val interfaceName = (implementsDefinition as TypeName ).name
@@ -150,10 +145,7 @@ class SchemaParser internal constructor(
150
145
}
151
146
}
152
147
153
- val objectType = builder.build()
154
- val directiveHelperParameters = SchemaGeneratorDirectiveHelper .Parameters (null , runtimeWiring, null , codeRegistryBuilder)
155
-
156
- return schemaGeneratorDirectiveHelper.onObject(objectType, directiveHelperParameters)
148
+ return directiveWiringHelper.wireObject(builder.build())
157
149
}
158
150
159
151
private fun createInputObject (definition : InputObjectTypeDefinition , inputObjects : List <GraphQLInputObjectType >,
@@ -165,9 +157,7 @@ class SchemaParser internal constructor(
165
157
.definition(definition)
166
158
.extensionDefinitions(extensionDefinitions)
167
159
.description(getDocumentation(definition, options))
168
-
169
- builder.withDirectives(* buildDirectives(definition.directives, Introspection .DirectiveLocation .INPUT_OBJECT ))
170
- builder.withAppliedDirectives(* buildAppliedDirectives(definition.directives))
160
+ .withAppliedDirectives(* buildAppliedDirectives(definition.directives))
171
161
172
162
referencingInputObjects.add(definition.name)
173
163
@@ -179,13 +169,12 @@ class SchemaParser internal constructor(
179
169
.description(getDocumentation(inputDefinition, options))
180
170
.apply { inputDefinition.defaultValue?.let { v -> defaultValueLiteral(v) } }
181
171
.type(determineInputType(inputDefinition.type, inputObjects, referencingInputObjects))
182
- .withDirectives(* buildDirectives(inputDefinition.directives, Introspection .DirectiveLocation .INPUT_FIELD_DEFINITION ))
183
172
.withAppliedDirectives(* buildAppliedDirectives(inputDefinition.directives))
184
173
builder.field(fieldBuilder.build())
185
174
}
186
175
}
187
176
188
- return schemaGeneratorDirectiveHelper.onInputObjectType (builder.build(), schemaDirectiveParameters )
177
+ return directiveWiringHelper.wireInputObject (builder.build())
189
178
}
190
179
191
180
private fun createEnumObject (definition : EnumTypeDefinition ): GraphQLEnumType {
@@ -198,24 +187,20 @@ class SchemaParser internal constructor(
198
187
.name(name)
199
188
.definition(definition)
200
189
.description(getDocumentation(definition, options))
201
-
202
- builder.withDirectives(* buildDirectives(definition.directives, Introspection .DirectiveLocation .ENUM ))
203
- builder.withAppliedDirectives(* buildAppliedDirectives(definition.directives))
190
+ .withAppliedDirectives(* buildAppliedDirectives(definition.directives))
204
191
205
192
definition.enumValueDefinitions.forEach { enumDefinition ->
206
193
val enumName = enumDefinition.name
207
194
val enumValue = type.unwrap().enumConstants.find { (it as Enum <* >).name == enumName }
208
195
? : throw SchemaError (" Expected value for name '$enumName ' in enum '${type.unwrap().simpleName} ' but found none!" )
209
196
210
- val enumValueDirectives = buildDirectives(enumDefinition.directives, Introspection .DirectiveLocation .ENUM_VALUE )
211
197
val enumValueAppliedDirectives = buildAppliedDirectives(enumDefinition.directives)
212
198
getDeprecated(enumDefinition.directives).let {
213
199
val enumValueDefinition = GraphQLEnumValueDefinition .newEnumValueDefinition()
214
200
.name(enumName)
215
201
.description(getDocumentation(enumDefinition, options))
216
202
.value(enumValue)
217
203
.deprecationReason(it)
218
- .withDirectives(* enumValueDirectives)
219
204
.withAppliedDirectives(* enumValueAppliedDirectives)
220
205
.definition(enumDefinition)
221
206
.build()
@@ -224,7 +209,7 @@ class SchemaParser internal constructor(
224
209
}
225
210
}
226
211
227
- return schemaGeneratorDirectiveHelper.onEnum (builder.build(), schemaDirectiveParameters )
212
+ return directiveWiringHelper.wireEnum (builder.build())
228
213
}
229
214
230
215
private fun createInterfaceObject (interfaceDefinition : InterfaceTypeDefinition , inputObjects : List <GraphQLInputObjectType >): GraphQLInterfaceType {
@@ -233,9 +218,7 @@ class SchemaParser internal constructor(
233
218
.name(name)
234
219
.definition(interfaceDefinition)
235
220
.description(getDocumentation(interfaceDefinition, options))
236
-
237
- builder.withDirectives(* buildDirectives(interfaceDefinition.directives, Introspection .DirectiveLocation .INTERFACE ))
238
- builder.withAppliedDirectives(* buildAppliedDirectives(interfaceDefinition.directives))
221
+ .withAppliedDirectives(* buildAppliedDirectives(interfaceDefinition.directives))
239
222
240
223
interfaceDefinition.fieldDefinitions.forEach { fieldDefinition ->
241
224
builder.field { field -> createField(field, fieldDefinition, inputObjects) }
@@ -246,7 +229,7 @@ class SchemaParser internal constructor(
246
229
builder.withInterface(GraphQLTypeReference (interfaceName))
247
230
}
248
231
249
- return schemaGeneratorDirectiveHelper.onInterface (builder.build(), schemaDirectiveParameters )
232
+ return directiveWiringHelper.wireInterFace (builder.build())
250
233
}
251
234
252
235
private fun createUnionObject (definition : UnionTypeDefinition , types : List <GraphQLObjectType >): GraphQLUnionType {
@@ -255,12 +238,10 @@ class SchemaParser internal constructor(
255
238
.name(name)
256
239
.definition(definition)
257
240
.description(getDocumentation(definition, options))
258
-
259
- builder.withDirectives(* buildDirectives(definition.directives, Introspection .DirectiveLocation .UNION ))
260
- builder.withAppliedDirectives(* buildAppliedDirectives(definition.directives))
241
+ .withAppliedDirectives(* buildAppliedDirectives(definition.directives))
261
242
262
243
getLeafUnionObjects(definition, types).forEach { builder.possibleType(it) }
263
- return schemaGeneratorDirectiveHelper.onUnion (builder.build(), schemaDirectiveParameters )
244
+ return directiveWiringHelper.wireUnion (builder.build())
264
245
}
265
246
266
247
private fun getLeafUnionObjects (definition : UnionTypeDefinition , types : List <GraphQLObjectType >): List <GraphQLObjectType > {
@@ -290,6 +271,7 @@ class SchemaParser internal constructor(
290
271
.definition(fieldDefinition)
291
272
.apply { getDeprecated(fieldDefinition.directives)?.let { deprecate(it) } }
292
273
.type(determineOutputType(fieldDefinition.type, inputObjects))
274
+ .withAppliedDirectives(* buildAppliedDirectives(fieldDefinition.directives))
293
275
294
276
fieldDefinition.inputValueDefinitions.forEach { argumentDefinition ->
295
277
val argumentBuilder = GraphQLArgument .newArgument()
@@ -298,13 +280,10 @@ class SchemaParser internal constructor(
298
280
.description(getDocumentation(argumentDefinition, options))
299
281
.type(determineInputType(argumentDefinition.type, inputObjects, setOf ()))
300
282
.apply { argumentDefinition.defaultValue?.let { defaultValueLiteral(it) } }
301
- .withDirectives(* buildDirectives(argumentDefinition.directives, Introspection .DirectiveLocation .ARGUMENT_DEFINITION ))
302
283
.withAppliedDirectives(* buildAppliedDirectives(argumentDefinition.directives))
303
284
304
285
field.argument(argumentBuilder.build())
305
286
}
306
- field.withDirectives(* buildDirectives(fieldDefinition.directives, Introspection .DirectiveLocation .FIELD_DEFINITION ))
307
- field.withAppliedDirectives(* buildAppliedDirectives(fieldDefinition.directives))
308
287
309
288
return field
310
289
}
@@ -327,7 +306,6 @@ class SchemaParser internal constructor(
327
306
.description(getDocumentation(arg, options))
328
307
.type(determineInputType(arg.type, inputObjects, setOf ()))
329
308
.apply { arg.defaultValue?.let { defaultValueLiteral(it) } }
330
- .withDirectives(* buildDirectives(arg.directives, Introspection .DirectiveLocation .ARGUMENT_DEFINITION ))
331
309
.withAppliedDirectives(* buildAppliedDirectives(arg.directives))
332
310
.build())
333
311
}
@@ -337,36 +315,6 @@ class SchemaParser internal constructor(
337
315
return graphQLDirective
338
316
}
339
317
340
- private fun buildDirectives (directives : List <Directive >, directiveLocation : Introspection .DirectiveLocation ): Array <GraphQLDirective > {
341
- val names = mutableSetOf<String >()
342
-
343
- val output = mutableListOf<GraphQLDirective >()
344
- for (directive in directives) {
345
- if (! names.contains(directive.name)) {
346
- names.add(directive.name)
347
- val graphQLDirective = GraphQLDirective .newDirective()
348
- .name(directive.name)
349
- .description(getDocumentation(directive, options))
350
- .comparatorRegistry(runtimeWiring.comparatorRegistry)
351
- .validLocation(directiveLocation)
352
- .apply {
353
- directive.arguments.forEach { arg ->
354
- argument(GraphQLArgument .newArgument()
355
- .name(arg.name)
356
- .type(buildDirectiveInputType(arg.value))
357
- .valueLiteral(arg.value)
358
- .build())
359
- }
360
- }
361
- .build()
362
-
363
- output.add(graphQLDirective)
364
- }
365
- }
366
-
367
- return output.toTypedArray()
368
- }
369
-
370
318
private fun buildAppliedDirectives (directives : List <Directive >): Array <GraphQLAppliedDirective > {
371
319
val names = mutableSetOf<String >()
372
320
@@ -382,7 +330,7 @@ class SchemaParser internal constructor(
382
330
directive.arguments.forEach { arg ->
383
331
argument(GraphQLAppliedDirectiveArgument .newArgument()
384
332
.name(arg.name)
385
- .type(buildDirectiveInputType(arg.value))
333
+ .type(directiveWiringHelper. buildDirectiveInputType(arg.value))
386
334
.valueLiteral(arg.value)
387
335
.build())
388
336
}
@@ -396,45 +344,6 @@ class SchemaParser internal constructor(
396
344
return output.toTypedArray()
397
345
}
398
346
399
- private fun buildDirectiveInputType (value : Value <* >): GraphQLInputType ? {
400
- return when (value) {
401
- is NullValue -> Scalars .GraphQLString
402
- is FloatValue -> Scalars .GraphQLFloat
403
- is StringValue -> Scalars .GraphQLString
404
- is IntValue -> Scalars .GraphQLInt
405
- is BooleanValue -> Scalars .GraphQLBoolean
406
- is ArrayValue -> GraphQLList .list(buildDirectiveInputType(getArrayValueWrappedType(value)))
407
- else -> throw SchemaError (" Directive values of type '${value::class .simpleName} ' are not supported yet." )
408
- }
409
- }
410
-
411
- private fun getArrayValueWrappedType (value : ArrayValue ): Value <* > {
412
- // empty array [] is equivalent to [null]
413
- if (value.values.isEmpty()) {
414
- return NullValue .newNullValue().build()
415
- }
416
-
417
- // get rid of null values
418
- val nonNullValueList = value.values.filter { v -> v !is NullValue }
419
-
420
- // [null, null, ...] unwrapped is null
421
- if (nonNullValueList.isEmpty()) {
422
- return NullValue .newNullValue().build()
423
- }
424
-
425
- // make sure the array isn't polymorphic
426
- val distinctTypes = nonNullValueList
427
- .map { it::class .java }
428
- .distinct()
429
-
430
- if (distinctTypes.size > 1 ) {
431
- throw SchemaError (" Arrays containing multiple types of values are not supported yet." )
432
- }
433
-
434
- // peek at first value, value exists and is assured to be non-null
435
- return nonNullValueList[0 ]
436
- }
437
-
438
347
private fun determineOutputType (typeDefinition : Type <* >, inputObjects : List <GraphQLInputObjectType >) =
439
348
determineType(GraphQLOutputType ::class , typeDefinition, permittedTypesForObject, inputObjects) as GraphQLOutputType
440
349
0 commit comments