zf

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

type_names_are_reserved.ex (2497B)


      1 defmodule Absinthe.Phase.Schema.Validation.TypeNamesAreReserved do
      2   @moduledoc false
      3 
      4   use Absinthe.Phase
      5   alias Absinthe.Blueprint
      6   alias Absinthe.Blueprint.Schema
      7 
      8   def run(bp, _) do
      9     bp = Blueprint.prewalk(bp, &validate_reserved/1)
     10     {:ok, bp}
     11   end
     12 
     13   def allow_reserved(node = %{flags: nil}) do
     14     allow_reserved(%{node | flags: %{}})
     15   end
     16 
     17   def allow_reserved(node = %{flags: flags}) do
     18     flags =
     19       flags
     20       |> Map.put(:reserved_name, true)
     21 
     22     %{node | flags: flags}
     23   end
     24 
     25   def make_reserved(node = %{name: "__" <> _}) do
     26     allow_reserved(node)
     27   end
     28 
     29   def make_reserved(node = %{name: name, identifier: identifier}) do
     30     node = %{
     31       node
     32       | name: name |> String.replace_prefix("", "__"),
     33         identifier:
     34           identifier |> to_string() |> String.replace_prefix("", "__") |> String.to_atom()
     35     }
     36 
     37     allow_reserved(node)
     38   end
     39 
     40   defp validate_reserved(%struct{name: "__" <> _} = entity) do
     41     reserved_ok =
     42       Absinthe.Type.built_in_module?(entity.__reference__.module) ||
     43         reserved_name_ok_flag?(entity)
     44 
     45     if reserved_ok do
     46       entity
     47     else
     48       kind = struct_to_kind(struct)
     49 
     50       detail = %{artifact: "#{kind} name", value: entity.name}
     51 
     52       entity |> put_error(error(entity, detail))
     53     end
     54   end
     55 
     56   defp validate_reserved(entity) do
     57     entity
     58   end
     59 
     60   defp reserved_name_ok_flag?(%{flags: flags}) do
     61     flags[:reserved_name]
     62   end
     63 
     64   defp reserved_name_ok_flag?(_) do
     65     false
     66   end
     67 
     68   defp error(object, data) do
     69     %Absinthe.Phase.Error{
     70       message: explanation(data),
     71       locations: [object.__reference__.location],
     72       phase: __MODULE__,
     73       extra: data
     74     }
     75   end
     76 
     77   defp struct_to_kind(Schema.InputValueDefinition), do: "argument"
     78   defp struct_to_kind(Schema.FieldDefinition), do: "field"
     79   defp struct_to_kind(Schema.DirectiveDefinition), do: "directive"
     80   defp struct_to_kind(_), do: "type"
     81 
     82   @description """
     83   Type system artifacts must not begin with two leading underscores.
     84 
     85   > GraphQL type system authors must not define any types, fields, arguments,
     86   > or any other type system artifact with two leading underscores.
     87 
     88   Reference: https://github.com/facebook/graphql/blob/master/spec/Section%204%20--%20Introspection.md#naming-conventions
     89 
     90   """
     91 
     92   def explanation(%{artifact: artifact, value: value}) do
     93     artifact_name = String.capitalize(artifact)
     94 
     95     """
     96     #{artifact_name} #{inspect(value)} starts with two leading underscores.
     97 
     98     #{@description}
     99     """
    100   end
    101 end