Packages
absinthe
1.7.2
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/directive_imports.ex
defmodule Absinthe.Phase.Schema.DirectiveImports do
@moduledoc false
use Absinthe.Phase
alias Absinthe.Blueprint
alias Absinthe.Blueprint.Schema
def run(blueprint, opts) do
blueprint = Blueprint.prewalk(blueprint, &handle_imports(&1, opts))
{:ok, blueprint}
end
def handle_imports(%Schema.SchemaDefinition{} = schema, opts) do
default_imports = Keyword.get(opts, :directive_imports, [])
{directives, schema} =
do_imports(
default_imports ++ schema.directive_imports,
schema.directive_definitions,
schema
)
{:halt, %{schema | directive_definitions: directives}}
end
def handle_imports(node, _opts), do: node
defp do_imports([], types, schema) do
{types, schema}
end
defp do_imports([{module, opts} | rest], acc, schema) do
case ensure_compiled(module) do
{:module, module} ->
[other_def] = module.__absinthe_blueprint__.schema_definitions
rejections = MapSet.new(Keyword.get(opts, :except, []))
types = Enum.reject(other_def.directive_definitions, &(&1.identifier in rejections))
types =
case Keyword.fetch(opts, :only) do
{:ok, selections} ->
Enum.filter(types, &(&1.identifier in selections))
_ ->
types
end
do_imports(other_def.directive_imports ++ rest, types ++ acc, schema)
{:error, reason} ->
do_imports(rest, acc, schema |> put_error(error(module, reason)))
end
end
# Elixir v1.12 includes a Code.ensure_compiled!/1 that tells
# the compiler it should only continue if the module is available.
# This gives the Elixir compiler more information to address
# deadlocks.
# TODO: Remove the else clause once we require Elixir v1.12+.
@compile {:no_warn_undefined, {Code, :ensure_compiled!, 1}}
@dialyzer {:nowarn_function, [ensure_compiled: 1]}
defp ensure_compiled(module) do
if function_exported?(Code, :ensure_compiled!, 1) do
{:module, Code.ensure_compiled!(module)}
else
Code.ensure_compiled(module)
end
end
# Generate an error when loading module fails
@spec error(module :: module(), error :: :embedded | :badfile | :nofile | :on_load_failure) ::
Absinthe.Phase.Error.t()
defp error(module, reason) do
%Absinthe.Phase.Error{
message: "Could not load module `#{module}`. It returned reason: `#{reason}`.",
phase: __MODULE__
}
end
end