diff --git a/graphql-dgs-codegen-client-core/src/main/kotlin/com/netflix/graphql/dgs/client/codegen/Kotlin2Core.kt b/graphql-dgs-codegen-client-core/src/main/kotlin/com/netflix/graphql/dgs/client/codegen/Kotlin2Core.kt new file mode 100644 index 000000000..cee7282c8 --- /dev/null +++ b/graphql-dgs-codegen-client-core/src/main/kotlin/com/netflix/graphql/dgs/client/codegen/Kotlin2Core.kt @@ -0,0 +1,73 @@ +/* + * + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.graphql.dgs.client.codegen + +@DslMarker +annotation class QueryProjectionMarker + +@QueryProjectionMarker +abstract class GraphQLProjection(defaultFields: Set = setOf("__typename")) : GraphQLInput() { + + private val builder = StringBuilder("{ ${defaultFields.joinToString(" ")} ") + + protected fun field(field: String) { + builder.append("$field ") + } + + protected fun project(field: String, projection: T, projectionFields: T.() -> T) { + builder.append("$field ") + projectionFields.invoke(projection) + builder.append(projection.asQuery()) + } + + fun asQuery() = "$builder}" +} + +abstract class GraphQLInput { + + companion object { + + private val inputSerializer = InputValueSerializer() + + protected fun inputToString(value: Any?): String { + // TODO escape newlines in InputValueSerializer + return inputSerializer.serialize(value).replace("\n", "\\n") + } + + val defaults: ThreadLocal> = ThreadLocal.withInitial { mutableSetOf() } + + @JvmStatic + protected fun default(arg: String): T? { + defaults.get().add(arg) + return null + } + } + + private val _defaults = defaults.get() + + init { + defaults.set(mutableSetOf()) + } + + protected fun formatArgs(vararg args: Pair): String { + return args + .filter { (k, _) -> !_defaults.contains(k) } + .joinToString(", ") { (k, v) -> "$k: ${inputToString(v)}" } + } +} diff --git a/graphql-dgs-codegen-core/build.gradle b/graphql-dgs-codegen-core/build.gradle index f4f330e18..797cd63b2 100644 --- a/graphql-dgs-codegen-core/build.gradle +++ b/graphql-dgs-codegen-core/build.gradle @@ -29,6 +29,7 @@ dependencies { implementation(project(":graphql-dgs-codegen-client-core")) implementation 'com.graphql-java:graphql-java' implementation 'com.fasterxml.jackson.core:jackson-annotations' + implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'org.slf4j:slf4j-api' implementation 'com.squareup:javapoet:1.13.+' diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/CodeGen.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/CodeGen.kt index 2d7ed1225..1d80ad820 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/CodeGen.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/CodeGen.kt @@ -20,6 +20,11 @@ package com.netflix.graphql.dgs.codegen import com.netflix.graphql.dgs.codegen.generators.java.* import com.netflix.graphql.dgs.codegen.generators.kotlin.* +import com.netflix.graphql.dgs.codegen.generators.kotlin2.generateKotlin2ClientTypes +import com.netflix.graphql.dgs.codegen.generators.kotlin2.generateKotlin2DataTypes +import com.netflix.graphql.dgs.codegen.generators.kotlin2.generateKotlin2EnumTypes +import com.netflix.graphql.dgs.codegen.generators.kotlin2.generateKotlin2InputTypes +import com.netflix.graphql.dgs.codegen.generators.kotlin2.generateKotlin2Interfaces import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findEnumExtensions import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findInputExtensions import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findInterfaceExtensions @@ -32,6 +37,7 @@ import graphql.language.* import graphql.parser.MultiSourceReader import graphql.parser.Parser import graphql.parser.ParserOptions +import graphql.schema.idl.TypeUtil import java.io.File import java.nio.file.Path import java.nio.file.Paths @@ -73,10 +79,12 @@ class CodeGen(private val config: CodeGenConfig) { } codeGenResult.javaConstants.forEach { it.writeTo(config.outputDir) } codeGenResult.kotlinDataTypes.forEach { it.writeTo(config.outputDir) } + codeGenResult.kotlinInputTypes.forEach { it.writeTo(config.outputDir) } codeGenResult.kotlinInterfaces.forEach { it.writeTo(config.outputDir) } codeGenResult.kotlinEnumTypes.forEach { it.writeTo(config.outputDir) } codeGenResult.kotlinDataFetchers.forEach { it.writeTo(config.examplesOutputDir) } codeGenResult.kotlinConstants.forEach { it.writeTo(config.outputDir) } + codeGenResult.kotlinClientTypes.forEach { it.writeTo(config.outputDir) } } return codeGenResult @@ -105,9 +113,50 @@ class CodeGen(private val config: CodeGenConfig) { readerBuilder.string(schema, null) } - return readerBuilder.build().use { reader -> + val document = readerBuilder.build().use { reader -> parser.parseDocument(reader, options) } + + return document.transform { + + // for kotlin2, add implicit types like PageInfo to the schema so classes are generated + if (config.generateKotlinNullableClasses || config.generateKotlinClosureProjections) { + val objectTypeDefs = document.getDefinitionsOfType(ObjectTypeDefinition::class.java) + if (!objectTypeDefs.any { def -> def.name == "PageInfo" } && + objectTypeDefs.any { def -> def.fieldDefinitions.any { field -> TypeUtil.unwrapAll(field.type).name == "PageInfo" } } + ) { + it.definition( + ObjectTypeDefinition.newObjectTypeDefinition() + .name("PageInfo") + .fieldDefinition( + FieldDefinition.newFieldDefinition() + .name("hasNextPage") + .type(NonNullType(TypeName("Boolean"))) + .build() + ) + .fieldDefinition( + FieldDefinition.newFieldDefinition() + .name("hasPreviousPage") + .type(NonNullType(TypeName("Boolean"))) + .build() + ) + .fieldDefinition( + FieldDefinition.newFieldDefinition() + .name("startCursor") + .type(TypeName("String")) + .build() + ) + .fieldDefinition( + FieldDefinition.newFieldDefinition() + .name("endCursor") + .type(TypeName("String")) + .build() + ) + .build() + ) + } + } + } } private fun generateJava(): CodeGenResult { @@ -239,37 +288,72 @@ class CodeGen(private val config: CodeGenConfig) { private fun generateKotlin(): CodeGenResult { val definitions = document.definitions - val datatypesResult = generateKotlinDataTypes(definitions) - val inputTypes = generateKotlinInputTypes(definitions) - val interfacesResult = generateKotlinInterfaceTypes(definitions) + val requiredTypeCollector = RequiredTypeCollector( + document = document, + queries = config.includeQueries, + mutations = config.includeMutations, + subscriptions = config.includeSubscriptions, + ) + val requiredTypes = requiredTypeCollector.requiredTypes - val unionResult = definitions.asSequence() - .filterIsInstance() - .excludeSchemaTypeExtension() - .map { - val extensions = findUnionExtensions(it.name, definitions) - KotlinUnionTypeGenerator(config).generate(it, extensions) - } - .fold(CodeGenResult()) { t: CodeGenResult, u: CodeGenResult -> t.merge(u) } + val dataTypes = if (config.generateKotlinNullableClasses) { - val enumsResult = definitions.asSequence() - .filterIsInstance() - .excludeSchemaTypeExtension() - .filter { config.generateDataTypes || it.name in requiredTypeCollector.requiredTypes } - .map { - val extensions = findEnumExtensions(it.name, definitions) - KotlinEnumTypeGenerator(config).generate(it, extensions) - } - .fold(CodeGenResult()) { t: CodeGenResult, u: CodeGenResult -> t.merge(u) } + CodeGenResult( + kotlinDataTypes = generateKotlin2DataTypes(config, document, requiredTypes), + kotlinInputTypes = generateKotlin2InputTypes(config, document, requiredTypes), + kotlinInterfaces = generateKotlin2Interfaces(config, document), + kotlinEnumTypes = generateKotlin2EnumTypes(config, document, requiredTypes), + kotlinConstants = KotlinConstantsGenerator(config, document).generate().kotlinConstants, + ) + } else { - val constantsClass = KotlinConstantsGenerator(config, document).generate() + val datatypesResult = generateKotlinDataTypes(definitions) + val inputTypes = generateKotlinInputTypes(definitions) + val interfacesResult = generateKotlinInterfaceTypes(definitions) - val client = generateJavaClientApi(definitions) - val entitiesClient = generateJavaClientEntitiesApi(definitions) - val entitiesRepresentationsTypes = generateKotlinClientEntitiesRepresentations(definitions) + val unionResult = definitions.asSequence() + .filterIsInstance() + .excludeSchemaTypeExtension() + .map { + val extensions = findUnionExtensions(it.name, definitions) + KotlinUnionTypeGenerator(config).generate(it, extensions) + } + .fold(CodeGenResult()) { t: CodeGenResult, u: CodeGenResult -> t.merge(u) } + + val enumsResult = definitions.asSequence() + .filterIsInstance() + .excludeSchemaTypeExtension() + .filter { config.generateDataTypes || it.name in requiredTypeCollector.requiredTypes } + .map { + val extensions = findEnumExtensions(it.name, definitions) + KotlinEnumTypeGenerator(config).generate(it, extensions) + } + .fold(CodeGenResult()) { t: CodeGenResult, u: CodeGenResult -> t.merge(u) } + + val constantsClass = KotlinConstantsGenerator(config, document).generate() + + datatypesResult + .merge(inputTypes) + .merge(interfacesResult) + .merge(unionResult) + .merge(enumsResult) + .merge(constantsClass) + } - return datatypesResult.merge(inputTypes).merge(interfacesResult).merge(unionResult).merge(enumsResult) - .merge(client).merge(entitiesClient).merge(entitiesRepresentationsTypes).merge(constantsClass) + val clientTypes = if (config.generateKotlinClosureProjections) { + CodeGenResult( + kotlinClientTypes = generateKotlin2ClientTypes(config, document), + ) + } else { + + val client = generateJavaClientApi(definitions) + val entitiesClient = generateJavaClientEntitiesApi(definitions) + val entitiesRepresentationsTypes = generateKotlinClientEntitiesRepresentations(definitions) + + client.merge(entitiesClient).merge(entitiesRepresentationsTypes) + } + + return dataTypes.merge(clientTypes) } private fun generateKotlinClientEntitiesRepresentations(definitions: Collection>): CodeGenResult { @@ -354,6 +438,8 @@ data class CodeGenConfig( val generateBoxedTypes: Boolean = false, val generateClientApi: Boolean = false, val generateInterfaces: Boolean = false, + val generateKotlinNullableClasses: Boolean = false, + val generateKotlinClosureProjections: Boolean = false, val typeMapping: Map = emptyMap(), val includeQueries: Set = emptySet(), val includeMutations: Set = emptySet(), @@ -398,7 +484,7 @@ data class CodeGenConfig( enum class Language { JAVA, - KOTLIN + KOTLIN, } data class CodeGenResult( @@ -410,10 +496,12 @@ data class CodeGenResult( val clientProjections: List = listOf(), val javaConstants: List = listOf(), val kotlinDataTypes: List = listOf(), + val kotlinInputTypes: List = listOf(), val kotlinInterfaces: List = listOf(), val kotlinEnumTypes: List = listOf(), val kotlinDataFetchers: List = listOf(), - val kotlinConstants: List = emptyList() + val kotlinConstants: List = listOf(), + val kotlinClientTypes: List = listOf(), ) { fun merge(current: CodeGenResult): CodeGenResult { val javaDataTypes = this.javaDataTypes.plus(current.javaDataTypes) @@ -424,10 +512,12 @@ data class CodeGenResult( val clientProjections = this.clientProjections.plus(current.clientProjections) val javaConstants = this.javaConstants.plus(current.javaConstants) val kotlinDataTypes = this.kotlinDataTypes.plus(current.kotlinDataTypes) + val kotlinInputTypes = this.kotlinInputTypes.plus(current.kotlinInputTypes) val kotlinInterfaces = this.kotlinInterfaces.plus(current.kotlinInterfaces) val kotlinEnumTypes = this.kotlinEnumTypes.plus(current.kotlinEnumTypes) val kotlinDataFetchers = this.kotlinDataFetchers.plus(current.kotlinDataFetchers) val kotlinConstants = this.kotlinConstants.plus(current.kotlinConstants) + val kotlinClientTypes = this.kotlinClientTypes.plus(current.kotlinClientTypes) return CodeGenResult( javaDataTypes = javaDataTypes, @@ -438,32 +528,32 @@ data class CodeGenResult( clientProjections = clientProjections, javaConstants = javaConstants, kotlinDataTypes = kotlinDataTypes, + kotlinInputTypes = kotlinInputTypes, kotlinInterfaces = kotlinInterfaces, kotlinEnumTypes = kotlinEnumTypes, kotlinDataFetchers = kotlinDataFetchers, - kotlinConstants = kotlinConstants + kotlinConstants = kotlinConstants, + kotlinClientTypes = kotlinClientTypes, ) } fun javaSources(): List { return javaDataTypes - .asSequence() .plus(javaInterfaces) .plus(javaEnumTypes) .plus(javaDataFetchers) .plus(javaQueryTypes) .plus(clientProjections) .plus(javaConstants) - .toList() } fun kotlinSources(): List { return kotlinDataTypes - .asSequence() + .plus(kotlinInputTypes) .plus(kotlinInterfaces) .plus(kotlinEnumTypes) .plus(kotlinConstants) - .toList() + .plus(kotlinClientTypes) } } @@ -498,21 +588,10 @@ fun List.filterIncludedInConfig(definitionName: String, config: } } -fun ObjectTypeDefinition.shouldSkip(config: CodeGenConfig): Boolean = shouldSkip(this, config) - -fun InputObjectTypeDefinition.shouldSkip(config: CodeGenConfig): Boolean = shouldSkip(this, config) - -fun InterfaceTypeDefinition.shouldSkip(config: CodeGenConfig): Boolean = shouldSkip(this, config) - -fun UnionTypeDefinition.shouldSkip(config: CodeGenConfig): Boolean = shouldSkip(this, config) - -fun EnumTypeDefinition.shouldSkip(config: CodeGenConfig): Boolean = shouldSkip(this, config) - -private fun > shouldSkip( - typeDefinition: DirectivesContainer, +fun > DirectivesContainer.shouldSkip( config: CodeGenConfig ): Boolean { - return typeDefinition.directives.any { it.name == "skipcodegen" } || config.typeMapping.containsKey((typeDefinition as NamedNode<*>).name) + return directives.any { it.name == "skipcodegen" } || config.typeMapping.containsKey((this as NamedNode<*>).name) } fun TypeDefinition<*>.fieldDefinitions(): List { diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/DataTypeGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/DataTypeGenerator.kt index c2176a8c2..5179d94bd 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/DataTypeGenerator.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/DataTypeGenerator.kt @@ -309,7 +309,7 @@ abstract class BaseDataTypeGenerator(internal val packageName: String, config: C private fun addFieldWithGetterAndSetter(returnType: com.squareup.javapoet.TypeName?, fieldDefinition: Field, javaType: TypeSpec.Builder) { val fieldBuilder = if (fieldDefinition.initialValue != null) { - FieldSpec.builder(fieldDefinition.type, fieldDefinition.name).addModifiers(Modifier.PRIVATE).initializer(fieldDefinition.initialValue) + FieldSpec.builder(fieldDefinition.type, ReservedKeywordSanitizer.sanitize(fieldDefinition.name)).addModifiers(Modifier.PRIVATE).initializer(fieldDefinition.initialValue) } else { FieldSpec.builder(returnType, ReservedKeywordSanitizer.sanitize(fieldDefinition.name)).addModifiers(Modifier.PRIVATE) } diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt index 2e996ffce..5e34afeb3 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt @@ -125,7 +125,7 @@ class InterfaceGenerator(private val config: CodeGenConfig, private val document if (config.generateInterfaceSetters) { val setterBuilder = MethodSpec.methodBuilder("set${fieldName.capitalized()}") .addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC) - .addParameter(returnType, fieldName) + .addParameter(returnType, ReservedKeywordSanitizer.sanitize(fieldName)) if (fieldDefinition.description != null) { setterBuilder.addJavadoc(fieldDefinition.description.content.lines().joinToString("\n")) diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin/KotlinPoetUtils.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin/KotlinPoetUtils.kt index 4cb00f343..1654154e3 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin/KotlinPoetUtils.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin/KotlinPoetUtils.kt @@ -18,12 +18,16 @@ package com.netflix.graphql.dgs.codegen.generators.kotlin +import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder import com.squareup.kotlinpoet.* import graphql.introspection.Introspection import graphql.language.Description + /** * Generate a [JsonTypeInfo] annotation, which allows for Jackson * polymorphic type handling when deserializing from JSON. @@ -93,6 +97,33 @@ fun jsonSubTypesAnnotation(subTypes: Collection): AnnotationSpec { .build() } +/** + * Generate a [JsonDeserialize] annotation for the builder class. + * + * Example generated annotation: + * ``` + * @JsonDeserialize(builder = Movie.Builder::class) + * ``` + */ +fun jsonDeserializeAnnotation(builderType: ClassName): AnnotationSpec { + return AnnotationSpec.builder(JsonDeserialize::class) + .addMember("builder = %T::class", builderType) + .build() +} + +/** + * Generate a [JsonPOJOBuilder] annotation for the builder class. + * + * Example generated annotation: + * ``` + * @JsonPOJOBuilder + * ``` + */ +fun jsonBuilderAnnotation(): AnnotationSpec { + return AnnotationSpec.builder(JsonPOJOBuilder::class) + .build() +} + /** * Generate a [JsonProperty] annotation for the supplied * field name. @@ -108,6 +139,21 @@ fun jsonPropertyAnnotation(name: String): AnnotationSpec { .build() } +/** + * Generate a [JsonIgnoreProperties] annotation for the supplied + * property name. + * + * Example generated annotation: + * ``` + * @JsonIgnoreProperties("__typename") + * ``` + */ +fun jsonIgnorePropertiesAnnotation(name: String): AnnotationSpec { + return AnnotationSpec.builder(JsonIgnoreProperties::class) + .addMember("%S", name) + .build() +} + fun Description.sanitizeKdoc(): String { return this.content.lineSequence().joinToString("\n") } @@ -155,3 +201,18 @@ private fun ktTypeClassBestGuess(name: String): ClassName { else -> ClassName.bestGuess(name) } } + +fun FunSpec.Builder.addControlFlow( + controlFlow: String, + vararg args: Any, + builder: FunSpec.Builder.() -> Unit, +): FunSpec.Builder { + this.beginControlFlow(controlFlow, *args) + builder.invoke(this) + this.endControlFlow() + return this +} + +fun TypeSpec.Builder.addEnumConstants(enumSpecs: Iterable): TypeSpec.Builder = apply { + enumSpecs.map { addEnumConstant(it.name!!, it) } +} diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin/KotlinTypeUtils.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin/KotlinTypeUtils.kt index 0e6aaf310..b41f4c107 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin/KotlinTypeUtils.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin/KotlinTypeUtils.kt @@ -79,6 +79,17 @@ class KotlinTypeUtils(private val packageName: String, private val config: CodeG fieldType !is NonNullType } + private val builtinScalars = setOf("ID", "Boolean", "Int", "Long", "Float", "String", "DateTime") + + fun isScalar(type: Type<*>, enums: Set): Boolean { + return when (type) { + is TypeName -> builtinScalars.contains(type.name) || enums.contains(type.name) + is ListType -> isScalar(type.type, enums) + is NonNullType -> isScalar(type.type, enums) + else -> throw UnsupportedOperationException(type::class.qualifiedName) + } + } + private fun TypeName.toKtTypeName(): KtTypeName { if (name in config.typeMapping) { val mappedType = config.typeMapping.getValue(name) diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2ClientTypeGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2ClientTypeGenerator.kt new file mode 100644 index 000000000..7caa41bb9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2ClientTypeGenerator.kt @@ -0,0 +1,295 @@ +/* + * + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.graphql.dgs.codegen.generators.kotlin2 + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import com.netflix.graphql.dgs.codegen.CodeGenConfig +import com.netflix.graphql.dgs.codegen.filterSkipped +import com.netflix.graphql.dgs.codegen.generators.kotlin.KotlinTypeUtils +import com.netflix.graphql.dgs.codegen.generators.kotlin.ReservedKeywordFilter +import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils +import com.netflix.graphql.dgs.codegen.generators.shared.enumFields +import com.netflix.graphql.dgs.codegen.generators.shared.excludeSchemaTypeExtension +import com.netflix.graphql.dgs.codegen.generators.shared.invertedInterfaceLookup +import com.netflix.graphql.dgs.codegen.shouldSkip +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.LambdaTypeName +import com.squareup.kotlinpoet.ParameterSpec +import com.squareup.kotlinpoet.ParameterizedTypeName +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.TypeName +import com.squareup.kotlinpoet.TypeSpec +import graphql.language.DirectivesContainer +import graphql.language.Document +import graphql.language.InputValueDefinition +import graphql.language.InterfaceTypeDefinition +import graphql.language.NamedNode +import graphql.language.ObjectTypeDefinition +import graphql.language.UnionTypeDefinition + +fun generateKotlin2ClientTypes( + config: CodeGenConfig, + document: Document, +): List { + + if (!config.generateClientApi) { + return emptyList() + } + + val typeUtils = KotlinTypeUtils(config.packageNameClient, config, document) + val inputTypeUtils = KotlinTypeUtils(config.packageNameTypes, config, document) + + // get a map of all enums in the document + val enumFields = document.enumFields() + + // invert the interface mapping to create a lookup from interfaces to implementors + val interfaceLookup = document.invertedInterfaceLookup() + + // create a projection class for every interface & data type + val dataProjections = document.getDefinitionsOfType(ObjectTypeDefinition::class.java) + .plus(document.getDefinitionsOfType(InterfaceTypeDefinition::class.java)) + .excludeSchemaTypeExtension() + .filter { !(it as DirectivesContainer<*>).shouldSkip(config) } + .map { typeDefinition -> + + // get any fields defined via schema extensions + val extensionTypes = SchemaExtensionsUtils.findTypeExtensions(typeDefinition.name, document.definitions) + + // the name of the type is used in every parameter & return value + val typeName = ClassName(config.packageNameClient, "${typeDefinition.name}Projection") + + // get all fields defined on the type itself or any extension types + val fields = listOf(typeDefinition) + .plus(extensionTypes) + .flatMap { it.fieldDefinitions } + .filterSkipped() + .filter(ReservedKeywordFilter.filterInvalidNames) + .map { field -> + + val isScalar = typeUtils.isScalar(field.type, enumFields.keys) + val hasArgs = field.inputValueDefinitions.isNotEmpty() + + when { + + // scalars without args are just parameters that note the field is requested + isScalar && !hasArgs -> { + PropertySpec.builder( + name = field.name, + type = typeName, + ) + .getter( + FunSpec.getterBuilder() + .addStatement("field(%S)", field.name) + .addStatement("return this") + .build() + ) + .build() + } + + // scalars with args are functions to take the args with no projection + isScalar && hasArgs -> { + FunSpec.builder(field.name) + .addInputArgs(inputTypeUtils, field.inputValueDefinitions) + .returns(typeName) + .addStatement("""field("${field.name}(${'$'}args)")""") + .addStatement("return this") + .build() + } + + // types without args just have a projection + !isScalar && !hasArgs -> { + + val projectTypeName = projectionTypeName(typeUtils.findReturnType(field.type)) + val (projectionType, projection) = projectionType(config.packageNameClient, projectTypeName) + + FunSpec.builder(field.name) + .addParameter(projection) + .returns(typeName) + .addStatement("project(%S, %T(), _projection)", field.name, projectionType) + .addStatement("return this") + .build() + } + + // function that has args and a projection + // !isScalar && hasArgs + else -> { + + val projectTypeName = projectionTypeName(typeUtils.findReturnType(field.type)) + val (projectionType, projection) = projectionType(config.packageNameClient, projectTypeName) + + FunSpec.builder(field.name) + .addInputArgs(inputTypeUtils, field.inputValueDefinitions) + .addParameter(projection) + .returns(typeName) + .addStatement( + """project("${field.name}(${'$'}args)", %T(), _projection)""", + projectionType + ) + .addStatement("return this") + .build() + } + } + } + + // add the `... on XXX` projection for implementors of this interface + val implementors = interfaceLookup[typeDefinition.name] + ?.map { subclassName -> onSubclassProjection(config.packageNameClient, typeName, subclassName) } + ?: emptyList() + + // create the projection class + val typeSpec = TypeSpec.classBuilder(typeName) + .superclass(GraphQLProjection::class) + // we can't ask for `__typename` on a `Subscription` object + .apply { + if (typeDefinition.name == "Subscription") { + addSuperclassConstructorParameter("defaultFields = emptySet()") + } + } + .addProperties(fields.filterIsInstance()) + .addFunctions(fields.filterIsInstance()) + .addFunctions(implementors) + .build() + + // return a file per type + FileSpec.get(config.packageNameClient, typeSpec) + } + + // create a projection for each union + val unionProjections = document.getDefinitionsOfType(UnionTypeDefinition::class.java) + .excludeSchemaTypeExtension() + .filter { !it.shouldSkip(config) } + .map { unionDefinition -> + + // the name of the type is used in every parameter & return value + val typeName = ClassName(config.packageNameClient, "${unionDefinition.name}Projection") + + // get any members defined via schema extensions + val extensionTypes = SchemaExtensionsUtils.findUnionExtensions(unionDefinition.name, document.definitions) + + val implementations = unionDefinition.memberTypes + .plus(extensionTypes.flatMap { it.memberTypes }) + + val typeSpec = TypeSpec.classBuilder(typeName) + .superclass(GraphQLProjection::class) + .addFunctions( + implementations.map { subclass -> + onSubclassProjection(config.packageNameClient, typeName, (subclass as NamedNode<*>).name) + } + ) + .build() + + // return a file per type + FileSpec.get(config.packageNameClient, typeSpec) + } + + // create a top-level client class + val topLevelTypes = setOf("Query", "Mutation", "Subscription") + .intersect(document.getDefinitionsOfType(ObjectTypeDefinition::class.java).map { it.name }) + + val clientSpec = TypeSpec.objectBuilder("DgsClient") + .addFunctions( + topLevelTypes.map { type -> + + val (projectionType, projection) = projectionType(config.packageNameClient, type) + + FunSpec.builder("build$type") + .addParameter(projection) + .returns(String::class) + .addStatement("val projection = %T()", projectionType) + .addStatement("_projection.invoke(projection)") + .addStatement("""return "${type.lowercase()} ${'$'}{projection.asQuery()}"""") + .build() + } + ) + .build() + + val clientFile = FileSpec.get(config.packageName, clientSpec) + + return dataProjections.plus(unionProjections).plus(clientFile) +} + +// unpack the type to get the underlying type of the projection +private fun projectionTypeName(type: TypeName): String { + return when (type) { + is ClassName -> type.simpleName + is ParameterizedTypeName -> projectionTypeName(type.typeArguments.first()) + else -> throw UnsupportedOperationException(type::class.simpleName) + } +} + +// create the `_projection = FooProjection.() -> FooProjection` parameter +private fun projectionType(packageName: String, type: String): Pair { + + val projectionType = ClassName( + packageName = packageName, + simpleNames = listOf("${type}Projection"), + ) + + val parameter = ParameterSpec( + name = "_projection", + type = LambdaTypeName.get( + receiver = projectionType, + returnType = projectionType, + ) + ) + + return projectionType to parameter +} + +private fun FunSpec.Builder.addInputArgs( + typeUtils: KotlinTypeUtils, + inputValueDefinitions: List, +): FunSpec.Builder { + + return this + .addParameters( + inputValueDefinitions.map { + val returnType = typeUtils.findReturnType(it.type) + ParameterSpec.builder(it.name, returnType) + .apply { + if (returnType.isNullable) { + defaultValue("default(%S)", it.name) + } + } + .build() + } + ) + .addStatement( + "val args = formatArgs(%L)", + inputValueDefinitions.joinToString(", ") { """"${it.name}" to ${it.name}""" } + ) +} + +private fun onSubclassProjection( + packageName: String, + typeName: ClassName, + subclassName: String +): FunSpec { + + val (projectionType, projection) = projectionType(packageName, subclassName) + + return FunSpec.builder("on$subclassName") + .addParameter(projection) + .returns(typeName) + .addStatement("""project("... on $subclassName", %T(), _projection)""", projectionType) + .addStatement("return this") + .build() +} diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2DataTypeGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2DataTypeGenerator.kt new file mode 100644 index 000000000..c8ffeecf4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2DataTypeGenerator.kt @@ -0,0 +1,247 @@ +/* + * + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.graphql.dgs.codegen.generators.kotlin2 + +import com.netflix.graphql.dgs.codegen.CodeGenConfig +import com.netflix.graphql.dgs.codegen.filterSkipped +import com.netflix.graphql.dgs.codegen.generators.kotlin.KotlinTypeUtils +import com.netflix.graphql.dgs.codegen.generators.kotlin.ReservedKeywordFilter +import com.netflix.graphql.dgs.codegen.generators.kotlin.addControlFlow +import com.netflix.graphql.dgs.codegen.generators.kotlin.disableJsonTypeInfoAnnotation +import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonBuilderAnnotation +import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonDeserializeAnnotation +import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonIgnorePropertiesAnnotation +import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonPropertyAnnotation +import com.netflix.graphql.dgs.codegen.generators.kotlin.sanitizeKdoc +import com.netflix.graphql.dgs.codegen.generators.shared.CodeGeneratorUtils.capitalized +import com.netflix.graphql.dgs.codegen.generators.shared.Field +import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findTypeExtensions +import com.netflix.graphql.dgs.codegen.generators.shared.excludeSchemaTypeExtension +import com.netflix.graphql.dgs.codegen.generators.shared.implementedInterfaces +import com.netflix.graphql.dgs.codegen.generators.shared.interfaceFields +import com.netflix.graphql.dgs.codegen.generators.shared.invertedUnionLookup +import com.netflix.graphql.dgs.codegen.generators.shared.overrideFields +import com.netflix.graphql.dgs.codegen.shouldSkip +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.LambdaTypeName +import com.squareup.kotlinpoet.ParameterSpec +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.TypeSpec +import com.squareup.kotlinpoet.buildCodeBlock +import graphql.language.Document +import graphql.language.ObjectTypeDefinition +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +internal val logger: Logger = LoggerFactory.getLogger("com.netflix.graphql.dgs.codegen.generators.kotlin2") + +fun generateKotlin2DataTypes( + config: CodeGenConfig, + document: Document, + requiredTypes: Set, +): List { + + val typeUtils = KotlinTypeUtils(config.packageNameTypes, config, document) + + // get a map of all interfaces > fields + val interfaceFields = document.interfaceFields() + + // invert the union mapping to create a lookup from members to union + val unionTypes = document.invertedUnionLookup() + + return document + .getDefinitionsOfType(ObjectTypeDefinition::class.java) + .excludeSchemaTypeExtension() + .filter { config.generateDataTypes || it.name in requiredTypes } + .filter { !it.shouldSkip(config) } + .map { typeDefinition -> + + logger.info("Generating data type ${typeDefinition.name}") + + // get all interfaces this type implements + val implementedInterfaces = typeDefinition.implementedInterfaces() + val implementedUnionTypes = unionTypes[typeDefinition.name] ?: emptyList() + val superInterfaces = implementedInterfaces + implementedUnionTypes + + // get any fields defined via schema extensions + val extensionTypes = findTypeExtensions(typeDefinition.name, document.definitions) + + // get all fields defined on the type itself or any extension types + val fields = listOf(typeDefinition) + .plus(extensionTypes) + .flatMap { it.fieldDefinitions } + .filterSkipped() + .filter(ReservedKeywordFilter.filterInvalidNames) + .map { + Field( + name = it.name, + type = typeUtils.findReturnType(it.type), + description = it.description, + ) + } + + // get a list of fields to override + val overrideFields = overrideFields(interfaceFields, implementedInterfaces) + + // create a companion object to store defaults for each field + val companionObject = TypeSpec.companionObjectBuilder() + // add a default lambda for each field that throws if accessed + .addProperties( + fields.map { field -> + PropertySpec.builder( + name = "${field.name}Default", + type = LambdaTypeName.get(returnType = field.type), + ) + .addModifiers(KModifier.PRIVATE) + .initializer( + buildCodeBlock { + addStatement( + "\n{ throw %T(%S) }", + IllegalStateException::class, + "Field `${field.name}` was not requested" + ) + } + ) + .build() + } + ) + .build() + + // create a builder for this class; default to lambda that throws if accessed + val builderClassName = ClassName(config.packageNameTypes, typeDefinition.name, "Builder") + val builder = TypeSpec.classBuilder("Builder") + .addAnnotation(jsonBuilderAnnotation()) + .addAnnotation(jsonIgnorePropertiesAnnotation("__typename")) + // add a backing property for each field + .addProperties( + fields.map { field -> + PropertySpec.builder( + name = field.name, + type = LambdaTypeName.get(returnType = field.type), + ) + .addModifiers(KModifier.PRIVATE) + .mutable() + .initializer("${field.name}Default") + .build() + } + ) + // add a method to set the field + .addFunctions( + fields.map { field -> + FunSpec.builder("with${field.name.capitalized()}") + .addAnnotation(jsonPropertyAnnotation(field.name)) + .addParameter(field.name, field.type) + .addControlFlow("return this.apply") { + addStatement("this.${field.name} = { ${field.name} }") + } + .returns(builderClassName) + .build() + } + ) + // add a build method to return the constructed class + .addFunction( + FunSpec.builder("build") + .addStatement("return ${typeDefinition.name}(\n${fields.joinToString("\n") { " ${it.name} = ${it.name}," }}\n)") + .build() + ) + .build() + + // create the data class + val typeSpec = TypeSpec.classBuilder(typeDefinition.name) + // add docs if available + .apply { + if (typeDefinition.description != null) { + addKdoc("%L", typeDefinition.description.sanitizeKdoc()) + } + } + // add jackson annotations + .addAnnotation(disableJsonTypeInfoAnnotation()) + .addAnnotation( + jsonDeserializeAnnotation( + builderClassName + ) + ) + // add nested classes + .addType(companionObject) + .addType(builder) + // add interfaces to implement + .addSuperinterfaces( + superInterfaces.map { ClassName.bestGuess("${config.packageNameTypes}.$it") } + ) + // add a constructor with a supplier for every field + .primaryConstructor( + FunSpec.constructorBuilder() + .addParameters( + fields.map { field -> + ParameterSpec.builder( + name = field.name, + type = LambdaTypeName.get(returnType = field.type), + ) + .defaultValue("${field.name}Default") + .build() + } + ) + .build() + ) + // add a backing property for each field + .addProperties( + fields.map { field -> + PropertySpec.builder( + name = "_${field.name}", + type = LambdaTypeName.get(returnType = field.type), + ) + .addModifiers(KModifier.PRIVATE) + .initializer(field.name) + .build() + } + ) + // add a getter for each field + .addProperties( + fields.map { field -> + PropertySpec.builder( + name = field.name, + type = field.type, + ) + .apply { + if (field.description != null) { + addKdoc("%L", field.description.sanitizeKdoc()) + } + } + .apply { + if (field.name in overrideFields) { + addModifiers(KModifier.OVERRIDE) + } + } + .getter( + FunSpec.getterBuilder() + .addStatement("return _${field.name}.invoke()") + .build() + ) + .build() + } + ) + .build() + + // return a file per type + FileSpec.get(config.packageNameTypes, typeSpec) + } +} diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2EnumTypeGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2EnumTypeGenerator.kt new file mode 100644 index 000000000..9ede58a75 --- /dev/null +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2EnumTypeGenerator.kt @@ -0,0 +1,82 @@ +/* + * + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.graphql.dgs.codegen.generators.kotlin2 + +import com.netflix.graphql.dgs.codegen.CodeGenConfig +import com.netflix.graphql.dgs.codegen.generators.kotlin.addEnumConstants +import com.netflix.graphql.dgs.codegen.generators.kotlin.sanitizeKdoc +import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findEnumExtensions +import com.netflix.graphql.dgs.codegen.generators.shared.excludeSchemaTypeExtension +import com.netflix.graphql.dgs.codegen.shouldSkip +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.TypeSpec +import graphql.language.Document +import graphql.language.EnumTypeDefinition + +fun generateKotlin2EnumTypes( + config: CodeGenConfig, + document: Document, + requiredTypes: Set, +): List { + + return document + .getDefinitionsOfType(EnumTypeDefinition::class.java) + .excludeSchemaTypeExtension() + .filter { config.generateDataTypes || it.name in requiredTypes } + .filter { !it.shouldSkip(config) } + .map { enumDefinition -> + + logger.info("Generating enum type ${enumDefinition.name}") + + // get any fields defined via schema extensions + val extensionTypes = findEnumExtensions(enumDefinition.name, document.definitions) + + // get all fields defined on the type itself or any extension types + val fields = listOf(enumDefinition) + .plus(extensionTypes) + .flatMap { it.enumValueDefinitions } + + // create the enum class + val enumSpec = TypeSpec.classBuilder(enumDefinition.name) + .addModifiers(KModifier.ENUM) + // add docs if available + .apply { + if (enumDefinition.description != null) { + addKdoc("%L", enumDefinition.description.sanitizeKdoc()) + } + } + // add all fields + .addEnumConstants( + fields.map { field -> + TypeSpec.enumBuilder(field.name) + .apply { + if (field.description != null) { + addKdoc("%L", field.description.sanitizeKdoc()) + } + } + .build() + } + ) + .build() + + // return a file per enum + FileSpec.get(config.packageNameTypes, enumSpec) + } +} diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2InputTypeGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2InputTypeGenerator.kt new file mode 100644 index 000000000..ad44a1ff5 --- /dev/null +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2InputTypeGenerator.kt @@ -0,0 +1,115 @@ +/* + * + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.graphql.dgs.codegen.generators.kotlin2 + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import com.netflix.graphql.dgs.codegen.CodeGenConfig +import com.netflix.graphql.dgs.codegen.generators.kotlin.KotlinTypeUtils +import com.netflix.graphql.dgs.codegen.generators.kotlin.ReservedKeywordFilter +import com.netflix.graphql.dgs.codegen.generators.kotlin.sanitizeKdoc +import com.netflix.graphql.dgs.codegen.generators.shared.Field +import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findInputExtensions +import com.netflix.graphql.dgs.codegen.generators.shared.excludeSchemaTypeExtension +import com.netflix.graphql.dgs.codegen.shouldSkip +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.ParameterSpec +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.TypeSpec +import graphql.language.Document +import graphql.language.InputObjectTypeDefinition + +fun generateKotlin2InputTypes( + config: CodeGenConfig, + document: Document, + requiredTypes: Set, +): List { + + val typeUtils = KotlinTypeUtils(config.packageNameTypes, config, document) + + return document + .getDefinitionsOfType(InputObjectTypeDefinition::class.java) + .excludeSchemaTypeExtension() + .filter { config.generateDataTypes || it.name in requiredTypes } + .filter { !it.shouldSkip(config) } + .map { inputDefinition -> + + logger.info("Generating input type ${inputDefinition.name}") + + // get any fields defined via schema extensions + val extensionTypes = findInputExtensions(inputDefinition.name, document.definitions) + + // get all fields defined on the type itself or any extension types + val fields = listOf(inputDefinition) + .plus(extensionTypes) + .flatMap { it.inputValueDefinitions } + .filter(ReservedKeywordFilter.filterInvalidNames) + .map { + Field( + name = it.name, + type = typeUtils.findReturnType(it.type), + description = it.description, + ) + } + + // create the input class + val typeSpec = TypeSpec.classBuilder(inputDefinition.name) + // add docs if available + .apply { + if (inputDefinition.description != null) { + addKdoc("%L", inputDefinition.description.sanitizeKdoc()) + } + } + .superclass(GraphQLInput::class) + // add a constructor with a parameter for every field + .primaryConstructor( + FunSpec.constructorBuilder() + .addParameters( + fields.map { field -> + ParameterSpec.builder( + name = field.name, + type = field.type, + ) + .apply { + if (field.type.isNullable) { + defaultValue("default(%S)", field.name) + } + } + .build() + } + ) + .build() + ) + // add a backing property for each field + .addProperties( + fields.map { field -> + PropertySpec.builder( + name = field.name, + type = field.type, + ) + .initializer(field.name) + .build() + } + ) + .build() + + // return a file per type + FileSpec.get(config.packageNameTypes, typeSpec) + } +} diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2InterfaceTypeGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2InterfaceTypeGenerator.kt new file mode 100644 index 000000000..a8bbc2bc6 --- /dev/null +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/Kotlin2InterfaceTypeGenerator.kt @@ -0,0 +1,174 @@ +/* + * + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.graphql.dgs.codegen.generators.kotlin2 + +import com.netflix.graphql.dgs.codegen.CodeGenConfig +import com.netflix.graphql.dgs.codegen.filterSkipped +import com.netflix.graphql.dgs.codegen.generators.kotlin.KotlinTypeUtils +import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonSubTypesAnnotation +import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonTypeInfoAnnotation +import com.netflix.graphql.dgs.codegen.generators.kotlin.sanitizeKdoc +import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findInterfaceExtensions +import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findUnionExtensions +import com.netflix.graphql.dgs.codegen.generators.shared.excludeSchemaTypeExtension +import com.netflix.graphql.dgs.codegen.generators.shared.implementedInterfaces +import com.netflix.graphql.dgs.codegen.generators.shared.interfaceFields +import com.netflix.graphql.dgs.codegen.generators.shared.overrideFields +import com.netflix.graphql.dgs.codegen.shouldSkip +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.TypeSpec +import graphql.language.Document +import graphql.language.InterfaceTypeDefinition +import graphql.language.NamedNode +import graphql.language.ObjectTypeDefinition +import graphql.language.TypeName +import graphql.language.UnionTypeDefinition + +fun generateKotlin2Interfaces( + config: CodeGenConfig, + document: Document, +): List { + + if (!config.generateDataTypes) { + return emptyList() + } + + val typeUtils = KotlinTypeUtils(config.packageNameTypes, config, document) + + // get a map of all interfaces > fields + val interfaceFields = document.interfaceFields() + + val interfaceClasses = document + .getDefinitionsOfType(InterfaceTypeDefinition::class.java) + .excludeSchemaTypeExtension() + .filter { !it.shouldSkip(config) } + .map { interfaceDefinition -> + + logger.info("Generating interface type ${interfaceDefinition.name}") + + // get all types that implement this interface + val implementations = document + .getDefinitionsOfType(ObjectTypeDefinition::class.java) + .filter { node -> node.implements.any { it.isEqualTo(TypeName(interfaceDefinition.name)) } } + .map { node -> ClassName(config.packageNameTypes, node.name) } + + // get all interfaces that this interface implements + val implementedInterfaces = interfaceDefinition.implementedInterfaces() + + // get any fields defined via schema extensions + val extensionTypes = findInterfaceExtensions(interfaceDefinition.name, document.definitions) + + // get all fields defined on the type itself or any extension types + val fields = listOf(interfaceDefinition) + .plus(extensionTypes) + .flatMap { it.fieldDefinitions } + .filterSkipped() + + // get a list of fields to override + val overrideFields = overrideFields(interfaceFields, implementedInterfaces) + + // create the interface + val interfaceSpec = TypeSpec.interfaceBuilder(interfaceDefinition.name) + .addModifiers(KModifier.SEALED) + // add docs if available + .apply { + if (interfaceDefinition.description != null) { + addKdoc("%L", interfaceDefinition.description.sanitizeKdoc()) + } + } + // add jackson annotations + .addAnnotation(jsonTypeInfoAnnotation()) + .apply { + if (implementations.isNotEmpty()) { + addAnnotation(jsonSubTypesAnnotation(implementations)) + } + } + // add interfaces to implement + .addSuperinterfaces( + implementedInterfaces.map { ClassName(config.packageNameTypes, it) } + ) + // add fields, overriding if needed + .addProperties( + fields.map { field -> + PropertySpec.builder( + name = field.name, + type = typeUtils.findReturnType(field.type) + ) + .apply { + if (field.description != null) { + addKdoc("%L", field.description.sanitizeKdoc()) + } + } + .apply { + if (field.name in overrideFields) { + addModifiers(KModifier.OVERRIDE) + } + } + .build() + } + ) + .build() + + // return a file per interface + FileSpec.get(config.packageNameTypes, interfaceSpec) + } + + val unionClasses = document.getDefinitionsOfType(UnionTypeDefinition::class.java) + .excludeSchemaTypeExtension() + .filter { !it.shouldSkip(config) } + .map { unionDefinition -> + + logger.info("Generating union type ${unionDefinition.name}") + + // get any members defined via schema extensions + val extensionTypes = findUnionExtensions(unionDefinition.name, document.definitions) + + // get all types that implement this union + val implementations = unionDefinition.memberTypes + .plus(extensionTypes.flatMap { it.memberTypes }) + .filterIsInstance>() + .map { node -> ClassName(config.packageNameTypes, node.name) } + + // create the interface + val interfaceSpec = TypeSpec.interfaceBuilder(unionDefinition.name) + .addModifiers(KModifier.SEALED) + // add docs if available + .apply { + if (unionDefinition.description != null) { + addKdoc("%L", unionDefinition.description.sanitizeKdoc()) + } + } + // add jackson annotations + .addAnnotation(jsonTypeInfoAnnotation()) + .apply { + if (implementations.isNotEmpty()) { + addAnnotation(jsonSubTypesAnnotation(implementations)) + } + } + .build() + + // return a file per interface + FileSpec.get(config.packageNameTypes, interfaceSpec) + } + + return interfaceClasses.plus(unionClasses) +} diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/shared/DocumentUtils.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/shared/DocumentUtils.kt new file mode 100644 index 000000000..8d569ba23 --- /dev/null +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/shared/DocumentUtils.kt @@ -0,0 +1,86 @@ +/* + * + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.graphql.dgs.codegen.generators.shared + +import com.squareup.kotlinpoet.TypeName +import graphql.language.Description +import graphql.language.Document +import graphql.language.EnumTypeDefinition +import graphql.language.ImplementingTypeDefinition +import graphql.language.InterfaceTypeDefinition +import graphql.language.NamedNode +import graphql.language.ObjectTypeDefinition +import graphql.language.UnionTypeDefinition + +internal data class Field( + val name: String, + val type: TypeName, + val description: Description?, +) + +/** + * Returns a map of interface name to list of field names for all interfaces in the document + */ +internal fun Document.interfaceFields(): Map> { + return getDefinitionsOfType(InterfaceTypeDefinition::class.java) + .associate { i -> i.name to i.fieldDefinitions.map { it.name } } +} + +/** + * Returns a map of enum name to list of field names for all enums in the document + */ +internal fun Document.enumFields(): Map> { + return getDefinitionsOfType(EnumTypeDefinition::class.java) + .associate { i -> i.name to i.enumValueDefinitions.map { it.name } } +} + +/** + * Returns the list of interfaces that this type implements + */ +internal fun ImplementingTypeDefinition<*>.implementedInterfaces(): List { + return implements + .filterIsInstance>() + .map { it.name } +} + +/** + * Returns the set of fields that should be overridden + */ +internal fun overrideFields( + interfaceFields: Map>, + implementedInterfaces: List, +): Set { + return implementedInterfaces + .mapNotNull { interfaceFields[it] } + .flatten() + .toSet() +} + +internal fun Document.invertedUnionLookup(): Map> { + return getDefinitionsOfType(UnionTypeDefinition::class.java) + .flatMap { u -> u.memberTypes.filterIsInstance>().map { m -> m.name to u.name } } + .groupBy(keySelector = { it.first }, valueTransform = { it.second }) +} + +internal fun Document.invertedInterfaceLookup(): Map> { + return getDefinitionsOfType(InterfaceTypeDefinition::class.java) + .plus(getDefinitionsOfType(ObjectTypeDefinition::class.java)) + .flatMap { o -> o.implements.filterIsInstance>().map { i -> i.name to o.name } } + .groupBy(keySelector = { it.first }, valueTransform = { it.second }) +} diff --git a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/Kotlin2CodeGenTest.kt b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/Kotlin2CodeGenTest.kt new file mode 100644 index 000000000..c90c0c994 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/Kotlin2CodeGenTest.kt @@ -0,0 +1,128 @@ +/* + * + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.graphql.dgs.codegen + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.fail +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import kotlin.io.path.createDirectories +import kotlin.io.path.exists +import kotlin.io.path.listDirectoryEntries +import kotlin.streams.toList + +class Kotlin2CodeGenTest { + + // set this to true to update all expected outputs instead of running tests + private val updateExpected = false + + companion object { + + private fun getAbsolutePath(suffix: String): Path { + val projectDirAbsolutePath = Paths.get("").toAbsolutePath().toString() + return Paths.get(projectDirAbsolutePath, "/src/test/resources/$suffix") + } + + private fun listAllFiles(suffix: String): List { + val path = getAbsolutePath(suffix) + return Files.walk(path) + .filter { Files.isRegularFile(it) } + .toList() + } + + @Suppress("unused") + @JvmStatic + fun listTestsToRun(): List { + return getAbsolutePath("kotlin2") + .listDirectoryEntries() + .map { it.getName(it.nameCount.dec()).toString() } + .sorted() + } + + private fun readResource(fileName: String): String { + return this::class.java.getResource(fileName) + ?.readText() + ?: throw IllegalArgumentException("Missing file: $fileName") + } + + private fun writeExpected(fileName: String, content: String) { + val path = getAbsolutePath(fileName) + + if (!path.exists()) { + path.parent.createDirectories() + } + + path.toFile().writeText(content) + } + } + + @ParameterizedTest + @MethodSource("listTestsToRun") + fun testCodeGen(testName: String) { + + val schema = readResource("/kotlin2/$testName/schema.graphql") + + val codeGenResult = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + packageName = "kotlin2.$testName.expected", + language = Language.KOTLIN, + generateClientApi = true, + generateKotlinNullableClasses = true, + generateKotlinClosureProjections = true, + ) + ).generate() + + val fileNames = codeGenResult.kotlinSources() + .groupingBy { it.packageName.substringAfterLast('.') to it.name } + .eachCount() + + // fail if any file was defined twice + fileNames + .filterValues { it > 1 } + .keys + .forEach { fail("Duplicate file: ${it.first}.${it.second}") } + + // fail if any file was expected that's not generated + listAllFiles("/kotlin2/$testName/expected") + .map { + it.getName(it.nameCount - 2).toString() to it.getName(it.nameCount - 1).toString().removeSuffix(".kt") + } + .toSet().subtract(fileNames.keys) + .forEach { fail("Missing expected file: ${it.first}.${it.second}") } + + codeGenResult.kotlinSources().forEach { spec -> + + val type = spec.packageName.substringAfterLast("expected").trimStart('.') + val fileName = "/kotlin2/$testName/expected/$type/${spec.name}.kt" + val actual = spec.toString() + + if (updateExpected) { + writeExpected(fileName, actual) + } else { + assertEquals(readResource(fileName), actual) + } + } + + assertCompilesKotlin(codeGenResult) + } +} diff --git a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/KotlinCodeGenTest.kt b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/KotlinCodeGenTest.kt index 0870beceb..ef0d0d0a3 100644 --- a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/KotlinCodeGenTest.kt +++ b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/KotlinCodeGenTest.kt @@ -1392,6 +1392,57 @@ class KotlinCodeGenTest { assertCompilesKotlin(dataTypes) } + @Test + fun `Should be able to generate successfully when java keywords and default value are used as input types`() { + val schema = """ + type Query { + foo(fooInput: FooInput): Baz + bar(barInput: BarInput): Baz + } + + input FooInput { + public: Boolean = true + } + + input BarInput { + public: Boolean + } + + type Baz { + public: Boolean + } + """.trimIndent() + + val codeGenResult = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + packageName = basePackageName, + language = Language.KOTLIN, + generateDataTypes = false, + generateClientApi = true, + includeQueries = setOf("foo", "bar") + ) + ).generate() + + assertThat(codeGenResult.kotlinDataTypes.size).isEqualTo(2) + + val fileSpec0 = codeGenResult.kotlinDataTypes[0] as FileSpec + assertThat(fileSpec0.name).isEqualTo("FooInput") + assertThat(fileSpec0.members.size).isEqualTo(1) + val typeSpec0 = fileSpec0.members[0] as TypeSpec + assertThat(typeSpec0.propertySpecs.size).isEqualTo(1) + assertThat(typeSpec0.propertySpecs[0].name).isEqualTo("public") + + val fileSpec1 = codeGenResult.kotlinDataTypes[1] as FileSpec + assertThat(fileSpec1.name).isEqualTo("BarInput") + assertThat(fileSpec1.members.size).isEqualTo(1) + val typeSpec1 = fileSpec1.members[0] as TypeSpec + assertThat(typeSpec1.propertySpecs.size).isEqualTo(1) + assertThat(typeSpec1.propertySpecs[0].name).isEqualTo("public") + + assertCompilesKotlin(codeGenResult.kotlinDataTypes) + } + @ParameterizedTest(name = "{index} => Snake Case? {0}; expected names {1}") @MethodSource("generateConstantsArguments") fun `Generates constants from Type names available via the DgsConstants class`( @@ -2262,6 +2313,61 @@ It takes a title and such. assertCompilesKotlin(interfaces) } + @Test + fun `can generate code based on GraphQL interfaces, which fields express java key-words`() { + val schema = """ + type Query { + queryRoot: QueryRoot + } + + interface HasDefaultField { + default: String + public: String + private: Boolean + } + + type QueryRoot implements HasDefaultField { + name: String + default: String + public: String + private: Boolean + } + """.trimIndent() + + val codeGenResult = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + packageName = basePackageName, + language = Language.KOTLIN + ) + ).generate() + + assertThat(codeGenResult.kotlinDataTypes.size).isEqualTo(1) + assertThat(codeGenResult.kotlinDataTypes[0].name).isEqualTo("QueryRoot") + assertThat(codeGenResult.kotlinDataTypes[0].members.size).isEqualTo(1) + + val dataTypeSpec = codeGenResult.kotlinDataTypes[0].members[0] as TypeSpec + + assertThat(dataTypeSpec.propertySpecs.size).isEqualTo(4) + assertThat(dataTypeSpec.propertySpecs[0].name).isEqualTo("name") + assertThat(dataTypeSpec.propertySpecs[1].name).isEqualTo("default") + assertThat(dataTypeSpec.propertySpecs[2].name).isEqualTo("public") + assertThat(dataTypeSpec.propertySpecs[3].name).isEqualTo("private") + + val interfaces = codeGenResult.kotlinInterfaces + + assertThat(interfaces.size).isEqualTo(1) + + val interfaceTypeSpec = interfaces[0].members[0] as TypeSpec + + assertThat(interfaceTypeSpec.propertySpecs.size).isEqualTo(3) + assertThat(interfaceTypeSpec.propertySpecs[0].name).isEqualTo("default") + assertThat(interfaceTypeSpec.propertySpecs[1].name).isEqualTo("public") + assertThat(interfaceTypeSpec.propertySpecs[2].name).isEqualTo("private") + + assertCompilesKotlin(codeGenResult) + } + @Test fun generateEnumKDoc() { val schema = """ diff --git a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/TestUtils.kt b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/TestUtils.kt index c42ffccbb..0259c7c5e 100644 --- a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/TestUtils.kt +++ b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/TestUtils.kt @@ -54,6 +54,9 @@ fun assertCompilesJava(javaFiles: Collection): Compilation { return result } +fun assertCompilesKotlin(codeGenResult: CodeGenResult) = + assertCompilesKotlin(codeGenResult.kotlinSources()) + fun assertCompilesKotlin(files: Collection): Path { val srcDir = Files.createTempDirectory("src") val buildDir = Files.createTempDirectory("build") diff --git a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt index 80785ea36..e35788e8e 100644 --- a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt +++ b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt @@ -459,6 +459,52 @@ class ClientApiGenQueryTest { ) } + @Test + fun interfaceWithKeywords() { + val schema = """ + type Query { + queryRoot: QueryRoot + } + + interface HasDefaultField { + default: String + public: String + private: Boolean + } + + type QueryRoot implements HasDefaultField { + name: String + default: String + public: String + private: Boolean + } + """.trimIndent() + + val codeGenResult = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + packageName = basePackageName, + generateClientApi = true, + ) + ).generate() + + assertThat(codeGenResult.javaQueryTypes.size).isEqualTo(1) + assertThat(codeGenResult.javaQueryTypes[0].typeSpec.name).isEqualTo("QueryRootGraphQLQuery") + + assertThat(codeGenResult.javaInterfaces.size).isEqualTo(1) + assertThat(codeGenResult.javaInterfaces[0].typeSpec.name).isEqualTo("HasDefaultField") + + assertThat(codeGenResult.javaDataTypes.size).isEqualTo(1) + assertThat(codeGenResult.javaDataTypes[0].typeSpec.fieldSpecs.size).isEqualTo(4) + assertThat(codeGenResult.javaDataTypes[0].typeSpec.fieldSpecs[0].name).isEqualTo("name") + assertThat(codeGenResult.javaDataTypes[0].typeSpec.fieldSpecs[1].name).isEqualTo("_default") + assertThat(codeGenResult.javaDataTypes[0].typeSpec.fieldSpecs[2].name).isEqualTo("_public") + + assertCompilesJava( + codeGenResult.clientProjections + codeGenResult.javaQueryTypes + codeGenResult.javaEnumTypes + codeGenResult.javaDataTypes + codeGenResult.javaInterfaces + ) + } + @Test fun `The Query API should support sub-projects on fields with Basic Types`() { // given @@ -819,4 +865,47 @@ class ClientApiGenQueryTest { "_while" ) } + + @Test + fun `Should be able to generate successfully when java keywords and default value are used as input types`() { + val schema = """ + type Query { + foo(fooInput: FooInput): Baz + bar(barInput: BarInput): Baz + } + + input FooInput { + public: Boolean = true + } + + input BarInput { + public: Boolean + } + + type Baz { + public: Boolean + } + """.trimIndent() + + val codeGenResult = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + packageName = basePackageName, + generateDataTypes = false, + generateClientApi = true, + includeQueries = setOf("foo", "bar") + ) + ).generate() + + assertThat(codeGenResult.javaDataTypes.size).isEqualTo(2) + + assertThat(codeGenResult.javaDataTypes[0].typeSpec.name).isEqualTo("FooInput") + assertThat(codeGenResult.javaDataTypes[0].typeSpec.fieldSpecs[0].name).isEqualTo("_public") + assertThat(codeGenResult.javaDataTypes[0].typeSpec.fieldSpecs[0].initializer.toString()).isEqualTo("true") + + assertThat(codeGenResult.javaDataTypes[1].typeSpec.name).isEqualTo("BarInput") + assertThat(codeGenResult.javaDataTypes[1].typeSpec.fieldSpecs[0].initializer.toString()).isEqualTo("") + + assertCompilesJava(codeGenResult.javaDataTypes) + } } diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/DgsClient.kt new file mode 100644 index 000000000..e6e543524 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.constantsForInputTypes.expected + +import kotlin.String +import kotlin2.constantsForInputTypes.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/DgsConstants.kt new file mode 100644 index 000000000..b67a506ed --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/DgsConstants.kt @@ -0,0 +1,27 @@ +package kotlin2.constantsForInputTypes.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + } + + public object PERSONFILTER { + public const val TYPE_NAME: String = "PersonFilter" + + public const val Email: String = "email" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/client/PersonProjection.kt new file mode 100644 index 000000000..6b3e42d63 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.constantsForInputTypes.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/client/QueryProjection.kt new file mode 100644 index 000000000..831b0ab71 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/client/QueryProjection.kt @@ -0,0 +1,13 @@ +package kotlin2.constantsForInputTypes.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin2.constantsForInputTypes.expected.types.PersonFilter + +public class QueryProjection : GraphQLProjection() { + public fun people(filter: PersonFilter? = default("filter"), + _projection: PersonProjection.() -> PersonProjection): QueryProjection { + val args = formatArgs("filter" to filter) + project("people($args)", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/Person.kt new file mode 100644 index 000000000..301b438a9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/Person.kt @@ -0,0 +1,59 @@ +package kotlin2.constantsForInputTypes.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + firstname: () -> String? = firstnameDefault, + lastname: () -> String? = lastnameDefault +) { + private val _firstname: () -> String? = firstname + + private val _lastname: () -> String? = lastname + + public val firstname: String? + get() = _firstname.invoke() + + public val lastname: String? + get() = _lastname.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + public fun build() = Person( + firstname = firstname, + lastname = lastname, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/PersonFilter.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/PersonFilter.kt new file mode 100644 index 000000000..96ebac999 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/PersonFilter.kt @@ -0,0 +1,8 @@ +package kotlin2.constantsForInputTypes.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.String + +public class PersonFilter( + public val email: String? = default("email") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/Query.kt new file mode 100644 index 000000000..cb8cdbda5 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.constantsForInputTypes.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/schema.graphql new file mode 100644 index 000000000..d1c4b5459 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsForInputTypes/schema.graphql @@ -0,0 +1,12 @@ +type Query { + people(filter: PersonFilter): [Person] +} + +type Person { + firstname: String + lastname: String +} + +input PersonFilter { + email: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/DgsClient.kt new file mode 100644 index 000000000..50ec566ae --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.constantsWithExtendedInputTypes.expected + +import kotlin.String +import kotlin2.constantsWithExtendedInputTypes.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/DgsConstants.kt new file mode 100644 index 000000000..e62c1b2b1 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/DgsConstants.kt @@ -0,0 +1,29 @@ +package kotlin2.constantsWithExtendedInputTypes.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + } + + public object PERSONFILTER { + public const val TYPE_NAME: String = "PersonFilter" + + public const val Email: String = "email" + + public const val BirthYear: String = "birthYear" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/client/PersonProjection.kt new file mode 100644 index 000000000..1a28da606 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.constantsWithExtendedInputTypes.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/client/QueryProjection.kt new file mode 100644 index 000000000..822387752 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/client/QueryProjection.kt @@ -0,0 +1,13 @@ +package kotlin2.constantsWithExtendedInputTypes.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin2.constantsWithExtendedInputTypes.expected.types.PersonFilter + +public class QueryProjection : GraphQLProjection() { + public fun people(filter: PersonFilter? = default("filter"), + _projection: PersonProjection.() -> PersonProjection): QueryProjection { + val args = formatArgs("filter" to filter) + project("people($args)", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/Person.kt new file mode 100644 index 000000000..5a7f464a8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/Person.kt @@ -0,0 +1,59 @@ +package kotlin2.constantsWithExtendedInputTypes.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + firstname: () -> String? = firstnameDefault, + lastname: () -> String? = lastnameDefault +) { + private val _firstname: () -> String? = firstname + + private val _lastname: () -> String? = lastname + + public val firstname: String? + get() = _firstname.invoke() + + public val lastname: String? + get() = _lastname.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + public fun build() = Person( + firstname = firstname, + lastname = lastname, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/PersonFilter.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/PersonFilter.kt new file mode 100644 index 000000000..75e5df356 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/PersonFilter.kt @@ -0,0 +1,10 @@ +package kotlin2.constantsWithExtendedInputTypes.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.Int +import kotlin.String + +public class PersonFilter( + public val email: String? = default("email"), + public val birthYear: Int? = default("birthYear") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/Query.kt new file mode 100644 index 000000000..501c86256 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.constantsWithExtendedInputTypes.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/schema.graphql new file mode 100644 index 000000000..2cfb6286a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInputTypes/schema.graphql @@ -0,0 +1,16 @@ +type Query { + people(filter: PersonFilter): [Person] +} + +type Person { + firstname: String + lastname: String +} + +input PersonFilter { + email: String +} + +extend input PersonFilter { + birthYear: Int +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/DgsClient.kt new file mode 100644 index 000000000..e68599484 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.constantsWithExtendedInterface.expected + +import kotlin.String +import kotlin2.constantsWithExtendedInterface.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/DgsConstants.kt new file mode 100644 index 000000000..c3715ec53 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/DgsConstants.kt @@ -0,0 +1,23 @@ +package kotlin2.constantsWithExtendedInterface.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Age: String = "age" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/client/PersonProjection.kt new file mode 100644 index 000000000..694d9dac9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.constantsWithExtendedInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/client/QueryProjection.kt new file mode 100644 index 000000000..90d57775b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.constantsWithExtendedInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/types/Person.kt new file mode 100644 index 000000000..d69f49344 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/types/Person.kt @@ -0,0 +1,18 @@ +package kotlin2.constantsWithExtendedInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.Int +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +public sealed interface Person { + public val firstname: String + + public val lastname: String? + + public val age: Int? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/types/Query.kt new file mode 100644 index 000000000..8613ec431 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.constantsWithExtendedInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/schema.graphql new file mode 100644 index 000000000..2c9a62c06 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedInterface/schema.graphql @@ -0,0 +1,12 @@ +type Query { + people: [Person] +} + +interface Person { + firstname: String! + lastname: String +} + +extend interface Person { + age: Int +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/DgsClient.kt new file mode 100644 index 000000000..c6b968c75 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.constantsWithExtendedQuery.expected + +import kotlin.String +import kotlin2.constantsWithExtendedQuery.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/DgsConstants.kt new file mode 100644 index 000000000..49a688f27 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/DgsConstants.kt @@ -0,0 +1,23 @@ +package kotlin2.constantsWithExtendedQuery.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + + public const val Friends: String = "friends" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/client/PersonProjection.kt new file mode 100644 index 000000000..d78e67618 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.constantsWithExtendedQuery.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/client/QueryProjection.kt new file mode 100644 index 000000000..b07ccb2c4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/client/QueryProjection.kt @@ -0,0 +1,15 @@ +package kotlin2.constantsWithExtendedQuery.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } + + public fun friends(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("friends", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/types/Person.kt new file mode 100644 index 000000000..23702f5c9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/types/Person.kt @@ -0,0 +1,59 @@ +package kotlin2.constantsWithExtendedQuery.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + firstname: () -> String? = firstnameDefault, + lastname: () -> String? = lastnameDefault +) { + private val _firstname: () -> String? = firstname + + private val _lastname: () -> String? = lastname + + public val firstname: String? + get() = _firstname.invoke() + + public val lastname: String? + get() = _lastname.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + public fun build() = Person( + firstname = firstname, + lastname = lastname, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/types/Query.kt new file mode 100644 index 000000000..1c5710045 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/expected/types/Query.kt @@ -0,0 +1,59 @@ +package kotlin2.constantsWithExtendedQuery.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault, + friends: () -> List? = friendsDefault +) { + private val _people: () -> List? = people + + private val _friends: () -> List? = friends + + public val people: List? + get() = _people.invoke() + + public val friends: List? + get() = _friends.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + + private val friendsDefault: () -> List? = + { throw IllegalStateException("Field `friends` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + private var friends: () -> List? = friendsDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + @JsonProperty("friends") + public fun withFriends(friends: List?): Builder = this.apply { + this.friends = { friends } + } + + public fun build() = Query( + people = people, + friends = friends, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/schema.graphql new file mode 100644 index 000000000..5e59e34ff --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedQuery/schema.graphql @@ -0,0 +1,12 @@ +type Query { + people: [Person] +} + +type Person { + firstname: String + lastname: String +} + +extend type Query { + friends: [Person] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/DgsClient.kt new file mode 100644 index 000000000..7beb5f81f --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.constantsWithExtendedTypes.expected + +import kotlin.String +import kotlin2.constantsWithExtendedTypes.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/DgsConstants.kt new file mode 100644 index 000000000..1fdaaf508 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/DgsConstants.kt @@ -0,0 +1,23 @@ +package kotlin2.constantsWithExtendedTypes.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Email: String = "email" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/client/PersonProjection.kt new file mode 100644 index 000000000..c16f9f594 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/client/PersonProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.constantsWithExtendedTypes.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } + + public val email: PersonProjection + get() { + field("email") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/client/QueryProjection.kt new file mode 100644 index 000000000..2db209327 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.constantsWithExtendedTypes.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/types/Person.kt new file mode 100644 index 000000000..725386f74 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/types/Person.kt @@ -0,0 +1,77 @@ +package kotlin2.constantsWithExtendedTypes.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + firstname: () -> String? = firstnameDefault, + lastname: () -> String? = lastnameDefault, + email: () -> String? = emailDefault +) { + private val _firstname: () -> String? = firstname + + private val _lastname: () -> String? = lastname + + private val _email: () -> String? = email + + public val firstname: String? + get() = _firstname.invoke() + + public val lastname: String? + get() = _lastname.invoke() + + public val email: String? + get() = _email.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + + private val emailDefault: () -> String? = + { throw IllegalStateException("Field `email` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + private var email: () -> String? = emailDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + @JsonProperty("email") + public fun withEmail(email: String?): Builder = this.apply { + this.email = { email } + } + + public fun build() = Person( + firstname = firstname, + lastname = lastname, + email = email, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/types/Query.kt new file mode 100644 index 000000000..8ad77f26b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.constantsWithExtendedTypes.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/schema.graphql new file mode 100644 index 000000000..1071abd18 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/constantsWithExtendedTypes/schema.graphql @@ -0,0 +1,12 @@ +type Query { + people: [Person] +} + +type Person { + firstname: String + lastname: String +} + +extend type Person { + email: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/DgsClient.kt new file mode 100644 index 000000000..32dde64ef --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassDocs.expected + +import kotlin.String +import kotlin2.dataClassDocs.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/DgsConstants.kt new file mode 100644 index 000000000..2652c10f6 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/DgsConstants.kt @@ -0,0 +1,25 @@ +package kotlin2.dataClassDocs.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Search: String = "search" + } + + public object MOVIE { + public const val TYPE_NAME: String = "Movie" + + public const val Title: String = "title" + } + + public object MOVIEFILTER { + public const val TYPE_NAME: String = "MovieFilter" + + public const val TitleFilter: String = "titleFilter" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/client/MovieProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/client/MovieProjection.kt new file mode 100644 index 000000000..02bc4ce98 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/client/MovieProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.dataClassDocs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class MovieProjection : GraphQLProjection() { + public val title: MovieProjection + get() { + field("title") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/client/QueryProjection.kt new file mode 100644 index 000000000..9a62a8a79 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/client/QueryProjection.kt @@ -0,0 +1,13 @@ +package kotlin2.dataClassDocs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin2.dataClassDocs.expected.types.MovieFilter + +public class QueryProjection : GraphQLProjection() { + public fun search(movieFilter: MovieFilter, _projection: MovieProjection.() -> MovieProjection): + QueryProjection { + val args = formatArgs("movieFilter" to movieFilter) + project("search($args)", MovieProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/Movie.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/Movie.kt new file mode 100644 index 000000000..695fafdf9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/Movie.kt @@ -0,0 +1,45 @@ +package kotlin2.dataClassDocs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +/** + * Movies are fun to watch. + * They also work well as examples in GraphQL. + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Movie.Builder::class) +public class Movie( + title: () -> String? = titleDefault +) { + private val _title: () -> String? = title + + public val title: String? + get() = _title.invoke() + + public companion object { + private val titleDefault: () -> String? = + { throw IllegalStateException("Field `title` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var title: () -> String? = titleDefault + + @JsonProperty("title") + public fun withTitle(title: String?): Builder = this.apply { + this.title = { title } + } + + public fun build() = Movie( + title = title, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/MovieFilter.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/MovieFilter.kt new file mode 100644 index 000000000..bd4299cb3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/MovieFilter.kt @@ -0,0 +1,13 @@ +package kotlin2.dataClassDocs.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.String + +/** + * Example filter for Movies. + * + * It takes a title and such. + */ +public class MovieFilter( + public val titleFilter: String? = default("titleFilter") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/Query.kt new file mode 100644 index 000000000..2f9681d74 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/expected/types/Query.kt @@ -0,0 +1,40 @@ +package kotlin2.dataClassDocs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + search: () -> Movie? = searchDefault +) { + private val _search: () -> Movie? = search + + public val search: Movie? + get() = _search.invoke() + + public companion object { + private val searchDefault: () -> Movie? = + { throw IllegalStateException("Field `search` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var search: () -> Movie? = searchDefault + + @JsonProperty("search") + public fun withSearch(search: Movie?): Builder = this.apply { + this.search = { search } + } + + public fun build() = Query( + search = search, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/schema.graphql new file mode 100644 index 000000000..09e4f5f93 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassDocs/schema.graphql @@ -0,0 +1,20 @@ +type Query { + search(movieFilter: MovieFilter!): Movie +} + +""" +Movies are fun to watch. +They also work well as examples in GraphQL. +""" +type Movie { + title: String +} + +""" +Example filter for Movies. + +It takes a title and such. +""" +input MovieFilter { + titleFilter: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/DgsClient.kt new file mode 100644 index 000000000..ca7f6f86f --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassFieldDocs.expected + +import kotlin.String +import kotlin2.dataClassFieldDocs.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/DgsConstants.kt new file mode 100644 index 000000000..f4398792d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/DgsConstants.kt @@ -0,0 +1,25 @@ +package kotlin2.dataClassFieldDocs.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Search: String = "search" + } + + public object MOVIE { + public const val TYPE_NAME: String = "Movie" + + public const val Title: String = "title" + } + + public object MOVIEFILTER { + public const val TYPE_NAME: String = "MovieFilter" + + public const val TitleFilter: String = "titleFilter" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/client/MovieProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/client/MovieProjection.kt new file mode 100644 index 000000000..22c8b04a5 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/client/MovieProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.dataClassFieldDocs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class MovieProjection : GraphQLProjection() { + public val title: MovieProjection + get() { + field("title") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/client/QueryProjection.kt new file mode 100644 index 000000000..2cb0fd3ed --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/client/QueryProjection.kt @@ -0,0 +1,13 @@ +package kotlin2.dataClassFieldDocs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin2.dataClassFieldDocs.expected.types.MovieFilter + +public class QueryProjection : GraphQLProjection() { + public fun search(movieFilter: MovieFilter, _projection: MovieProjection.() -> MovieProjection): + QueryProjection { + val args = formatArgs("movieFilter" to movieFilter) + project("search($args)", MovieProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/Movie.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/Movie.kt new file mode 100644 index 000000000..90a250186 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/Movie.kt @@ -0,0 +1,44 @@ +package kotlin2.dataClassFieldDocs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Movie.Builder::class) +public class Movie( + title: () -> String? = titleDefault +) { + private val _title: () -> String? = title + + /** + * The original, non localized title with some specials characters : %!({[*$,.:;. + */ + public val title: String? + get() = _title.invoke() + + public companion object { + private val titleDefault: () -> String? = + { throw IllegalStateException("Field `title` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var title: () -> String? = titleDefault + + @JsonProperty("title") + public fun withTitle(title: String?): Builder = this.apply { + this.title = { title } + } + + public fun build() = Movie( + title = title, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/MovieFilter.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/MovieFilter.kt new file mode 100644 index 000000000..077e2c8b5 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/MovieFilter.kt @@ -0,0 +1,8 @@ +package kotlin2.dataClassFieldDocs.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.String + +public class MovieFilter( + public val titleFilter: String? = default("titleFilter") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/Query.kt new file mode 100644 index 000000000..ed19342ed --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/expected/types/Query.kt @@ -0,0 +1,40 @@ +package kotlin2.dataClassFieldDocs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + search: () -> Movie? = searchDefault +) { + private val _search: () -> Movie? = search + + public val search: Movie? + get() = _search.invoke() + + public companion object { + private val searchDefault: () -> Movie? = + { throw IllegalStateException("Field `search` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var search: () -> Movie? = searchDefault + + @JsonProperty("search") + public fun withSearch(search: Movie?): Builder = this.apply { + this.search = { search } + } + + public fun build() = Query( + search = search, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/schema.graphql new file mode 100644 index 000000000..ddf1bbf7a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassFieldDocs/schema.graphql @@ -0,0 +1,17 @@ +type Query { + search(movieFilter: MovieFilter!): Movie +} + +type Movie { + """ + The original, non localized title with some specials characters : %!({[*$,.:;. + """ + title: String +} + +input MovieFilter { + """ + Starts-with filter + """ + titleFilter: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/DgsClient.kt new file mode 100644 index 000000000..d1beb2bd3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWIthNoFields.expected + +import kotlin.String +import kotlin2.dataClassWIthNoFields.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/DgsConstants.kt new file mode 100644 index 000000000..02b5b7219 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/DgsConstants.kt @@ -0,0 +1,17 @@ +package kotlin2.dataClassWIthNoFields.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Me: String = "me" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/client/PersonProjection.kt new file mode 100644 index 000000000..9d6132e2d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/client/PersonProjection.kt @@ -0,0 +1,5 @@ +package kotlin2.dataClassWIthNoFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/client/QueryProjection.kt new file mode 100644 index 000000000..f3d548c73 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWIthNoFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun me(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("me", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/types/Person.kt new file mode 100644 index 000000000..c11ef816d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/types/Person.kt @@ -0,0 +1,20 @@ +package kotlin2.dataClassWIthNoFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person() { + public companion object + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + public fun build() = Person( + + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/types/Query.kt new file mode 100644 index 000000000..b2bc0e502 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/expected/types/Query.kt @@ -0,0 +1,40 @@ +package kotlin2.dataClassWIthNoFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + me: () -> Person? = meDefault +) { + private val _me: () -> Person? = me + + public val me: Person? + get() = _me.invoke() + + public companion object { + private val meDefault: () -> Person? = + { throw IllegalStateException("Field `me` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var me: () -> Person? = meDefault + + @JsonProperty("me") + public fun withMe(me: Person?): Builder = this.apply { + this.me = { me } + } + + public fun build() = Query( + me = me, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/schema.graphql new file mode 100644 index 000000000..708d6dcbc --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWIthNoFields/schema.graphql @@ -0,0 +1,6 @@ +type Query { + me: Person +} + +type Person { +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/DgsClient.kt new file mode 100644 index 000000000..f7987d48a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected + +import kotlin.String +import kotlin2.dataClassWithDeeplyNestedComplexField.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/DgsConstants.kt new file mode 100644 index 000000000..56ad9d6f1 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/DgsConstants.kt @@ -0,0 +1,43 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Cars: String = "cars" + } + + public object CAR { + public const val TYPE_NAME: String = "Car" + + public const val Make: String = "make" + + public const val Model: String = "model" + + public const val Engine: String = "engine" + } + + public object ENGINE { + public const val TYPE_NAME: String = "Engine" + + public const val Type: String = "type" + + public const val Bhp: String = "bhp" + + public const val Size: String = "size" + + public const val Performance: String = "performance" + } + + public object PERFORMANCE { + public const val TYPE_NAME: String = "Performance" + + public const val ZeroToSixty: String = "zeroToSixty" + + public const val QuarterMile: String = "quarterMile" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/CarProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/CarProjection.kt new file mode 100644 index 000000000..bde9faade --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/CarProjection.kt @@ -0,0 +1,22 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class CarProjection : GraphQLProjection() { + public val make: CarProjection + get() { + field("make") + return this + } + + public val model: CarProjection + get() { + field("model") + return this + } + + public fun engine(_projection: EngineProjection.() -> EngineProjection): CarProjection { + project("engine", EngineProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/EngineProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/EngineProjection.kt new file mode 100644 index 000000000..7ab869d18 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/EngineProjection.kt @@ -0,0 +1,29 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class EngineProjection : GraphQLProjection() { + public val type: EngineProjection + get() { + field("type") + return this + } + + public val bhp: EngineProjection + get() { + field("bhp") + return this + } + + public val size: EngineProjection + get() { + field("size") + return this + } + + public fun performance(_projection: PerformanceProjection.() -> PerformanceProjection): + EngineProjection { + project("performance", PerformanceProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/PerformanceProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/PerformanceProjection.kt new file mode 100644 index 000000000..5b9ea8623 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/PerformanceProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PerformanceProjection : GraphQLProjection() { + public val zeroToSixty: PerformanceProjection + get() { + field("zeroToSixty") + return this + } + + public val quarterMile: PerformanceProjection + get() { + field("quarterMile") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/QueryProjection.kt new file mode 100644 index 000000000..6d8d25206 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun cars(_projection: CarProjection.() -> CarProjection): QueryProjection { + project("cars", CarProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Car.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Car.kt new file mode 100644 index 000000000..bd08790ad --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Car.kt @@ -0,0 +1,77 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Car.Builder::class) +public class Car( + make: () -> String? = makeDefault, + model: () -> String? = modelDefault, + engine: () -> Engine? = engineDefault +) { + private val _make: () -> String? = make + + private val _model: () -> String? = model + + private val _engine: () -> Engine? = engine + + public val make: String? + get() = _make.invoke() + + public val model: String? + get() = _model.invoke() + + public val engine: Engine? + get() = _engine.invoke() + + public companion object { + private val makeDefault: () -> String? = + { throw IllegalStateException("Field `make` was not requested") } + + + private val modelDefault: () -> String? = + { throw IllegalStateException("Field `model` was not requested") } + + + private val engineDefault: () -> Engine? = + { throw IllegalStateException("Field `engine` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var make: () -> String? = makeDefault + + private var model: () -> String? = modelDefault + + private var engine: () -> Engine? = engineDefault + + @JsonProperty("make") + public fun withMake(make: String?): Builder = this.apply { + this.make = { make } + } + + @JsonProperty("model") + public fun withModel(model: String?): Builder = this.apply { + this.model = { model } + } + + @JsonProperty("engine") + public fun withEngine(engine: Engine?): Builder = this.apply { + this.engine = { engine } + } + + public fun build() = Car( + make = make, + model = model, + engine = engine, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Engine.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Engine.kt new file mode 100644 index 000000000..90165f375 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Engine.kt @@ -0,0 +1,97 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.Double +import kotlin.Int +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Engine.Builder::class) +public class Engine( + type: () -> String? = typeDefault, + bhp: () -> Int? = bhpDefault, + size: () -> Double? = sizeDefault, + performance: () -> Performance? = performanceDefault +) { + private val _type: () -> String? = type + + private val _bhp: () -> Int? = bhp + + private val _size: () -> Double? = size + + private val _performance: () -> Performance? = performance + + public val type: String? + get() = _type.invoke() + + public val bhp: Int? + get() = _bhp.invoke() + + public val size: Double? + get() = _size.invoke() + + public val performance: Performance? + get() = _performance.invoke() + + public companion object { + private val typeDefault: () -> String? = + { throw IllegalStateException("Field `type` was not requested") } + + + private val bhpDefault: () -> Int? = + { throw IllegalStateException("Field `bhp` was not requested") } + + + private val sizeDefault: () -> Double? = + { throw IllegalStateException("Field `size` was not requested") } + + + private val performanceDefault: () -> Performance? = + { throw IllegalStateException("Field `performance` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var type: () -> String? = typeDefault + + private var bhp: () -> Int? = bhpDefault + + private var size: () -> Double? = sizeDefault + + private var performance: () -> Performance? = performanceDefault + + @JsonProperty("type") + public fun withType(type: String?): Builder = this.apply { + this.type = { type } + } + + @JsonProperty("bhp") + public fun withBhp(bhp: Int?): Builder = this.apply { + this.bhp = { bhp } + } + + @JsonProperty("size") + public fun withSize(size: Double?): Builder = this.apply { + this.size = { size } + } + + @JsonProperty("performance") + public fun withPerformance(performance: Performance?): Builder = this.apply { + this.performance = { performance } + } + + public fun build() = Engine( + type = type, + bhp = bhp, + size = size, + performance = performance, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Performance.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Performance.kt new file mode 100644 index 000000000..5e6826d33 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Performance.kt @@ -0,0 +1,59 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.Double + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Performance.Builder::class) +public class Performance( + zeroToSixty: () -> Double? = zeroToSixtyDefault, + quarterMile: () -> Double? = quarterMileDefault +) { + private val _zeroToSixty: () -> Double? = zeroToSixty + + private val _quarterMile: () -> Double? = quarterMile + + public val zeroToSixty: Double? + get() = _zeroToSixty.invoke() + + public val quarterMile: Double? + get() = _quarterMile.invoke() + + public companion object { + private val zeroToSixtyDefault: () -> Double? = + { throw IllegalStateException("Field `zeroToSixty` was not requested") } + + + private val quarterMileDefault: () -> Double? = + { throw IllegalStateException("Field `quarterMile` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var zeroToSixty: () -> Double? = zeroToSixtyDefault + + private var quarterMile: () -> Double? = quarterMileDefault + + @JsonProperty("zeroToSixty") + public fun withZeroToSixty(zeroToSixty: Double?): Builder = this.apply { + this.zeroToSixty = { zeroToSixty } + } + + @JsonProperty("quarterMile") + public fun withQuarterMile(quarterMile: Double?): Builder = this.apply { + this.quarterMile = { quarterMile } + } + + public fun build() = Performance( + zeroToSixty = zeroToSixty, + quarterMile = quarterMile, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Query.kt new file mode 100644 index 000000000..75fdea2ae --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithDeeplyNestedComplexField.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + cars: () -> List? = carsDefault +) { + private val _cars: () -> List? = cars + + public val cars: List? + get() = _cars.invoke() + + public companion object { + private val carsDefault: () -> List? = + { throw IllegalStateException("Field `cars` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var cars: () -> List? = carsDefault + + @JsonProperty("cars") + public fun withCars(cars: List?): Builder = this.apply { + this.cars = { cars } + } + + public fun build() = Query( + cars = cars, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/schema.graphql new file mode 100644 index 000000000..fd4bdff39 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithDeeplyNestedComplexField/schema.graphql @@ -0,0 +1,21 @@ +type Query { + cars: [Car] +} + +type Car { + make: String + model: String + engine: Engine +} + +type Engine { + type: String + bhp: Int + size: Float + performance: Performance +} + +type Performance { + zeroToSixty: Float + quarterMile: Float +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/DgsClient.kt new file mode 100644 index 000000000..8fc630749 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithExtendedInterface.expected + +import kotlin.String +import kotlin2.dataClassWithExtendedInterface.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/DgsConstants.kt new file mode 100644 index 000000000..24e215f2f --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/DgsConstants.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithExtendedInterface.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Age: String = "age" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/client/PersonProjection.kt new file mode 100644 index 000000000..4ad42bea4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.dataClassWithExtendedInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/client/QueryProjection.kt new file mode 100644 index 000000000..0e0423129 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithExtendedInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/types/Person.kt new file mode 100644 index 000000000..2e6d06dc4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/types/Person.kt @@ -0,0 +1,18 @@ +package kotlin2.dataClassWithExtendedInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.Int +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +public sealed interface Person { + public val firstname: String + + public val lastname: String? + + public val age: Int? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/types/Query.kt new file mode 100644 index 000000000..1e81b78b8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithExtendedInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/schema.graphql new file mode 100644 index 000000000..2c9a62c06 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithExtendedInterface/schema.graphql @@ -0,0 +1,12 @@ +type Query { + people: [Person] +} + +interface Person { + firstname: String! + lastname: String +} + +extend interface Person { + age: Int +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/DgsClient.kt new file mode 100644 index 000000000..72c6413ef --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithInterface.expected + +import kotlin.String +import kotlin2.dataClassWithInterface.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/DgsConstants.kt new file mode 100644 index 000000000..62c4a0b51 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/DgsConstants.kt @@ -0,0 +1,31 @@ +package kotlin2.dataClassWithInterface.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object EMPLOYEE { + public const val TYPE_NAME: String = "Employee" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Company: String = "company" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/EmployeeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/EmployeeProjection.kt new file mode 100644 index 000000000..955a2ebaf --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/EmployeeProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class EmployeeProjection : GraphQLProjection() { + public val firstname: EmployeeProjection + get() { + field("firstname") + return this + } + + public val lastname: EmployeeProjection + get() { + field("lastname") + return this + } + + public val company: EmployeeProjection + get() { + field("company") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/PersonProjection.kt new file mode 100644 index 000000000..f819329bd --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/PersonProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } + + public fun onEmployee(_projection: EmployeeProjection.() -> EmployeeProjection): + PersonProjection { + project("... on Employee", EmployeeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/QueryProjection.kt new file mode 100644 index 000000000..9bc0ab67e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Employee.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Employee.kt new file mode 100644 index 000000000..8543d6f08 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Employee.kt @@ -0,0 +1,77 @@ +package kotlin2.dataClassWithInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Employee.Builder::class) +public class Employee( + firstname: () -> String? = firstnameDefault, + lastname: () -> String? = lastnameDefault, + company: () -> String? = companyDefault +) : Person { + private val _firstname: () -> String? = firstname + + private val _lastname: () -> String? = lastname + + private val _company: () -> String? = company + + public override val firstname: String? + get() = _firstname.invoke() + + public override val lastname: String? + get() = _lastname.invoke() + + public val company: String? + get() = _company.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + + private val companyDefault: () -> String? = + { throw IllegalStateException("Field `company` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + private var company: () -> String? = companyDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + @JsonProperty("company") + public fun withCompany(company: String?): Builder = this.apply { + this.company = { company } + } + + public fun build() = Employee( + firstname = firstname, + lastname = lastname, + company = company, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Person.kt new file mode 100644 index 000000000..ae40a22e9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Person.kt @@ -0,0 +1,19 @@ +package kotlin2.dataClassWithInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Employee::class, name = "Employee") +]) +public sealed interface Person { + public val firstname: String? + + public val lastname: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Query.kt new file mode 100644 index 000000000..38b96296f --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/schema.graphql new file mode 100644 index 000000000..43fb6eb4d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterface/schema.graphql @@ -0,0 +1,14 @@ +type Query { + people: [Person] +} + +interface Person { + firstname: String + lastname: String +} + +type Employee implements Person { + firstname: String + lastname: String + company: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/DgsClient.kt new file mode 100644 index 000000000..0733a37b8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected + +import kotlin.String +import kotlin2.dataClassWithInterfaceInheritance.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/DgsConstants.kt new file mode 100644 index 000000000..27de65234 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/DgsConstants.kt @@ -0,0 +1,43 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object TALENT { + public const val TYPE_NAME: String = "Talent" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Company: String = "company" + + public const val ImdbProfile: String = "imdbProfile" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + } + + public object EMPLOYEE { + public const val TYPE_NAME: String = "Employee" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Company: String = "company" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/EmployeeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/EmployeeProjection.kt new file mode 100644 index 000000000..8a083b91e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/EmployeeProjection.kt @@ -0,0 +1,28 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class EmployeeProjection : GraphQLProjection() { + public val firstname: EmployeeProjection + get() { + field("firstname") + return this + } + + public val lastname: EmployeeProjection + get() { + field("lastname") + return this + } + + public val company: EmployeeProjection + get() { + field("company") + return this + } + + public fun onTalent(_projection: TalentProjection.() -> TalentProjection): EmployeeProjection { + project("... on Talent", TalentProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/PersonProjection.kt new file mode 100644 index 000000000..66d15ccfe --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/PersonProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } + + public fun onEmployee(_projection: EmployeeProjection.() -> EmployeeProjection): + PersonProjection { + project("... on Employee", EmployeeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/QueryProjection.kt new file mode 100644 index 000000000..2da1c673c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/TalentProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/TalentProjection.kt new file mode 100644 index 000000000..3b8afd883 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/client/TalentProjection.kt @@ -0,0 +1,29 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class TalentProjection : GraphQLProjection() { + public val firstname: TalentProjection + get() { + field("firstname") + return this + } + + public val lastname: TalentProjection + get() { + field("lastname") + return this + } + + public val company: TalentProjection + get() { + field("company") + return this + } + + public val imdbProfile: TalentProjection + get() { + field("imdbProfile") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Employee.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Employee.kt new file mode 100644 index 000000000..20a8fe303 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Employee.kt @@ -0,0 +1,21 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Talent::class, name = "Talent") +]) +public sealed interface Employee : Person { + public override val firstname: String + + public override val lastname: String? + + public val company: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Person.kt new file mode 100644 index 000000000..4d7075ed7 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Person.kt @@ -0,0 +1,15 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected.types + +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +public sealed interface Person { + public val firstname: String + + public val lastname: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Query.kt new file mode 100644 index 000000000..59f78a391 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Talent.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Talent.kt new file mode 100644 index 000000000..272c7c21e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/expected/types/Talent.kt @@ -0,0 +1,95 @@ +package kotlin2.dataClassWithInterfaceInheritance.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Talent.Builder::class) +public class Talent( + firstname: () -> String = firstnameDefault, + lastname: () -> String? = lastnameDefault, + company: () -> String? = companyDefault, + imdbProfile: () -> String? = imdbProfileDefault +) : Employee { + private val _firstname: () -> String = firstname + + private val _lastname: () -> String? = lastname + + private val _company: () -> String? = company + + private val _imdbProfile: () -> String? = imdbProfile + + public override val firstname: String + get() = _firstname.invoke() + + public override val lastname: String? + get() = _lastname.invoke() + + public override val company: String? + get() = _company.invoke() + + public val imdbProfile: String? + get() = _imdbProfile.invoke() + + public companion object { + private val firstnameDefault: () -> String = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + + private val companyDefault: () -> String? = + { throw IllegalStateException("Field `company` was not requested") } + + + private val imdbProfileDefault: () -> String? = + { throw IllegalStateException("Field `imdbProfile` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + private var company: () -> String? = companyDefault + + private var imdbProfile: () -> String? = imdbProfileDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + @JsonProperty("company") + public fun withCompany(company: String?): Builder = this.apply { + this.company = { company } + } + + @JsonProperty("imdbProfile") + public fun withImdbProfile(imdbProfile: String?): Builder = this.apply { + this.imdbProfile = { imdbProfile } + } + + public fun build() = Talent( + firstname = firstname, + lastname = lastname, + company = company, + imdbProfile = imdbProfile, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/schema.graphql new file mode 100644 index 000000000..7b4220af0 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithInterfaceInheritance/schema.graphql @@ -0,0 +1,21 @@ +type Query { + people: [Person] +} + +interface Person { + firstname: String! + lastname: String +} + +interface Employee implements Person { + firstname: String! + lastname: String + company: String +} + +type Talent implements Employee { + firstname: String! + lastname: String + company: String + imdbProfile: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/DgsClient.kt new file mode 100644 index 000000000..f1bae0800 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithListProperties.expected + +import kotlin.String +import kotlin2.dataClassWithListProperties.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/DgsConstants.kt new file mode 100644 index 000000000..cc3fc63ca --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/DgsConstants.kt @@ -0,0 +1,21 @@ +package kotlin2.dataClassWithListProperties.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Name: String = "name" + + public const val Email: String = "email" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/client/PersonProjection.kt new file mode 100644 index 000000000..9806fd811 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.dataClassWithListProperties.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val name: PersonProjection + get() { + field("name") + return this + } + + public val email: PersonProjection + get() { + field("email") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/client/QueryProjection.kt new file mode 100644 index 000000000..eb808296e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithListProperties.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/types/Person.kt new file mode 100644 index 000000000..5e9ec5b23 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/types/Person.kt @@ -0,0 +1,60 @@ +package kotlin2.dataClassWithListProperties.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + name: () -> String? = nameDefault, + email: () -> List? = emailDefault +) { + private val _name: () -> String? = name + + private val _email: () -> List? = email + + public val name: String? + get() = _name.invoke() + + public val email: List? + get() = _email.invoke() + + public companion object { + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + + private val emailDefault: () -> List? = + { throw IllegalStateException("Field `email` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String? = nameDefault + + private var email: () -> List? = emailDefault + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + @JsonProperty("email") + public fun withEmail(email: List?): Builder = this.apply { + this.email = { email } + } + + public fun build() = Person( + name = name, + email = email, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/types/Query.kt new file mode 100644 index 000000000..da7cf5f08 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithListProperties.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/schema.graphql new file mode 100644 index 000000000..b4bc39563 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithListProperties/schema.graphql @@ -0,0 +1,8 @@ +type Query { + people: [Person] +} + +type Person { + name: String + email: [String] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/DgsClient.kt new file mode 100644 index 000000000..846e32f81 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithNonNullableAndInterface.expected + +import kotlin.String +import kotlin2.dataClassWithNonNullableAndInterface.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/DgsConstants.kt new file mode 100644 index 000000000..90fbb3433 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/DgsConstants.kt @@ -0,0 +1,33 @@ +package kotlin2.dataClassWithNonNullableAndInterface.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object EMPLOYEE { + public const val TYPE_NAME: String = "Employee" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Company: String = "company" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Company: String = "company" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/EmployeeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/EmployeeProjection.kt new file mode 100644 index 000000000..32c871125 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/EmployeeProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithNonNullableAndInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class EmployeeProjection : GraphQLProjection() { + public val firstname: EmployeeProjection + get() { + field("firstname") + return this + } + + public val lastname: EmployeeProjection + get() { + field("lastname") + return this + } + + public val company: EmployeeProjection + get() { + field("company") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/PersonProjection.kt new file mode 100644 index 000000000..1f24ace69 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/PersonProjection.kt @@ -0,0 +1,29 @@ +package kotlin2.dataClassWithNonNullableAndInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } + + public val company: PersonProjection + get() { + field("company") + return this + } + + public fun onEmployee(_projection: EmployeeProjection.() -> EmployeeProjection): + PersonProjection { + project("... on Employee", EmployeeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/QueryProjection.kt new file mode 100644 index 000000000..b532d0efe --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithNonNullableAndInterface.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Employee.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Employee.kt new file mode 100644 index 000000000..916b1c0be --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Employee.kt @@ -0,0 +1,77 @@ +package kotlin2.dataClassWithNonNullableAndInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Employee.Builder::class) +public class Employee( + firstname: () -> String = firstnameDefault, + lastname: () -> String = lastnameDefault, + company: () -> String? = companyDefault +) : Person { + private val _firstname: () -> String = firstname + + private val _lastname: () -> String = lastname + + private val _company: () -> String? = company + + public override val firstname: String + get() = _firstname.invoke() + + public override val lastname: String + get() = _lastname.invoke() + + public override val company: String? + get() = _company.invoke() + + public companion object { + private val firstnameDefault: () -> String = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String = + { throw IllegalStateException("Field `lastname` was not requested") } + + + private val companyDefault: () -> String? = + { throw IllegalStateException("Field `company` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String = firstnameDefault + + private var lastname: () -> String = lastnameDefault + + private var company: () -> String? = companyDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String): Builder = this.apply { + this.lastname = { lastname } + } + + @JsonProperty("company") + public fun withCompany(company: String?): Builder = this.apply { + this.company = { company } + } + + public fun build() = Employee( + firstname = firstname, + lastname = lastname, + company = company, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Person.kt new file mode 100644 index 000000000..5b169e64a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Person.kt @@ -0,0 +1,21 @@ +package kotlin2.dataClassWithNonNullableAndInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Employee::class, name = "Employee") +]) +public sealed interface Person { + public val firstname: String + + public val lastname: String + + public val company: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Query.kt new file mode 100644 index 000000000..5e65d275e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithNonNullableAndInterface.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/schema.graphql new file mode 100644 index 000000000..aa012a27c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableAndInterface/schema.graphql @@ -0,0 +1,15 @@ +type Query { + people: [Person] +} + +interface Person { + firstname: String! + lastname: String! + company: String +} + +type Employee implements Person { + firstname: String! + lastname: String! + company: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/DgsClient.kt new file mode 100644 index 000000000..420360815 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.dataClassWithNonNullableComplexType.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/DgsConstants.kt new file mode 100644 index 000000000..462f0585e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/DgsConstants.kt @@ -0,0 +1,17 @@ +package kotlin2.dataClassWithNonNullableComplexType.expected + +import kotlin.String + +public object DgsConstants { + public object MYTYPE { + public const val TYPE_NAME: String = "MyType" + + public const val Other: String = "other" + } + + public object OTHERTYPE { + public const val TYPE_NAME: String = "OtherType" + + public const val Name: String = "name" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/client/MyTypeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/client/MyTypeProjection.kt new file mode 100644 index 000000000..c61a2f029 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/client/MyTypeProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithNonNullableComplexType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class MyTypeProjection : GraphQLProjection() { + public fun other(_projection: OtherTypeProjection.() -> OtherTypeProjection): MyTypeProjection { + project("other", OtherTypeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/client/OtherTypeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/client/OtherTypeProjection.kt new file mode 100644 index 000000000..53c907dac --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/client/OtherTypeProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.dataClassWithNonNullableComplexType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class OtherTypeProjection : GraphQLProjection() { + public val name: OtherTypeProjection + get() { + field("name") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/types/MyType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/types/MyType.kt new file mode 100644 index 000000000..3b32dec08 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/types/MyType.kt @@ -0,0 +1,40 @@ +package kotlin2.dataClassWithNonNullableComplexType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = MyType.Builder::class) +public class MyType( + other: () -> OtherType = otherDefault +) { + private val _other: () -> OtherType = other + + public val other: OtherType + get() = _other.invoke() + + public companion object { + private val otherDefault: () -> OtherType = + { throw IllegalStateException("Field `other` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var other: () -> OtherType = otherDefault + + @JsonProperty("other") + public fun withOther(other: OtherType): Builder = this.apply { + this.other = { other } + } + + public fun build() = MyType( + other = other, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/types/OtherType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/types/OtherType.kt new file mode 100644 index 000000000..ad304e605 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/expected/types/OtherType.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithNonNullableComplexType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = OtherType.Builder::class) +public class OtherType( + name: () -> String = nameDefault +) { + private val _name: () -> String = name + + public val name: String + get() = _name.invoke() + + public companion object { + private val nameDefault: () -> String = + { throw IllegalStateException("Field `name` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String = nameDefault + + @JsonProperty("name") + public fun withName(name: String): Builder = this.apply { + this.name = { name } + } + + public fun build() = OtherType( + name = name, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/schema.graphql new file mode 100644 index 000000000..3228badf6 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableComplexType/schema.graphql @@ -0,0 +1,7 @@ +type MyType { + other: OtherType! +} + +type OtherType { + name: String! +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/DgsClient.kt new file mode 100644 index 000000000..1de06c8a1 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithNonNullableListOfNullableValues.expected + +import kotlin.String +import kotlin2.dataClassWithNonNullableListOfNullableValues.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/DgsConstants.kt new file mode 100644 index 000000000..e21dbc503 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/DgsConstants.kt @@ -0,0 +1,21 @@ +package kotlin2.dataClassWithNonNullableListOfNullableValues.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Name: String = "name" + + public const val Email: String = "email" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/client/PersonProjection.kt new file mode 100644 index 000000000..76f0b8be8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.dataClassWithNonNullableListOfNullableValues.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val name: PersonProjection + get() { + field("name") + return this + } + + public val email: PersonProjection + get() { + field("email") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/client/QueryProjection.kt new file mode 100644 index 000000000..1cfdc834a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithNonNullableListOfNullableValues.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/types/Person.kt new file mode 100644 index 000000000..ae9f218d0 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/types/Person.kt @@ -0,0 +1,60 @@ +package kotlin2.dataClassWithNonNullableListOfNullableValues.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + name: () -> String = nameDefault, + email: () -> List = emailDefault +) { + private val _name: () -> String = name + + private val _email: () -> List = email + + public val name: String + get() = _name.invoke() + + public val email: List + get() = _email.invoke() + + public companion object { + private val nameDefault: () -> String = + { throw IllegalStateException("Field `name` was not requested") } + + + private val emailDefault: () -> List = + { throw IllegalStateException("Field `email` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String = nameDefault + + private var email: () -> List = emailDefault + + @JsonProperty("name") + public fun withName(name: String): Builder = this.apply { + this.name = { name } + } + + @JsonProperty("email") + public fun withEmail(email: List): Builder = this.apply { + this.email = { email } + } + + public fun build() = Person( + name = name, + email = email, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/types/Query.kt new file mode 100644 index 000000000..906763dcd --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithNonNullableListOfNullableValues.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/schema.graphql new file mode 100644 index 000000000..41e4bc818 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableListOfNullableValues/schema.graphql @@ -0,0 +1,8 @@ +type Query { + people: [Person] +} + +type Person { + name: String! + email: [String]! +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/DgsClient.kt new file mode 100644 index 000000000..9bc7f0e49 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.dataClassWithNonNullablePrimitive.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/DgsConstants.kt new file mode 100644 index 000000000..2a7b0bdf9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/DgsConstants.kt @@ -0,0 +1,15 @@ +package kotlin2.dataClassWithNonNullablePrimitive.expected + +import kotlin.String + +public object DgsConstants { + public object MYTYPE { + public const val TYPE_NAME: String = "MyType" + + public const val Count: String = "count" + + public const val Truth: String = "truth" + + public const val Floaty: String = "floaty" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/client/MyTypeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/client/MyTypeProjection.kt new file mode 100644 index 000000000..ce66fc522 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/client/MyTypeProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithNonNullablePrimitive.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class MyTypeProjection : GraphQLProjection() { + public val count: MyTypeProjection + get() { + field("count") + return this + } + + public val truth: MyTypeProjection + get() { + field("truth") + return this + } + + public val floaty: MyTypeProjection + get() { + field("floaty") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/types/MyType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/types/MyType.kt new file mode 100644 index 000000000..f8ee0453c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/expected/types/MyType.kt @@ -0,0 +1,79 @@ +package kotlin2.dataClassWithNonNullablePrimitive.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.Boolean +import kotlin.Double +import kotlin.Int + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = MyType.Builder::class) +public class MyType( + count: () -> Int = countDefault, + truth: () -> Boolean = truthDefault, + floaty: () -> Double = floatyDefault +) { + private val _count: () -> Int = count + + private val _truth: () -> Boolean = truth + + private val _floaty: () -> Double = floaty + + public val count: Int + get() = _count.invoke() + + public val truth: Boolean + get() = _truth.invoke() + + public val floaty: Double + get() = _floaty.invoke() + + public companion object { + private val countDefault: () -> Int = + { throw IllegalStateException("Field `count` was not requested") } + + + private val truthDefault: () -> Boolean = + { throw IllegalStateException("Field `truth` was not requested") } + + + private val floatyDefault: () -> Double = + { throw IllegalStateException("Field `floaty` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var count: () -> Int = countDefault + + private var truth: () -> Boolean = truthDefault + + private var floaty: () -> Double = floatyDefault + + @JsonProperty("count") + public fun withCount(count: Int): Builder = this.apply { + this.count = { count } + } + + @JsonProperty("truth") + public fun withTruth(truth: Boolean): Builder = this.apply { + this.truth = { truth } + } + + @JsonProperty("floaty") + public fun withFloaty(floaty: Double): Builder = this.apply { + this.floaty = { floaty } + } + + public fun build() = MyType( + count = count, + truth = truth, + floaty = floaty, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/schema.graphql new file mode 100644 index 000000000..22eb28bee --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitive/schema.graphql @@ -0,0 +1,5 @@ +type MyType { + count: Int! + truth: Boolean! + floaty: Float! +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/DgsClient.kt new file mode 100644 index 000000000..e2e9fe55d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.dataClassWithNonNullablePrimitiveInList.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/DgsConstants.kt new file mode 100644 index 000000000..3a5cf817a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/DgsConstants.kt @@ -0,0 +1,15 @@ +package kotlin2.dataClassWithNonNullablePrimitiveInList.expected + +import kotlin.String + +public object DgsConstants { + public object MYTYPE { + public const val TYPE_NAME: String = "MyType" + + public const val Count: String = "count" + + public const val Truth: String = "truth" + + public const val Floaty: String = "floaty" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/client/MyTypeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/client/MyTypeProjection.kt new file mode 100644 index 000000000..e93a0c766 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/client/MyTypeProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithNonNullablePrimitiveInList.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class MyTypeProjection : GraphQLProjection() { + public val count: MyTypeProjection + get() { + field("count") + return this + } + + public val truth: MyTypeProjection + get() { + field("truth") + return this + } + + public val floaty: MyTypeProjection + get() { + field("floaty") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/types/MyType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/types/MyType.kt new file mode 100644 index 000000000..2a5c1eb73 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/expected/types/MyType.kt @@ -0,0 +1,80 @@ +package kotlin2.dataClassWithNonNullablePrimitiveInList.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.Boolean +import kotlin.Double +import kotlin.Int +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = MyType.Builder::class) +public class MyType( + count: () -> List? = countDefault, + truth: () -> List? = truthDefault, + floaty: () -> List? = floatyDefault +) { + private val _count: () -> List? = count + + private val _truth: () -> List? = truth + + private val _floaty: () -> List? = floaty + + public val count: List? + get() = _count.invoke() + + public val truth: List? + get() = _truth.invoke() + + public val floaty: List? + get() = _floaty.invoke() + + public companion object { + private val countDefault: () -> List? = + { throw IllegalStateException("Field `count` was not requested") } + + + private val truthDefault: () -> List? = + { throw IllegalStateException("Field `truth` was not requested") } + + + private val floatyDefault: () -> List? = + { throw IllegalStateException("Field `floaty` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var count: () -> List? = countDefault + + private var truth: () -> List? = truthDefault + + private var floaty: () -> List? = floatyDefault + + @JsonProperty("count") + public fun withCount(count: List?): Builder = this.apply { + this.count = { count } + } + + @JsonProperty("truth") + public fun withTruth(truth: List?): Builder = this.apply { + this.truth = { truth } + } + + @JsonProperty("floaty") + public fun withFloaty(floaty: List?): Builder = this.apply { + this.floaty = { floaty } + } + + public fun build() = MyType( + count = count, + truth = truth, + floaty = floaty, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/schema.graphql new file mode 100644 index 000000000..f93e60245 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullablePrimitiveInList/schema.graphql @@ -0,0 +1,5 @@ +type MyType { + count: [Int!] + truth: [Boolean!] + floaty: [Float!] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/DgsClient.kt new file mode 100644 index 000000000..86ef40b94 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithNonNullableProperties.expected + +import kotlin.String +import kotlin2.dataClassWithNonNullableProperties.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/DgsConstants.kt new file mode 100644 index 000000000..2610a30a3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/DgsConstants.kt @@ -0,0 +1,21 @@ +package kotlin2.dataClassWithNonNullableProperties.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Name: String = "name" + + public const val Email: String = "email" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/client/PersonProjection.kt new file mode 100644 index 000000000..70aa8f9db --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.dataClassWithNonNullableProperties.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val name: PersonProjection + get() { + field("name") + return this + } + + public val email: PersonProjection + get() { + field("email") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/client/QueryProjection.kt new file mode 100644 index 000000000..97369561e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithNonNullableProperties.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/types/Person.kt new file mode 100644 index 000000000..1269ee353 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/types/Person.kt @@ -0,0 +1,60 @@ +package kotlin2.dataClassWithNonNullableProperties.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + name: () -> String = nameDefault, + email: () -> List = emailDefault +) { + private val _name: () -> String = name + + private val _email: () -> List = email + + public val name: String + get() = _name.invoke() + + public val email: List + get() = _email.invoke() + + public companion object { + private val nameDefault: () -> String = + { throw IllegalStateException("Field `name` was not requested") } + + + private val emailDefault: () -> List = + { throw IllegalStateException("Field `email` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String = nameDefault + + private var email: () -> List = emailDefault + + @JsonProperty("name") + public fun withName(name: String): Builder = this.apply { + this.name = { name } + } + + @JsonProperty("email") + public fun withEmail(email: List): Builder = this.apply { + this.email = { email } + } + + public fun build() = Person( + name = name, + email = email, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/types/Query.kt new file mode 100644 index 000000000..2a8a28d08 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithNonNullableProperties.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/schema.graphql new file mode 100644 index 000000000..3df803dd8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNonNullableProperties/schema.graphql @@ -0,0 +1,8 @@ +type Query { + people: [Person!] +} + +type Person { + name: String! + email: [String!]! +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/DgsClient.kt new file mode 100644 index 000000000..b832c0d2e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.dataClassWithNullablePrimitive.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/DgsConstants.kt new file mode 100644 index 000000000..293ac1a77 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/DgsConstants.kt @@ -0,0 +1,15 @@ +package kotlin2.dataClassWithNullablePrimitive.expected + +import kotlin.String + +public object DgsConstants { + public object MYTYPE { + public const val TYPE_NAME: String = "MyType" + + public const val Count: String = "count" + + public const val Truth: String = "truth" + + public const val Floaty: String = "floaty" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/client/MyTypeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/client/MyTypeProjection.kt new file mode 100644 index 000000000..39a87b5bd --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/client/MyTypeProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithNullablePrimitive.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class MyTypeProjection : GraphQLProjection() { + public val count: MyTypeProjection + get() { + field("count") + return this + } + + public val truth: MyTypeProjection + get() { + field("truth") + return this + } + + public val floaty: MyTypeProjection + get() { + field("floaty") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/types/MyType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/types/MyType.kt new file mode 100644 index 000000000..5f36dc940 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/expected/types/MyType.kt @@ -0,0 +1,79 @@ +package kotlin2.dataClassWithNullablePrimitive.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.Boolean +import kotlin.Double +import kotlin.Int + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = MyType.Builder::class) +public class MyType( + count: () -> Int? = countDefault, + truth: () -> Boolean? = truthDefault, + floaty: () -> Double? = floatyDefault +) { + private val _count: () -> Int? = count + + private val _truth: () -> Boolean? = truth + + private val _floaty: () -> Double? = floaty + + public val count: Int? + get() = _count.invoke() + + public val truth: Boolean? + get() = _truth.invoke() + + public val floaty: Double? + get() = _floaty.invoke() + + public companion object { + private val countDefault: () -> Int? = + { throw IllegalStateException("Field `count` was not requested") } + + + private val truthDefault: () -> Boolean? = + { throw IllegalStateException("Field `truth` was not requested") } + + + private val floatyDefault: () -> Double? = + { throw IllegalStateException("Field `floaty` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var count: () -> Int? = countDefault + + private var truth: () -> Boolean? = truthDefault + + private var floaty: () -> Double? = floatyDefault + + @JsonProperty("count") + public fun withCount(count: Int?): Builder = this.apply { + this.count = { count } + } + + @JsonProperty("truth") + public fun withTruth(truth: Boolean?): Builder = this.apply { + this.truth = { truth } + } + + @JsonProperty("floaty") + public fun withFloaty(floaty: Double?): Builder = this.apply { + this.floaty = { floaty } + } + + public fun build() = MyType( + count = count, + truth = truth, + floaty = floaty, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/schema.graphql new file mode 100644 index 000000000..80eaa1df3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithNullablePrimitive/schema.graphql @@ -0,0 +1,5 @@ +type MyType { + count: Int + truth: Boolean + floaty: Float +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/DgsClient.kt new file mode 100644 index 000000000..090c61a51 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithRecursiveField.expected + +import kotlin.String +import kotlin2.dataClassWithRecursiveField.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/DgsConstants.kt new file mode 100644 index 000000000..c0ed28de8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/DgsConstants.kt @@ -0,0 +1,23 @@ +package kotlin2.dataClassWithRecursiveField.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Friends: String = "friends" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/client/PersonProjection.kt new file mode 100644 index 000000000..daf7a55dc --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/client/PersonProjection.kt @@ -0,0 +1,22 @@ +package kotlin2.dataClassWithRecursiveField.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } + + public fun friends(_projection: PersonProjection.() -> PersonProjection): PersonProjection { + project("friends", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/client/QueryProjection.kt new file mode 100644 index 000000000..539fec637 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithRecursiveField.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/types/Person.kt new file mode 100644 index 000000000..1e91844dd --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/types/Person.kt @@ -0,0 +1,78 @@ +package kotlin2.dataClassWithRecursiveField.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + firstname: () -> String? = firstnameDefault, + lastname: () -> String? = lastnameDefault, + friends: () -> List? = friendsDefault +) { + private val _firstname: () -> String? = firstname + + private val _lastname: () -> String? = lastname + + private val _friends: () -> List? = friends + + public val firstname: String? + get() = _firstname.invoke() + + public val lastname: String? + get() = _lastname.invoke() + + public val friends: List? + get() = _friends.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + + private val friendsDefault: () -> List? = + { throw IllegalStateException("Field `friends` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + private var friends: () -> List? = friendsDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + @JsonProperty("friends") + public fun withFriends(friends: List?): Builder = this.apply { + this.friends = { friends } + } + + public fun build() = Person( + firstname = firstname, + lastname = lastname, + friends = friends, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/types/Query.kt new file mode 100644 index 000000000..80896d375 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithRecursiveField.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/schema.graphql new file mode 100644 index 000000000..0a86355d3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithRecursiveField/schema.graphql @@ -0,0 +1,9 @@ +type Query { + people: [Person] +} + +type Person { + firstname: String + lastname: String + friends: [Person] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/DgsClient.kt new file mode 100644 index 000000000..bacabc582 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.dataClassWithStringProperties.expected + +import kotlin.String +import kotlin2.dataClassWithStringProperties.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/DgsConstants.kt new file mode 100644 index 000000000..a6f33a038 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/DgsConstants.kt @@ -0,0 +1,21 @@ +package kotlin2.dataClassWithStringProperties.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/client/PersonProjection.kt new file mode 100644 index 000000000..9ad041a98 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.dataClassWithStringProperties.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/client/QueryProjection.kt new file mode 100644 index 000000000..193b5e0ca --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.dataClassWithStringProperties.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/types/Person.kt new file mode 100644 index 000000000..b0dfd96c1 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/types/Person.kt @@ -0,0 +1,59 @@ +package kotlin2.dataClassWithStringProperties.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + firstname: () -> String? = firstnameDefault, + lastname: () -> String? = lastnameDefault +) { + private val _firstname: () -> String? = firstname + + private val _lastname: () -> String? = lastname + + public val firstname: String? + get() = _firstname.invoke() + + public val lastname: String? + get() = _lastname.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + public fun build() = Person( + firstname = firstname, + lastname = lastname, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/types/Query.kt new file mode 100644 index 000000000..a0d901aab --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.dataClassWithStringProperties.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/schema.graphql new file mode 100644 index 000000000..cdeb9d40d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/dataClassWithStringProperties/schema.graphql @@ -0,0 +1,8 @@ +type Query { + people: [Person] +} + +type Person { + firstname: String + lastname: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/DgsClient.kt new file mode 100644 index 000000000..594df9f06 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.`enum`.expected + +import kotlin.String +import kotlin2.`enum`.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/DgsConstants.kt new file mode 100644 index 000000000..4c8cd919e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/DgsConstants.kt @@ -0,0 +1,13 @@ +package kotlin2.`enum`.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Types: String = "types" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/client/QueryProjection.kt new file mode 100644 index 000000000..66eda6c18 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/client/QueryProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.`enum`.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public val types: QueryProjection + get() { + field("types") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/types/EmployeeTypes.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/types/EmployeeTypes.kt new file mode 100644 index 000000000..2839fb001 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/types/EmployeeTypes.kt @@ -0,0 +1,7 @@ +package kotlin2.`enum`.expected.types + +public enum class EmployeeTypes { + ENGINEER, + MANAGER, + DIRECTOR, +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/types/Query.kt new file mode 100644 index 000000000..1e0142fc9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.`enum`.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + types: () -> List? = typesDefault +) { + private val _types: () -> List? = types + + public val types: List? + get() = _types.invoke() + + public companion object { + private val typesDefault: () -> List? = + { throw IllegalStateException("Field `types` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var types: () -> List? = typesDefault + + @JsonProperty("types") + public fun withTypes(types: List?): Builder = this.apply { + this.types = { types } + } + + public fun build() = Query( + types = types, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/schema.graphql new file mode 100644 index 000000000..9b3e9a9f3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enum/schema.graphql @@ -0,0 +1,9 @@ +type Query { + types: [EmployeeTypes] +} + +enum EmployeeTypes { + ENGINEER + MANAGER + DIRECTOR +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/DgsClient.kt new file mode 100644 index 000000000..eb5c88cd9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.enumDocs.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/DgsConstants.kt new file mode 100644 index 000000000..801a5bd94 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/DgsConstants.kt @@ -0,0 +1,3 @@ +package kotlin2.enumDocs.expected + +public object DgsConstants diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/types/Color.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/types/Color.kt new file mode 100644 index 000000000..7a5eead81 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/expected/types/Color.kt @@ -0,0 +1,10 @@ +package kotlin2.enumDocs.expected.types + +/** + * Some options + */ +public enum class Color { + red, + white, + blue, +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/schema.graphql new file mode 100644 index 000000000..655b53a04 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumDocs/schema.graphql @@ -0,0 +1,6 @@ +""" +Some options +""" +enum Color { + red,white,blue +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/DgsClient.kt new file mode 100644 index 000000000..a80d4b46d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.enumWithExtendedType.expected + +import kotlin.String +import kotlin2.enumWithExtendedType.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/DgsConstants.kt new file mode 100644 index 000000000..9f34603fb --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/DgsConstants.kt @@ -0,0 +1,13 @@ +package kotlin2.enumWithExtendedType.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Types: String = "types" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/client/QueryProjection.kt new file mode 100644 index 000000000..ac98b1f39 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/client/QueryProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.enumWithExtendedType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public val types: QueryProjection + get() { + field("types") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/types/EmployeeTypes.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/types/EmployeeTypes.kt new file mode 100644 index 000000000..a35dc1f29 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/types/EmployeeTypes.kt @@ -0,0 +1,8 @@ +package kotlin2.enumWithExtendedType.expected.types + +public enum class EmployeeTypes { + ENGINEER, + MANAGER, + DIRECTOR, + QA, +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/types/Query.kt new file mode 100644 index 000000000..ee964b7c2 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.enumWithExtendedType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + types: () -> List? = typesDefault +) { + private val _types: () -> List? = types + + public val types: List? + get() = _types.invoke() + + public companion object { + private val typesDefault: () -> List? = + { throw IllegalStateException("Field `types` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var types: () -> List? = typesDefault + + @JsonProperty("types") + public fun withTypes(types: List?): Builder = this.apply { + this.types = { types } + } + + public fun build() = Query( + types = types, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/schema.graphql new file mode 100644 index 000000000..43c0ef2ea --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/enumWithExtendedType/schema.graphql @@ -0,0 +1,13 @@ +type Query { + types: [EmployeeTypes] +} + +enum EmployeeTypes { + ENGINEER + MANAGER + DIRECTOR +} + +extend enum EmployeeTypes { + QA +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/DgsClient.kt new file mode 100644 index 000000000..08cd584a8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.input.expected + +import kotlin.String +import kotlin2.input.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/DgsConstants.kt new file mode 100644 index 000000000..150dd4968 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/DgsConstants.kt @@ -0,0 +1,19 @@ +package kotlin2.input.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Movies: String = "movies" + } + + public object MOVIEFILTER { + public const val TYPE_NAME: String = "MovieFilter" + + public const val Genre: String = "genre" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/client/QueryProjection.kt new file mode 100644 index 000000000..1c5afd2ca --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/client/QueryProjection.kt @@ -0,0 +1,12 @@ +package kotlin2.input.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin2.input.expected.types.MovieFilter + +public class QueryProjection : GraphQLProjection() { + public fun movies(filter: MovieFilter? = default("filter")): QueryProjection { + val args = formatArgs("filter" to filter) + field("movies($args)") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/types/MovieFilter.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/types/MovieFilter.kt new file mode 100644 index 000000000..88079cb19 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/types/MovieFilter.kt @@ -0,0 +1,8 @@ +package kotlin2.input.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.String + +public class MovieFilter( + public val genre: String? = default("genre") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/types/Query.kt new file mode 100644 index 000000000..3ae8bfa28 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/expected/types/Query.kt @@ -0,0 +1,42 @@ +package kotlin2.input.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + movies: () -> List? = moviesDefault +) { + private val _movies: () -> List? = movies + + public val movies: List? + get() = _movies.invoke() + + public companion object { + private val moviesDefault: () -> List? = + { throw IllegalStateException("Field `movies` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var movies: () -> List? = moviesDefault + + @JsonProperty("movies") + public fun withMovies(movies: List?): Builder = this.apply { + this.movies = { movies } + } + + public fun build() = Query( + movies = movies, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/schema.graphql new file mode 100644 index 000000000..9c42d7dc2 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/input/schema.graphql @@ -0,0 +1,7 @@ +type Query { + movies(filter: MovieFilter): [String] +} + +input MovieFilter { + genre: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/DgsClient.kt new file mode 100644 index 000000000..b953da415 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.inputWithDefaultEnumValueForArray.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/DgsConstants.kt new file mode 100644 index 000000000..8cda5526a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/DgsConstants.kt @@ -0,0 +1,11 @@ +package kotlin2.inputWithDefaultEnumValueForArray.expected + +import kotlin.String + +public object DgsConstants { + public object SOMETYPE { + public const val TYPE_NAME: String = "SomeType" + + public const val Colors: String = "colors" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/types/Color.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/types/Color.kt new file mode 100644 index 000000000..e54a32fe4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/types/Color.kt @@ -0,0 +1,6 @@ +package kotlin2.inputWithDefaultEnumValueForArray.expected.types + +public enum class Color { + red, + blue, +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/types/SomeType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/types/SomeType.kt new file mode 100644 index 000000000..88999b215 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/expected/types/SomeType.kt @@ -0,0 +1,8 @@ +package kotlin2.inputWithDefaultEnumValueForArray.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.collections.List + +public class SomeType( + public val colors: List? = default("colors") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/schema.graphql new file mode 100644 index 000000000..9b1a329c1 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultEnumValueForArray/schema.graphql @@ -0,0 +1,8 @@ +input SomeType { + colors: [Color] = [red] +} + +enum Color { + red, + blue +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/DgsClient.kt new file mode 100644 index 000000000..d7c95349d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.inputWithDefaultIntValueForArray.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/DgsConstants.kt new file mode 100644 index 000000000..c4c6ce74a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/DgsConstants.kt @@ -0,0 +1,11 @@ +package kotlin2.inputWithDefaultIntValueForArray.expected + +import kotlin.String + +public object DgsConstants { + public object SOMETYPE { + public const val TYPE_NAME: String = "SomeType" + + public const val Numbers: String = "numbers" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/types/SomeType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/types/SomeType.kt new file mode 100644 index 000000000..6739bcb51 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/expected/types/SomeType.kt @@ -0,0 +1,9 @@ +package kotlin2.inputWithDefaultIntValueForArray.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.Int +import kotlin.collections.List + +public class SomeType( + public val numbers: List? = default("numbers") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/schema.graphql new file mode 100644 index 000000000..ee055a47b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultIntValueForArray/schema.graphql @@ -0,0 +1,3 @@ +input SomeType { + numbers: [Int] = [1, 2, 3] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/DgsClient.kt new file mode 100644 index 000000000..a1038da5c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.inputWithDefaultStringValueForArray.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/DgsConstants.kt new file mode 100644 index 000000000..d607b48e9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/DgsConstants.kt @@ -0,0 +1,11 @@ +package kotlin2.inputWithDefaultStringValueForArray.expected + +import kotlin.String + +public object DgsConstants { + public object SOMETYPE { + public const val TYPE_NAME: String = "SomeType" + + public const val Names: String = "names" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/types/SomeType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/types/SomeType.kt new file mode 100644 index 000000000..fe9d647bb --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/expected/types/SomeType.kt @@ -0,0 +1,9 @@ +package kotlin2.inputWithDefaultStringValueForArray.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.String +import kotlin.collections.List + +public class SomeType( + public val names: List? = default("names") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/schema.graphql new file mode 100644 index 000000000..33823b80f --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultStringValueForArray/schema.graphql @@ -0,0 +1,3 @@ +input SomeType { + names: [String] = ["A", "B"] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/DgsClient.kt new file mode 100644 index 000000000..ac6e538e0 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.inputWithDefaultValueForArray.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/DgsConstants.kt new file mode 100644 index 000000000..7e6d8510b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/DgsConstants.kt @@ -0,0 +1,11 @@ +package kotlin2.inputWithDefaultValueForArray.expected + +import kotlin.String + +public object DgsConstants { + public object SOMETYPE { + public const val TYPE_NAME: String = "SomeType" + + public const val Names: String = "names" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/types/SomeType.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/types/SomeType.kt new file mode 100644 index 000000000..e91afdc9a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/expected/types/SomeType.kt @@ -0,0 +1,9 @@ +package kotlin2.inputWithDefaultValueForArray.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.String +import kotlin.collections.List + +public class SomeType( + public val names: List? = default("names") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/schema.graphql new file mode 100644 index 000000000..0cadf1680 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForArray/schema.graphql @@ -0,0 +1,3 @@ +input SomeType { + names: [String] = [] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/DgsClient.kt new file mode 100644 index 000000000..f93a5f9e4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.inputWithDefaultValueForEnum.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/DgsConstants.kt new file mode 100644 index 000000000..7183478e7 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/DgsConstants.kt @@ -0,0 +1,11 @@ +package kotlin2.inputWithDefaultValueForEnum.expected + +import kotlin.String + +public object DgsConstants { + public object COLORFILTER { + public const val TYPE_NAME: String = "ColorFilter" + + public const val Color: String = "color" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/types/Color.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/types/Color.kt new file mode 100644 index 000000000..e7b85c7bf --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/types/Color.kt @@ -0,0 +1,5 @@ +package kotlin2.inputWithDefaultValueForEnum.expected.types + +public enum class Color { + red, +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/types/ColorFilter.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/types/ColorFilter.kt new file mode 100644 index 000000000..e5ef204e5 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/expected/types/ColorFilter.kt @@ -0,0 +1,7 @@ +package kotlin2.inputWithDefaultValueForEnum.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput + +public class ColorFilter( + public val color: Color? = default("color") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/schema.graphql new file mode 100644 index 000000000..ca2a46f39 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithDefaultValueForEnum/schema.graphql @@ -0,0 +1,7 @@ +enum Color { + red +} + +input ColorFilter { + color: Color = red +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/DgsClient.kt new file mode 100644 index 000000000..ad6b757dd --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.inputWithExtendedType.expected + +import kotlin.String +import kotlin2.inputWithExtendedType.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/DgsConstants.kt new file mode 100644 index 000000000..e2e993711 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/DgsConstants.kt @@ -0,0 +1,21 @@ +package kotlin2.inputWithExtendedType.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Movies: String = "movies" + } + + public object MOVIEFILTER { + public const val TYPE_NAME: String = "MovieFilter" + + public const val Genre: String = "genre" + + public const val ReleaseYear: String = "releaseYear" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/client/QueryProjection.kt new file mode 100644 index 000000000..4d8e1af43 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/client/QueryProjection.kt @@ -0,0 +1,12 @@ +package kotlin2.inputWithExtendedType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin2.inputWithExtendedType.expected.types.MovieFilter + +public class QueryProjection : GraphQLProjection() { + public fun movies(filter: MovieFilter? = default("filter")): QueryProjection { + val args = formatArgs("filter" to filter) + field("movies($args)") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/types/MovieFilter.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/types/MovieFilter.kt new file mode 100644 index 000000000..8d9d58edc --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/types/MovieFilter.kt @@ -0,0 +1,10 @@ +package kotlin2.inputWithExtendedType.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.Int +import kotlin.String + +public class MovieFilter( + public val genre: String? = default("genre"), + public val releaseYear: Int? = default("releaseYear") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/types/Query.kt new file mode 100644 index 000000000..593b58782 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/expected/types/Query.kt @@ -0,0 +1,42 @@ +package kotlin2.inputWithExtendedType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + movies: () -> List? = moviesDefault +) { + private val _movies: () -> List? = movies + + public val movies: List? + get() = _movies.invoke() + + public companion object { + private val moviesDefault: () -> List? = + { throw IllegalStateException("Field `movies` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var movies: () -> List? = moviesDefault + + @JsonProperty("movies") + public fun withMovies(movies: List?): Builder = this.apply { + this.movies = { movies } + } + + public fun build() = Query( + movies = movies, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/schema.graphql new file mode 100644 index 000000000..e35fc6c65 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/inputWithExtendedType/schema.graphql @@ -0,0 +1,11 @@ +type Query { + movies(filter: MovieFilter): [String] +} + +input MovieFilter { + genre: String +} + +extend input MovieFilter { + releaseYear: Int +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/DgsClient.kt new file mode 100644 index 000000000..a67b01f3e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.interfaceClassWithInterfaceFields.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/DgsConstants.kt new file mode 100644 index 000000000..799555c3e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/DgsConstants.kt @@ -0,0 +1,53 @@ +package kotlin2.interfaceClassWithInterfaceFields.expected + +import kotlin.String + +public object DgsConstants { + public object DOG { + public const val TYPE_NAME: String = "Dog" + + public const val Id: String = "id" + + public const val Name: String = "name" + + public const val Address: String = "address" + + public const val Mother: String = "mother" + + public const val Father: String = "father" + + public const val Parents: String = "parents" + } + + public object BIRD { + public const val TYPE_NAME: String = "Bird" + + public const val Id: String = "id" + + public const val Name: String = "name" + + public const val Address: String = "address" + + public const val Mother: String = "mother" + + public const val Father: String = "father" + + public const val Parents: String = "parents" + } + + public object PET { + public const val TYPE_NAME: String = "Pet" + + public const val Id: String = "id" + + public const val Name: String = "name" + + public const val Address: String = "address" + + public const val Mother: String = "mother" + + public const val Father: String = "father" + + public const val Parents: String = "parents" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/BirdProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/BirdProjection.kt new file mode 100644 index 000000000..9e9ba6033 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/BirdProjection.kt @@ -0,0 +1,38 @@ +package kotlin2.interfaceClassWithInterfaceFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class BirdProjection : GraphQLProjection() { + public val id: BirdProjection + get() { + field("id") + return this + } + + public val name: BirdProjection + get() { + field("name") + return this + } + + public val address: BirdProjection + get() { + field("address") + return this + } + + public fun mother(_projection: BirdProjection.() -> BirdProjection): BirdProjection { + project("mother", BirdProjection(), _projection) + return this + } + + public fun father(_projection: BirdProjection.() -> BirdProjection): BirdProjection { + project("father", BirdProjection(), _projection) + return this + } + + public fun parents(_projection: BirdProjection.() -> BirdProjection): BirdProjection { + project("parents", BirdProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/DogProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/DogProjection.kt new file mode 100644 index 000000000..60fbcdc7d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/DogProjection.kt @@ -0,0 +1,38 @@ +package kotlin2.interfaceClassWithInterfaceFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class DogProjection : GraphQLProjection() { + public val id: DogProjection + get() { + field("id") + return this + } + + public val name: DogProjection + get() { + field("name") + return this + } + + public val address: DogProjection + get() { + field("address") + return this + } + + public fun mother(_projection: DogProjection.() -> DogProjection): DogProjection { + project("mother", DogProjection(), _projection) + return this + } + + public fun father(_projection: DogProjection.() -> DogProjection): DogProjection { + project("father", DogProjection(), _projection) + return this + } + + public fun parents(_projection: DogProjection.() -> DogProjection): DogProjection { + project("parents", DogProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/PetProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/PetProjection.kt new file mode 100644 index 000000000..2939ce13b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/client/PetProjection.kt @@ -0,0 +1,48 @@ +package kotlin2.interfaceClassWithInterfaceFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PetProjection : GraphQLProjection() { + public val id: PetProjection + get() { + field("id") + return this + } + + public val name: PetProjection + get() { + field("name") + return this + } + + public val address: PetProjection + get() { + field("address") + return this + } + + public fun mother(_projection: PetProjection.() -> PetProjection): PetProjection { + project("mother", PetProjection(), _projection) + return this + } + + public fun father(_projection: PetProjection.() -> PetProjection): PetProjection { + project("father", PetProjection(), _projection) + return this + } + + public fun parents(_projection: PetProjection.() -> PetProjection): PetProjection { + project("parents", PetProjection(), _projection) + return this + } + + public fun onDog(_projection: DogProjection.() -> DogProjection): PetProjection { + project("... on Dog", DogProjection(), _projection) + return this + } + + public fun onBird(_projection: BirdProjection.() -> BirdProjection): PetProjection { + project("... on Bird", BirdProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Bird.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Bird.kt new file mode 100644 index 000000000..f4bfcea10 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Bird.kt @@ -0,0 +1,132 @@ +package kotlin2.interfaceClassWithInterfaceFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Bird.Builder::class) +public class Bird( + id: () -> String = idDefault, + name: () -> String? = nameDefault, + address: () -> List = addressDefault, + mother: () -> Bird = motherDefault, + father: () -> Bird? = fatherDefault, + parents: () -> List? = parentsDefault +) : Pet { + private val _id: () -> String = id + + private val _name: () -> String? = name + + private val _address: () -> List = address + + private val _mother: () -> Bird = mother + + private val _father: () -> Bird? = father + + private val _parents: () -> List? = parents + + public override val id: String + get() = _id.invoke() + + public override val name: String? + get() = _name.invoke() + + public override val address: List + get() = _address.invoke() + + public override val mother: Bird + get() = _mother.invoke() + + public override val father: Bird? + get() = _father.invoke() + + public override val parents: List? + get() = _parents.invoke() + + public companion object { + private val idDefault: () -> String = + { throw IllegalStateException("Field `id` was not requested") } + + + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + + private val addressDefault: () -> List = + { throw IllegalStateException("Field `address` was not requested") } + + + private val motherDefault: () -> Bird = + { throw IllegalStateException("Field `mother` was not requested") } + + + private val fatherDefault: () -> Bird? = + { throw IllegalStateException("Field `father` was not requested") } + + + private val parentsDefault: () -> List? = + { throw IllegalStateException("Field `parents` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var id: () -> String = idDefault + + private var name: () -> String? = nameDefault + + private var address: () -> List = addressDefault + + private var mother: () -> Bird = motherDefault + + private var father: () -> Bird? = fatherDefault + + private var parents: () -> List? = parentsDefault + + @JsonProperty("id") + public fun withId(id: String): Builder = this.apply { + this.id = { id } + } + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + @JsonProperty("address") + public fun withAddress(address: List): Builder = this.apply { + this.address = { address } + } + + @JsonProperty("mother") + public fun withMother(mother: Bird): Builder = this.apply { + this.mother = { mother } + } + + @JsonProperty("father") + public fun withFather(father: Bird?): Builder = this.apply { + this.father = { father } + } + + @JsonProperty("parents") + public fun withParents(parents: List?): Builder = this.apply { + this.parents = { parents } + } + + public fun build() = Bird( + id = id, + name = name, + address = address, + mother = mother, + father = father, + parents = parents, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Dog.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Dog.kt new file mode 100644 index 000000000..601da629b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Dog.kt @@ -0,0 +1,132 @@ +package kotlin2.interfaceClassWithInterfaceFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Dog.Builder::class) +public class Dog( + id: () -> String = idDefault, + name: () -> String? = nameDefault, + address: () -> List = addressDefault, + mother: () -> Dog = motherDefault, + father: () -> Dog? = fatherDefault, + parents: () -> List? = parentsDefault +) : Pet { + private val _id: () -> String = id + + private val _name: () -> String? = name + + private val _address: () -> List = address + + private val _mother: () -> Dog = mother + + private val _father: () -> Dog? = father + + private val _parents: () -> List? = parents + + public override val id: String + get() = _id.invoke() + + public override val name: String? + get() = _name.invoke() + + public override val address: List + get() = _address.invoke() + + public override val mother: Dog + get() = _mother.invoke() + + public override val father: Dog? + get() = _father.invoke() + + public override val parents: List? + get() = _parents.invoke() + + public companion object { + private val idDefault: () -> String = + { throw IllegalStateException("Field `id` was not requested") } + + + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + + private val addressDefault: () -> List = + { throw IllegalStateException("Field `address` was not requested") } + + + private val motherDefault: () -> Dog = + { throw IllegalStateException("Field `mother` was not requested") } + + + private val fatherDefault: () -> Dog? = + { throw IllegalStateException("Field `father` was not requested") } + + + private val parentsDefault: () -> List? = + { throw IllegalStateException("Field `parents` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var id: () -> String = idDefault + + private var name: () -> String? = nameDefault + + private var address: () -> List = addressDefault + + private var mother: () -> Dog = motherDefault + + private var father: () -> Dog? = fatherDefault + + private var parents: () -> List? = parentsDefault + + @JsonProperty("id") + public fun withId(id: String): Builder = this.apply { + this.id = { id } + } + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + @JsonProperty("address") + public fun withAddress(address: List): Builder = this.apply { + this.address = { address } + } + + @JsonProperty("mother") + public fun withMother(mother: Dog): Builder = this.apply { + this.mother = { mother } + } + + @JsonProperty("father") + public fun withFather(father: Dog?): Builder = this.apply { + this.father = { father } + } + + @JsonProperty("parents") + public fun withParents(parents: List?): Builder = this.apply { + this.parents = { parents } + } + + public fun build() = Dog( + id = id, + name = name, + address = address, + mother = mother, + father = father, + parents = parents, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Pet.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Pet.kt new file mode 100644 index 000000000..24e194b13 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/expected/types/Pet.kt @@ -0,0 +1,29 @@ +package kotlin2.interfaceClassWithInterfaceFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Dog::class, name = "Dog"), + JsonSubTypes.Type(value = Bird::class, name = "Bird") +]) +public sealed interface Pet { + public val id: String + + public val name: String? + + public val address: List + + public val mother: Pet + + public val father: Pet? + + public val parents: List? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/schema.graphql new file mode 100644 index 000000000..d693365d3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFields/schema.graphql @@ -0,0 +1,24 @@ +interface Pet { + id: ID! + name: String + address: [String!]! + mother: Pet! + father: Pet + parents: [Pet] +} +type Dog implements Pet { + id: ID! + name: String + address: [String!]! + mother: Dog! + father: Dog + parents: [Dog] +} +type Bird implements Pet { + id: ID! + name: String + address: [String!]! + mother: Bird! + father: Bird + parents: [Bird] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/DgsClient.kt new file mode 100644 index 000000000..029ab81d6 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/DgsConstants.kt new file mode 100644 index 000000000..93ca93ea2 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/DgsConstants.kt @@ -0,0 +1,35 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected + +import kotlin.String + +public object DgsConstants { + public object VEGETARIAN { + public const val TYPE_NAME: String = "Vegetarian" + + public const val Calories: String = "calories" + + public const val Vegetables: String = "vegetables" + } + + public object DOG { + public const val TYPE_NAME: String = "Dog" + + public const val Name: String = "name" + + public const val Diet: String = "diet" + } + + public object PET { + public const val TYPE_NAME: String = "Pet" + + public const val Name: String = "name" + + public const val Diet: String = "diet" + } + + public object DIET { + public const val TYPE_NAME: String = "Diet" + + public const val Calories: String = "calories" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/DietProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/DietProjection.kt new file mode 100644 index 000000000..e27dbd0c2 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/DietProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class DietProjection : GraphQLProjection() { + public val calories: DietProjection + get() { + field("calories") + return this + } + + public fun onVegetarian(_projection: VegetarianProjection.() -> VegetarianProjection): + DietProjection { + project("... on Vegetarian", VegetarianProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/DogProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/DogProjection.kt new file mode 100644 index 000000000..bcfa997db --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/DogProjection.kt @@ -0,0 +1,16 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class DogProjection : GraphQLProjection() { + public val name: DogProjection + get() { + field("name") + return this + } + + public fun diet(_projection: VegetarianProjection.() -> VegetarianProjection): DogProjection { + project("diet", VegetarianProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/PetProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/PetProjection.kt new file mode 100644 index 000000000..c2cdf55f0 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/PetProjection.kt @@ -0,0 +1,21 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PetProjection : GraphQLProjection() { + public val name: PetProjection + get() { + field("name") + return this + } + + public fun diet(_projection: DietProjection.() -> DietProjection): PetProjection { + project("diet", DietProjection(), _projection) + return this + } + + public fun onDog(_projection: DogProjection.() -> DogProjection): PetProjection { + project("... on Dog", DogProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/VegetarianProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/VegetarianProjection.kt new file mode 100644 index 000000000..fd482f3f4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/client/VegetarianProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class VegetarianProjection : GraphQLProjection() { + public val calories: VegetarianProjection + get() { + field("calories") + return this + } + + public val vegetables: VegetarianProjection + get() { + field("vegetables") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Diet.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Diet.kt new file mode 100644 index 000000000..b9d5b6ff4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Diet.kt @@ -0,0 +1,17 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Vegetarian::class, name = "Vegetarian") +]) +public sealed interface Diet { + public val calories: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Dog.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Dog.kt new file mode 100644 index 000000000..c9c880428 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Dog.kt @@ -0,0 +1,59 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Dog.Builder::class) +public class Dog( + name: () -> String? = nameDefault, + diet: () -> Vegetarian? = dietDefault +) : Pet { + private val _name: () -> String? = name + + private val _diet: () -> Vegetarian? = diet + + public override val name: String? + get() = _name.invoke() + + public override val diet: Vegetarian? + get() = _diet.invoke() + + public companion object { + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + + private val dietDefault: () -> Vegetarian? = + { throw IllegalStateException("Field `diet` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String? = nameDefault + + private var diet: () -> Vegetarian? = dietDefault + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + @JsonProperty("diet") + public fun withDiet(diet: Vegetarian?): Builder = this.apply { + this.diet = { diet } + } + + public fun build() = Dog( + name = name, + diet = diet, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Pet.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Pet.kt new file mode 100644 index 000000000..f6274581f --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Pet.kt @@ -0,0 +1,19 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Dog::class, name = "Dog") +]) +public sealed interface Pet { + public val name: String? + + public val diet: Diet? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Vegetarian.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Vegetarian.kt new file mode 100644 index 000000000..cb2ee4b58 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/expected/types/Vegetarian.kt @@ -0,0 +1,60 @@ +package kotlin2.interfaceClassWithInterfaceFieldsOfDifferentType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Vegetarian.Builder::class) +public class Vegetarian( + calories: () -> String? = caloriesDefault, + vegetables: () -> List? = vegetablesDefault +) : Diet { + private val _calories: () -> String? = calories + + private val _vegetables: () -> List? = vegetables + + public override val calories: String? + get() = _calories.invoke() + + public val vegetables: List? + get() = _vegetables.invoke() + + public companion object { + private val caloriesDefault: () -> String? = + { throw IllegalStateException("Field `calories` was not requested") } + + + private val vegetablesDefault: () -> List? = + { throw IllegalStateException("Field `vegetables` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var calories: () -> String? = caloriesDefault + + private var vegetables: () -> List? = vegetablesDefault + + @JsonProperty("calories") + public fun withCalories(calories: String?): Builder = this.apply { + this.calories = { calories } + } + + @JsonProperty("vegetables") + public fun withVegetables(vegetables: List?): Builder = this.apply { + this.vegetables = { vegetables } + } + + public fun build() = Vegetarian( + calories = calories, + vegetables = vegetables, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/schema.graphql new file mode 100644 index 000000000..a7879549b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithInterfaceFieldsOfDifferentType/schema.graphql @@ -0,0 +1,18 @@ +interface Pet { + name: String + diet: Diet +} + +interface Diet { + calories: String +} + +type Vegetarian implements Diet { + calories: String + vegetables: [String] +} + +type Dog implements Pet { + name: String + diet: Vegetarian +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/DgsClient.kt new file mode 100644 index 000000000..53f327390 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.interfaceClassWithNonNullableFields.expected + +import kotlin.String +import kotlin2.interfaceClassWithNonNullableFields.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/DgsConstants.kt new file mode 100644 index 000000000..be2ecc959 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/DgsConstants.kt @@ -0,0 +1,31 @@ +package kotlin2.interfaceClassWithNonNullableFields.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val People: String = "people" + } + + public object EMPLOYEE { + public const val TYPE_NAME: String = "Employee" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + + public const val Company: String = "company" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + + public const val Lastname: String = "lastname" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/EmployeeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/EmployeeProjection.kt new file mode 100644 index 000000000..77a8879f9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/EmployeeProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.interfaceClassWithNonNullableFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class EmployeeProjection : GraphQLProjection() { + public val firstname: EmployeeProjection + get() { + field("firstname") + return this + } + + public val lastname: EmployeeProjection + get() { + field("lastname") + return this + } + + public val company: EmployeeProjection + get() { + field("company") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/PersonProjection.kt new file mode 100644 index 000000000..d32fb8053 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/PersonProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.interfaceClassWithNonNullableFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public val lastname: PersonProjection + get() { + field("lastname") + return this + } + + public fun onEmployee(_projection: EmployeeProjection.() -> EmployeeProjection): + PersonProjection { + project("... on Employee", EmployeeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/QueryProjection.kt new file mode 100644 index 000000000..adc77c2ca --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.interfaceClassWithNonNullableFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Employee.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Employee.kt new file mode 100644 index 000000000..cdc544c30 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Employee.kt @@ -0,0 +1,77 @@ +package kotlin2.interfaceClassWithNonNullableFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Employee.Builder::class) +public class Employee( + firstname: () -> String = firstnameDefault, + lastname: () -> String? = lastnameDefault, + company: () -> String? = companyDefault +) : Person { + private val _firstname: () -> String = firstname + + private val _lastname: () -> String? = lastname + + private val _company: () -> String? = company + + public override val firstname: String + get() = _firstname.invoke() + + public override val lastname: String? + get() = _lastname.invoke() + + public val company: String? + get() = _company.invoke() + + public companion object { + private val firstnameDefault: () -> String = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val lastnameDefault: () -> String? = + { throw IllegalStateException("Field `lastname` was not requested") } + + + private val companyDefault: () -> String? = + { throw IllegalStateException("Field `company` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String = firstnameDefault + + private var lastname: () -> String? = lastnameDefault + + private var company: () -> String? = companyDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("lastname") + public fun withLastname(lastname: String?): Builder = this.apply { + this.lastname = { lastname } + } + + @JsonProperty("company") + public fun withCompany(company: String?): Builder = this.apply { + this.company = { company } + } + + public fun build() = Employee( + firstname = firstname, + lastname = lastname, + company = company, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Person.kt new file mode 100644 index 000000000..090c7efa3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Person.kt @@ -0,0 +1,19 @@ +package kotlin2.interfaceClassWithNonNullableFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Employee::class, name = "Employee") +]) +public sealed interface Person { + public val firstname: String + + public val lastname: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Query.kt new file mode 100644 index 000000000..70dc9e28a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.interfaceClassWithNonNullableFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + people: () -> List? = peopleDefault +) { + private val _people: () -> List? = people + + public val people: List? + get() = _people.invoke() + + public companion object { + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var people: () -> List? = peopleDefault + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/schema.graphql new file mode 100644 index 000000000..d636b284c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceClassWithNonNullableFields/schema.graphql @@ -0,0 +1,14 @@ +type Query { + people: [Person] +} + +interface Person { + firstname: String! + lastname: String +} + +type Employee implements Person { + firstname: String! + lastname: String + company: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/DgsClient.kt new file mode 100644 index 000000000..513465361 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.interfaceDocs.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/DgsConstants.kt new file mode 100644 index 000000000..99d14ae91 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/DgsConstants.kt @@ -0,0 +1,11 @@ +package kotlin2.interfaceDocs.expected + +import kotlin.String + +public object DgsConstants { + public object TITLED { + public const val TYPE_NAME: String = "Titled" + + public const val Title: String = "title" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/client/TitledProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/client/TitledProjection.kt new file mode 100644 index 000000000..f9b0fce7f --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/client/TitledProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.interfaceDocs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class TitledProjection : GraphQLProjection() { + public val title: TitledProjection + get() { + field("title") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/types/Titled.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/types/Titled.kt new file mode 100644 index 000000000..f11d64aa7 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/expected/types/Titled.kt @@ -0,0 +1,16 @@ +package kotlin2.interfaceDocs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +/** + * Anything with a title! + */ +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +public sealed interface Titled { + public val title: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/schema.graphql new file mode 100644 index 000000000..6f701ed77 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceDocs/schema.graphql @@ -0,0 +1,6 @@ +""" +Anything with a title! +""" +interface Titled { + title: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/DgsClient.kt new file mode 100644 index 000000000..f54ef9e6d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.interfaceFieldsDocs.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/DgsConstants.kt new file mode 100644 index 000000000..8b8692e61 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/DgsConstants.kt @@ -0,0 +1,11 @@ +package kotlin2.interfaceFieldsDocs.expected + +import kotlin.String + +public object DgsConstants { + public object TITLED { + public const val TYPE_NAME: String = "Titled" + + public const val Title: String = "title" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/client/TitledProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/client/TitledProjection.kt new file mode 100644 index 000000000..31e3cd2cd --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/client/TitledProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.interfaceFieldsDocs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class TitledProjection : GraphQLProjection() { + public val title: TitledProjection + get() { + field("title") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/types/Titled.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/types/Titled.kt new file mode 100644 index 000000000..0c8bdd0c2 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/expected/types/Titled.kt @@ -0,0 +1,16 @@ +package kotlin2.interfaceFieldsDocs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +public sealed interface Titled { + /** + * The original, non localized title. + */ + public val title: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/schema.graphql new file mode 100644 index 000000000..7effcb9df --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceFieldsDocs/schema.graphql @@ -0,0 +1,6 @@ +interface Titled { + """ + The original, non localized title. + """ + title: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/DgsClient.kt new file mode 100644 index 000000000..a88891df1 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected + +import kotlin.String +import kotlin2.interfaceWithInterfaceInheritance.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/DgsConstants.kt new file mode 100644 index 000000000..ebe6c3399 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/DgsConstants.kt @@ -0,0 +1,33 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Fruits: String = "fruits" + } + + public object SEED { + public const val TYPE_NAME: String = "Seed" + + public const val Name: String = "name" + } + + public object FRUIT { + public const val TYPE_NAME: String = "Fruit" + + public const val Seeds: String = "seeds" + } + + public object STONEFRUIT { + public const val TYPE_NAME: String = "StoneFruit" + + public const val Seeds: String = "seeds" + + public const val Fuzzy: String = "fuzzy" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/FruitProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/FruitProjection.kt new file mode 100644 index 000000000..46a257f18 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/FruitProjection.kt @@ -0,0 +1,16 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class FruitProjection : GraphQLProjection() { + public fun seeds(_projection: SeedProjection.() -> SeedProjection): FruitProjection { + project("seeds", SeedProjection(), _projection) + return this + } + + public fun onStoneFruit(_projection: StoneFruitProjection.() -> StoneFruitProjection): + FruitProjection { + project("... on StoneFruit", StoneFruitProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/QueryProjection.kt new file mode 100644 index 000000000..6943d2c4a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/QueryProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun fruits(_projection: FruitProjection.() -> FruitProjection): QueryProjection { + project("fruits", FruitProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/SeedProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/SeedProjection.kt new file mode 100644 index 000000000..a285880eb --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/SeedProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class SeedProjection : GraphQLProjection() { + public val name: SeedProjection + get() { + field("name") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/StoneFruitProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/StoneFruitProjection.kt new file mode 100644 index 000000000..9573b0e6d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/client/StoneFruitProjection.kt @@ -0,0 +1,16 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class StoneFruitProjection : GraphQLProjection() { + public val fuzzy: StoneFruitProjection + get() { + field("fuzzy") + return this + } + + public fun seeds(_projection: SeedProjection.() -> SeedProjection): StoneFruitProjection { + project("seeds", SeedProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Fruit.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Fruit.kt new file mode 100644 index 000000000..21283ceca --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Fruit.kt @@ -0,0 +1,13 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected.types + +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.collections.List + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +public sealed interface Fruit { + public val seeds: List? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Query.kt new file mode 100644 index 000000000..33f89b823 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + fruits: () -> List? = fruitsDefault +) { + private val _fruits: () -> List? = fruits + + public val fruits: List? + get() = _fruits.invoke() + + public companion object { + private val fruitsDefault: () -> List? = + { throw IllegalStateException("Field `fruits` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var fruits: () -> List? = fruitsDefault + + @JsonProperty("fruits") + public fun withFruits(fruits: List?): Builder = this.apply { + this.fruits = { fruits } + } + + public fun build() = Query( + fruits = fruits, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Seed.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Seed.kt new file mode 100644 index 000000000..90c81e657 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/Seed.kt @@ -0,0 +1,41 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Seed.Builder::class) +public class Seed( + name: () -> String? = nameDefault +) { + private val _name: () -> String? = name + + public val name: String? + get() = _name.invoke() + + public companion object { + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String? = nameDefault + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + public fun build() = Seed( + name = name, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/StoneFruit.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/StoneFruit.kt new file mode 100644 index 000000000..132ff8a1e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/expected/types/StoneFruit.kt @@ -0,0 +1,16 @@ +package kotlin2.interfaceWithInterfaceInheritance.expected.types + +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.Boolean +import kotlin.collections.List + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +public sealed interface StoneFruit : Fruit { + public override val seeds: List? + + public val fuzzy: Boolean? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/schema.graphql new file mode 100644 index 000000000..40b9ae6da --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/interfaceWithInterfaceInheritance/schema.graphql @@ -0,0 +1,16 @@ +type Query { + fruits: [Fruit] +} + +type Seed { + name: String +} + +interface Fruit { + seeds: [Seed] +} + +interface StoneFruit implements Fruit { + seeds: [Seed] + fuzzy: Boolean +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/DgsClient.kt new file mode 100644 index 000000000..496ac4bc3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.projectionWithEnum.expected + +import kotlin.String +import kotlin2.projectionWithEnum.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/DgsConstants.kt new file mode 100644 index 000000000..9f7134670 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/DgsConstants.kt @@ -0,0 +1,15 @@ +package kotlin2.projectionWithEnum.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val E: String = "e" + + public const val Es: String = "es" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/client/QueryProjection.kt new file mode 100644 index 000000000..921fd3fd7 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/client/QueryProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithEnum.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public val e: QueryProjection + get() { + field("e") + return this + } + + public val es: QueryProjection + get() { + field("es") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/types/E.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/types/E.kt new file mode 100644 index 000000000..86c646d93 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/types/E.kt @@ -0,0 +1,5 @@ +package kotlin2.projectionWithEnum.expected.types + +public enum class E { + V, +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/types/Query.kt new file mode 100644 index 000000000..f21356892 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/expected/types/Query.kt @@ -0,0 +1,59 @@ +package kotlin2.projectionWithEnum.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + e: () -> E? = eDefault, + es: () -> List? = esDefault +) { + private val _e: () -> E? = e + + private val _es: () -> List? = es + + public val e: E? + get() = _e.invoke() + + public val es: List? + get() = _es.invoke() + + public companion object { + private val eDefault: () -> E? = + { throw IllegalStateException("Field `e` was not requested") } + + + private val esDefault: () -> List? = + { throw IllegalStateException("Field `es` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var e: () -> E? = eDefault + + private var es: () -> List? = esDefault + + @JsonProperty("e") + public fun withE(e: E?): Builder = this.apply { + this.e = { e } + } + + @JsonProperty("es") + public fun withEs(es: List?): Builder = this.apply { + this.es = { es } + } + + public fun build() = Query( + e = e, + es = es, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/schema.graphql new file mode 100644 index 000000000..3792f03a9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithEnum/schema.graphql @@ -0,0 +1,8 @@ +type Query { + e: E + es: [E] +} + +enum E { + V +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/DgsClient.kt new file mode 100644 index 000000000..0e513ace5 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.projectionWithPrimitiveAndArgs.expected + +import kotlin.String +import kotlin2.projectionWithPrimitiveAndArgs.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/DgsConstants.kt new file mode 100644 index 000000000..9ce9860d4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/DgsConstants.kt @@ -0,0 +1,19 @@ +package kotlin2.projectionWithPrimitiveAndArgs.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val String: String = "string" + } + + public object I { + public const val TYPE_NAME: String = "I" + + public const val Arg: String = "arg" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/client/QueryProjection.kt new file mode 100644 index 000000000..fa79ea30b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/client/QueryProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithPrimitiveAndArgs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin.String +import kotlin2.projectionWithPrimitiveAndArgs.expected.types.I + +public class QueryProjection : GraphQLProjection() { + public fun string( + a1: String? = default("a1"), + a2: String, + a3: I? = default("a3") + ): QueryProjection { + val args = formatArgs("a1" to a1, "a2" to a2, "a3" to a3) + field("string($args)") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/types/I.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/types/I.kt new file mode 100644 index 000000000..c3ace45ef --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/types/I.kt @@ -0,0 +1,8 @@ +package kotlin2.projectionWithPrimitiveAndArgs.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.String + +public class I( + public val arg: String? = default("arg") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/types/Query.kt new file mode 100644 index 000000000..7f04bed14 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.projectionWithPrimitiveAndArgs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + string: () -> String? = stringDefault +) { + private val _string: () -> String? = string + + public val string: String? + get() = _string.invoke() + + public companion object { + private val stringDefault: () -> String? = + { throw IllegalStateException("Field `string` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var string: () -> String? = stringDefault + + @JsonProperty("string") + public fun withString(string: String?): Builder = this.apply { + this.string = { string } + } + + public fun build() = Query( + string = string, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/schema.graphql new file mode 100644 index 000000000..fe2fcc911 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitiveAndArgs/schema.graphql @@ -0,0 +1,7 @@ +type Query { + string(a1: String, a2: String!, a3: I): String +} + +input I { + arg: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/DgsClient.kt new file mode 100644 index 000000000..27af7052a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.projectionWithPrimitives.expected + +import kotlin.String +import kotlin2.projectionWithPrimitives.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/DgsConstants.kt new file mode 100644 index 000000000..4ef8509d2 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/DgsConstants.kt @@ -0,0 +1,15 @@ +package kotlin2.projectionWithPrimitives.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val String: String = "string" + + public const val Strings: String = "strings" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/client/QueryProjection.kt new file mode 100644 index 000000000..1f5f02278 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/client/QueryProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithPrimitives.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public val string: QueryProjection + get() { + field("string") + return this + } + + public val strings: QueryProjection + get() { + field("strings") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/types/Query.kt new file mode 100644 index 000000000..6201db435 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/expected/types/Query.kt @@ -0,0 +1,60 @@ +package kotlin2.projectionWithPrimitives.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + string: () -> String? = stringDefault, + strings: () -> List? = stringsDefault +) { + private val _string: () -> String? = string + + private val _strings: () -> List? = strings + + public val string: String? + get() = _string.invoke() + + public val strings: List? + get() = _strings.invoke() + + public companion object { + private val stringDefault: () -> String? = + { throw IllegalStateException("Field `string` was not requested") } + + + private val stringsDefault: () -> List? = + { throw IllegalStateException("Field `strings` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var string: () -> String? = stringDefault + + private var strings: () -> List? = stringsDefault + + @JsonProperty("string") + public fun withString(string: String?): Builder = this.apply { + this.string = { string } + } + + @JsonProperty("strings") + public fun withStrings(strings: List?): Builder = this.apply { + this.strings = { strings } + } + + public fun build() = Query( + string = string, + strings = strings, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/schema.graphql new file mode 100644 index 000000000..4139076b9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithPrimitives/schema.graphql @@ -0,0 +1,4 @@ +type Query { + string: String + strings: [String] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/DgsClient.kt new file mode 100644 index 000000000..a6d6573b6 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.projectionWithType.expected + +import kotlin.String +import kotlin2.projectionWithType.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/DgsConstants.kt new file mode 100644 index 000000000..801a0b1b4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/DgsConstants.kt @@ -0,0 +1,29 @@ +package kotlin2.projectionWithType.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Person: String = "person" + + public const val People: String = "people" + } + + public object EMPLOYEE { + public const val TYPE_NAME: String = "Employee" + + public const val Firstname: String = "firstname" + + public const val Company: String = "company" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/EmployeeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/EmployeeProjection.kt new file mode 100644 index 000000000..a7ec58e40 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/EmployeeProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class EmployeeProjection : GraphQLProjection() { + public val firstname: EmployeeProjection + get() { + field("firstname") + return this + } + + public val company: EmployeeProjection + get() { + field("company") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/PersonProjection.kt new file mode 100644 index 000000000..b657b7c08 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public fun onEmployee(_projection: EmployeeProjection.() -> EmployeeProjection): + PersonProjection { + project("... on Employee", EmployeeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/QueryProjection.kt new file mode 100644 index 000000000..47b65f28d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/client/QueryProjection.kt @@ -0,0 +1,15 @@ +package kotlin2.projectionWithType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun person(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("person", PersonProjection(), _projection) + return this + } + + public fun people(_projection: PersonProjection.() -> PersonProjection): QueryProjection { + project("people", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Employee.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Employee.kt new file mode 100644 index 000000000..dee8adada --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Employee.kt @@ -0,0 +1,59 @@ +package kotlin2.projectionWithType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Employee.Builder::class) +public class Employee( + firstname: () -> String? = firstnameDefault, + company: () -> String? = companyDefault +) : Person { + private val _firstname: () -> String? = firstname + + private val _company: () -> String? = company + + public override val firstname: String? + get() = _firstname.invoke() + + public val company: String? + get() = _company.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val companyDefault: () -> String? = + { throw IllegalStateException("Field `company` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var company: () -> String? = companyDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("company") + public fun withCompany(company: String?): Builder = this.apply { + this.company = { company } + } + + public fun build() = Employee( + firstname = firstname, + company = company, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Person.kt new file mode 100644 index 000000000..0cb71c219 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Person.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Employee::class, name = "Employee") +]) +public sealed interface Person { + public val firstname: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Query.kt new file mode 100644 index 000000000..e90325c4e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/expected/types/Query.kt @@ -0,0 +1,59 @@ +package kotlin2.projectionWithType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + person: () -> Person? = personDefault, + people: () -> List? = peopleDefault +) { + private val _person: () -> Person? = person + + private val _people: () -> List? = people + + public val person: Person? + get() = _person.invoke() + + public val people: List? + get() = _people.invoke() + + public companion object { + private val personDefault: () -> Person? = + { throw IllegalStateException("Field `person` was not requested") } + + + private val peopleDefault: () -> List? = + { throw IllegalStateException("Field `people` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var person: () -> Person? = personDefault + + private var people: () -> List? = peopleDefault + + @JsonProperty("person") + public fun withPerson(person: Person?): Builder = this.apply { + this.person = { person } + } + + @JsonProperty("people") + public fun withPeople(people: List?): Builder = this.apply { + this.people = { people } + } + + public fun build() = Query( + person = person, + people = people, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/schema.graphql new file mode 100644 index 000000000..cfc6cbb60 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithType/schema.graphql @@ -0,0 +1,13 @@ +type Query { + person: Person + people: [Person] +} + +interface Person { + firstname: String +} + +type Employee implements Person { + firstname: String + company: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/DgsClient.kt new file mode 100644 index 000000000..2392af98c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.projectionWithTypeAndArgs.expected + +import kotlin.String +import kotlin2.projectionWithTypeAndArgs.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/DgsConstants.kt new file mode 100644 index 000000000..5018eda13 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/DgsConstants.kt @@ -0,0 +1,33 @@ +package kotlin2.projectionWithTypeAndArgs.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Person: String = "person" + } + + public object EMPLOYEE { + public const val TYPE_NAME: String = "Employee" + + public const val Firstname: String = "firstname" + + public const val Company: String = "company" + } + + public object I { + public const val TYPE_NAME: String = "I" + + public const val Arg: String = "arg" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/EmployeeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/EmployeeProjection.kt new file mode 100644 index 000000000..010dc50b0 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/EmployeeProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithTypeAndArgs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class EmployeeProjection : GraphQLProjection() { + public val firstname: EmployeeProjection + get() { + field("firstname") + return this + } + + public val company: EmployeeProjection + get() { + field("company") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/PersonProjection.kt new file mode 100644 index 000000000..cf475756a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithTypeAndArgs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public fun onEmployee(_projection: EmployeeProjection.() -> EmployeeProjection): + PersonProjection { + project("... on Employee", EmployeeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/QueryProjection.kt new file mode 100644 index 000000000..5240f602d --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/client/QueryProjection.kt @@ -0,0 +1,18 @@ +package kotlin2.projectionWithTypeAndArgs.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin.String +import kotlin2.projectionWithTypeAndArgs.expected.types.I + +public class QueryProjection : GraphQLProjection() { + public fun person( + a1: String? = default("a1"), + a2: String, + a3: I? = default("a3"), + _projection: PersonProjection.() -> PersonProjection + ): QueryProjection { + val args = formatArgs("a1" to a1, "a2" to a2, "a3" to a3) + project("person($args)", PersonProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Employee.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Employee.kt new file mode 100644 index 000000000..d83179c66 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Employee.kt @@ -0,0 +1,59 @@ +package kotlin2.projectionWithTypeAndArgs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Employee.Builder::class) +public class Employee( + firstname: () -> String? = firstnameDefault, + company: () -> String? = companyDefault +) : Person { + private val _firstname: () -> String? = firstname + + private val _company: () -> String? = company + + public override val firstname: String? + get() = _firstname.invoke() + + public val company: String? + get() = _company.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val companyDefault: () -> String? = + { throw IllegalStateException("Field `company` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var company: () -> String? = companyDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("company") + public fun withCompany(company: String?): Builder = this.apply { + this.company = { company } + } + + public fun build() = Employee( + firstname = firstname, + company = company, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/I.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/I.kt new file mode 100644 index 000000000..8772cd4f9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/I.kt @@ -0,0 +1,8 @@ +package kotlin2.projectionWithTypeAndArgs.expected.types + +import com.netflix.graphql.dgs.client.codegen.GraphQLInput +import kotlin.String + +public class I( + public val arg: String? = default("arg") +) : GraphQLInput() diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Person.kt new file mode 100644 index 000000000..e0fe6cdca --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Person.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithTypeAndArgs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Employee::class, name = "Employee") +]) +public sealed interface Person { + public val firstname: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Query.kt new file mode 100644 index 000000000..f7c7da77e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/expected/types/Query.kt @@ -0,0 +1,40 @@ +package kotlin2.projectionWithTypeAndArgs.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + person: () -> Person? = personDefault +) { + private val _person: () -> Person? = person + + public val person: Person? + get() = _person.invoke() + + public companion object { + private val personDefault: () -> Person? = + { throw IllegalStateException("Field `person` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var person: () -> Person? = personDefault + + @JsonProperty("person") + public fun withPerson(person: Person?): Builder = this.apply { + this.person = { person } + } + + public fun build() = Query( + person = person, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/schema.graphql new file mode 100644 index 000000000..fc06af865 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithTypeAndArgs/schema.graphql @@ -0,0 +1,16 @@ +type Query { + person(a1: String, a2: String!, a3: I): Person +} + +interface Person { + firstname: String +} + +type Employee implements Person { + firstname: String + company: String +} + +input I { + arg: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/DgsClient.kt new file mode 100644 index 000000000..b9ae9fe87 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.projectionWithUnion.expected + +import kotlin.String +import kotlin2.projectionWithUnion.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/DgsConstants.kt new file mode 100644 index 000000000..2408970de --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/DgsConstants.kt @@ -0,0 +1,33 @@ +package kotlin2.projectionWithUnion.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val U: String = "u" + + public const val Us: String = "us" + } + + public object EMPLOYEE { + public const val TYPE_NAME: String = "Employee" + + public const val Firstname: String = "firstname" + + public const val Company: String = "company" + } + + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Firstname: String = "firstname" + } + + public object U { + public const val TYPE_NAME: String = "U" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/EmployeeProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/EmployeeProjection.kt new file mode 100644 index 000000000..f8673e5a4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/EmployeeProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithUnion.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class EmployeeProjection : GraphQLProjection() { + public val firstname: EmployeeProjection + get() { + field("firstname") + return this + } + + public val company: EmployeeProjection + get() { + field("company") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/PersonProjection.kt new file mode 100644 index 000000000..d6ac2039e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/PersonProjection.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithUnion.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val firstname: PersonProjection + get() { + field("firstname") + return this + } + + public fun onEmployee(_projection: EmployeeProjection.() -> EmployeeProjection): + PersonProjection { + project("... on Employee", EmployeeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/QueryProjection.kt new file mode 100644 index 000000000..1234dc7c8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/QueryProjection.kt @@ -0,0 +1,15 @@ +package kotlin2.projectionWithUnion.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun u(_projection: UProjection.() -> UProjection): QueryProjection { + project("u", UProjection(), _projection) + return this + } + + public fun us(_projection: UProjection.() -> UProjection): QueryProjection { + project("us", UProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/UProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/UProjection.kt new file mode 100644 index 000000000..69414dc30 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/client/UProjection.kt @@ -0,0 +1,10 @@ +package kotlin2.projectionWithUnion.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class UProjection : GraphQLProjection() { + public fun onEmployee(_projection: EmployeeProjection.() -> EmployeeProjection): UProjection { + project("... on Employee", EmployeeProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Employee.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Employee.kt new file mode 100644 index 000000000..f972d35e5 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Employee.kt @@ -0,0 +1,59 @@ +package kotlin2.projectionWithUnion.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Employee.Builder::class) +public class Employee( + firstname: () -> String? = firstnameDefault, + company: () -> String? = companyDefault +) : Person, U { + private val _firstname: () -> String? = firstname + + private val _company: () -> String? = company + + public override val firstname: String? + get() = _firstname.invoke() + + public val company: String? + get() = _company.invoke() + + public companion object { + private val firstnameDefault: () -> String? = + { throw IllegalStateException("Field `firstname` was not requested") } + + + private val companyDefault: () -> String? = + { throw IllegalStateException("Field `company` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var firstname: () -> String? = firstnameDefault + + private var company: () -> String? = companyDefault + + @JsonProperty("firstname") + public fun withFirstname(firstname: String?): Builder = this.apply { + this.firstname = { firstname } + } + + @JsonProperty("company") + public fun withCompany(company: String?): Builder = this.apply { + this.company = { company } + } + + public fun build() = Employee( + firstname = firstname, + company = company, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Person.kt new file mode 100644 index 000000000..439c5db7c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Person.kt @@ -0,0 +1,17 @@ +package kotlin2.projectionWithUnion.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Employee::class, name = "Employee") +]) +public sealed interface Person { + public val firstname: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Query.kt new file mode 100644 index 000000000..aafb8ad78 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/Query.kt @@ -0,0 +1,59 @@ +package kotlin2.projectionWithUnion.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + u: () -> U? = uDefault, + us: () -> List? = usDefault +) { + private val _u: () -> U? = u + + private val _us: () -> List? = us + + public val u: U? + get() = _u.invoke() + + public val us: List? + get() = _us.invoke() + + public companion object { + private val uDefault: () -> U? = + { throw IllegalStateException("Field `u` was not requested") } + + + private val usDefault: () -> List? = + { throw IllegalStateException("Field `us` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var u: () -> U? = uDefault + + private var us: () -> List? = usDefault + + @JsonProperty("u") + public fun withU(u: U?): Builder = this.apply { + this.u = { u } + } + + @JsonProperty("us") + public fun withUs(us: List?): Builder = this.apply { + this.us = { us } + } + + public fun build() = Query( + u = u, + us = us, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/U.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/U.kt new file mode 100644 index 000000000..a9998247a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/expected/types/U.kt @@ -0,0 +1,14 @@ +package kotlin2.projectionWithUnion.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Employee::class, name = "Employee") +]) +public sealed interface U diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/schema.graphql new file mode 100644 index 000000000..4ace41ccf --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/projectionWithUnion/schema.graphql @@ -0,0 +1,15 @@ +type Query { + u: U + us: [U] +} + +interface Person { + firstname: String +} + +type Employee implements Person { + firstname: String + company: String +} + +union U = Employee diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/DgsClient.kt new file mode 100644 index 000000000..b53816938 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.skipCodegenOnFields.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/DgsConstants.kt new file mode 100644 index 000000000..89e962685 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/DgsConstants.kt @@ -0,0 +1,13 @@ +package kotlin2.skipCodegenOnFields.expected + +import kotlin.String + +public object DgsConstants { + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Name: String = "name" + + public const val Email: String = "email" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/client/PersonProjection.kt new file mode 100644 index 000000000..4ad420567 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/client/PersonProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.skipCodegenOnFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val name: PersonProjection + get() { + field("name") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/types/Person.kt new file mode 100644 index 000000000..473b3b091 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/expected/types/Person.kt @@ -0,0 +1,41 @@ +package kotlin2.skipCodegenOnFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + name: () -> String? = nameDefault +) { + private val _name: () -> String? = name + + public val name: String? + get() = _name.invoke() + + public companion object { + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String? = nameDefault + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + public fun build() = Person( + name = name, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/schema.graphql new file mode 100644 index 000000000..876e9f158 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnFields/schema.graphql @@ -0,0 +1,4 @@ +type Person { + name: String + email: String @skipcodegen +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/DgsClient.kt new file mode 100644 index 000000000..aa3583cf8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.skipCodegenOnInterfaceFields.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/DgsConstants.kt new file mode 100644 index 000000000..74e0c798e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/DgsConstants.kt @@ -0,0 +1,13 @@ +package kotlin2.skipCodegenOnInterfaceFields.expected + +import kotlin.String + +public object DgsConstants { + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Name: String = "name" + + public const val Email: String = "email" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/client/PersonProjection.kt new file mode 100644 index 000000000..1fbd6e0e6 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/client/PersonProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.skipCodegenOnInterfaceFields.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val name: PersonProjection + get() { + field("name") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/types/Person.kt new file mode 100644 index 000000000..fcb44afc7 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/expected/types/Person.kt @@ -0,0 +1,13 @@ +package kotlin2.skipCodegenOnInterfaceFields.expected.types + +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import kotlin.String + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +public sealed interface Person { + public val name: String? +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/schema.graphql new file mode 100644 index 000000000..884631044 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnInterfaceFields/schema.graphql @@ -0,0 +1,4 @@ +interface Person { + name: String + email: String @skipcodegen +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/DgsClient.kt new file mode 100644 index 000000000..77cac88d8 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/DgsClient.kt @@ -0,0 +1,3 @@ +package kotlin2.skipCodegenOnTypes.expected + +public object DgsClient diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/DgsConstants.kt new file mode 100644 index 000000000..bf4174f25 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/DgsConstants.kt @@ -0,0 +1,17 @@ +package kotlin2.skipCodegenOnTypes.expected + +import kotlin.String + +public object DgsConstants { + public object PERSON { + public const val TYPE_NAME: String = "Person" + + public const val Name: String = "name" + } + + public object CAR { + public const val TYPE_NAME: String = "Car" + + public const val Make: String = "make" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/client/PersonProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/client/PersonProjection.kt new file mode 100644 index 000000000..917158cf9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/client/PersonProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.skipCodegenOnTypes.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class PersonProjection : GraphQLProjection() { + public val name: PersonProjection + get() { + field("name") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/types/Person.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/types/Person.kt new file mode 100644 index 000000000..2d06ec5cb --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/expected/types/Person.kt @@ -0,0 +1,41 @@ +package kotlin2.skipCodegenOnTypes.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Person.Builder::class) +public class Person( + name: () -> String? = nameDefault +) { + private val _name: () -> String? = name + + public val name: String? + get() = _name.invoke() + + public companion object { + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String? = nameDefault + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + public fun build() = Person( + name = name, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/schema.graphql new file mode 100644 index 000000000..042d18b53 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/skipCodegenOnTypes/schema.graphql @@ -0,0 +1,7 @@ +type Person { + name: String +} + +type Car @skipcodegen { + make: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/DgsClient.kt new file mode 100644 index 000000000..cac761d91 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.union.expected + +import kotlin.String +import kotlin2.union.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/DgsConstants.kt new file mode 100644 index 000000000..72e27fce6 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/DgsConstants.kt @@ -0,0 +1,29 @@ +package kotlin2.union.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Search: String = "search" + } + + public object MOVIE { + public const val TYPE_NAME: String = "Movie" + + public const val Title: String = "title" + } + + public object ACTOR { + public const val TYPE_NAME: String = "Actor" + + public const val Name: String = "name" + } + + public object SEARCHRESULT { + public const val TYPE_NAME: String = "SearchResult" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/ActorProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/ActorProjection.kt new file mode 100644 index 000000000..4d47d86b9 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/ActorProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.union.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class ActorProjection : GraphQLProjection() { + public val name: ActorProjection + get() { + field("name") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/MovieProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/MovieProjection.kt new file mode 100644 index 000000000..36bbf2282 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/MovieProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.union.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class MovieProjection : GraphQLProjection() { + public val title: MovieProjection + get() { + field("title") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/QueryProjection.kt new file mode 100644 index 000000000..c0d34a23a --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/QueryProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.union.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun search(_projection: SearchResultProjection.() -> SearchResultProjection): + QueryProjection { + project("search", SearchResultProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/SearchResultProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/SearchResultProjection.kt new file mode 100644 index 000000000..e03438146 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/client/SearchResultProjection.kt @@ -0,0 +1,15 @@ +package kotlin2.union.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class SearchResultProjection : GraphQLProjection() { + public fun onMovie(_projection: MovieProjection.() -> MovieProjection): SearchResultProjection { + project("... on Movie", MovieProjection(), _projection) + return this + } + + public fun onActor(_projection: ActorProjection.() -> ActorProjection): SearchResultProjection { + project("... on Actor", ActorProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Actor.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Actor.kt new file mode 100644 index 000000000..8b33e7bf7 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Actor.kt @@ -0,0 +1,41 @@ +package kotlin2.union.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Actor.Builder::class) +public class Actor( + name: () -> String? = nameDefault +) : SearchResult { + private val _name: () -> String? = name + + public val name: String? + get() = _name.invoke() + + public companion object { + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String? = nameDefault + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + public fun build() = Actor( + name = name, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Movie.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Movie.kt new file mode 100644 index 000000000..93fd27cd2 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Movie.kt @@ -0,0 +1,41 @@ +package kotlin2.union.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Movie.Builder::class) +public class Movie( + title: () -> String? = titleDefault +) : SearchResult { + private val _title: () -> String? = title + + public val title: String? + get() = _title.invoke() + + public companion object { + private val titleDefault: () -> String? = + { throw IllegalStateException("Field `title` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var title: () -> String? = titleDefault + + @JsonProperty("title") + public fun withTitle(title: String?): Builder = this.apply { + this.title = { title } + } + + public fun build() = Movie( + title = title, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Query.kt new file mode 100644 index 000000000..1a24ee0bd --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.union.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + search: () -> List? = searchDefault +) { + private val _search: () -> List? = search + + public val search: List? + get() = _search.invoke() + + public companion object { + private val searchDefault: () -> List? = + { throw IllegalStateException("Field `search` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var search: () -> List? = searchDefault + + @JsonProperty("search") + public fun withSearch(search: List?): Builder = this.apply { + this.search = { search } + } + + public fun build() = Query( + search = search, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/SearchResult.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/SearchResult.kt new file mode 100644 index 000000000..ba335d2de --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/expected/types/SearchResult.kt @@ -0,0 +1,15 @@ +package kotlin2.union.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Movie::class, name = "Movie"), + JsonSubTypes.Type(value = Actor::class, name = "Actor") +]) +public sealed interface SearchResult diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/schema.graphql new file mode 100644 index 000000000..6470afb5f --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/union/schema.graphql @@ -0,0 +1,13 @@ +type Query { + search: [SearchResult] +} + +union SearchResult = Movie | Actor + +type Movie { + title: String +} + +type Actor { + name: String +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/DgsClient.kt new file mode 100644 index 000000000..1ae2ebb23 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected + +import kotlin.String +import kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/DgsConstants.kt new file mode 100644 index 000000000..45b519b0e --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/DgsConstants.kt @@ -0,0 +1,43 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Search: String = "search" + } + + public object HUMAN { + public const val TYPE_NAME: String = "Human" + + public const val Id: String = "id" + + public const val Name: String = "name" + + public const val TotalCredits: String = "totalCredits" + } + + public object DROID { + public const val TYPE_NAME: String = "Droid" + + public const val Id: String = "id" + + public const val Name: String = "name" + + public const val PrimaryFunction: String = "primaryFunction" + } + + public object SEARCHRESULTPAGE { + public const val TYPE_NAME: String = "SearchResultPage" + + public const val Items: String = "items" + } + + public object SEARCHRESULT { + public const val TYPE_NAME: String = "SearchResult" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/DroidProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/DroidProjection.kt new file mode 100644 index 000000000..9f4869d86 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/DroidProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class DroidProjection : GraphQLProjection() { + public val id: DroidProjection + get() { + field("id") + return this + } + + public val name: DroidProjection + get() { + field("name") + return this + } + + public val primaryFunction: DroidProjection + get() { + field("primaryFunction") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/HumanProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/HumanProjection.kt new file mode 100644 index 000000000..1ffc30d39 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/HumanProjection.kt @@ -0,0 +1,23 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class HumanProjection : GraphQLProjection() { + public val id: HumanProjection + get() { + field("id") + return this + } + + public val name: HumanProjection + get() { + field("name") + return this + } + + public val totalCredits: HumanProjection + get() { + field("totalCredits") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/QueryProjection.kt new file mode 100644 index 000000000..5fe5c68a6 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/QueryProjection.kt @@ -0,0 +1,13 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection +import kotlin.String + +public class QueryProjection : GraphQLProjection() { + public fun search(text: String, + _projection: SearchResultPageProjection.() -> SearchResultPageProjection): QueryProjection { + val args = formatArgs("text" to text) + project("search($args)", SearchResultPageProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/SearchResultPageProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/SearchResultPageProjection.kt new file mode 100644 index 000000000..1e36e29a2 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/SearchResultPageProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class SearchResultPageProjection : GraphQLProjection() { + public fun items(_projection: SearchResultProjection.() -> SearchResultProjection): + SearchResultPageProjection { + project("items", SearchResultProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/SearchResultProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/SearchResultProjection.kt new file mode 100644 index 000000000..8e4604db0 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/client/SearchResultProjection.kt @@ -0,0 +1,15 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class SearchResultProjection : GraphQLProjection() { + public fun onHuman(_projection: HumanProjection.() -> HumanProjection): SearchResultProjection { + project("... on Human", HumanProjection(), _projection) + return this + } + + public fun onDroid(_projection: DroidProjection.() -> DroidProjection): SearchResultProjection { + project("... on Droid", DroidProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Droid.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Droid.kt new file mode 100644 index 000000000..96f5406f3 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Droid.kt @@ -0,0 +1,77 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Droid.Builder::class) +public class Droid( + id: () -> String = idDefault, + name: () -> String = nameDefault, + primaryFunction: () -> String? = primaryFunctionDefault +) : SearchResult { + private val _id: () -> String = id + + private val _name: () -> String = name + + private val _primaryFunction: () -> String? = primaryFunction + + public val id: String + get() = _id.invoke() + + public val name: String + get() = _name.invoke() + + public val primaryFunction: String? + get() = _primaryFunction.invoke() + + public companion object { + private val idDefault: () -> String = + { throw IllegalStateException("Field `id` was not requested") } + + + private val nameDefault: () -> String = + { throw IllegalStateException("Field `name` was not requested") } + + + private val primaryFunctionDefault: () -> String? = + { throw IllegalStateException("Field `primaryFunction` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var id: () -> String = idDefault + + private var name: () -> String = nameDefault + + private var primaryFunction: () -> String? = primaryFunctionDefault + + @JsonProperty("id") + public fun withId(id: String): Builder = this.apply { + this.id = { id } + } + + @JsonProperty("name") + public fun withName(name: String): Builder = this.apply { + this.name = { name } + } + + @JsonProperty("primaryFunction") + public fun withPrimaryFunction(primaryFunction: String?): Builder = this.apply { + this.primaryFunction = { primaryFunction } + } + + public fun build() = Droid( + id = id, + name = name, + primaryFunction = primaryFunction, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Human.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Human.kt new file mode 100644 index 000000000..9567ead99 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Human.kt @@ -0,0 +1,78 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.Int +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Human.Builder::class) +public class Human( + id: () -> String = idDefault, + name: () -> String = nameDefault, + totalCredits: () -> Int? = totalCreditsDefault +) : SearchResult { + private val _id: () -> String = id + + private val _name: () -> String = name + + private val _totalCredits: () -> Int? = totalCredits + + public val id: String + get() = _id.invoke() + + public val name: String + get() = _name.invoke() + + public val totalCredits: Int? + get() = _totalCredits.invoke() + + public companion object { + private val idDefault: () -> String = + { throw IllegalStateException("Field `id` was not requested") } + + + private val nameDefault: () -> String = + { throw IllegalStateException("Field `name` was not requested") } + + + private val totalCreditsDefault: () -> Int? = + { throw IllegalStateException("Field `totalCredits` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var id: () -> String = idDefault + + private var name: () -> String = nameDefault + + private var totalCredits: () -> Int? = totalCreditsDefault + + @JsonProperty("id") + public fun withId(id: String): Builder = this.apply { + this.id = { id } + } + + @JsonProperty("name") + public fun withName(name: String): Builder = this.apply { + this.name = { name } + } + + @JsonProperty("totalCredits") + public fun withTotalCredits(totalCredits: Int?): Builder = this.apply { + this.totalCredits = { totalCredits } + } + + public fun build() = Human( + id = id, + name = name, + totalCredits = totalCredits, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Query.kt new file mode 100644 index 000000000..9b57eea91 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/Query.kt @@ -0,0 +1,40 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + search: () -> SearchResultPage? = searchDefault +) { + private val _search: () -> SearchResultPage? = search + + public val search: SearchResultPage? + get() = _search.invoke() + + public companion object { + private val searchDefault: () -> SearchResultPage? = + { throw IllegalStateException("Field `search` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var search: () -> SearchResultPage? = searchDefault + + @JsonProperty("search") + public fun withSearch(search: SearchResultPage?): Builder = this.apply { + this.search = { search } + } + + public fun build() = Query( + search = search, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/SearchResult.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/SearchResult.kt new file mode 100644 index 000000000..51e5c87d1 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/SearchResult.kt @@ -0,0 +1,15 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Human::class, name = "Human"), + JsonSubTypes.Type(value = Droid::class, name = "Droid") +]) +public sealed interface SearchResult diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/SearchResultPage.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/SearchResultPage.kt new file mode 100644 index 000000000..757224181 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/expected/types/SearchResultPage.kt @@ -0,0 +1,41 @@ +package kotlin2.unionTypesWithoutInterfaceCanDeserialize.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = SearchResultPage.Builder::class) +public class SearchResultPage( + items: () -> List? = itemsDefault +) { + private val _items: () -> List? = items + + public val items: List? + get() = _items.invoke() + + public companion object { + private val itemsDefault: () -> List? = + { throw IllegalStateException("Field `items` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var items: () -> List? = itemsDefault + + @JsonProperty("items") + public fun withItems(items: List?): Builder = this.apply { + this.items = { items } + } + + public fun build() = SearchResultPage( + items = items, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/schema.graphql new file mode 100644 index 000000000..e7f44f32b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionTypesWithoutInterfaceCanDeserialize/schema.graphql @@ -0,0 +1,21 @@ +type Query { + search(text: String!): SearchResultPage +} + +type Human { + id: ID! + name: String! + totalCredits: Int +} + +type Droid { + id: ID! + name: String! + primaryFunction: String +} + +union SearchResult = Human | Droid + +type SearchResultPage { + items: [SearchResult] +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/DgsClient.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/DgsClient.kt new file mode 100644 index 000000000..d4b49fbe4 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/DgsClient.kt @@ -0,0 +1,12 @@ +package kotlin2.unionWithExtendedType.expected + +import kotlin.String +import kotlin2.unionWithExtendedType.expected.client.QueryProjection + +public object DgsClient { + public fun buildQuery(_projection: QueryProjection.() -> QueryProjection): String { + val projection = QueryProjection() + _projection.invoke(projection) + return "query ${projection.asQuery()}" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/DgsConstants.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/DgsConstants.kt new file mode 100644 index 000000000..c9c236088 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/DgsConstants.kt @@ -0,0 +1,35 @@ +package kotlin2.unionWithExtendedType.expected + +import kotlin.String + +public object DgsConstants { + public const val QUERY_TYPE: String = "Query" + + public object QUERY { + public const val TYPE_NAME: String = "Query" + + public const val Search: String = "search" + } + + public object MOVIE { + public const val TYPE_NAME: String = "Movie" + + public const val Title: String = "title" + } + + public object ACTOR { + public const val TYPE_NAME: String = "Actor" + + public const val Name: String = "name" + } + + public object RATING { + public const val TYPE_NAME: String = "Rating" + + public const val Stars: String = "stars" + } + + public object SEARCHRESULT { + public const val TYPE_NAME: String = "SearchResult" + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/ActorProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/ActorProjection.kt new file mode 100644 index 000000000..4a9376717 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/ActorProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.unionWithExtendedType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class ActorProjection : GraphQLProjection() { + public val name: ActorProjection + get() { + field("name") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/MovieProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/MovieProjection.kt new file mode 100644 index 000000000..6710dba18 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/MovieProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.unionWithExtendedType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class MovieProjection : GraphQLProjection() { + public val title: MovieProjection + get() { + field("title") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/QueryProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/QueryProjection.kt new file mode 100644 index 000000000..f4a87e7df --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/QueryProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.unionWithExtendedType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class QueryProjection : GraphQLProjection() { + public fun search(_projection: SearchResultProjection.() -> SearchResultProjection): + QueryProjection { + project("search", SearchResultProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/RatingProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/RatingProjection.kt new file mode 100644 index 000000000..cc615385c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/RatingProjection.kt @@ -0,0 +1,11 @@ +package kotlin2.unionWithExtendedType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class RatingProjection : GraphQLProjection() { + public val stars: RatingProjection + get() { + field("stars") + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/SearchResultProjection.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/SearchResultProjection.kt new file mode 100644 index 000000000..220239b69 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/client/SearchResultProjection.kt @@ -0,0 +1,21 @@ +package kotlin2.unionWithExtendedType.expected.client + +import com.netflix.graphql.dgs.client.codegen.GraphQLProjection + +public class SearchResultProjection : GraphQLProjection() { + public fun onMovie(_projection: MovieProjection.() -> MovieProjection): SearchResultProjection { + project("... on Movie", MovieProjection(), _projection) + return this + } + + public fun onActor(_projection: ActorProjection.() -> ActorProjection): SearchResultProjection { + project("... on Actor", ActorProjection(), _projection) + return this + } + + public fun onRating(_projection: RatingProjection.() -> RatingProjection): + SearchResultProjection { + project("... on Rating", RatingProjection(), _projection) + return this + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Actor.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Actor.kt new file mode 100644 index 000000000..0fef18c1b --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Actor.kt @@ -0,0 +1,41 @@ +package kotlin2.unionWithExtendedType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Actor.Builder::class) +public class Actor( + name: () -> String? = nameDefault +) : SearchResult { + private val _name: () -> String? = name + + public val name: String? + get() = _name.invoke() + + public companion object { + private val nameDefault: () -> String? = + { throw IllegalStateException("Field `name` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var name: () -> String? = nameDefault + + @JsonProperty("name") + public fun withName(name: String?): Builder = this.apply { + this.name = { name } + } + + public fun build() = Actor( + name = name, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Movie.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Movie.kt new file mode 100644 index 000000000..829d5994c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Movie.kt @@ -0,0 +1,41 @@ +package kotlin2.unionWithExtendedType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.String + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Movie.Builder::class) +public class Movie( + title: () -> String? = titleDefault +) : SearchResult { + private val _title: () -> String? = title + + public val title: String? + get() = _title.invoke() + + public companion object { + private val titleDefault: () -> String? = + { throw IllegalStateException("Field `title` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var title: () -> String? = titleDefault + + @JsonProperty("title") + public fun withTitle(title: String?): Builder = this.apply { + this.title = { title } + } + + public fun build() = Movie( + title = title, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Query.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Query.kt new file mode 100644 index 000000000..9e4af0f43 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Query.kt @@ -0,0 +1,41 @@ +package kotlin2.unionWithExtendedType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.collections.List + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Query.Builder::class) +public class Query( + search: () -> List? = searchDefault +) { + private val _search: () -> List? = search + + public val search: List? + get() = _search.invoke() + + public companion object { + private val searchDefault: () -> List? = + { throw IllegalStateException("Field `search` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var search: () -> List? = searchDefault + + @JsonProperty("search") + public fun withSearch(search: List?): Builder = this.apply { + this.search = { search } + } + + public fun build() = Query( + search = search, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Rating.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Rating.kt new file mode 100644 index 000000000..f622eb58c --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/Rating.kt @@ -0,0 +1,41 @@ +package kotlin2.unionWithExtendedType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties +import com.fasterxml.jackson.`annotation`.JsonProperty +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize +import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import java.lang.IllegalStateException +import kotlin.Int + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(builder = Rating.Builder::class) +public class Rating( + stars: () -> Int? = starsDefault +) : SearchResult { + private val _stars: () -> Int? = stars + + public val stars: Int? + get() = _stars.invoke() + + public companion object { + private val starsDefault: () -> Int? = + { throw IllegalStateException("Field `stars` was not requested") } + + } + + @JsonPOJOBuilder + @JsonIgnoreProperties("__typename") + public class Builder { + private var stars: () -> Int? = starsDefault + + @JsonProperty("stars") + public fun withStars(stars: Int?): Builder = this.apply { + this.stars = { stars } + } + + public fun build() = Rating( + stars = stars, + ) + } +} diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/SearchResult.kt b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/SearchResult.kt new file mode 100644 index 000000000..c9f5fa140 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/expected/types/SearchResult.kt @@ -0,0 +1,16 @@ +package kotlin2.unionWithExtendedType.expected.types + +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename" +) +@JsonSubTypes(value = [ + JsonSubTypes.Type(value = Movie::class, name = "Movie"), + JsonSubTypes.Type(value = Actor::class, name = "Actor"), + JsonSubTypes.Type(value = Rating::class, name = "Rating") +]) +public sealed interface SearchResult diff --git a/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/schema.graphql b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/schema.graphql new file mode 100644 index 000000000..7183ca630 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/kotlin2/unionWithExtendedType/schema.graphql @@ -0,0 +1,19 @@ +type Query { + search: [SearchResult] +} + +union SearchResult = Movie | Actor + +type Movie { + title: String +} + +type Actor { + name: String +} + +type Rating { + stars: Int +} + +extend union SearchResult = Rating diff --git a/graphql-dgs-codegen-gradle/src/main/kotlin/com/netflix/graphql/dgs/codegen/gradle/GenerateJavaTask.kt b/graphql-dgs-codegen-gradle/src/main/kotlin/com/netflix/graphql/dgs/codegen/gradle/GenerateJavaTask.kt index c80372fd9..b31426674 100644 --- a/graphql-dgs-codegen-gradle/src/main/kotlin/com/netflix/graphql/dgs/codegen/gradle/GenerateJavaTask.kt +++ b/graphql-dgs-codegen-gradle/src/main/kotlin/com/netflix/graphql/dgs/codegen/gradle/GenerateJavaTask.kt @@ -74,6 +74,12 @@ open class GenerateJavaTask : DefaultTask() { @Input var generateClient = false + @Input + var generateKotlinNullableClasses = false + + @Input + var generateKotlinClosureProjections = false + @Input var generateDataTypes = true @@ -144,6 +150,8 @@ open class GenerateJavaTask : DefaultTask() { language = Language.valueOf(language.uppercase(Locale.getDefault())), generateBoxedTypes = generateBoxedTypes, generateClientApi = generateClient, + generateKotlinNullableClasses = generateKotlinNullableClasses, + generateKotlinClosureProjections = generateKotlinClosureProjections, generateInterfaces = generateInterfaces, generateInterfaceSetters = generateInterfaceSetters, typeMapping = typeMapping,