lone_anonymous_operation.ex (1636B)
1 defmodule Absinthe.Phase.Document.Validation.LoneAnonymousOperation do 2 @moduledoc false 3 4 # Validates document to ensure that only one operation is provided without 5 # a name. 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 # Find the root and check for multiple anonymous operations 22 @spec handle_node(Blueprint.node_t()) :: Blueprint.node_t() 23 defp handle_node(%Blueprint{} = node) do 24 ops = process(node.operations) 25 %{node | operations: ops} 26 end 27 28 defp handle_node(node) do 29 node 30 end 31 32 @spec process([Blueprint.Document.Operation.t()]) :: [Blueprint.Document.Operation.t()] 33 defp process(operations) do 34 do_process(operations, length(operations)) 35 end 36 37 @spec do_process([Blueprint.Document.Operation.t()], integer) :: [ 38 Blueprint.Document.Operation.t() 39 ] 40 defp do_process(operations, count) when count < 2 do 41 operations 42 end 43 44 defp do_process(operations, _) do 45 Enum.map(operations, fn 46 %{name: nil} = op -> 47 flag_invalid(op, :bad_name) 48 |> put_error(error(op)) 49 50 other -> 51 other 52 end) 53 end 54 55 # Generate the error for the node 56 @spec error(Blueprint.node_t()) :: Phase.Error.t() 57 defp error(node) do 58 %Phase.Error{ 59 phase: __MODULE__, 60 message: "This anonymous operation must be the only defined operation.", 61 locations: [node.source_location] 62 } 63 end 64 end