Packages
ash_graphql
1.8.3
1.10.0
1.9.4
1.9.3
1.9.2
1.9.1
1.9.0
1.8.5
1.8.4
1.8.3
1.8.2
1.8.1
1.8.0
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.0
1.5.1
1.5.0
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.5
1.0.0-rc.4
retired
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.28.1
0.28.0
0.27.1
0.27.0
0.26.9
0.26.8
0.26.7
0.26.6
0.26.5
0.26.4
0.26.3
0.26.2
0.26.0
0.25.13
0.25.12
0.25.10
0.25.9
0.25.8
0.25.7
0.25.6
0.25.5
0.25.4
0.25.3
0.25.2
0.25.1
0.25.0
0.24.1
0.24.0
0.23.3
0.23.2
0.23.1
0.23.0
0.22.13
0.22.12
0.22.11
0.22.10
0.22.9
0.22.8
0.22.7
0.22.6
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.0
retired
0.20.5
0.20.4
0.20.3
0.20.2
0.20.1
0.20.0-rc.3
0.20.0-rc.2
0.20.0-rc.1
0.20.0-rc.0
0.19.0
0.18.0-rc0
0.17.5
0.17.5-rc0
0.17.4
0.17.2
0.17.1
0.17.0
0.16.28
0.16.27
0.16.26
0.16.25
0.16.24
0.16.23
0.16.22
0.16.21
0.16.20
0.16.18-rc5
0.16.18-rc4
0.16.18-rc3
0.16.18-rc2
0.16.18-rc1
0.16.18-rc0
0.16.17
0.16.16
0.16.15
0.16.14
0.16.13
0.16.12
0.16.11
0.16.10
0.16.9
0.16.8
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.1
0.14.0
0.13.1
0.13.0
0.12.5
0.12.4
0.12.3
0.12.1
0.12.0
0.10.0
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.3
0.1.2
The extension for building GraphQL APIs with Ash
Current section
Files
Jump to
Current section
Files
lib/resource/transformers/validate_compatible_names.ex
defmodule AshGraphql.Resource.Transformers.ValidateCompatibleNames do
# Ensures that all field names are valid or remapped to something valid exist
@moduledoc false
use Spark.Dsl.Transformer
alias Spark.Dsl.Transformer
def after_compile?, do: true
def transform(dsl) do
field_names = AshGraphql.Resource.Info.field_names(dsl)
argument_names = AshGraphql.Resource.Info.argument_names(dsl)
resource = Transformer.get_persisted(dsl, :module)
dsl
|> Ash.Resource.Info.public_attributes()
|> Enum.concat(Ash.Resource.Info.public_aggregates(dsl))
|> Enum.concat(Ash.Resource.Info.public_calculations(dsl))
|> Enum.concat(Ash.Resource.Info.public_relationships(dsl))
|> Enum.filter(&AshGraphql.Resource.Info.show_field?(resource, &1.name))
|> Enum.each(fn field ->
name = field_names[field.name] || field.name
if invalid_name?(name) do
raise_invalid_name_error(resource, field, name)
end
end)
dsl
|> Transformer.get_entities([:graphql, :queries])
|> Enum.concat(Transformer.get_entities(dsl, [:graphql, :mutations]))
|> Enum.map(& &1.action)
|> Enum.uniq()
|> Enum.each(fn action ->
action = Ash.Resource.Info.action(dsl, action)
Enum.each(action.arguments, fn argument ->
name = argument_names[action.name][argument.name] || argument.name
if invalid_name?(name) do
raise_invalid_argument_name_error(resource, action, argument.name, name)
end
end)
end)
{:ok, dsl}
end
defp invalid_name?(name) do
Regex.match?(~r/_+\d/, to_string(name))
end
defp raise_invalid_name_error(resource, field, name) do
path =
case field do
%Ash.Resource.Relationships.BelongsTo{} -> [:relationships, :belongs_to, field.name]
%Ash.Resource.Relationships.HasMany{} -> [:relationships, :has_many, field.name]
%Ash.Resource.Relationships.HasOne{} -> [:relationships, :has_one, field.name]
%Ash.Resource.Relationships.ManyToMany{} -> [:relationships, :many_to_many, field.name]
%Ash.Resource.Calculation{} -> [:calculations, field.name]
%Ash.Resource.Aggregate{} -> [:aggregates, field.name]
%Ash.Resource.Attribute{} -> [:attributes, field.name]
end
raise Spark.Error.DslError,
module: resource,
path: path,
message: """
Name #{name} is invalid.
Due to issues in the underlying tooling with camel/snake case conversion of names that
include underscores immediately preceding integers, a different name must be provided to
use in the graphql. To do so, add a mapping in your configured field_names, i.e
graphql do
...
field_names #{name}: :#{make_name_better(name)}
...
end
For more information on the underlying issue, see: https://github.com/absinthe-graphql/absinthe/issues/601
"""
end
defp raise_invalid_argument_name_error(resource, action, argument_name, name) do
path = [:actions, action.type, action.name, :argument, argument_name]
raise Spark.Error.DslError,
module: resource,
path: path,
message: """
Name #{name} is invalid.
Due to issues in the underlying tooling with camel/snake case conversion of names that
include underscores immediately preceding integers, a different name must be provided to
use in the graphql. To do so, add a mapping in your configured argument_names, i.e
graphql do
...
argument_names #{action.name}: [#{argument_name}: :#{make_name_better(name)}]
...
end
For more information on the underlying issue, see: https://github.com/absinthe-graphql/absinthe/issues/601
"""
end
defp make_name_better(name) do
name
|> to_string()
|> String.replace(~r/_+\d/, fn v ->
String.trim_leading(v, "_")
end)
end
end