diff --git a/pom.xml b/pom.xml
index 093e689c..cd1a5311 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
2.3.10
1.10.2
2.22.3
- 25.1
+ 26.1
1.0.4
${java.version}
diff --git a/src/main/kotlin/graphql/kickstart/tools/DictionaryTypeResolver.kt b/src/main/kotlin/graphql/kickstart/tools/DictionaryTypeResolver.kt
index d7c40b6e..301dc411 100644
--- a/src/main/kotlin/graphql/kickstart/tools/DictionaryTypeResolver.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/DictionaryTypeResolver.kt
@@ -22,7 +22,7 @@ internal abstract class DictionaryTypeResolver(
}
override fun getType(env: TypeResolutionEnvironment): GraphQLObjectType? {
- val clazz = env.getObject().javaClass
+ val clazz = env.getObject()!!.javaClass
val name = getTypeDefinition(clazz)?.name ?: clazz.simpleName
return env.schema.getObjectType(name) ?: throw TypeResolverError(getError(name))
}
diff --git a/src/main/kotlin/graphql/kickstart/tools/SchemaObjects.kt b/src/main/kotlin/graphql/kickstart/tools/SchemaObjects.kt
index efc53693..0c4744fa 100644
--- a/src/main/kotlin/graphql/kickstart/tools/SchemaObjects.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/SchemaObjects.kt
@@ -14,6 +14,10 @@ data class SchemaObjects(
val codeRegistryBuilder: GraphQLCodeRegistry.Builder,
val description: String?
) {
+ // TODO change dictionary to Set in the next major version and remove this cast
+ @Suppress("UNCHECKED_CAST")
+ private fun namedDictionary(): Set = dictionary as Set
+
/**
* Makes a GraphQLSchema with query, mutation and subscription.
*/
@@ -23,7 +27,7 @@ data class SchemaObjects(
.query(query)
.mutation(mutation)
.subscription(subscription)
- .additionalTypes(dictionary)
+ .additionalTypes(namedDictionary())
.additionalDirectives(directives)
.codeRegistry(codeRegistryBuilder.build())
.build()
@@ -35,6 +39,6 @@ data class SchemaObjects(
fun toReadOnlySchema(): GraphQLSchema = GraphQLSchema.newSchema()
.description(description)
.query(query)
- .additionalTypes(dictionary)
+ .additionalTypes(namedDictionary())
.build()
}
diff --git a/src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt b/src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt
index c26efc81..d2049ada 100644
--- a/src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt
@@ -1,5 +1,6 @@
package graphql.kickstart.tools
+import graphql.Directives
import graphql.introspection.Introspection
import graphql.introspection.Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION
import graphql.kickstart.tools.directive.DirectiveWiringHelper
@@ -8,7 +9,6 @@ import graphql.kickstart.tools.util.getExtendedFieldDefinitions
import graphql.kickstart.tools.util.unwrap
import graphql.language.*
import graphql.schema.*
-import graphql.schema.idl.DirectiveInfo
import graphql.schema.idl.RuntimeWiring
import graphql.schema.idl.ScalarInfo
import graphql.schema.visibility.NoIntrospectionGraphqlFieldVisibility
@@ -351,7 +351,7 @@ class SchemaParser internal constructor(
private fun buildAppliedDirectives(directives: List): Array {
return directives.map { directive ->
val graphQLDirective = schemaDirectives.find { d -> d.name == directive.name }
- ?: DirectiveInfo.GRAPHQL_SPECIFICATION_DIRECTIVE_MAP[directive.name]
+ ?: BUILT_IN_DIRECTIVES[directive.name]
?: throw SchemaError("Found applied directive ${directive.name} without corresponding directive definition.")
val graphQLArguments = graphQLDirective.arguments.associateBy { it.name }
@@ -374,6 +374,22 @@ class SchemaParser internal constructor(
)
}
}
+ .apply {
+ // a bare @deprecated has no "reason" argument, which makes SchemaPrinter throw a NPE.
+ // copy the default from the directive definition (for the built-in one: "No longer supported").
+ if (directive.name == Directives.DeprecatedDirective.name && directive.arguments.none { it.name == "reason" }) {
+ val reasonArgument = graphQLArguments["reason"]
+ if (reasonArgument != null && reasonArgument.hasSetDefaultValue()) {
+ argument(GraphQLAppliedDirectiveArgument.newArgument()
+ .name(reasonArgument.name)
+ .type(reasonArgument.type)
+ .description(reasonArgument.description)
+ .inputValueWithState(reasonArgument.argumentDefaultValue)
+ .build()
+ )
+ }
+ }
+ }
.build()
}.toTypedArray()
}
@@ -391,7 +407,7 @@ class SchemaParser internal constructor(
if (repeatable || !names.contains(directive.name)) {
names.add(directive.name)
val graphQLDirective = this.schemaDirectives.find { d -> d.name == directive.name }
- ?: DirectiveInfo.GRAPHQL_SPECIFICATION_DIRECTIVE_MAP[directive.name]
+ ?: BUILT_IN_DIRECTIVES[directive.name]
?: throw SchemaError("Found applied directive ${directive.name} without corresponding directive definition.")
val graphQLArguments = graphQLDirective.arguments.associateBy { it.name }
output.add(
@@ -521,4 +537,16 @@ class SchemaError(message: String, cause: Throwable? = null) : RuntimeException(
val GRAPHQL_SCALARS = ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS.associateBy { it.name }
+// Built from the individual constants rather than Directives.BUILT_IN_DIRECTIVES_MAP (added in graphql-java 26)
+// so that the library keeps working with graphql-java 25. TODO replace with Directives.BUILT_IN_DIRECTIVES_MAP once we deploy a major version
+private val BUILT_IN_DIRECTIVES = listOf(
+ Directives.IncludeDirective,
+ Directives.SkipDirective,
+ Directives.DeprecatedDirective,
+ Directives.SpecifiedByDirective,
+ Directives.OneOfDirective,
+ Directives.DeferDirective,
+ Directives.ExperimentalDisableErrorPropagationDirective
+).associateBy { it.name }
+
const val DEFAULT_DEPRECATION_MESSAGE = "No longer supported"
diff --git a/src/main/kotlin/graphql/kickstart/tools/relay/RelayConnectionFactory.kt b/src/main/kotlin/graphql/kickstart/tools/relay/RelayConnectionFactory.kt
index b3e05db6..465d5bc4 100644
--- a/src/main/kotlin/graphql/kickstart/tools/relay/RelayConnectionFactory.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/relay/RelayConnectionFactory.kt
@@ -1,5 +1,6 @@
package graphql.kickstart.tools.relay
+import graphql.kickstart.tools.SchemaError
import graphql.kickstart.tools.TypeDefinitionFactory
import graphql.language.*
@@ -54,7 +55,7 @@ class RelayConnectionFactory : TypeDefinitionFactory {
.fieldDefinition(FieldDefinition("pageInfo", TypeName("PageInfo")))
.build()
- private fun createEdgeDefinition(connectionType: String, nodeType: String?): ObjectTypeDefinition =
+ private fun createEdgeDefinition(connectionType: String, nodeType: String): ObjectTypeDefinition =
ObjectTypeDefinition.newObjectTypeDefinition()
.name(connectionType + "Edge")
.fieldDefinition(FieldDefinition("cursor", TypeName("String")))
@@ -70,9 +71,9 @@ class RelayConnectionFactory : TypeDefinitionFactory {
.fieldDefinition(FieldDefinition("endCursor", TypeName("String")))
.build()
- private fun Directive.forTypeName(): String? {
- return (this.getArgument("for").value as StringValue).value
- }
+ private fun Directive.forTypeName(): String =
+ (getArgument("for")?.value as? StringValue)?.value
+ ?: throw SchemaError("@connection directive is missing the required 'for' argument")
private fun Directive.withField(field: FieldDefinition): DirectiveWithField {
return DirectiveWithField(field, this.name, this.arguments, this.sourceLocation, this.comments)
@@ -92,9 +93,9 @@ class RelayConnectionFactory : TypeDefinitionFactory {
fun getTypeName(): String {
val type = field.type
if (type is NonNullType) {
- return (type.type as TypeName).name
+ return (type.type as TypeName).name!!
}
- return (field.type as TypeName).name
+ return (field.type as TypeName).name!!
}
}
}
diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt
index 76fc7f19..3a0ccd11 100644
--- a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt
@@ -141,7 +141,7 @@ internal class MethodFieldResolver(
is ListType -> List::class.java.isAssignableFrom(this.genericType.getRawClass(genericParameterType))
&& isConcreteScalarType(environment, type.type, this.genericType.unwrapGenericType(genericParameterType))
- is TypeName -> environment.graphQLSchema?.getType(type.name)?.let { isScalar(it) && type.name != "ID" }
+ is TypeName -> environment.graphQLSchema?.getType(type.name!!)?.let { isScalar(it) && type.name != "ID" }
?: false
is NonNullType -> isConcreteScalarType(environment, type.type, genericParameterType)
diff --git a/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt b/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt
index e61e88c9..7a646182 100644
--- a/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt
@@ -52,7 +52,7 @@ internal val Class<*>.declaredNonProxyMethods: List
internal fun getDocumentation(node: AbstractNode<*>, options: SchemaParserOptions): String? =
when {
- node is AbstractDescribedNode<*> && node.description != null -> node.description.content
+ node is AbstractDescribedNode<*> && node.description != null -> node.description?.content
!options.useCommentsForDescriptions -> null
node.comments.isNullOrEmpty() -> null
else -> node.comments.asSequence()
diff --git a/src/test/kotlin/graphql/kickstart/tools/DeepGenericsHierarchyTest.kt b/src/test/kotlin/graphql/kickstart/tools/DeepGenericsHierarchyTest.kt
index 8871e662..7707f2bc 100644
--- a/src/test/kotlin/graphql/kickstart/tools/DeepGenericsHierarchyTest.kt
+++ b/src/test/kotlin/graphql/kickstart/tools/DeepGenericsHierarchyTest.kt
@@ -18,8 +18,8 @@ class PlaceTest {
val executionInput = ExecutionInput.newExecutionInput().query(query).build()
val result = graphql.execute(executionInput)
- assert(result.getData