@@ -23,7 +23,6 @@ import graphql.language.*
2323import graphql.schema.*
2424import graphql.schema.idl.RuntimeWiring
2525import graphql.schema.idl.ScalarInfo
26- import graphql.schema.visibility.BlockedFields
2726import org.slf4j.LoggerFactory
2827import kotlin.reflect.KClass
2928
@@ -79,14 +78,6 @@ class SchemaParser internal constructor(
7978 * Parses the given schema with respect to the given dictionary and returns GraphQL objects.
8079 */
8180 fun parseSchemaObjects (): SchemaObjects {
82- @Suppress(" DEPRECATION" )
83- if (! options.introspectionEnabled) {
84- // What the deprecated NoIntrospectionGraphqlFieldVisibility does. Its suggested replacement,
85- // Introspection.enabledJvmWide, would also turn introspection off for every other schema in the JVM.
86- // TODO remove this in 15.0.0 (#858)
87- codeRegistryBuilder.fieldVisibility(BlockedFields .newBlock().addPattern(" __.*" ).build())
88- }
89- // this overrides the above introspection enabled setting obviously... todo: add documentation
9081 options.fieldVisibility?.let { codeRegistryBuilder.fieldVisibility(it) }
9182
9283 // Create GraphQL objects
@@ -173,7 +164,7 @@ class SchemaParser internal constructor(
173164 val extensions = typeExtensions.extensionsOf<ObjectTypeExtensionDefinition >(name)
174165 val directives = sdlDirectives.directivesOf(objectDefinition, extensions)
175166 val fieldDefinitions = objectDefinition.withExtensions(typeExtensions).flatMap { it.fieldDefinitions }
176- warnRepeatedFields (name, fieldDefinitions)
167+ rejectRepeated (name, " field " , fieldDefinitions)
177168 val builder = GraphQLObjectType .newObject()
178169 .name(name)
179170 .definition(objectDefinition)
@@ -212,8 +203,8 @@ class SchemaParser internal constructor(
212203 inputObjectsInProgress : MutableSet <String >): GraphQLInputObjectType {
213204 val extensionDefinitions = typeExtensions.extensionsOf<InputObjectTypeExtensionDefinition >(definition.name)
214205 val directives = sdlDirectives.directivesOf(definition, extensionDefinitions)
215- val fieldDefinitions = (extensionDefinitions + definition).flatMap { it.inputValueDefinitions }
216- warnRepeatedFields (definition.name, fieldDefinitions )
206+ val inputValueDefinitions = definition.withExtensions(typeExtensions ).flatMap { it.inputValueDefinitions }
207+ rejectRepeated (definition.name, " field " , inputValueDefinitions )
217208
218209 inputObjectsInProgress.add(definition.name)
219210
@@ -224,7 +215,7 @@ class SchemaParser internal constructor(
224215 .description(getDocumentation(definition, options))
225216 .withSdlDirectives(directives, INPUT_OBJECT )
226217 .apply {
227- fieldDefinitions .forEach { fieldDefinition ->
218+ inputValueDefinitions .forEach { fieldDefinition ->
228219 field(
229220 GraphQLInputObjectField .newInputObjectField()
230221 .name(fieldDefinition.name)
@@ -252,15 +243,15 @@ class SchemaParser internal constructor(
252243 val extensions = typeExtensions.extensionsOf<EnumTypeExtensionDefinition >(name)
253244 val directives = sdlDirectives.directivesOf(definition, extensions)
254245 val values = definition.withExtensions(typeExtensions).flatMap { it.enumValueDefinitions }
255- warnRepeated (name, " value" , values.map { it.name } )
246+ rejectRepeated (name, " value" , values)
256247 val builder = GraphQLEnumType .newEnum()
257248 .name(name)
258249 .definition(definition)
259250 .extensionDefinitions(extensions)
260251 .description(getDocumentation(definition, options))
261252 .withSdlDirectives(directives, ENUM )
262253 .apply {
263- values.distinctBy { it.name }. forEach { valueDefinition ->
254+ values.forEach { valueDefinition ->
264255 val enumName = valueDefinition.name
265256 val enumValue = if (enumClass == null ) {
266257 enumName
@@ -306,15 +297,15 @@ class SchemaParser internal constructor(
306297 val extensions = typeExtensions.extensionsOf<InterfaceTypeExtensionDefinition >(interfaceDefinition.name)
307298 val directives = sdlDirectives.directivesOf(interfaceDefinition, extensions)
308299 val fieldDefinitions = interfaceDefinition.withExtensions(typeExtensions).flatMap { it.fieldDefinitions }
309- warnRepeated (interfaceDefinition.name, " field" , fieldDefinitions.map { it.name } )
300+ rejectRepeated (interfaceDefinition.name, " field" , fieldDefinitions)
310301 val builder = GraphQLInterfaceType .newInterface()
311302 .name(interfaceDefinition.name)
312303 .definition(interfaceDefinition)
313304 .extensionDefinitions(extensions)
314305 .description(getDocumentation(interfaceDefinition, options))
315306 .withSdlDirectives(directives, INTERFACE )
316307 .apply {
317- fieldDefinitions.distinctBy { it.name }. forEach { fieldDefinition ->
308+ fieldDefinitions.forEach { fieldDefinition ->
318309 field { field -> createField(field, fieldDefinition, inputObjects) }
319310 }
320311 }
@@ -331,7 +322,7 @@ class SchemaParser internal constructor(
331322 private fun createUnionObject (definition : UnionTypeDefinition , types : List <GraphQLObjectType >): GraphQLUnionType {
332323 val extensions = typeExtensions.extensionsOf<UnionTypeExtensionDefinition >(definition.name)
333324 val directives = sdlDirectives.directivesOf(definition, extensions)
334- warnRepeated (definition.name, " member" , definition.withExtensions(typeExtensions).flatMap { it.memberTypes }.map { ( it as TypeName ).name })
325+ rejectRepeated (definition.name, " member" , definition.withExtensions(typeExtensions).flatMap { it.memberTypes }.map { it as TypeName })
335326 val builder = GraphQLUnionType .newUnionType()
336327 .name(definition.name)
337328 .definition(definition)
@@ -373,21 +364,10 @@ class SchemaParser internal constructor(
373364 return leafObjects
374365 }
375366
376- // TODO throw a SchemaError instead in 15.0.0 (#863), like graphql-java does
377- private fun warnRepeated (typeName : String , kind : String , names : List <String ?>) {
378- names.groupingBy { it }.eachCount().filterValues { it > 1 }.keys.forEach {
379- log.warn(" Type '$typeName ' declares $kind '$it ' more than once, only the first one is kept." )
380- }
381- }
382-
383- // TODO throw a SchemaError instead in 15.0.0 (#865), like graphql-java does
384- private fun warnRepeatedFields (typeName : String , fieldDefinitions : List <NamedNode <* >>) {
385- fieldDefinitions.groupBy { it.name }.values.filter { it.size > 1 }.forEach { declarations ->
386- val kept = declarations.last()
387- val location = kept.sourceLocation.describe()
388- val which = if (location.isEmpty()) " one of them" else " the one$location "
389- log.warn(" Type '$typeName ' declares field '${kept.name} ' more than once, only $which is kept." )
390- }
367+ private fun rejectRepeated (typeName : String , kind : String , declarations : List <NamedNode <* >>) {
368+ val names = mutableSetOf<String ?>()
369+ val repeat = declarations.firstOrNull { ! names.add(it.name) } ? : return
370+ throw SchemaError (" Type '$typeName ' declares $kind '${repeat.name} ' more than once${repeat.sourceLocation.describe()} ." )
391371 }
392372
393373 private fun createField (field : GraphQLFieldDefinition .Builder , fieldDefinition : FieldDefinition , inputObjects : List <GraphQLInputObjectType >): GraphQLFieldDefinition .Builder {
0 commit comments