Skip to content

Commit

Permalink
add input value deprecation
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanda Steinwedel committed Oct 12, 2023
1 parent 424ebb2 commit 5f77579
Show file tree
Hide file tree
Showing 18 changed files with 577 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ object IntrospectionParser {
name = mapStringField(value, "name", path),
description = mapStringFieldOpt(value, "description"),
tpe = parseTypeRef(mapField(value, "type", path), path :+ "type"),
defaultValue = mapStringFieldOpt(value, "defaultValue")
defaultValue = mapStringFieldOpt(value, "defaultValue"),
isDeprecated = mapBooleanFieldOpt(value, "isDeprecated", path),
deprecationReason = mapStringFieldOpt(value, "deprecationReason")
)

private def parseField[In: InputUnmarshaller](field: In, path: Vector[String]) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,10 @@ case class IntrospectionInputValue(
name: String,
description: Option[String],
tpe: IntrospectionTypeRef,
defaultValue: Option[String])
defaultValue: Option[String],
isDeprecated: Option[Boolean],
deprecationReason: Option[String]
)

sealed trait IntrospectionTypeRef {
def kind: TypeKind.Value
Expand Down
68 changes: 55 additions & 13 deletions modules/core/src/main/scala/sangria/introspection/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,20 @@ package object introspection {
List[Field[Unit, Field[_, _]]](
Field("name", StringType, resolve = _.value.name),
Field("description", OptionType(StringType), resolve = _.value.description),
Field("args", ListType(__InputValue), resolve = _.value.arguments),
Field(
"args",
ListType(__InputValue),
arguments = includeDeprecated :: Nil,
resolve = ctx => {
val incDep = ctx.arg(includeDeprecated)

if (incDep) {
ctx.value.arguments
} else {
ctx.value.arguments.filter(_.deprecationReason.isEmpty)
}
}
),
Field("type", __Type, resolve = false -> _.value.fieldType),
Field("isDeprecated", BooleanType, resolve = _.value.deprecationReason.isDefined),
Field("deprecationReason", OptionType(StringType), resolve = _.value.deprecationReason)
Expand Down Expand Up @@ -309,10 +322,17 @@ package object introspection {
Field(
"inputFields",
OptionType(ListType(__InputValue)),
resolve = _.value._2 match {
case io: InputObjectType[_] => Some(io.fields)
case _ => None
}),
arguments = includeDeprecated :: Nil,
resolve = ctx => {
val incDep = ctx.arg(includeDeprecated)

ctx.value._2 match {
case io: InputObjectType[_] if incDep => Some(io.fields)
case io: InputObjectType[_] => Some(io.fields.filter(_.deprecationReason.isEmpty))
case _ => None
}
}
),
Field(
"ofType",
OptionType(__Type),
Expand Down Expand Up @@ -342,7 +362,9 @@ package object introspection {
Some("A GraphQL-formatted string representing the default value for this input value."),
resolve = ctx =>
ctx.value.defaultValue.flatMap(ctx.renderInputValueCompact(_, ctx.value.inputValueType))
)
),
Field("isDeprecated", OptionType(BooleanType), resolve = _.value.deprecationReason.isDefined),
Field("deprecationReason", OptionType(StringType), resolve = _.value.deprecationReason)
)
)

Expand Down Expand Up @@ -374,7 +396,20 @@ package object introspection {
"locations",
ListType(__DirectiveLocation),
resolve = _.value.locations.toVector.sorted),
Field("args", ListType(__InputValue), resolve = _.value.arguments),
Field(
"args",
ListType(__InputValue),
arguments = includeDeprecated :: Nil,
resolve = ctx => {
val incDep = ctx.arg(includeDeprecated)

if (incDep) {
ctx.value.arguments
} else {
ctx.value.arguments.filter(_.deprecationReason.isEmpty)
}
}
),
Field(
"isRepeatable",
BooleanType,
Expand Down Expand Up @@ -457,12 +492,17 @@ package object introspection {

def introspectionQuery(
schemaDescription: Boolean = true,
directiveRepeatableFlag: Boolean = true): ast.Document =
QueryParser.parse(introspectionQueryString(schemaDescription, directiveRepeatableFlag)).get
directiveRepeatableFlag: Boolean = true,
inputValueDeprecation: Boolean = false): ast.Document =
QueryParser
.parse(
introspectionQueryString(schemaDescription, directiveRepeatableFlag, inputValueDeprecation))
.get

def introspectionQueryString(
schemaDescription: Boolean = true,
directiveRepeatableFlag: Boolean = true): String =
directiveRepeatableFlag: Boolean = true,
inputValueDeprecation: Boolean = false): String =
s"""query IntrospectionQuery {
| __schema {
| queryType { name }
Expand All @@ -475,7 +515,7 @@ package object introspection {
| name
| description
| locations
| args {
| args${if (inputValueDeprecation) "(includeDeprecated: true)" else ""} {
| ...InputValue
| }
| ${if (directiveRepeatableFlag) "isRepeatable" else ""}
Expand All @@ -490,7 +530,7 @@ package object introspection {
| fields(includeDeprecated: true) {
| name
| description
| args {
| args${if (inputValueDeprecation) "(includeDeprecated: true)" else ""} {
| ...InputValue
| }
| type {
Expand All @@ -499,7 +539,7 @@ package object introspection {
| isDeprecated
| deprecationReason
| }
| inputFields {
| inputFields${if (inputValueDeprecation) "(includeDeprecated: true)" else ""} {
| ...InputValue
| }
| interfaces {
Expand All @@ -520,6 +560,8 @@ package object introspection {
| description
| type { ...TypeRef }
| defaultValue
${if (inputValueDeprecation) """| isDeprecated
| deprecationReason""" else "|"}
|}
|fragment TypeRef on __Type {
| kind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ object SchemaRenderer {
arg.name,
renderTypeNameAst(arg.argumentType),
arg.defaultValue.flatMap(renderDefault(_, arg.argumentType)),
arg.astDirectives,
withoutDeprecated(arg.astDirectives) ++ renderDeprecation(
arg.deprecationReason.isDefined,
arg.deprecationReason),
renderDescription(arg.description)
)

Expand Down Expand Up @@ -138,14 +140,18 @@ object SchemaRenderer {
field.name,
renderTypeName(field.tpe),
renderDefault(field.defaultValue),
description = renderDescription(field.description))
directives = renderDeprecation(field.isDeprecated.getOrElse(false), field.deprecationReason),
description = renderDescription(field.description)
)

def renderInputField(field: InputField[_]) =
ast.InputValueDefinition(
field.name,
renderTypeNameAst(field.fieldType),
field.defaultValue.flatMap(renderDefault(_, field.fieldType)),
field.astDirectives,
withoutDeprecated(field.astDirectives) ++ renderDeprecation(
field.deprecationReason.isDefined,
field.deprecationReason),
renderDescription(field.description)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ class DefaultAstSchemaBuilder[Ctx] extends AstSchemaBuilder[Ctx] {
fieldType = tpe,
defaultValue = defaultValue,
astDirectives = definition.directives,
deprecationReason = inputValueDeprecationReason(definition),
astNodes = Vector(definition)
))

Expand Down Expand Up @@ -719,7 +720,8 @@ class DefaultAstSchemaBuilder[Ctx] extends AstSchemaBuilder[Ctx] {
defaultValue = defaultValue,
fromInput = argumentFromInput(typeDefinition, fieldDefinition, definition),
astDirectives = definition.directives,
astNodes = Vector(definition)
astNodes = Vector(definition),
deprecationReason = inputValueDeprecationReason(definition)
))

def buildArgumentType(
Expand Down Expand Up @@ -853,6 +855,9 @@ class DefaultAstSchemaBuilder[Ctx] extends AstSchemaBuilder[Ctx] {
def enumValueDeprecationReason(definition: ast.EnumValueDefinition): Option[String] =
deprecationReason(definition.directives.toList)

def inputValueDeprecationReason(definition: ast.InputValueDefinition): Option[String] =
deprecationReason(definition.directives.toList)

def fieldDeprecationReason(definition: ast.FieldDefinition): Option[String] =
deprecationReason(definition.directives.toList)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ class DefaultIntrospectionSchemaBuilder[Ctx] extends IntrospectionSchemaBuilder[
InputField(
name = inputFieldName(definition),
description = inputFieldDescription(definition),
deprecationReason = inputValueDeprecationReason(definition),
fieldType = tpe,
defaultValue = defaultValue,
astDirectives = Vector.empty,
Expand All @@ -280,7 +281,8 @@ class DefaultIntrospectionSchemaBuilder[Ctx] extends IntrospectionSchemaBuilder[
defaultValue = defaultValue,
fromInput = argumentFromInput(fieldDefinition, definition),
astDirectives = Vector.empty,
astNodes = Vector.empty
astNodes = Vector.empty,
deprecationReason = inputValueDeprecationReason(definition)
))

def buildDirective(
Expand Down Expand Up @@ -377,6 +379,11 @@ class DefaultIntrospectionSchemaBuilder[Ctx] extends IntrospectionSchemaBuilder[
def enumValue(definition: IntrospectionEnumValue): String =
definition.name

def inputValueDeprecationReason(definition: IntrospectionInputValue): Option[String] =
definition.deprecationReason.orElse(
if (definition.isDeprecated.getOrElse(false)) Some(DefaultDeprecationReason) else None
)

def fieldDeprecationReason(definition: IntrospectionField): Option[String] =
definition.deprecationReason.orElse(
if (definition.isDeprecated) Some(DefaultDeprecationReason) else None)
Expand Down
Loading

0 comments on commit 5f77579

Please sign in to comment.