flag_invalid.ex (1631B)
1 defmodule Absinthe.Phase.Document.Arguments.FlagInvalid do 2 @moduledoc false 3 4 # Marks arguments as bad if they have any invalid children. 5 # 6 # This is later used by the ArgumentsOfCorrectType phase. 7 8 alias Absinthe.{Blueprint, Phase, Type} 9 10 use Absinthe.Phase 11 12 @doc """ 13 Run this validation. 14 """ 15 @spec run(Blueprint.t(), Keyword.t()) :: Phase.result_t() 16 def run(input, _options \\ []) do 17 result = Blueprint.postwalk(input, &handle_node/1) 18 {:ok, result} 19 end 20 21 defp handle_node(%{schema_node: nil, flags: %{}} = node) do 22 node |> flag_invalid(:extra) 23 end 24 25 defp handle_node(%Blueprint.Input.Argument{} = node) do 26 check_child(node, node.input_value.normalized, :bad_argument) 27 end 28 29 defp handle_node(%Blueprint.Input.Field{} = node) do 30 check_child(node, node.input_value.normalized, :bad_field) 31 end 32 33 defp handle_node(%Blueprint.Input.List{} = node) do 34 check_children(node, node.items |> Enum.map(& &1.normalized), :bad_list) 35 end 36 37 defp handle_node(%Blueprint.Input.Object{schema_node: %Type.Scalar{open_ended: true}} = node) do 38 node 39 end 40 41 defp handle_node(%Blueprint.Input.Object{} = node) do 42 check_children(node, node.fields, :bad_object) 43 end 44 45 defp handle_node(node), do: node 46 47 defp check_child(node, %{flags: %{invalid: _}}, flag) do 48 flag_invalid(node, flag) 49 end 50 51 defp check_child(node, _, _) do 52 node 53 end 54 55 defp check_children(node, children, flag) do 56 invalid? = fn 57 %{flags: %{invalid: _}} -> true 58 _ -> false 59 end 60 61 if Enum.any?(children, invalid?) do 62 flag_invalid(node, flag) 63 else 64 node 65 end 66 end 67 end