zf

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

known_argument_names.ex (3511B)


      1 defmodule Absinthe.Phase.Document.Validation.KnownArgumentNames do
      2   @moduledoc false
      3 
      4   # Validates document to ensure that all arguments are in the schema.
      5   #
      6   # Note: while graphql-js doesn't add errors to unknown arguments that
      7   # are provided to unknown fields, Absinthe does -- but when the errors
      8   # are harvested from the Blueprint tree, only the first layer of unknown
      9   # errors (eg, the field) should be presented to the user.
     10 
     11   alias Absinthe.{Blueprint, Phase, Schema, Type}
     12 
     13   use Absinthe.Phase
     14 
     15   @doc """
     16   Run the validation.
     17   """
     18   @spec run(Blueprint.t(), Keyword.t()) :: Phase.result_t()
     19   def run(input, _options \\ []) do
     20     result = Blueprint.prewalk(input, &handle_node(&1, input.schema))
     21     {:ok, result}
     22   end
     23 
     24   @spec handle_node(Blueprint.node_t(), Schema.t()) :: Blueprint.node_t()
     25   defp handle_node(%{schema_node: nil} = node, _schema) do
     26     node
     27   end
     28 
     29   defp handle_node(%{selections: _, schema_node: schema_node} = node, schema) do
     30     selections =
     31       Enum.map(node.selections, fn
     32         %{arguments: arguments} = field ->
     33           arguments =
     34             Enum.map(arguments, fn
     35               %{schema_node: nil} = arg ->
     36                 arg
     37                 |> flag_invalid(:no_schema_node)
     38                 |> put_error(field_error(arg, field, type_name(schema_node, schema)))
     39 
     40               other ->
     41                 other
     42             end)
     43 
     44           %{field | arguments: arguments}
     45 
     46         other ->
     47           other
     48       end)
     49 
     50     %{node | selections: selections}
     51   end
     52 
     53   defp handle_node(%Blueprint.Directive{} = node, _) do
     54     arguments =
     55       Enum.map(node.arguments, fn
     56         %{schema_node: nil} = arg ->
     57           arg
     58           |> flag_invalid(:no_schema_node)
     59           |> put_error(directive_error(arg, node))
     60 
     61         other ->
     62           other
     63       end)
     64 
     65     %{node | arguments: arguments}
     66   end
     67 
     68   defp handle_node(node, _) do
     69     node
     70   end
     71 
     72   @spec type_name(Type.t(), Schema.t()) :: String.t()
     73   defp type_name(%Type.Field{} = node, schema) do
     74     node.type
     75     |> Type.unwrap()
     76     |> schema.__absinthe_lookup__()
     77     |> Map.fetch!(:name)
     78   end
     79 
     80   defp type_name(node, _) do
     81     node.name
     82   end
     83 
     84   # Generate the error for a directive argument
     85   @spec directive_error(Blueprint.node_t(), Blueprint.node_t()) :: Phase.Error.t()
     86   defp directive_error(argument_node, directive_node) do
     87     %Phase.Error{
     88       phase: __MODULE__,
     89       message: directive_error_message(argument_node.name, directive_node.name),
     90       locations: [argument_node.source_location]
     91     }
     92   end
     93 
     94   # Generate the error for a field argument
     95   @spec field_error(Blueprint.node_t(), Blueprint.node_t(), String.t()) :: Phase.Error.t()
     96   defp field_error(argument_node, field_node, type_name) do
     97     %Phase.Error{
     98       phase: __MODULE__,
     99       message: field_error_message(argument_node.name, field_node.name, type_name),
    100       locations: [argument_node.source_location]
    101     }
    102   end
    103 
    104   @doc """
    105   Generate an error for a directive argument
    106   """
    107   @spec directive_error_message(String.t(), String.t()) :: String.t()
    108   def directive_error_message(argument_name, directive_name) do
    109     ~s(Unknown argument "#{argument_name}" on directive "@#{directive_name}".)
    110   end
    111 
    112   @doc """
    113   Generate an error for a field argument
    114   """
    115   @spec field_error_message(String.t(), String.t(), String.t()) :: String.t()
    116   def field_error_message(argument_name, field_name, type_name) do
    117     ~s(Unknown argument "#{argument_name}" on field "#{field_name}" of type "#{type_name}".)
    118   end
    119 end