Skip to content

Commit

Permalink
Merge pull request #1291 from jgautsch/introspect-deprecated-input-fi…
Browse files Browse the repository at this point in the history
…elds

Support deprecated input object fields in introspection query (fixes #1241)
  • Loading branch information
benwilson512 authored Jan 29, 2024
2 parents cd4ab0e + 2323cbe commit b2d68df
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 22 deletions.
78 changes: 56 additions & 22 deletions lib/absinthe/type/built_ins/introspection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,17 @@ defmodule Absinthe.Type.BuiltIns.Introspection do

field :args,
type: non_null(list_of(non_null(:__inputvalue))),
resolve: fn _, %{source: source} ->
args: [
include_deprecated: [
type: :boolean,
default_value: false
]
],
resolve: fn %{include_deprecated: show_deprecated}, %{source: source} ->
args =
source.args
|> Map.values()
|> filter_deprecated(show_deprecated)
|> Enum.sort_by(& &1.identifier)

{:ok, args}
Expand Down Expand Up @@ -108,18 +115,9 @@ defmodule Absinthe.Type.BuiltIns.Introspection do
when str in [Absinthe.Type.Object, Absinthe.Type.Interface] ->
result =
fields
|> Enum.flat_map(fn {_, %{deprecation: is_deprecated} = field} ->
cond do
Absinthe.Type.introspection?(field) ->
[]

!is_deprecated || (is_deprecated && show_deprecated) ->
[field]

true ->
[]
end
end)
|> Map.values()
|> filter_deprecated(show_deprecated)
|> Enum.filter(&(!Absinthe.Type.introspection?(&1)))
|> Enum.sort_by(& &1.identifier)

{:ok, result}
Expand Down Expand Up @@ -174,13 +172,8 @@ defmodule Absinthe.Type.BuiltIns.Introspection do
%{include_deprecated: show_deprecated}, %{source: %Absinthe.Type.Enum{values: values}} ->
result =
values
|> Enum.flat_map(fn {_, %{deprecation: is_deprecated} = value} ->
if !is_deprecated || (is_deprecated && show_deprecated) do
[value]
else
[]
end
end)
|> Map.values()
|> filter_deprecated(show_deprecated)
|> Enum.sort_by(& &1.value)

{:ok, result}
Expand All @@ -191,11 +184,19 @@ defmodule Absinthe.Type.BuiltIns.Introspection do

field :input_fields,
type: list_of(non_null(:__inputvalue)),
args: [
include_deprecated: [
type: :boolean,
default_value: false
]
],
resolve: fn
_, %{source: %Absinthe.Type.InputObject{fields: fields}} ->
%{include_deprecated: show_deprecated},
%{source: %Absinthe.Type.InputObject{fields: fields}} ->
input_fields =
fields
|> Map.values()
|> filter_deprecated(show_deprecated)
|> Enum.sort_by(& &1.identifier)

{:ok, input_fields}
Expand Down Expand Up @@ -226,10 +227,17 @@ defmodule Absinthe.Type.BuiltIns.Introspection do

field :args,
type: non_null(list_of(non_null(:__inputvalue))),
resolve: fn _, %{source: %{args: args}} ->
args: [
include_deprecated: [
type: :boolean,
default_value: false
]
],
resolve: fn %{include_deprecated: show_deprecated}, %{source: %{args: args}} ->
args =
args
|> Map.values()
|> filter_deprecated(show_deprecated)
|> Enum.sort_by(& &1.identifier)

{:ok, args}
Expand Down Expand Up @@ -299,6 +307,26 @@ defmodule Absinthe.Type.BuiltIns.Introspection do
_, %{source: _} ->
{:ok, nil}
end

field :is_deprecated,
type: non_null(:boolean),
resolve: fn
_, %{source: %{deprecation: nil}} ->
{:ok, false}

_, _ ->
{:ok, true}
end

field :deprecation_reason,
type: :string,
resolve: fn
_, %{source: %{deprecation: nil}} ->
{:ok, nil}

_, %{source: %{deprecation: dep}} ->
{:ok, dep.reason}
end
end

object :__enumvalue, name: "__EnumValue" do
Expand Down Expand Up @@ -364,4 +392,10 @@ defmodule Absinthe.Type.BuiltIns.Introspection do
inspect(Absinthe.Type.Scalar.serialize(sc, value))
end
end

defp filter_deprecated(values, show_deprecated) do
Enum.filter(values, fn %{deprecation: is_deprecated} ->
!is_deprecated || show_deprecated
end)
end
end
87 changes: 87 additions & 0 deletions test/absinthe/introspection_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,93 @@ defmodule Absinthe.IntrospectionTest do
assert !match?({:ok, %{data: %{"__type" => %{"fields" => _}}}}, result)
end

test "can include deprecated fields based on an arg" do
result =
"""
{
__type(name: "ProfileInput") {
kind
name
description
inputFields(includeDeprecated: true) {
name
description
type {
kind
name
ofType {
kind
name
}
}
defaultValue
isDeprecated
deprecationReason
}
}
}
"""
|> run(Absinthe.Fixtures.ContactSchema)

assert_result(
{:ok,
%{
data: %{
"__type" => %{
"description" => "The basic details for a person",
"inputFields" => [
%{
"defaultValue" => nil,
"description" => nil,
"name" => "address",
"type" => %{
"kind" => "SCALAR",
"name" => "String",
"ofType" => nil
},
"deprecationReason" => "change of privacy policy",
"isDeprecated" => true
},
%{
"defaultValue" => "43",
"description" => "The person's age",
"name" => "age",
"type" => %{"kind" => "SCALAR", "name" => "Int", "ofType" => nil},
"deprecationReason" => nil,
"isDeprecated" => false
},
%{
"defaultValue" => nil,
"description" => nil,
"name" => "code",
"type" => %{
"kind" => "NON_NULL",
"name" => nil,
"ofType" => %{"kind" => "SCALAR", "name" => "String"}
},
"deprecationReason" => nil,
"isDeprecated" => false
},
%{
"defaultValue" => "\"Janet\"",
"description" => "The person's name",
"name" => "name",
"type" => %{"kind" => "SCALAR", "name" => "String", "ofType" => nil},
"deprecationReason" => nil,
"isDeprecated" => false
}
],
"kind" => "INPUT_OBJECT",
"name" => "ProfileInput"
}
}
}},
result
)

assert !match?({:ok, %{data: %{"__type" => %{"fields" => _}}}}, result)
end

defmodule ComplexDefaultSchema do
use Absinthe.Schema

Expand Down
1 change: 1 addition & 0 deletions test/support/fixtures/contact_schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ defmodule Absinthe.Fixtures.ContactSchema do
field :code, type: non_null(:string)
field :name, type: :string, description: "The person's name", default_value: "Janet"
field :age, type: :integer, description: "The person's age", default_value: 43
field :address, type: :string, deprecate: "change of privacy policy"
end

interface :named_entity do
Expand Down

0 comments on commit b2d68df

Please sign in to comment.