@@ -76,7 +76,7 @@ class SchemaParser internal constructor(
76
76
val inputObjects: MutableList <GraphQLInputObjectType > = mutableListOf ()
77
77
inputObjectDefinitions.forEach {
78
78
if (inputObjects.none { io -> io.name == it.name }) {
79
- inputObjects.add(createInputObject(it, inputObjects))
79
+ inputObjects.add(createInputObject(it, inputObjects, mutableSetOf () ))
80
80
}
81
81
}
82
82
val interfaces = interfaceDefinitions.map { createInterfaceObject(it, inputObjects) }
@@ -155,7 +155,8 @@ class SchemaParser internal constructor(
155
155
return schemaGeneratorDirectiveHelper.onObject(objectType, directiveHelperParameters)
156
156
}
157
157
158
- private fun createInputObject (definition : InputObjectTypeDefinition , inputObjects : List <GraphQLInputObjectType >): GraphQLInputObjectType {
158
+ private fun createInputObject (definition : InputObjectTypeDefinition , inputObjects : List <GraphQLInputObjectType >,
159
+ referencingInputObjects : MutableSet <String >): GraphQLInputObjectType {
159
160
val extensionDefinitions = inputExtensionDefinitions.filter { it.name == definition.name }
160
161
161
162
val builder = GraphQLInputObjectType .newInputObject()
@@ -166,14 +167,16 @@ class SchemaParser internal constructor(
166
167
167
168
builder.withDirectives(* buildDirectives(definition.directives, Introspection .DirectiveLocation .INPUT_OBJECT ))
168
169
170
+ referencingInputObjects.add(definition.name)
171
+
169
172
(extensionDefinitions + definition).forEach {
170
173
it.inputValueDefinitions.forEach { inputDefinition ->
171
174
val fieldBuilder = GraphQLInputObjectField .newInputObjectField()
172
175
.name(inputDefinition.name)
173
176
.definition(inputDefinition)
174
177
.description(if (inputDefinition.description != null ) inputDefinition.description.content else getDocumentation(inputDefinition))
175
178
.defaultValue(buildDefaultValue(inputDefinition.defaultValue))
176
- .type(determineInputType(inputDefinition.type, inputObjects))
179
+ .type(determineInputType(inputDefinition.type, inputObjects, referencingInputObjects ))
177
180
.withDirectives(* buildDirectives(inputDefinition.directives, Introspection .DirectiveLocation .INPUT_FIELD_DEFINITION ))
178
181
builder.field(fieldBuilder.build())
179
182
}
@@ -280,7 +283,7 @@ class SchemaParser internal constructor(
280
283
.name(argumentDefinition.name)
281
284
.definition(argumentDefinition)
282
285
.description(if (argumentDefinition.description != null ) argumentDefinition.description.content else getDocumentation(argumentDefinition))
283
- .type(determineInputType(argumentDefinition.type, inputObjects))
286
+ .type(determineInputType(argumentDefinition.type, inputObjects, setOf () ))
284
287
.apply { buildDefaultValue(argumentDefinition.defaultValue)?.let { defaultValue(it) } }
285
288
.withDirectives(* buildDirectives(argumentDefinition.directives, Introspection .DirectiveLocation .ARGUMENT_DEFINITION ))
286
289
@@ -380,7 +383,7 @@ class SchemaParser internal constructor(
380
383
is NonNullType -> GraphQLNonNull (determineType(expectedType, typeDefinition.type, allowedTypeReferences, inputObjects))
381
384
is InputObjectTypeDefinition -> {
382
385
log.info(" Create input object" )
383
- createInputObject(typeDefinition, inputObjects)
386
+ createInputObject(typeDefinition, inputObjects, mutableSetOf () )
384
387
}
385
388
is TypeName -> {
386
389
val scalarType = customScalars[typeDefinition.name]
@@ -398,16 +401,19 @@ class SchemaParser internal constructor(
398
401
else -> throw SchemaError (" Unknown type: $typeDefinition " )
399
402
}
400
403
401
- private fun determineInputType (typeDefinition : Type <* >, inputObjects : List <GraphQLInputObjectType >) =
402
- determineInputType(GraphQLInputType ::class , typeDefinition, permittedTypesForInputObject, inputObjects) as GraphQLInputType
404
+ private fun determineInputType (typeDefinition : Type <* >, inputObjects : List <GraphQLInputObjectType >, referencingInputObjects : Set < String > ) =
405
+ determineInputType(GraphQLInputType ::class , typeDefinition, permittedTypesForInputObject, inputObjects, referencingInputObjects ) as GraphQLInputType
403
406
404
- private fun <T : Any > determineInputType (expectedType : KClass <T >, typeDefinition : Type <* >, allowedTypeReferences : Set <String >, inputObjects : List <GraphQLInputObjectType >): GraphQLType =
407
+ private fun <T : Any > determineInputType (expectedType : KClass <T >,
408
+ typeDefinition : Type <* >, allowedTypeReferences : Set <String >,
409
+ inputObjects : List <GraphQLInputObjectType >,
410
+ referencingInputObjects : Set <String >): GraphQLType =
405
411
when (typeDefinition) {
406
412
is ListType -> GraphQLList (determineType(expectedType, typeDefinition.type, allowedTypeReferences, inputObjects))
407
413
is NonNullType -> GraphQLNonNull (determineType(expectedType, typeDefinition.type, allowedTypeReferences, inputObjects))
408
414
is InputObjectTypeDefinition -> {
409
415
log.info(" Create input object" )
410
- createInputObject(typeDefinition, inputObjects)
416
+ createInputObject(typeDefinition, inputObjects, referencingInputObjects as MutableSet < String > )
411
417
}
412
418
is TypeName -> {
413
419
val scalarType = customScalars[typeDefinition.name]
@@ -425,9 +431,14 @@ class SchemaParser internal constructor(
425
431
} else {
426
432
val filteredDefinitions = inputObjectDefinitions.filter { it.name == typeDefinition.name }
427
433
if (filteredDefinitions.isNotEmpty()) {
428
- val inputObject = createInputObject(filteredDefinitions[0 ], inputObjects)
429
- (inputObjects as MutableList ).add(inputObject)
430
- inputObject
434
+ val referencingInputObject = referencingInputObjects.find { it == typeDefinition.name }
435
+ if (referencingInputObject != null ) {
436
+ GraphQLTypeReference (referencingInputObject)
437
+ } else {
438
+ val inputObject = createInputObject(filteredDefinitions[0 ], inputObjects, referencingInputObjects as MutableSet <String >)
439
+ (inputObjects as MutableList ).add(inputObject)
440
+ inputObject
441
+ }
431
442
} else {
432
443
// todo: handle enum type
433
444
GraphQLTypeReference (typeDefinition.name)
0 commit comments