Skip to content

Commit

Permalink
Add union type redirect
Browse files Browse the repository at this point in the history
  • Loading branch information
paulpdaniels committed Jul 31, 2021
1 parent 09d4782 commit 58650f9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
9 changes: 8 additions & 1 deletion core/src/main/scala-2/caliban/schema/SchemaDerivation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@ trait SchemaDerivation[R] extends LowPriorityDerivedSchema {

type Typeclass[T] = Schema[R, T]

def isValueType[T](ctx: ReadOnlyCaseClass[Typeclass, T]): Boolean =
ctx.annotations.exists {
case GQLValueType() => true
case _ => false
}

def combine[T](ctx: ReadOnlyCaseClass[Typeclass, T]): Typeclass[T] = new Typeclass[T] {
override def toType(isInput: Boolean, isSubscription: Boolean): __Type =
if (ctx.isValueClass && ctx.parameters.nonEmpty) ctx.parameters.head.typeclass.toType_(isInput, isSubscription)
if ((ctx.isValueClass || isValueType(ctx)) && ctx.parameters.nonEmpty)
ctx.parameters.head.typeclass.toType_(isInput, isSubscription)
else if (isInput)
makeInputObject(
Some(ctx.annotations.collectFirst { case GQLInputName(suffix) => suffix }
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/scala/caliban/schema/Annotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ object Annotations {
* Annotation to make a sealed trait a union instead of an enum
*/
case class GQLUnion() extends StaticAnnotation

/**
* Annotation to make a union or interface redirect to a value type
*/
case class GQLValueType() extends StaticAnnotation
}
34 changes: 33 additions & 1 deletion core/src/test/scala/caliban/schema/SchemaSpec.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package caliban.schema

import caliban.Rendering

import java.util.UUID
import caliban.introspection.adt.{ __DeprecatedArgs, __Type, __TypeKind }
import caliban.schema.Annotations.{ GQLInterface, GQLUnion }
import caliban.schema.Annotations.{ GQLInterface, GQLUnion, GQLValueType }
import zio.blocking.Blocking
import zio.console.Console
import zio.query.ZQuery
Expand Down Expand Up @@ -126,6 +128,24 @@ object SchemaSpec extends DefaultRunnableSpec {
implicit val somethingSchema: Schema[Any, Something] = Schema.gen[Something].rename("SomethingElse")

assert(Types.innerType(introspectSubscription[Something]).name)(isSome(equalTo("SomethingElse")))
},
test("union redirect") {
case class Queries(union: RedirectingUnion)

implicit val queriesSchema: Schema[Any, Queries] = Schema.gen[Queries]

val types = Types.collectTypes(introspect[Queries])
val subTypes = types.find(_.name.contains("RedirectingUnion")).flatMap(_.possibleTypes)
val fieldNames =
subTypes.toList.flatMap(_.flatMap(_.fields(__DeprecatedArgs()).map(_.map(_.name)))).toSet.flatten
assert(subTypes.map(_.flatMap(_.name)))(
isSome(
hasSameElements(
List("A", "B")
)
)
) &&
assert(fieldNames)(hasSameElements(List("common")))
}
)

Expand All @@ -148,6 +168,18 @@ object SchemaSpec extends DefaultRunnableSpec {
case object B extends EnumLikeUnion
}

@GQLUnion
sealed trait RedirectingUnion

object RedirectingUnion {
case class B(common: Int)

case class A(common: Int) extends RedirectingUnion

@GQLValueType
case class Redirect(value: B) extends RedirectingUnion
}

@GQLInterface
sealed trait EnumLikeInterface
object EnumLikeInterface {
Expand Down

0 comments on commit 58650f9

Please sign in to comment.