names_must_be_valid.ex (2004B)
1 defmodule Absinthe.Phase.Schema.Validation.NamesMustBeValid do 2 @moduledoc false 3 4 use Absinthe.Phase 5 alias Absinthe.Blueprint 6 alias Absinthe.Blueprint.Schema 7 8 @valid_name_regex ~r/^[_A-Za-z][_0-9A-Za-z]*$/ 9 10 def run(bp, _) do 11 bp = Blueprint.prewalk(bp, &validate_names/1) 12 {:ok, bp} 13 end 14 15 defp validate_names(%{name: nil} = entity) do 16 entity 17 end 18 19 defp validate_names(%struct{name: name} = entity) do 20 if valid_name?(name) do 21 entity 22 else 23 kind = struct_to_kind(struct) 24 detail = %{artifact: "#{kind} name", value: entity.name} 25 entity |> put_error(error(entity, detail)) 26 end 27 end 28 29 defp validate_names(entity) do 30 entity 31 end 32 33 defp valid_name?(name) do 34 Regex.match?(@valid_name_regex, name) 35 end 36 37 defp error(object, data) do 38 %Absinthe.Phase.Error{ 39 message: explanation(data), 40 locations: [object.__reference__.location], 41 phase: __MODULE__, 42 extra: data 43 } 44 end 45 46 defp struct_to_kind(Schema.InputValueDefinition), do: "argument" 47 defp struct_to_kind(Schema.FieldDefinition), do: "field" 48 defp struct_to_kind(Schema.DirectiveDefinition), do: "directive" 49 defp struct_to_kind(Schema.ScalarTypeDefinition), do: "scalar" 50 defp struct_to_kind(Schema.ObjectTypeDefinition), do: "object" 51 defp struct_to_kind(Schema.InputObjectTypeDefinition), do: "input object" 52 defp struct_to_kind(Schema.EnumValueDefinition), do: "enum value" 53 defp struct_to_kind(_), do: "type" 54 55 @description """ 56 Name does not match possible #{inspect(@valid_name_regex)} regex. 57 58 > Names in GraphQL are limited to this ASCII subset of possible characters to 59 > support interoperation with as many other systems as possible. 60 61 Reference: https://graphql.github.io/graphql-spec/June2018/#sec-Names 62 63 """ 64 65 def explanation(%{artifact: artifact, value: value}) do 66 artifact_name = String.capitalize(artifact) 67 68 """ 69 #{artifact_name} #{inspect(value)} has invalid characters. 70 71 #{@description} 72 """ 73 end 74 end