From 9a7c2fcafe68a6c31c9ea4f1f84b703e8009bc3a Mon Sep 17 00:00:00 2001 From: "Stuebinger, Bernd" Date: Tue, 15 Oct 2024 17:42:23 +0200 Subject: [PATCH] Cleanup and prepare 0.21.0 --- README.MD | 10 +-- .../kotlin/library-conventions.gradle.kts | 2 +- .../kotlin/com/apurebase/kgraphql/Context.kt | 6 +- .../com/apurebase/kgraphql/GraphQLError.kt | 6 +- .../kotlin/com/apurebase/kgraphql/KGraphQL.kt | 4 +- .../kgraphql/request/CachingDocumentParser.kt | 2 +- .../com/apurebase/kgraphql/request/Lexer.kt | 71 +++++++++++-------- .../com/apurebase/kgraphql/request/Parser.kt | 16 ++--- .../kgraphql/request/TypeReference.kt | 4 +- .../apurebase/kgraphql/request/Variables.kt | 7 +- .../kgraphql/request/VariablesJson.kt | 5 +- .../kgraphql/schema/DefaultSchema.kt | 2 +- .../kgraphql/schema/dsl/KotlinPropertyDSL.kt | 7 +- .../kgraphql/schema/dsl/ResolverDSL.kt | 8 ++- .../kgraphql/schema/dsl/UnionPropertyDSL.kt | 2 +- .../schema/dsl/operations/MutationDSL.kt | 5 +- .../schema/dsl/operations/QueryDSL.kt | 5 +- .../schema/dsl/operations/SubscriptionDSL.kt | 5 +- .../kgraphql/schema/dsl/types/ScalarDSL.kt | 4 +- .../kgraphql/schema/dsl/types/TypeDSL.kt | 10 ++- .../schema/execution/ArgumentTransformer.kt | 22 +++--- .../schema/execution/ArgumentsHandler.kt | 4 +- .../DataLoaderPreparedRequestExecutor.kt | 12 ++-- .../kgraphql/schema/execution/Execution.kt | 5 +- .../kgraphql/schema/execution/Merge.kt | 6 +- .../execution/ParallelRequestExecutor.kt | 47 +++++++----- .../schema/introspection/SchemaProxy.kt | 2 +- .../kgraphql/schema/model/SchemaDefinition.kt | 4 +- .../kgraphql/schema/model/TypeDef.kt | 2 +- .../schema/model/ast/SelectionNode.kt | 2 - .../kgraphql/schema/scalar/Coercion.kt | 5 +- .../kgraphql/schema/structure/LookupSchema.kt | 9 +-- .../schema/structure/RequestInterpreter.kt | 21 +++--- .../schema/structure/SchemaCompilation.kt | 24 ++++--- .../kgraphql/schema/structure/SchemaModel.kt | 17 +++-- .../kgraphql/schema/structure/Type.kt | 5 +- .../kgraphql/schema/structure/Validation.kt | 5 +- .../kgraphql/schema/structure/blockString.kt | 6 +- .../com/apurebase/kgraphql/TestUtils.kt | 8 ++- .../kgraphql/server/HttpRequestHandler.kt | 11 ++- .../apurebase/kgraphql/server/NettyServer.kt | 2 - .../DeprecationSpecificationTest.kt | 1 + .../IntrospectionSpecificationTest.kt | 7 +- .../typesystem/ListsSpecificationTest.kt | 2 +- 44 files changed, 232 insertions(+), 178 deletions(-) diff --git a/README.MD b/README.MD index be18704..ca3a47e 100644 --- a/README.MD +++ b/README.MD @@ -2,8 +2,8 @@ [![Maven Central](https://img.shields.io/maven-central/v/de.stuebingerb/kgraphql.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22de.stuebingerb%22%20AND%20a:%22kgraphql%22) -KGraphQL is a [Kotlin](https://kotlinlang.org/) implementation of [GraphQL](http://graphql.org/). It provides a rich DSL -to set up the GraphQL schema. +KGraphQL is a [Kotlin](https://kotlinlang.org/) implementation of [GraphQL](http://graphql.org/) based +on https://github.com/aPureBase/KGraphQL. It provides a rich DSL to set up the GraphQL schema. ```kotlin data class Article(val id: Int, val text: String) @@ -45,7 +45,7 @@ All contributions are welcome. Feel free to open issues and PRs! ## Building -To build KGraphQL you only need to have JDK8 installed. invoke +To build KGraphQL you only need to have JDK 11 installed. Invoke ```bash ./gradlew build @@ -55,11 +55,11 @@ To perform local build. ## Versioning -The versioning is following [Semantic Versioning](http://semver.org/) +The versioning from 1.0.0 on is following [Semantic Versioning](http://semver.org/) ## Links -Specification : http://facebook.github.io/graphql/ +Specification: https://spec.graphql.org/ ## License diff --git a/buildSrc/src/main/kotlin/library-conventions.gradle.kts b/buildSrc/src/main/kotlin/library-conventions.gradle.kts index 477fc8d..dc5de7e 100644 --- a/buildSrc/src/main/kotlin/library-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/library-conventions.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "de.stuebingerb" -version = "0.20.0" +version = "0.21.0" kotlin { jvmToolchain(11) diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/Context.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/Context.kt index 9c7c210..44589dc 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/Context.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/Context.kt @@ -9,7 +9,11 @@ class Context(private val map: Map) { operator fun get(kClass: KClass): T? { val value = map[kClass] @Suppress("UNCHECKED_CAST") - return if (kClass.isInstance(value)) value as T else null + return if (kClass.isInstance(value)) { + value as T + } else { + null + } } inline fun get(): T? = get(T::class) diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/GraphQLError.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/GraphQLError.kt index b513bc6..60f4afd 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/GraphQLError.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/GraphQLError.kt @@ -71,8 +71,10 @@ open class GraphQLError( val locations: List? by lazy { if (positions != null && source != null) { positions.map { pos -> getLocation(source, pos) } - } else nodes?.mapNotNull { node -> - node.loc?.let { getLocation(it.source, it.start) } + } else { + nodes?.mapNotNull { node -> + node.loc?.let { getLocation(it.source, it.start) } + } } } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/KGraphQL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/KGraphQL.kt index 4cc3454..db3b946 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/KGraphQL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/KGraphQL.kt @@ -6,9 +6,7 @@ import com.apurebase.kgraphql.schema.dsl.SchemaBuilder class KGraphQL { companion object { fun schema(init: SchemaBuilder.() -> Unit): Schema { - return SchemaBuilder() - .apply(init) - .build() + return SchemaBuilder().apply(init).build() } } } \ No newline at end of file diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/CachingDocumentParser.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/CachingDocumentParser.kt index 86a8a0f..6ed7fdc 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/CachingDocumentParser.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/CachingDocumentParser.kt @@ -27,7 +27,7 @@ class CachingDocumentParser(cacheMaximumSize: Long = 1000L) { is Result.Exception -> throw result.exception else -> { cache.invalidateAll() - throw IllegalStateException("Internal error of CachingDocumentParser") + error("Internal error of CachingDocumentParser") } } } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Lexer.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Lexer.kt index d3b93b4..1df0e5e 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Lexer.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Lexer.kt @@ -66,7 +66,9 @@ data class Lexer( val nextToken = readToken(token) token.next = nextToken nextToken - } else token.next!! + } else { + token.next!! + } } while (token.kind === COMMENT) } return token @@ -128,7 +130,9 @@ data class Lexer( // . 46 -> if (body.getOrNull(pos + 1)?.code == 46 && body.getOrNull(pos + 2)?.code == 46) { tok(SPREAD, start = pos, end = pos + 3) - } else fail(code) + } else { + fail(code) + } // : 58 -> tok(COLON) // = @@ -150,10 +154,10 @@ data class Lexer( // - 0-9 45, in (48..57) -> readNumber(pos, code, col, prev) // " - 34 -> { - if (body.getOrNull(pos + 1)?.code == 34 && body.getOrNull(pos + 2)?.code == 34) - readBlockString(pos, col, prev) - else readString(pos, col, prev) + 34 -> if (body.getOrNull(pos + 1)?.code == 34 && body.getOrNull(pos + 2)?.code == 34) { + readBlockString(pos, col, prev) + } else { + readString(pos, col, prev) } else -> fail(code) @@ -361,7 +365,9 @@ data class Lexer( while (position < body.length) { code = body.getOrNull(position)?.code ?: break // not LineTerminator - if (code == 0x00a || code == 0x00d) break + if (code == 0x00a || code == 0x00d) { + break + } // Closing Quote (") if (code == 34) { @@ -543,31 +549,34 @@ data class Lexer( } private fun printCharCode(code: Int?) = - if (code == null) EOF.str - else StringBuilder().apply { - append("\"") - when (val char = code.toChar()) { - '\\' -> append("\\\\") - '"' -> append("\\\"") - '\b' -> append("\\b") - '\n' -> append("\\n") - '\r' -> append("\\r") - '\t' -> append("\\t") - else -> - if (code < 0x007f && char > ' ') { - // Refer: https://utf8-chartable.de/unicode-utf8-table.pl?number=128 - append(char) - } else { - append("\\u") - val hex = Integer.toHexString(code) - for (i in hex.length..3) { - append('0') + if (code == null) { + EOF.str + } else { + StringBuilder().apply { + append("\"") + when (val char = code.toChar()) { + '\\' -> append("\\\\") + '"' -> append("\\\"") + '\b' -> append("\\b") + '\n' -> append("\\n") + '\r' -> append("\\r") + '\t' -> append("\\t") + else -> + if (code < 0x007f && char > ' ') { + // Refer: https://utf8-chartable.de/unicode-utf8-table.pl?number=128 + append(char) + } else { + append("\\u") + val hex = Integer.toHexString(code) + for (i in hex.length..3) { + append('0') + } + append(hex.uppercase()) } - append(hex.uppercase()) - } - } - append("\"") - }.toString() + } + append("\"") + }.toString() + } /** * Report a message that an unexpected character was encountered. diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Parser.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Parser.kt index 444c6c5..231ad8b 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Parser.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Parser.kt @@ -133,10 +133,10 @@ open class Parser { loc = loc(start) ) } - val operation = this.parseOperationType() + val operation = parseOperationType() var name: NameNode? = null if (peek(NAME)) { - name = this.parseName() + name = parseName() } return DefinitionNode.ExecutableDefinitionNode.OperationDefinitionNode( operation = operation, @@ -295,10 +295,10 @@ open class Parser { */ private fun parseFragment(parent: SelectionNode?): SelectionNode.FragmentNode { val start = lexer.token - this.expectToken(SPREAD) + expectToken(SPREAD) val hasTypeCondition = expectOptionalKeyword("on") - if (!hasTypeCondition && this.peek(NAME)) { + if (!hasTypeCondition && peek(NAME)) { return SelectionNode.FragmentNode.FragmentSpreadNode( parent = parent, name = parseFragmentName(), @@ -428,7 +428,7 @@ open class Parser { */ private fun parseList(isConst: Boolean): ValueNode.ListValueNode { val start = lexer.token - val item = { this.parseValueLiteral(isConst) } + val item = { parseValueLiteral(isConst) } return ValueNode.ListValueNode( values = any(BRACKET_L, item, BRACKET_R), @@ -506,7 +506,7 @@ open class Parser { loc = loc(start) ) } else { - type = this.parseNamedType() + type = parseNamedType() } if (expectOptionalToken(BANG) != null) { @@ -655,7 +655,7 @@ open class Parser { */ private fun parseImplementsInterfaces(): MutableList { val types = mutableListOf() - if (this.expectOptionalKeyword("implements")) { + if (expectOptionalKeyword("implements")) { // Optional leading ampersand expectOptionalToken(AMP) do { @@ -1084,7 +1084,7 @@ open class Parser { val nodes = mutableListOf() do { nodes.add(parseFn()) - } while (this.expectOptionalToken(closeKind) == null) + } while (expectOptionalToken(closeKind) == null) return nodes } return mutableListOf() diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/TypeReference.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/TypeReference.kt index 1dd790c..cf8b3bf 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/TypeReference.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/TypeReference.kt @@ -12,7 +12,9 @@ data class TypeReference( override fun toString(): String = buildString { if (isList) { append("[").append(name) - if (!isElementNullable) append("!") + if (!isElementNullable) { + append("!") + } append("]") } else { append(name) diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Variables.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Variables.kt index 83bf285..9998661 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Variables.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/Variables.kt @@ -28,8 +28,9 @@ data class Variables( keyNode: ValueNode.VariableNode, transform: (value: ValueNode) -> Any? ): T? { - val variable = variables?.find { keyNode.name.value == it.variable.name.value } - ?: throw IllegalArgumentException("Variable '$${keyNode.name.value}' was not declared for this operation") + val variable = requireNotNull(variables?.firstOrNull { keyNode.name.value == it.variable.name.value }) { + "Variable '$${keyNode.name.value}' was not declared for this operation" + } val isIterable = kClass.isIterable() @@ -45,7 +46,7 @@ data class Variables( for (element in value as Iterable<*>) { if (element == null) { throw GraphQLError( - "Invalid argument value $value from variable $${keyNode.name.value}, expected list with non null arguments", + "Invalid argument value $value from variable $${keyNode.name.value}, expected list with non-null arguments", keyNode ) } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/VariablesJson.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/VariablesJson.kt index 2852edc..97802e7 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/VariablesJson.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/VariablesJson.kt @@ -39,9 +39,10 @@ interface VariablesJson { try { // TODO: Move away from jackson and only depend on kotlinx.serialization objectMapper.treeToValue(tree, kType.toTypeReference()) + } catch (e: GraphQLError) { + throw e } catch (e: Exception) { - throw if (e is GraphQLError) e - else ExecutionException("Failed to coerce $tree as $kType", key, e) + throw ExecutionException("Failed to coerce $tree as $kType", key, e) } } } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt index b1985da..399c904 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt @@ -63,7 +63,7 @@ class DefaultSchema( ) } - private fun String.isIntrospection() = this.contains("__schema") || this.contains("__type") + private fun String.isIntrospection() = contains("__schema") || contains("__type") override fun typeByKClass(kClass: KClass<*>): Type? = model.queryTypes[kClass] diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/KotlinPropertyDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/KotlinPropertyDSL.kt index 1d31293..ce847b5 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/KotlinPropertyDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/KotlinPropertyDSL.kt @@ -2,7 +2,6 @@ package com.apurebase.kgraphql.schema.dsl import com.apurebase.kgraphql.Context import com.apurebase.kgraphql.schema.model.PropertyDef -import java.lang.IllegalArgumentException import kotlin.reflect.KProperty1 class KotlinPropertyDSL( @@ -22,10 +21,12 @@ class KotlinPropertyDSL( if (parent != null) rule( parent, ctx - ) else IllegalArgumentException("Unexpected null parent of kotlin property") + ) else { + IllegalArgumentException("Unexpected null parent of kotlin property") + } } - this.accessRuleBlock = accessRuleAdapter + accessRuleBlock = accessRuleAdapter } fun toKQLProperty() = PropertyDef.Kotlin( diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/ResolverDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/ResolverDSL.kt index 6370abc..e8ed413 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/ResolverDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/ResolverDSL.kt @@ -9,9 +9,11 @@ class ResolverDSL(val target: Target) { fun withArgs(block: InputValuesDSL.() -> Unit) { val inputValuesDSL = InputValuesDSL().apply(block) - target.addInputValues(inputValuesDSL.inputValues.map { inputValue -> - (inputValue.toKQLInputValue()) - }) + target.addInputValues( + inputValuesDSL.inputValues.map { inputValue -> + inputValue.toKQLInputValue() + } + ) } inline fun returns(): ResolverDSL { diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/UnionPropertyDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/UnionPropertyDSL.kt index 6c2eefa..12c5983 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/UnionPropertyDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/UnionPropertyDSL.kt @@ -15,7 +15,7 @@ class UnionPropertyDSL(val name: String, block: UnionPropertyDSL.() block() } - internal lateinit var functionWrapper: FunctionWrapper + private lateinit var functionWrapper: FunctionWrapper lateinit var returnType: TypeID diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/MutationDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/MutationDSL.kt index 0d8ee30..7f58a66 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/MutationDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/MutationDSL.kt @@ -7,8 +7,9 @@ class MutationDSL( ) : AbstractOperationDSL(name) { internal fun toKQLMutation(): MutationDef { - val function = - functionWrapper ?: throw IllegalArgumentException("resolver has to be specified for mutation [$name]") + val function = requireNotNull(functionWrapper) { + "resolver has to be specified for mutation [$name]" + } return MutationDef( name = name, diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/QueryDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/QueryDSL.kt index 7411d85..f2545c9 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/QueryDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/QueryDSL.kt @@ -7,8 +7,9 @@ class QueryDSL( ) : AbstractOperationDSL(name) { internal fun toKQLQuery(): QueryDef { - val function = - functionWrapper ?: throw IllegalArgumentException("resolver has to be specified for query [$name]") + val function = requireNotNull(functionWrapper) { + "resolver has to be specified for query [$name]" + } return QueryDef( name = name, diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/SubscriptionDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/SubscriptionDSL.kt index 5dca851..eb07e39 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/SubscriptionDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/SubscriptionDSL.kt @@ -16,8 +16,9 @@ class SubscriptionDSL( ) : AbstractOperationDSL(name) { internal fun toKQLSubscription(): SubscriptionDef { - val function = - functionWrapper ?: throw IllegalArgumentException("resolver has to be specified for query [$name]") + val function = requireNotNull(functionWrapper) { + "resolver has to be specified for subscription [$name]" + } return SubscriptionDef( name = name, diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/ScalarDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/ScalarDSL.kt index 0e62b5d..192637d 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/ScalarDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/ScalarDSL.kt @@ -5,9 +5,7 @@ import com.apurebase.kgraphql.schema.dsl.ItemDSL import com.apurebase.kgraphql.schema.scalar.ScalarCoercion import kotlin.reflect.KClass -abstract class ScalarDSL( - kClass: KClass -) : ItemDSL() { +abstract class ScalarDSL(kClass: KClass) : ItemDSL() { companion object { const val PLEASE_SPECIFY_COERCION = diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/TypeDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/TypeDSL.kt index a2ab435..fa94734 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/TypeDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/TypeDSL.kt @@ -22,13 +22,13 @@ open class TypeDSL( var name = kClass.defaultKQLTypeName() - internal val transformationProperties = mutableSetOf>() + private val transformationProperties = mutableSetOf>() - internal val extensionProperties = mutableSetOf>() + private val extensionProperties = mutableSetOf>() - internal val unionProperties = mutableSetOf>() + private val unionProperties = mutableSetOf>() - internal val describedKotlinProperties = mutableMapOf, PropertyDef.Kotlin>() + private val describedKotlinProperties = mutableMapOf, PropertyDef.Kotlin>() val dataloadedExtensionProperties = mutableSetOf>() @@ -73,7 +73,6 @@ open class TypeDSL( transformationProperties.add(Transformation(kProperty, FunctionWrapper.on(function, true))) } - @OptIn(ExperimentalStdlibApi::class) inline fun dataProperty( name: String, noinline block: DataLoaderPropertyDSL.() -> Unit @@ -109,7 +108,6 @@ open class TypeDSL( unionProperties.add(property.toKQLProperty(union)) } - internal fun toKQLObject(): TypeDef.Object { return TypeDef.Object( name = name, diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ArgumentTransformer.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ArgumentTransformer.kt index 065f8cd..d4a2761 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ArgumentTransformer.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ArgumentTransformer.kt @@ -1,10 +1,10 @@ package com.apurebase.kgraphql.schema.execution import com.apurebase.kgraphql.ExecutionException +import com.apurebase.kgraphql.GraphQLError import com.apurebase.kgraphql.request.Variables import com.apurebase.kgraphql.schema.DefaultSchema import com.apurebase.kgraphql.schema.model.ast.ValueNode -import com.apurebase.kgraphql.GraphQLError import com.apurebase.kgraphql.schema.scalar.deserializeScalar import com.apurebase.kgraphql.schema.structure.InputValue import com.apurebase.kgraphql.schema.structure.Type @@ -41,8 +41,7 @@ open class ArgumentTransformer(val schema: DefaultSchema) { value ) - val paramType = inputField - .type as? Type + val paramType = inputField.type as? Type ?: throw GraphQLError( "Something went wrong while searching for the constructor parameter type : '${valueField.name.value}'", value @@ -51,8 +50,7 @@ open class ArgumentTransformer(val schema: DefaultSchema) { params.getValue(valueField.name.value) to transformValue(paramType, valueField.value, variables) } - val missingNonOptionalInputs = params.values - .filter { !it.isOptional && !valueMap.containsKey(it) } + val missingNonOptionalInputs = params.values.filter { !it.isOptional && !valueMap.containsKey(it) } if (missingNonOptionalInputs.isNotEmpty()) { val inputs = missingNonOptionalInputs.map { it.name }.joinToString(",") @@ -68,7 +66,9 @@ open class ArgumentTransformer(val schema: DefaultSchema) { "argument '${value.valueNodeName}' is not valid value of type ${type.unwrapped().name}", value ) - } else null + } else { + null + } } value is ValueNode.ListValueNode && type.isList() -> { @@ -101,10 +101,12 @@ open class ArgumentTransformer(val schema: DefaultSchema) { schema.model.enums[kClass]?.let { enumType -> return if (value is ValueNode.EnumValueNode) { enumType.values.find { it.name == value.value }?.value ?: throwInvalidEnumValue(enumType) - } else throw GraphQLError( - "String literal '${value.valueNodeName}' is invalid value for enum type ${enumType.name}", - value - ) + } else { + throw GraphQLError( + "String literal '${value.valueNodeName}' is invalid value for enum type ${enumType.name}", + value + ) + } } ?: schema.model.scalars[kClass]?.let { scalarType -> return deserializeScalar(scalarType, value) } ?: throw GraphQLError( diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ArgumentsHandler.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ArgumentsHandler.kt index 76fac22..78a334a 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ArgumentsHandler.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ArgumentsHandler.kt @@ -26,7 +26,7 @@ internal class ArgumentsHandler(schema: DefaultSchema) : ArgumentTransformer(sch if (unsupportedArguments?.isNotEmpty() == true) { throw GraphQLError( - "$funName does support arguments ${inputValues.map { it.name }}. found arguments ${args.keys}", + "$funName does support arguments ${inputValues.map { it.name }}. Found arguments ${args.keys}", executionNode.selectionNode ) } @@ -35,7 +35,7 @@ internal class ArgumentsHandler(schema: DefaultSchema) : ArgumentTransformer(sch val value = args?.get(parameter.name) when { - //inject request context + // inject request context parameter.type.isInstance(requestContext) -> requestContext parameter.type.isInstance(executionNode) -> executionNode value == null && parameter.type.kind != TypeKind.NON_NULL -> parameter.default diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor.kt index 1e7c167..fad6682 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor.kt @@ -211,7 +211,7 @@ class DataLoaderPreparedRequestExecutor(val schema: DefaultSchema) : RequestExec value, container.elements.first { expectedType.name == expectedType.name } as Execution.Fragment ) else { - throw IllegalStateException("fragments can be specified on object types, interfaces, and unions") + error("fragments can be specified on object types, interfaces, and unions") } } @@ -224,8 +224,9 @@ class DataLoaderPreparedRequestExecutor(val schema: DefaultSchema) : RequestExec ) { when (child) { is Execution.Union -> { - val field = type.unwrapped()[child.key] - ?: throw IllegalStateException("Execution unit ${child.key} is not contained by operation return type") + val field = checkNotNull(type.unwrapped()[child.key]) { + "Execution unit ${child.key} is not contained by operation return type" + } if (field is Field.Union<*>) { createUnionOperationNode(ctx, value, child, field as Field.Union, parentCount) } else { @@ -234,8 +235,9 @@ class DataLoaderPreparedRequestExecutor(val schema: DefaultSchema) : RequestExec } is Execution.Node -> { - val field = type.unwrapped()[child.key] - ?: throw IllegalStateException("Execution unit ${child.key} is not contained by operation return type") + val field = checkNotNull(type.unwrapped()[child.key]) { + "Execution unit ${child.key} is not contained by operation return type" + } createPropertyNodeAsync(ctx, value, child, field, parentCount) } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Execution.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Execution.kt index dc5114b..818e7c0 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Execution.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Execution.kt @@ -55,8 +55,9 @@ sealed class Execution { return Node( selectionNode = selectionNode, field = field, - children = memberChildren[type] - ?: throw IllegalArgumentException("Union ${unionField.name} has no member $type"), + children = requireNotNull(memberChildren[type]) { + "Union ${unionField.name} has no member $type" + }, key = key, alias = alias, arguments = arguments, diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Merge.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Merge.kt index 267e855..4e3476a 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Merge.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Merge.kt @@ -22,14 +22,14 @@ fun merge(key: String, node: JsonNode?, get: (String) -> JsonNode?, set: (String val existingNode = get(key) if (existingNode != null) { when { - node == null -> throw IllegalStateException("trying to merge null with non-null for $key") + node == null -> error("trying to merge null with non-null for $key") node is ObjectNode -> { check(existingNode is ObjectNode) { "trying to merge object with simple node for $key" } existingNode.merge(node) } - existingNode is ObjectNode -> throw IllegalStateException("trying to merge simple node with object node for $key") - node != existingNode -> throw IllegalStateException("trying to merge different simple nodes for $key") + existingNode is ObjectNode -> error("trying to merge simple node with object node for $key") + node != existingNode -> error("trying to merge different simple nodes for $key") } } else { set(key, node) diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt index ad1054e..75756fb 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt @@ -51,16 +51,21 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { val resultMap = plan.toMapAsync(dispatcher) { val ctx = ExecutionContext(Variables(schema, variables, it.variables), context) - if (determineInclude(ctx, it)) writeOperation( - isSubscription = plan.isSubscription, - ctx = ctx, - node = it, - operation = it.field as Field.Function<*, *> - ) else null + if (shouldInclude(ctx, it)) { + writeOperation( + isSubscription = plan.isSubscription, + ctx = ctx, + node = it, + operation = it.field as Field.Function<*, *> + ) + } else { + null + } } for (operation in plan) { - if (resultMap[operation] != null) { // Remove all by skip/include directives + // Remove all by skip/include directives + if (resultMap[operation] != null) { data.set(operation.aliasOrKey, resultMap[operation]) } } @@ -221,8 +226,9 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { when (child) { //Union is subclass of Node so check it first is Execution.Union -> { - val field = type.unwrapped()[child.key] - ?: throw IllegalStateException("Execution unit ${child.key} is not contained by operation return type") + val field = checkNotNull(type.unwrapped()[child.key]) { + "Execution unit ${child.key} is not contained by operation return type" + } if (field is Field.Union<*>) { return child.aliasOrKey to createUnionOperationNode(ctx, value, child, field as Field.Union) } else { @@ -231,8 +237,9 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { } is Execution.Node -> { - val field = type.unwrapped()[child.key] - ?: throw IllegalStateException("Execution unit ${child.key} is not contained by operation return type") + val field = checkNotNull(type.unwrapped()[child.key]) { + "Execution unit ${child.key} is not contained by operation return type" + } return child.aliasOrKey to (createPropertyNode(ctx, value, child, field) ?: return null) } @@ -248,7 +255,7 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { container: Execution.Fragment ): Map { val expectedType = container.condition.type - val include = determineInclude(ctx, container) + val include = shouldInclude(ctx, container) if (include) { if (expectedType.kind == TypeKind.OBJECT || expectedType.kind == TypeKind.INTERFACE) { @@ -265,7 +272,7 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { value, container.elements.first { expectedType.name == expectedType.name } as Execution.Fragment ) else { - throw IllegalStateException("fragments can be specified on object types, interfaces, and unions") + error("fragments can be specified on object types, interfaces, and unions") } } //not included, or type condition is not matched @@ -278,7 +285,7 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { node: Execution.Node, field: Field ): JsonNode? { - val include = determineInclude(ctx, node) + val include = shouldInclude(ctx, node) node.field.checkAccess(parentValue, ctx.requestContext) if (include) { @@ -361,8 +368,10 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { return createNode(ctx, result, node, field.returnType) } - private suspend fun determineInclude(ctx: ExecutionContext, executionNode: Execution): Boolean { - if (executionNode.directives?.isEmpty() == true) return true + private suspend fun shouldInclude(ctx: ExecutionContext, executionNode: Execution): Boolean { + if (executionNode.directives?.isEmpty() == true) { + return true + } return executionNode.directives?.map { (directive, arguments) -> directive.execution.invoke( funName = directive.name, @@ -394,7 +403,7 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { executionNode, ctx.requestContext ) - //exceptions are not caught on purpose to pass up business logic errors + // exceptions are not caught on purpose to pass up business logic errors return try { when { hasReceiver -> invoke(receiver, *transformedArgs.toTypedArray()) @@ -408,7 +417,9 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { } catch (e: Throwable) { if (schema.configuration.wrapErrors && e !is GraphQLError) { throw GraphQLError(e.message ?: "", nodes = listOf(executionNode.selectionNode), originalError = e) - } else throw e + } else { + throw e + } } } } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/SchemaProxy.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/SchemaProxy.kt index 071c1b1..896cda0 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/SchemaProxy.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/SchemaProxy.kt @@ -17,7 +17,7 @@ class SchemaProxy( const val ILLEGAL_STATE_MESSAGE = "Missing proxied __Schema instance" } - private fun getProxied() = proxiedSchema ?: throw IllegalStateException(ILLEGAL_STATE_MESSAGE) + private fun getProxied() = checkNotNull(proxiedSchema) { ILLEGAL_STATE_MESSAGE } override val types: List<__Type> get() = getProxied().types diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/SchemaDefinition.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/SchemaDefinition.kt index 8a9d11b..0c52050 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/SchemaDefinition.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/SchemaDefinition.kt @@ -6,9 +6,9 @@ import com.apurebase.kgraphql.schema.directive.Directive * [SchemaDefinition] represents unstructured schema components * * [SchemaDefinition] does not contain all nodes in schema, only these, - * which have been directly declared via [SchemaBuilder]. + * which have been directly declared via [com.apurebase.kgraphql.schema.dsl.SchemaBuilder]. * - * [SchemaStructure] contains full schema tree, with all types + * [SchemaDefinition] contains full schema tree, with all types */ data class SchemaDefinition( val objects: List>, diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/TypeDef.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/TypeDef.kt index 3a0d289..01ea1bd 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/TypeDef.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/TypeDef.kt @@ -26,7 +26,7 @@ interface TypeDef { description: String? = null ) : BaseKQLType(name, description), Kotlin { - val propertiesByName = kotlinProperties.mapKeys { entry -> entry.key.name } + private val propertiesByName = kotlinProperties.mapKeys { entry -> entry.key.name } fun isIgnored(property: String): Boolean = propertiesByName[property]?.isIgnored ?: false } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/SelectionNode.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/SelectionNode.kt index f47bff9..9710055 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/SelectionNode.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/SelectionNode.kt @@ -28,7 +28,6 @@ sealed class SelectionNode(val parent: SelectionNode?) : ASTNode() { val aliasOrName get() = alias ?: name override val fullPath get() = (parent?.fullPath?.let { "$it." } ?: "") + aliasOrName.value - } sealed class FragmentNode(parent: SelectionNode?, val directives: List?) : SelectionNode(parent) { @@ -68,5 +67,4 @@ sealed class SelectionNode(val parent: SelectionNode?) : ASTNode() { } } } - } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/Coercion.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/Coercion.kt index 4e3559b..c6f4eed 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/Coercion.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/Coercion.kt @@ -45,9 +45,10 @@ fun deserializeScalar(scalar: Type.Scalar, value: ValueNode): T { value ) } + } catch (e: GraphQLError) { + throw e } catch (e: Exception) { - throw if (e is GraphQLError) e - else GraphQLError( + throw GraphQLError( message = "argument '${value.valueNodeName}' is not valid value of type ${scalar.name}", nodes = listOf(value), originalError = e diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/LookupSchema.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/LookupSchema.kt index 2586f30..3b05ef7 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/LookupSchema.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/LookupSchema.kt @@ -24,20 +24,21 @@ interface LookupSchema : Schema { fun typeReference(kType: KType): TypeReference { if (kType.jvmErasure.isIterable()) { - val elementKType = kType.arguments.first().type - ?: throw IllegalArgumentException("Cannot transform kotlin collection type $kType to KGraphQL TypeReference") + val elementKType = requireNotNull(kType.arguments.first().type) { + "Cannot transform kotlin collection type $kType to KGraphQL TypeReference" + } val elementKTypeErasure = elementKType.jvmErasure val kqlType = typeByKClass(elementKTypeErasure) ?: inputTypeByKClass(elementKTypeErasure) ?: throw IllegalArgumentException("$kType has not been registered in this schema") - val name = kqlType.name ?: throw IllegalArgumentException("Cannot create type reference to unnamed type") + val name = requireNotNull(kqlType.name) { "Cannot create type reference to unnamed type" } return TypeReference(name, kType.isMarkedNullable, true, elementKType.isMarkedNullable) } else { val erasure = kType.jvmErasure val kqlType = typeByKClass(erasure) ?: inputTypeByKClass(erasure) ?: throw IllegalArgumentException("$kType has not been registered in this schema") - val name = kqlType.name ?: throw IllegalArgumentException("Cannot create type reference to unnamed type") + val name = requireNotNull(kqlType.name) { "Cannot create type reference to unnamed type" } return TypeReference(name, kType.isMarkedNullable) } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/RequestInterpreter.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/RequestInterpreter.kt index bade2dc..c76f07c 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/RequestInterpreter.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/RequestInterpreter.kt @@ -26,7 +26,7 @@ import com.apurebase.kgraphql.schema.model.ast.toArguments import java.util.Stack import kotlin.reflect.full.starProjectedType -class RequestInterpreter(val schemaModel: SchemaModel) { +class RequestInterpreter(private val schemaModel: SchemaModel) { private val directivesByName = schemaModel.directives.associateBy { it.name } @@ -36,10 +36,9 @@ class RequestInterpreter(val schemaModel: SchemaModel) { // prevent stack overflow private val fragmentsStack = Stack() fun get(node: FragmentSpreadNode): Execution.Fragment? { - if (fragmentsStack.contains(node.name.value)) throw GraphQLError( - "Fragment spread circular references are not allowed", - node - ) + if (fragmentsStack.contains(node.name.value)) { + throw GraphQLError("Fragment spread circular references are not allowed", node) + } val (conditionType, selectionSet) = fragments[node.name.value] ?: return null val condition = TypeCondition(conditionType) @@ -66,7 +65,9 @@ class RequestInterpreter(val schemaModel: SchemaModel) { 1 -> operations.first() else -> { val operationNamesFound = operations.mapNotNull { it.name?.value }.also { - if (it.size != operations.size) throw GraphQLError("anonymous operation must be the only defined operation") + if (it.size != operations.size) { + throw GraphQLError("anonymous operation must be the only defined operation") + } }.joinToString(prefix = "[", postfix = "]") val operationName = requestedOperationName ?: ( @@ -147,14 +148,14 @@ class RequestInterpreter(val schemaModel: SchemaModel) { enclosingType: Type ): Execution.Fragment = when (fragment) { is FragmentSpreadNode -> { - ctx.get(fragment) ?: throw throwUnknownFragmentTypeEx(fragment) + ctx.get(fragment) ?: throw unknownFragmentTypeException(fragment) } is InlineFragmentNode -> { val type = if (fragment.directives?.isNotEmpty() == true) { enclosingType } else { - schemaModel.queryTypesByName[fragment.typeCondition?.name?.value] ?: throw throwUnknownFragmentTypeEx( + schemaModel.queryTypesByName[fragment.typeCondition?.name?.value] ?: throw unknownFragmentTypeException( fragment ) } @@ -247,8 +248,8 @@ class RequestInterpreter(val schemaModel: SchemaModel) { } - private fun throwUnknownFragmentTypeEx(fragment: FragmentNode) = when (fragment) { - is FragmentSpreadNode -> throw IllegalArgumentException("This should never happen") + private fun unknownFragmentTypeException(fragment: FragmentNode) = when (fragment) { + is FragmentSpreadNode -> IllegalStateException("This should never happen") is InlineFragmentNode -> GraphQLError( message = "Unknown type ${fragment.typeCondition?.name?.value} in type condition on fragment ${fragment.typeCondition?.name?.value}", node = fragment diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/SchemaCompilation.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/SchemaCompilation.kt index e641ae1..536f18f 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/SchemaCompilation.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/SchemaCompilation.kt @@ -74,13 +74,19 @@ class SchemaCompilation( val model = SchemaModel( query = queryType, - mutation = if (mutationType.fields!!.isEmpty()) null else mutationType, - subscription = if (subscriptionType.fields!!.isEmpty()) null else subscriptionType, - + mutation = if (mutationType.fields!!.isEmpty()) { + null + } else { + mutationType + }, + subscription = if (subscriptionType.fields!!.isEmpty()) { + null + } else { + subscriptionType + }, enums = enums, scalars = scalars, unions = unions, - queryTypes = queryTypeProxies + enums + scalars, inputTypes = inputTypeProxies + enums + scalars, allTypes = queryTypeProxies.values @@ -170,7 +176,6 @@ class SchemaCompilation( private suspend fun handleUnionProperty(unionProperty: PropertyDef.Union<*>): Field { val inputValues = handleInputValues(unionProperty.name, unionProperty, unionProperty.inputValues) val type = handleUnionType(unionProperty.union) - return Field.Union(unionProperty, unionProperty.nullable, type, inputValues) } @@ -231,7 +236,6 @@ class SchemaCompilation( TypeCategory.INPUT -> inputTypeProxies } - return cachedInstances[kClass] ?: enums[kClass] ?: scalars[kClass] @@ -260,7 +264,7 @@ class SchemaCompilation( val objectDefs = definition.objects.filter { it.kClass.isSuperclassOf(kClass) } val objectDef = objectDefs.find { it.kClass == kClass } ?: TypeDef.Object(kClass.defaultKQLTypeName(), kClass) - //treat introspection types as objects -> adhere to reference implementation behaviour + // treat introspection types as objects -> adhere to reference implementation behaviour val kind = if (kClass.isFinal || objectDef.name.startsWith("__")) TypeKind.OBJECT else TypeKind.INTERFACE val objectType = if (kind == TypeKind.OBJECT) Type.Object(objectDef) else Type.Interface(objectDef) @@ -318,7 +322,11 @@ class SchemaCompilation( val allFields = declaredFields + __typenameField typeProxy.proxied = - if (kind == TypeKind.OBJECT) Type.Object(objectDef, allFields) else Type.Interface(objectDef, allFields) + if (kind == TypeKind.OBJECT) { + Type.Object(objectDef, allFields) + } else { + Type.Interface(objectDef, allFields) + } return typeProxy } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/SchemaModel.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/SchemaModel.kt index 7820593..2fb944b 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/SchemaModel.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/SchemaModel.kt @@ -29,15 +29,20 @@ data class SchemaModel( override val types: List<__Type> = toTypeList() private fun toTypeList(): List<__Type> { - var list = allTypes.toList() - //workaround on the fact that Double and Float are treated as GraphQL Float + val list = allTypes + // workaround on the fact that Double and Float are treated as GraphQL Float .filterNot { it is Type.Scalar<*> && it.kClass == Float::class } .filterNot { it.kClass?.findAnnotation() != null } - //query and mutation must be present in introspection 'types' field for introspection tools + // query and mutation must be present in introspection 'types' field for introspection tools .plus(query) - if (mutation != null) list = list.plus(mutation) - if (subscription != null) list = list.plus(subscription) - return list + .toMutableList() + if (mutation != null) { + list += mutation + } + if (subscription != null) { + list += subscription + } + return list.toList() } override val queryType: __Type = query diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/Type.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/Type.kt index 686f362..aea146e 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/Type.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/Type.kt @@ -49,8 +49,9 @@ interface Type : __Type { fun isInstance(value: Any?): Boolean = kClass?.isInstance(value) ?: false fun toKType(): KType { - val unwrappedKClass: KClass<*> = - unwrapped().kClass ?: throw IllegalArgumentException("This type cannot be represented as KType") + val unwrappedKClass: KClass<*> = requireNotNull(unwrapped().kClass) { + "This type cannot be represented as KType" + } return if (isList()) { List::class.createType( diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/Validation.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/Validation.kt index 9904e0d..b769ba5 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/Validation.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/Validation.kt @@ -19,7 +19,7 @@ fun validatePropertyArguments(parentType: Type, field: Field, requestNode: Field } fun Field.validateArguments(selectionArgs: List?, parentTypeName: String?): List { - if (!(this.arguments.isNotEmpty() || selectionArgs?.isNotEmpty() != true)) { + if (!(arguments.isNotEmpty() || selectionArgs?.isNotEmpty() != true)) { return listOf( ValidationException( message = "Property $name on type $parentTypeName has no arguments, found: ${selectionArgs.map { it.name.value }}", @@ -36,8 +36,7 @@ fun Field.validateArguments(selectionArgs: List?, parentTypeName: if (!invalidArguments.isNullOrEmpty()) { exceptions.add( ValidationException( - message = "$name does support arguments ${arguments.map { it.name }}. " + - "Found arguments ${selectionArgs.map { it.name.value }}" + message = "$name does support arguments $parameterNames. Found arguments ${selectionArgs.map { it.name.value }}" ) ) } diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/blockString.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/blockString.kt index ca4fa80..e8d787c 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/blockString.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/blockString.kt @@ -16,7 +16,11 @@ internal fun dedentBlockStringValue(rawString: String): String { if (commonIndent != 0) { for (index in lines.drop(1).indices) { val line = lines[index + 1] - val toRemove = if (line.length <= commonIndent - 1) line.length else commonIndent + val toRemove = if (line.length <= commonIndent - 1) { + line.length + } else { + commonIndent + } lines[index + 1] = line.removeRange(0, toRemove) } } diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/TestUtils.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/TestUtils.kt index 441ce98..eda4d4a 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/TestUtils.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/TestUtils.kt @@ -30,12 +30,16 @@ fun Map<*, *>.extract(path: String): T { try { return tokens.fold(this as Any?) { workingMap, token -> if (token.contains('[')) { - if (!(workingMap as Map<*, *>).containsKey(token.substringBefore('['))) throw IllegalArgumentException() + if (!(workingMap as Map<*, *>).containsKey(token.substringBefore('['))) { + throw IllegalArgumentException() + } val list = workingMap[token.substringBefore('[')] val index = token.substring(token.indexOf('[') + 1, token.length - 1).toInt() (list as List<*>)[index] } else { - if (!(workingMap as Map<*, *>).containsKey(token)) throw IllegalArgumentException() + if (!(workingMap as Map<*, *>).containsKey(token)) { + throw IllegalArgumentException() + } workingMap[token] } } as T diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/server/HttpRequestHandler.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/server/HttpRequestHandler.kt index afc74e0..b9caff9 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/server/HttpRequestHandler.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/server/HttpRequestHandler.kt @@ -1,7 +1,7 @@ package com.apurebase.kgraphql.server -import com.fasterxml.jackson.databind.ObjectMapper import com.apurebase.kgraphql.schema.DefaultSchema +import com.fasterxml.jackson.databind.ObjectMapper import io.netty.buffer.Unpooled import io.netty.channel.ChannelFutureListener import io.netty.channel.ChannelHandler @@ -23,9 +23,7 @@ import java.util.logging.Logger */ @ChannelHandler.Sharable class HttpRequestHandler(val schema: DefaultSchema) : SimpleChannelInboundHandler() { - private val logger: Logger = Logger.getLogger(HttpRequestHandler::class.qualifiedName) - private val objectMapper = ObjectMapper() override fun channelRead0(ctx: ChannelHandlerContext, msg: FullHttpRequest) { @@ -37,8 +35,9 @@ class HttpRequestHandler(val schema: DefaultSchema) : SimpleChannelInboundHandle private fun handleQuery(ctx: ChannelHandlerContext, msg: FullHttpRequest) { val content = msg.content().toString(Charset.defaultCharset()) - val query = objectMapper.readTree(content)["query"].textValue() - ?: throw IllegalArgumentException("Please specify only one query") + val query = requireNotNull(objectMapper.readTree(content)["query"].textValue()) { + "Please specify only one query" + } try { val response = schema.executeBlocking(query, null) writeResponse(ctx, response) @@ -65,7 +64,6 @@ class HttpRequestHandler(val schema: DefaultSchema) : SimpleChannelInboundHandle response: String, contentType: AsciiString = HttpHeaderValues.APPLICATION_JSON ) { - val httpResponse = DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.OK, @@ -74,7 +72,6 @@ class HttpRequestHandler(val schema: DefaultSchema) : SimpleChannelInboundHandle httpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, httpResponse.content().readableBytes()) httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType) - ctx.writeAndFlush(httpResponse) } diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/server/NettyServer.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/server/NettyServer.kt index d6e824b..aa114a6 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/server/NettyServer.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/server/NettyServer.kt @@ -12,9 +12,7 @@ import io.netty.handler.logging.LoggingHandler class NettyServer { companion object { - fun run(schema: Schema, port: Int) { - val workerGroup = NioEventLoopGroup() try { val channel = ServerBootstrap() diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/introspection/DeprecationSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/introspection/DeprecationSpecificationTest.kt index 74e778e..ef05c6b 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/introspection/DeprecationSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/introspection/DeprecationSpecificationTest.kt @@ -89,6 +89,7 @@ class DeprecationSpecificationTest { assertThat(response.extract("data/__type/fields[1]/isDeprecated"), equalTo(true)) } + @Suppress("unused") enum class SampleEnum { ONE, TWO, THREE } @Test diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/introspection/IntrospectionSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/introspection/IntrospectionSpecificationTest.kt index 1ddbfed..d466c5f 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/introspection/IntrospectionSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/introspection/IntrospectionSpecificationTest.kt @@ -207,14 +207,16 @@ class IntrospectionSpecificationTest { fun `__typename returns actual type of object`() { val schema = defaultSchema { query("interface") { - resolver { -> Face("~~MOCK~~") as Inter } + resolver { -> + @Suppress("USELESS_CAST") + Face("~~MOCK~~") as Inter + } } type() type() } - val response = deserialize(schema.executeBlocking("{interface{value, __typename ... on Face{value2}}}")) assertThat(response.extract("data/interface/__typename"), equalTo("Face")) assertThat(response.extract("data/interface/value2"), equalTo(false)) @@ -236,7 +238,6 @@ class IntrospectionSpecificationTest { type() } - val possibleTypes = schema.findTypeByName("Inter")?.possibleTypes?.map { it.name } assertThat(possibleTypes, equalTo(listOf("Face"))) diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/ListsSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/ListsSpecificationTest.kt index d66fe80..acbb9b0 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/ListsSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/ListsSpecificationTest.kt @@ -75,7 +75,7 @@ class ListsSpecificationTest { } shouldThrow GraphQLError::class with { println(prettyPrint()) message shouldBeEqualTo "Invalid argument value [GAGA, null, DADA, PADA] from variable \$list, " + - "expected list with non null arguments" + "expected list with non-null arguments" } }