unique_argument_names.ex (2024B)
1 defmodule Absinthe.Phase.Document.Validation.UniqueArgumentNames do 2 @moduledoc false 3 4 # Validates document to ensure that all arguments for a field or directive 5 # have unique names. 6 7 alias Absinthe.{Blueprint, Phase} 8 9 use Absinthe.Phase 10 use Absinthe.Phase.Validation 11 12 @doc """ 13 Run the validation. 14 """ 15 @spec run(Blueprint.t(), Keyword.t()) :: Phase.result_t() 16 def run(input, _options \\ []) do 17 result = Blueprint.prewalk(input, &handle_node/1) 18 {:ok, result} 19 end 20 21 @argument_hosts [ 22 Blueprint.Document.Field, 23 Blueprint.Directive 24 ] 25 26 # Find fields and directives to check arguments 27 @spec handle_node(Blueprint.node_t()) :: Blueprint.node_t() 28 defp handle_node(%argument_host{} = node) when argument_host in @argument_hosts do 29 arguments = Enum.map(node.arguments, &process(&1, node.arguments)) 30 %{node | arguments: arguments} 31 end 32 33 defp handle_node(node) do 34 node 35 end 36 37 # Check an argument, finding any duplicates 38 @spec process(Blueprint.Input.Argument.t(), [Blueprint.Input.Argument.t()]) :: 39 Blueprint.Input.Argument.t() 40 defp process(argument, arguments) do 41 check_duplicates(argument, Enum.filter(arguments, &(&1.name == argument.name))) 42 end 43 44 # Add flags and errors if necessary for each argument. 45 @spec check_duplicates(Blueprint.Input.Argument.t(), [Blueprint.Input.Argument.t()]) :: 46 Blueprint.Input.Argument.t() 47 defp check_duplicates(argument, [_single]) do 48 argument 49 end 50 51 defp check_duplicates(argument, _multiple) do 52 argument 53 |> flag_invalid(:duplicate_name) 54 |> put_error(error(argument)) 55 end 56 57 # Generate an error for a duplicate argument. 58 @spec error(Blueprint.Input.Argument.t()) :: Phase.Error.t() 59 defp error(node) do 60 %Phase.Error{ 61 phase: __MODULE__, 62 message: error_message(), 63 locations: [node.source_location] 64 } 65 end 66 67 @doc """ 68 Generate the error message. 69 """ 70 @spec error_message :: String.t() 71 def error_message do 72 "Duplicate argument name." 73 end 74 end