variables_are_input_types.ex (1641B)
1 defmodule Absinthe.Phase.Document.Validation.VariablesAreInputTypes do 2 @moduledoc false 3 4 # Validates document to ensure that all variable definitions are for 5 # input types. 6 7 alias Absinthe.{Blueprint, Phase, Schema, Type} 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, input.schema)) 18 {:ok, result} 19 end 20 21 # Find variable definitions 22 @spec handle_node(Blueprint.node_t(), Schema.t()) :: Blueprint.node_t() 23 defp handle_node(%Blueprint.Document.VariableDefinition{} = node, schema) do 24 schema 25 |> Schema.lookup_type(node.schema_node) 26 |> Type.unwrap() 27 |> case do 28 nil -> 29 node 30 31 type -> 32 if Type.input_type?(type) do 33 node 34 else 35 node 36 |> flag_invalid(:non_input_type) 37 |> put_error(error(node, Type.name(node.schema_node))) 38 end 39 end 40 end 41 42 defp handle_node(node, _) do 43 node 44 end 45 46 # Generate an error for an input field 47 @spec error(Blueprint.Document.VariableDefinition.t(), String.t()) :: Phase.Error.t() 48 defp error(node, type_rep) do 49 %Phase.Error{ 50 phase: __MODULE__, 51 message: error_message(node.name, type_rep), 52 locations: [node.source_location] 53 } 54 end 55 56 @doc """ 57 Generate the error message. 58 """ 59 @spec error_message(String.t(), String.t()) :: String.t() 60 def error_message(variable_name, type_rep) do 61 ~s(Variable "#{variable_name}" cannot be non-input type "#{type_rep}".) 62 end 63 end