zf

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

type_names_are_unique.ex (2693B)


      1 defmodule Absinthe.Phase.Schema.Validation.TypeNamesAreUnique do
      2   use Absinthe.Phase
      3   alias Absinthe.Blueprint
      4 
      5   def run(bp, _) do
      6     bp =
      7       bp
      8       |> Blueprint.prewalk(&handle_schemas(&1, :identifier))
      9       |> Blueprint.prewalk(&handle_schemas(&1, :name))
     10 
     11     {:ok, bp}
     12   end
     13 
     14   defp handle_schemas(%Blueprint.Schema.SchemaDefinition{} = schema, key) do
     15     if Enum.any?(schema.type_definitions, fn
     16          %Blueprint.Schema.SchemaDefinition{} ->
     17            true
     18 
     19          _ ->
     20            false
     21        end) do
     22       raise "SchemaDefinition Inside Schema Definition"
     23     end
     24 
     25     types = Enum.group_by(schema.type_definitions, &Map.fetch!(&1, key))
     26     directives = Enum.group_by(schema.directive_definitions, &Map.fetch!(&1, key))
     27 
     28     types = Map.merge(types, directives)
     29 
     30     schema = Blueprint.prewalk(schema, &validate_types(&1, types, key))
     31     {:halt, schema}
     32   end
     33 
     34   defp handle_schemas(obj, _) do
     35     obj
     36   end
     37 
     38   @types [
     39     Blueprint.Schema.DirectiveDefinition,
     40     Blueprint.Schema.EnumTypeDefinition,
     41     Blueprint.Schema.InputObjectTypeDefinition,
     42     Blueprint.Schema.InterfaceTypeDefinition,
     43     Blueprint.Schema.ObjectTypeDefinition,
     44     Blueprint.Schema.ScalarTypeDefinition,
     45     Blueprint.Schema.UnionTypeDefinition
     46   ]
     47   defp validate_types(%type{} = object, types, key) when type in @types do
     48     ident = Map.fetch!(object, key)
     49 
     50     case Map.fetch!(types, ident) do
     51       [_] ->
     52         object
     53 
     54       others ->
     55         detail = %{
     56           value: ident,
     57           artifact:
     58             case key do
     59               :identifier -> "Absinthe type identifier"
     60               :name -> "Type name"
     61             end
     62         }
     63 
     64         object |> put_error(error(detail, others))
     65     end
     66   end
     67 
     68   defp validate_types(type, _, _) do
     69     type
     70   end
     71 
     72   defp error(data, types) do
     73     %Absinthe.Phase.Error{
     74       message: explanation(data),
     75       locations: types |> Enum.map(& &1.__reference__.location),
     76       phase: __MODULE__,
     77       extra: data
     78     }
     79   end
     80 
     81   @moduledoc false
     82 
     83   @description """
     84   References to types must be unique.
     85 
     86   > All types within a GraphQL schema must have unique names. No two provided
     87   > types may have the same name. No provided type may have a name which
     88   > conflicts with any built in types (including Scalar and Introspection
     89   > types).
     90 
     91   Reference: https://github.com/facebook/graphql/blob/master/spec/Section%203%20--%20Type%20System.md#type-system
     92   """
     93 
     94   def explanation(%{artifact: artifact, value: name}) do
     95     """
     96     #{artifact} #{inspect(name)} is not unique.
     97 
     98     #{@description}
     99     """
    100   end
    101 
    102   # This rule is only used for its explanation. Error details are added during
    103   # compilation.
    104   def check(_), do: []
    105 end