marais.graphql.dsl.fields.kt Maven / Gradle / Ivy
package marais.graphql.dsl
import graphql.schema.DataFetcher
import kotlin.reflect.KFunction
import kotlin.reflect.KProperty1
import kotlin.reflect.KType
import kotlin.reflect.full.valueParameters
import kotlin.reflect.jvm.reflect
sealed class FieldSpec(val name: String, val description: String?) {
/**
* Field arguments as displayed in the schema, no special types
*/
abstract val arguments: List
/**
* The code behind this field returning a value
*/
abstract val dataFetcher: DataFetcher
/**
* The output type as shown in the schema (e.g. no async containers)
*/
abstract val outputType: KType
}
class CustomFieldSpec(
name: String,
description: String?,
override val outputType: KType,
override val arguments: List,
override val dataFetcher: DataFetcher
) : FieldSpec(name, description)
internal class SuspendLambdaFieldSpec(
name: String,
lambda: Function<*>,
arity: Int,
context: SchemaBuilderContext,
receiver: Any? = null,
reflected: KFunction<*> = lambda.reflect()!!
) : FieldSpec(name, context.takeDesc()) {
override val outputType: KType = reflected.returnType.unwrapAsyncType()
override val arguments: MutableList = mutableListOf(StaticArgument(lambda))
init {
reflected.valueParameters.mapTo(arguments) {
it.createArgument(context)
}
context.checkRemainingArgDesc()
}
override val dataFetcher: DataFetcher =
Lambdas.indirectCallSuspend(arity).fetcher(reflected.returnType, arguments, receiver, context)
}
internal class PropertyFieldSpec(
property: KProperty1,
name: String,
receiver: R? = null,
context: SchemaBuilderContext
) : FieldSpec(name, context.takeDesc() ?: property.extractDesc()) {
override val dataFetcher: DataFetcher =
property.getter.fetcher(property.returnType, emptyList(), receiver, context)
override val outputType: KType = property.returnType.unwrapAsyncType()
override val arguments: List = emptyList()
}
internal class FunctionFieldSpec(
func: KFunction,
name: String,
receiver: R?,
context: SchemaBuilderContext
) : FieldSpec(name, context.takeDesc() ?: func.extractDesc()) {
override val outputType: KType = func.returnType.unwrapAsyncType()
override val arguments: MutableList = mutableListOf()
init {
for (it in func.valueParameters) {
arguments += it.createArgument(context)
}
context.checkRemainingArgDesc()
}
override val dataFetcher: DataFetcher = func.fetcher(func.returnType, arguments, receiver, context)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy