Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [k2] add support for data types inherited from extended interface #741

Merged
merged 3 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.expected

import com.netflix.graphql.dgs.client.codegen.InputValueSerializerInterface
import com.netflix.graphql.dgs.codegen.GraphQLProjection
import com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.expected.client.QueryProjection
import graphql.language.OperationDefinition
import kotlin.String

public object DgsClient {
public fun buildQuery(inputValueSerializer: InputValueSerializerInterface? = null,
_projection: QueryProjection.() -> QueryProjection): String =
GraphQLProjection.asQuery(OperationDefinition.Operation.QUERY,
QueryProjection(inputValueSerializer), _projection)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.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 const val Age: String = "age"
}

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"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.expected.client

import com.netflix.graphql.dgs.client.codegen.InputValueSerializerInterface
import com.netflix.graphql.dgs.codegen.GraphQLProjection

public class EmployeeProjection(
inputValueSerializer: InputValueSerializerInterface? = null,
) : GraphQLProjection(inputValueSerializer) {
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 val age: EmployeeProjection
get() {
field("age")
return this
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.expected.client

import com.netflix.graphql.dgs.client.codegen.InputValueSerializerInterface
import com.netflix.graphql.dgs.codegen.GraphQLProjection

public class PersonProjection(
inputValueSerializer: InputValueSerializerInterface? = null,
) : GraphQLProjection(inputValueSerializer) {
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 {
fragment("Employee", EmployeeProjection(), _projection)
return this
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.expected.client

import com.netflix.graphql.dgs.client.codegen.InputValueSerializerInterface
import com.netflix.graphql.dgs.codegen.GraphQLProjection
import kotlin.String

public class QueryProjection(
inputValueSerializer: InputValueSerializerInterface? = null,
) : GraphQLProjection(inputValueSerializer) {
public fun people(_alias: String? = null, _projection: PersonProjection.() -> PersonProjection):
QueryProjection {
field(_alias, "people", PersonProjection(inputValueSerializer), _projection)
return this
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.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
import kotlin.Suppress
import kotlin.jvm.JvmName

@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonDeserialize(builder = Employee.Builder::class)
public class Employee(
firstname: () -> String = firstnameDefault,
lastname: () -> String? = lastnameDefault,
company: () -> String? = companyDefault,
age: () -> Int = ageDefault,
) : Person {
private val __firstname: () -> String = firstname

private val __lastname: () -> String? = lastname

private val __company: () -> String? = company

private val __age: () -> Int = age

@Suppress("INAPPLICABLE_JVM_NAME")
@get:JvmName("getFirstname")
override val firstname: String
get() = __firstname.invoke()

@Suppress("INAPPLICABLE_JVM_NAME")
@get:JvmName("getLastname")
override val lastname: String?
get() = __lastname.invoke()

@get:JvmName("getCompany")
public val company: String?
get() = __company.invoke()

@Suppress("INAPPLICABLE_JVM_NAME")
@get:JvmName("getAge")
override val age: Int
get() = __age.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 ageDefault: () -> Int =
{ throw IllegalStateException("Field `age` 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 age: () -> Int = ageDefault

@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("age")
public fun withAge(age: Int): Builder = this.apply {
this.age = { age }
}

public fun build(): Employee = Employee(
firstname = firstname,
lastname = lastname,
company = company,
age = age,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.expected.types

import com.fasterxml.jackson.`annotation`.JsonSubTypes
import com.fasterxml.jackson.`annotation`.JsonTypeInfo
import kotlin.Int
import kotlin.String
import kotlin.Suppress
import kotlin.jvm.JvmName

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "__typename",
)
@JsonSubTypes(value = [
JsonSubTypes.Type(value = Employee::class, name = "Employee")
])
public sealed interface Person {
@Suppress("INAPPLICABLE_JVM_NAME")
@get:JvmName("getFirstname")
public val firstname: String

@Suppress("INAPPLICABLE_JVM_NAME")
@get:JvmName("getLastname")
public val lastname: String?

@Suppress("INAPPLICABLE_JVM_NAME")
@get:JvmName("getAge")
public val age: Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.netflix.graphql.dgs.codegen.cases.dataClassWithExtendedInterfaceInheritance.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
import kotlin.jvm.JvmName

@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonDeserialize(builder = Query.Builder::class)
public class Query(
people: () -> List<Person?>? = peopleDefault,
) {
private val __people: () -> List<Person?>? = people

@get:JvmName("getPeople")
public val people: List<Person?>?
get() = __people.invoke()

public companion object {
private val peopleDefault: () -> List<Person?>? =
{ throw IllegalStateException("Field `people` was not requested") }
}

@JsonPOJOBuilder
@JsonIgnoreProperties("__typename")
public class Builder {
private var people: () -> List<Person?>? = peopleDefault

@JsonProperty("people")
public fun withPeople(people: List<Person?>?): Builder = this.apply {
this.people = { people }
}

public fun build(): Query = Query(
people = people,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
type Query {
people: [Person]
}

interface Person {
firstname: String!
lastname: String
}

type Employee implements Person {
firstname: String!
lastname: String
company: String
}

extend interface Person {
age: Int!
}

extend type Employee {
age: Int!
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ class Kotlin2TypeLookup(
*/
private val interfaceFields: Map<String, List<String>> = document
.getDefinitionsOfType(InterfaceTypeDefinition::class.java)
.associate { i -> i.name to i.fieldDefinitions.map { it.name } }
.groupBy(keySelector = { it.name }, valueTransform = { it.fieldDefinitions })
.mapValues { e -> e.value.flatten().map { i -> i.name } }

/**
* A map of interfaces to the types that implement them
Expand Down
Loading