Packages
absinthe
0.2.1
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
Current section
Files
Jump to
Current section
Files
lib/absinthe/schema/types.ex
defmodule Absinthe.Schema.Types do
@moduledoc false
alias Absinthe.Schema
alias Absinthe.Traversal
alias Absinthe.Type
@type typemap_t :: %{atom => Type.t}
@typep acc_t :: {typemap_t, typemap_t, [binary]}
alias Absinthe.Type
@builtin_type_modules [Type.Scalar]
# Discover the types available to and defined for a schema
@doc false
@spec setup(Schema.t) :: Schema.t
def setup(%{type_modules: extra_modules} = schema) do
type_modules = @builtin_type_modules ++ extra_modules
types_available = type_modules |> types_from_modules
initial_collected = @builtin_type_modules |> types_from_modules
case Traversal.reduce(schema, schema, {types_available, initial_collected, []}, &collect_types/3) do
{_, _, errors} when length(errors) > 0 ->
%{schema | errors: schema.errors ++ errors}
{_, result, _} ->
%{schema | types: result}
other ->
other
end
end
# TODO: Support abstract types
@spec collect_types(Traversal.Node.t, Traversal.t, acc_t) :: Traversal.instruction_t
defp collect_types(%{type: possibly_wrapped_type}, traversal, {avail, collect, errors} = acc) do
type = possibly_wrapped_type |> Type.unwrap
case {collect[type], avail[type]} do
# Invalid
{nil, nil} ->
avail_names = avail |> Map.keys |> Enum.join(", ")
{:prune, {avail, collect, ["Missing type #{type}; not found in #{avail_names}" | errors]}, traversal}
# Not yet collected
{nil, found} ->
new_collected = collect |> Map.put(type, found)
{
:ok,
{avail, new_collected, errors},
%{traversal | context: %{traversal.context | types: new_collected}}
}
# Already collected
_ ->
# No-op
{:ok, acc, traversal}
end
end
defp collect_types(_node, traversal, acc) do
{:ok, acc, traversal}
end
# Gracefully attempt to get the absinthe types
# on a given type module
defp absinthe_types(mod) do
try do
mod.absinthe_types
rescue
UndefinedFunctionError -> %{}
end
end
# Extract a mapping of all the types in a set of modules
@spec types_from_modules([atom]) :: typemap_t
defp types_from_modules(modules) do
modules
|> Enum.map(&absinthe_types/1)
|> Enum.reduce(%{}, fn
mapping, acc ->
acc |> Map.merge(mapping)
end)
end
end