zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

type_imports.ex (2776B)


      1 defmodule Absinthe.Phase.Schema.TypeImports do
      2   @moduledoc false
      3 
      4   use Absinthe.Phase
      5   alias Absinthe.Blueprint
      6 
      7   alias Absinthe.Blueprint.Schema
      8 
      9   def run(blueprint, _opts) do
     10     blueprint = Blueprint.prewalk(blueprint, &handle_imports/1)
     11     {:ok, blueprint}
     12   end
     13 
     14   @default_imports [
     15     {Absinthe.Type.BuiltIns.Scalars, []},
     16     {Absinthe.Type.BuiltIns.Directives, []},
     17     {Absinthe.Type.BuiltIns.Introspection, []}
     18   ]
     19   def handle_imports(%Schema.SchemaDefinition{} = schema) do
     20     {types, schema} =
     21       do_imports(@default_imports ++ schema.imports, schema.type_definitions, schema)
     22 
     23     # special casing the import of the built in directives
     24     [builtins] = Absinthe.Type.BuiltIns.Directives.__absinthe_blueprint__().schema_definitions
     25     directives = schema.directive_definitions ++ builtins.directive_definitions
     26     {:halt, %{schema | type_definitions: types, directive_definitions: directives}}
     27   end
     28 
     29   def handle_imports(node), do: node
     30 
     31   defp do_imports([], types, schema) do
     32     {types, schema}
     33   end
     34 
     35   defp do_imports([{module, opts} | rest], acc, schema) do
     36     case ensure_compiled(module) do
     37       {:module, module} ->
     38         [other_def] = module.__absinthe_blueprint__.schema_definitions
     39 
     40         rejections =
     41           MapSet.new([:query, :mutation, :subscription] ++ Keyword.get(opts, :except, []))
     42 
     43         types = Enum.reject(other_def.type_definitions, &(&1.identifier in rejections))
     44 
     45         types =
     46           case Keyword.fetch(opts, :only) do
     47             {:ok, selections} ->
     48               Enum.filter(types, &(&1.identifier in selections))
     49 
     50             _ ->
     51               types
     52           end
     53 
     54         do_imports(other_def.imports ++ rest, types ++ acc, schema)
     55 
     56       {:error, reason} ->
     57         do_imports(rest, acc, schema |> put_error(error(module, reason)))
     58     end
     59   end
     60 
     61   # Elixir v1.12 includes a Code.ensure_compiled!/1 that tells
     62   # the compiler it should only continue if the module is available.
     63   # This gives the Elixir compiler more information to address
     64   # deadlocks.
     65   # TODO: Remove the else clause once we require Elixir v1.12+.
     66   @compile {:no_warn_undefined, {Code, :ensure_compiled!, 1}}
     67   @dialyzer {:nowarn_function, [ensure_compiled: 1]}
     68   defp ensure_compiled(module) do
     69     if function_exported?(Code, :ensure_compiled!, 1) do
     70       {:module, Code.ensure_compiled!(module)}
     71     else
     72       Code.ensure_compiled(module)
     73     end
     74   end
     75 
     76   # Generate an error when loading module fails
     77   @spec error(module :: module(), error :: :embedded | :badfile | :nofile | :on_load_failure) ::
     78           Absinthe.Phase.Error.t()
     79   defp error(module, reason) do
     80     %Absinthe.Phase.Error{
     81       message: "Could not load module `#{module}`. It returned reason: `#{reason}`.",
     82       phase: __MODULE__
     83     }
     84   end
     85 end