Skip to content

Commit

Permalink
Merge 11cfb5b into 65ffe26
Browse files Browse the repository at this point in the history
  • Loading branch information
Axxiss committed Nov 20, 2018
2 parents 65ffe26 + 11cfb5b commit efb0be8
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/main/scala/sangria/schema/Schema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import sangria.{ast, introspection}
import sangria.validation._
import sangria.introspection._
import sangria.renderer.{SchemaFilter, SchemaRenderer}
import sangria.schema.transformations.TransformSchema
import sangria.streaming.SubscriptionStreamLike

import scala.annotation.implicitNotFound
Expand Down Expand Up @@ -906,6 +907,10 @@ case class Schema[Ctx, Val](
case ast.ListType(ofType, _) getOutputType(ofType) map (ListType(_))
}

def filterFields(filter: List[Field[Ctx, Any]] => List[Field[Ctx, Any]]): Schema[Ctx, Val] = {
TransformSchema.filterFields[Ctx, Val](this, filter)
}

lazy val directImplementations: Map[String, Vector[ObjectLikeType[_, _]]] = {
typeList
.collect{case objectLike: ObjectLikeType[_, _] objectLike}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package sangria.schema.transformations

import sangria.ast
import sangria.ast.InterfaceTypeExtensionDefinition
import sangria.schema.{AstSchemaMaterializer, DefaultAstSchemaBuilder, Field, InterfaceType, MatOrigin, ObjectType}


class FieldFilteredAstSchemaBuilder[Ctx](filter: List[Field[Ctx, Any]] => List[Field[Ctx, Any]]) extends DefaultAstSchemaBuilder[Ctx] {

override def extendObjectType(
origin: MatOrigin,
existing: ObjectType[Ctx, _],
extensions: List[ast.ObjectTypeExtensionDefinition],
fields: () List[Field[Ctx, Any]],
interfaces: List[InterfaceType[Ctx, Any]],
mat: AstSchemaMaterializer[Ctx]): ObjectType[Ctx, Any] = {
super.extendObjectType(origin, existing, extensions, applyFilter(fields), interfaces, mat)
}

override def extendInterfaceType(origin: MatOrigin,
existing: InterfaceType[Ctx, _],
extensions: List[InterfaceTypeExtensionDefinition],
fields: () => List[Field[Ctx, Any]],
mat: AstSchemaMaterializer[Ctx]): InterfaceType[Ctx, Any] = {
super.extendInterfaceType(origin, existing, extensions, applyFilter(fields), mat)
}

def applyFilter(fieldsFn: () => List[Field[Ctx, Any]]): () => List[Field[Ctx, Any]] = {
() => filter(fieldsFn())
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package sangria.schema.transformations

import sangria.ast.{Document, ObjectTypeExtensionDefinition}
import sangria.schema.{AstSchemaMaterializer, Field, Schema}

object TransformSchema {

def filterFields[Ctx, Val](schema: Schema[Ctx, Val], filter: List[Field[Ctx, Any]] => List[Field[Ctx, Any]]): Schema[Ctx, Val] = {
AstSchemaMaterializer.extendSchema(
schema,
emptyExtensionDocument(schema.query.name),
new FieldFilteredAstSchemaBuilder[Ctx](filter)
)
}

private def emptyExtensionDocument(queryName: String): Document = {
Document(Vector(
ObjectTypeExtensionDefinition(queryName, Vector.empty, Vector.empty)
))
}
}
37 changes: 37 additions & 0 deletions src/test/scala/sangria/schema/SchemaTransformationSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package sangria.schema

import org.scalatest.{Matchers, WordSpec}
import sangria.macros._
import sangria.renderer.SchemaRenderer
import sangria.util.{FutureResultSupport, StringMatchers}

class SchemaTransformationSpec extends WordSpec with Matchers with FutureResultSupport with StringMatchers {

private val testSchema = Schema.buildFromAst(graphql"""
type Query {
someObject: SomeObject
}

interface SomeInterface {
publicInterfaceField: String
privateInterfaceField: String
}

type SomeObject implements SomeInterface {
privateObjectField: String
publicObjectField: String
}
""")

"filterFields" should {
"filter fields on ObjectTypes" in {
val filteredSchema = testSchema.filterFields(_.filterNot(_.name == "privateObjectField"))
SchemaRenderer.renderSchema(filteredSchema) should not include "privateObjectField"
}

"filter fields on Interfaces" in {
val filteredSchema = testSchema.filterFields(_.filterNot(_.name == "privateInterfaceField"))
SchemaRenderer.renderSchema(filteredSchema) should not include "privateInterfaceField"
}
}
}

0 comments on commit efb0be8

Please sign in to comment.