zf

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

interfaces_must_resolve_types.ex (2106B)


      1 defmodule Absinthe.Phase.Schema.Validation.InterfacesMustResolveTypes do
      2   @moduledoc false
      3 
      4   use Absinthe.Phase
      5   alias Absinthe.Blueprint
      6 
      7   def run(bp, _) do
      8     bp = Blueprint.prewalk(bp, &handle_schemas/1)
      9     {:ok, bp}
     10   end
     11 
     12   defp handle_schemas(%Blueprint.Schema.SchemaDefinition{} = schema) do
     13     implementors =
     14       schema.type_definitions
     15       |> Enum.filter(&match?(%Blueprint.Schema.ObjectTypeDefinition{}, &1))
     16       |> Enum.flat_map(fn obj ->
     17         for iface <- obj.interfaces do
     18           {iface, obj}
     19         end
     20       end)
     21       |> Enum.group_by(fn {iface, _obj} -> iface end, fn {_iface, obj} -> obj end)
     22 
     23     schema = Blueprint.prewalk(schema, &validate_interface(&1, implementors))
     24     {:halt, schema}
     25   end
     26 
     27   defp handle_schemas(obj) do
     28     obj
     29   end
     30 
     31   defp validate_interface(%Blueprint.Schema.InterfaceTypeDefinition{} = iface, implementors) do
     32     resolve_type = Absinthe.Type.function(iface, :resolve_type)
     33 
     34     if(resolve_type || all_objects_is_type_of?(iface, implementors)) do
     35       iface
     36     else
     37       iface |> put_error(error(iface))
     38     end
     39   end
     40 
     41   defp validate_interface(type, _) do
     42     type
     43   end
     44 
     45   defp all_objects_is_type_of?(iface, implementors) do
     46     implementors
     47     |> Map.get(iface.identifier, [])
     48     |> Enum.all?(&Absinthe.Type.function(&1, :is_type_of))
     49   end
     50 
     51   defp error(interface) do
     52     %Absinthe.Phase.Error{
     53       message: explanation(interface.identifier),
     54       locations: [interface.__reference__.location],
     55       phase: __MODULE__,
     56       extra: interface.identifier
     57     }
     58   end
     59 
     60   @description """
     61   An interface must be able to resolve the implementing types of results.
     62 
     63   > The interface type should have some way of determining which object a given
     64   > result corresponds to.
     65 
     66   Reference: https://github.com/facebook/graphql/blob/master/spec/Section%203%20--%20Type%20System.md#interfaces
     67   """
     68 
     69   def explanation(interface) do
     70     """
     71     Interface type "#{interface}" either:
     72     * Does not have a `resolve_type` function.
     73     * Is missing a `is_type_of` function on all implementing types.
     74 
     75     #{@description}
     76     """
     77   end
     78 end