Packages
absinthe
1.5.0-rc.4
1.11.0
1.10.2
1.10.1
1.10.0
1.9.1
1.9.0
1.8.0
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.8
1.6.7
retired
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.6.0-rc.1
1.6.0-rc.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.5.0-rc.5
1.5.0-rc.4
1.5.0-rc.3
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.5.0-beta.2
1.5.0-beta.1
1.5.0-beta.0
1.5.0-alpha.4
1.5.0-alpha.3
1.5.0-alpha.2
1.5.0-alpha.1
1.5.0-alpha.0
1.4.16
1.4.15
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.4.9
1.4.8
retired
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.3
1.4.0-rc.2
1.4.0-rc.1
1.4.0-rc.0
1.4.0-beta.5
1.4.0-beta.4
1.4.0-beta.3
1.4.0-beta.2
1.4.0-beta.1
1.3.2
1.3.1
1.3.0
1.3.0-rc.0
1.3.0-beta.2
1.3.0-beta.1
1.3.0-beta.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.2.0-beta.0
1.2.0-alpha0
1.2.0-alpha.2
1.2.0-alpha.1
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.0
0.5.2
0.5.1
0.5.0
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.2.3
0.2.2
0.2.1
0.1.0
GraphQL for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/absinthe/phase/schema/hydrate.ex
defmodule Absinthe.Phase.Schema.Hydrate do
@moduledoc false
@behaviour Absinthe.Schema.Hydrator
use Absinthe.Phase
alias Absinthe.Blueprint
@hydrate [
Blueprint.Schema.DirectiveDefinition,
Blueprint.Schema.EnumTypeDefinition,
Blueprint.Schema.EnumValueDefinition,
Blueprint.Schema.FieldDefinition,
Blueprint.Schema.InputObjectTypeDefinition,
Blueprint.Schema.InputValueDefinition,
Blueprint.Schema.InterfaceTypeDefinition,
Blueprint.Schema.ObjectTypeDefinition,
Blueprint.Schema.ScalarTypeDefinition,
Blueprint.Schema.SchemaDefinition,
Blueprint.Schema.UnionTypeDefinition
]
@impl Absinthe.Phase
def run(blueprint, opts \\ []) do
{:ok, schema} = Keyword.fetch(opts, :schema)
hydrator = Keyword.get(opts, :hydrator, __MODULE__)
blueprint = Blueprint.prewalk(blueprint, &handle_node(&1, [], schema, hydrator))
{:ok, blueprint}
end
defp handle_node(%Blueprint{} = node, ancestors, schema, hydrator) do
node
|> hydrate_node(ancestors, schema, hydrator)
|> set_children(ancestors, schema, hydrator)
end
defp handle_node(%node_module{} = node, ancestors, schema, hydrator)
when node_module in @hydrate do
node
|> hydrate_node(ancestors, schema, hydrator)
|> set_children(ancestors, schema, hydrator)
end
defp handle_node(node, ancestors, schema, hydrator) do
set_children(node, ancestors, schema, hydrator)
end
defp set_children(parent, ancestors, schema, hydrator) do
Blueprint.prewalk(parent, fn
^parent -> parent
child -> {:halt, handle_node(child, [parent | ancestors], schema, hydrator)}
end)
end
defp hydrate_node(%{} = node, ancestors, schema, hydrator) do
hydrations = schema.hydrate(node, ancestors)
apply_hydrations(node, hydrations, hydrator)
end
defp apply_hydrations(node, hydrations, hydrator) do
hydrations
|> List.wrap()
|> Enum.reduce(node, fn hydration, node ->
hydrator.apply_hydration(node, hydration)
end)
end
@impl Absinthe.Schema.Hydrator
def apply_hydration(
node,
{:meta, keyword_list}
)
when is_list(keyword_list) do
%{node | __private__: Keyword.put(node.__private__, :meta, keyword_list)}
end
def apply_hydration(
node,
{:description, text}
) do
%{node | description: text}
end
def apply_hydration(
%Blueprint.Schema.FieldDefinition{} = node,
{:resolve, resolver}
) do
%{node | middleware: [{Absinthe.Resolution, resolver}]}
end
def apply_hydration(
%Blueprint.Schema.FieldDefinition{} = node,
{:middleware, {_module, _opts} = middleware}
) do
%{node | middleware: [middleware]}
end
def apply_hydration(
%Blueprint.Schema.FieldDefinition{} = node,
{:complexity, complexity}
)
when is_integer(complexity) do
%{node | complexity: complexity}
end
def apply_hydration(
%Blueprint.Schema.ScalarTypeDefinition{} = node,
{:parse, parse}
)
when is_function(parse) do
%{node | parse: parse}
end
def apply_hydration(
%Blueprint.Schema.ScalarTypeDefinition{} = node,
{:serialize, serialize}
)
when is_function(serialize) do
%{node | serialize: serialize}
end
def apply_hydration(
%Blueprint.Schema.InterfaceTypeDefinition{} = node,
{:resolve_type, resolve_type}
)
when is_function(resolve_type) do
%{node | resolve_type: resolve_type}
end
def apply_hydration(
%Blueprint.Schema.ObjectTypeDefinition{} = node,
{:is_type_of, is_type_of}
)
when is_function(is_type_of) do
%{node | is_type_of: is_type_of}
end
def apply_hydration(
%Blueprint.Schema.EnumValueDefinition{} = node,
{:as, value}
) do
%{node | value: value}
end
@hydration_level1 [
Blueprint.Schema.DirectiveDefinition,
Blueprint.Schema.EnumTypeDefinition,
Blueprint.Schema.InputObjectTypeDefinition,
Blueprint.Schema.InterfaceTypeDefinition,
Blueprint.Schema.ObjectTypeDefinition,
Blueprint.Schema.ScalarTypeDefinition,
Blueprint.Schema.UnionTypeDefinition
]
@hydration_level2 [
Blueprint.Schema.FieldDefinition,
Blueprint.Schema.EnumValueDefinition
]
@hydration_level3 [
Blueprint.Schema.InputValueDefinition
]
def apply_hydration(%Absinthe.Blueprint{} = root, %{} = sub_hydrations) do
{root, _} =
Blueprint.prewalk(root, nil, fn
%module{identifier: ident} = node, nil when module in @hydration_level1 ->
case Map.fetch(sub_hydrations, ident) do
:error ->
{node, nil}
{:ok, type_hydrations} ->
{apply_hydrations(node, type_hydrations, __MODULE__), nil}
end
node, nil ->
{node, nil}
end)
root
end
def apply_hydration(%module{} = root, %{} = sub_hydrations)
when module in @hydration_level1 do
{root, _} =
Blueprint.prewalk(root, nil, fn
%module{identifier: ident} = node, nil when module in @hydration_level2 ->
case Map.fetch(sub_hydrations, ident) do
:error ->
{node, nil}
{:ok, type_hydrations} ->
{apply_hydrations(node, type_hydrations, __MODULE__), nil}
end
node, nil ->
{node, nil}
end)
root
end
def apply_hydration(%module{} = root, %{} = sub_hydrations)
when module in @hydration_level2 do
{root, _} =
Blueprint.prewalk(root, nil, fn
%module{identifier: ident} = node, nil when module in @hydration_level3 ->
case Map.fetch(sub_hydrations, ident) do
:error ->
{node, nil}
{:ok, type_hydrations} ->
{apply_hydrations(node, type_hydrations, __MODULE__), nil}
end
node, nil ->
{node, nil}
end)
root
end
def apply_hydration(root, result) do
raise ArgumentError, """
Invalid hydration!
#{inspect(result)}
is not a valid way to hydrate
#{inspect(root)}
"""
end
end