Packages
ash_graphql
1.9.4
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/verifiers/verify_field_references.ex
# SPDX-FileCopyrightText: 2020 ash_graphql contributors <https://github.com/ash-project/ash_graphql/graphs/contributors>
#
# SPDX-License-Identifier: MIT
defmodule AshGraphql.Resource.Verifiers.VerifyFieldReferences do
# Validates that field names referenced in graphql DSL options actually exist on the resource.
@moduledoc false
use Spark.Dsl.Verifier
alias Spark.Dsl.Transformer
def verify(dsl) do
resource = Transformer.get_persisted(dsl, :module)
attribute_names = dsl |> Ash.Resource.Info.public_attributes() |> MapSet.new(& &1.name)
relationship_names = dsl |> Ash.Resource.Info.public_relationships() |> MapSet.new(& &1.name)
calculation_names = dsl |> Ash.Resource.Info.public_calculations() |> MapSet.new(& &1.name)
aggregate_names = dsl |> Ash.Resource.Info.public_aggregates() |> MapSet.new(& &1.name)
all_fields =
attribute_names
|> MapSet.union(relationship_names)
|> MapSet.union(calculation_names)
|> MapSet.union(aggregate_names)
non_relationship_fields =
attribute_names
|> MapSet.union(calculation_names)
|> MapSet.union(aggregate_names)
all_fields_desc = "attribute, relationship, calculation, or aggregate"
validate_option(dsl, resource, :show_fields, all_fields, all_fields_desc)
validate_option(dsl, resource, :hide_fields, all_fields, all_fields_desc)
validate_option(dsl, resource, :field_names, all_fields, all_fields_desc)
validate_option(dsl, resource, :nullable_fields, all_fields, all_fields_desc)
validate_option(dsl, resource, :filterable_fields, all_fields, all_fields_desc)
validate_option(
dsl,
resource,
:sortable_fields,
non_relationship_fields,
"attribute, calculation, or aggregate"
)
validate_option(dsl, resource, :relationships, relationship_names, "relationship")
validate_option(dsl, resource, :attribute_input_types, attribute_names, "attribute")
:ok
end
defp validate_option(dsl, resource, option, valid_fields, field_type_desc) do
value = get_option(dsl, option)
if is_list(value) do
Enum.each(value, fn
field when is_atom(field) ->
validate_field_exists(resource, option, field, valid_fields, field_type_desc)
{field, _value} when is_atom(field) ->
validate_field_exists(resource, option, field, valid_fields, field_type_desc)
_ ->
:ok
end)
end
end
defp validate_field_exists(resource, option, field, valid_fields, field_type_desc) do
if not MapSet.member?(valid_fields, field) do
available = valid_fields |> MapSet.to_list() |> Enum.sort()
raise Spark.Error.DslError,
module: resource,
path: [:graphql, option],
message: """
Unknown #{field_type_desc} `#{inspect(field)}` in `#{option}`.
Available: #{inspect(available)}
"""
end
end
defp get_option(dsl, :show_fields), do: AshGraphql.Resource.Info.show_fields(dsl)
defp get_option(dsl, :hide_fields), do: AshGraphql.Resource.Info.hide_fields(dsl)
defp get_option(dsl, :field_names), do: AshGraphql.Resource.Info.field_names(dsl)
defp get_option(dsl, :nullable_fields), do: AshGraphql.Resource.Info.nullable_fields(dsl)
defp get_option(dsl, :sortable_fields), do: AshGraphql.Resource.Info.sortable_fields(dsl)
defp get_option(dsl, :filterable_fields), do: AshGraphql.Resource.Info.filterable_fields(dsl)
defp get_option(dsl, :attribute_input_types),
do: AshGraphql.Resource.Info.attribute_input_types(dsl)
# relationships/1 in Info falls back to all public relationships when nil,
# so we read the raw option to only validate when explicitly set by the user.
defp get_option(dsl, :relationships) do
Spark.Dsl.Extension.get_opt(dsl, [:graphql], :relationships, nil)
end
end