mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
improvement: registry resource validations transformers -> verifiers
improvement: better error message on unknown relationship
This commit is contained in:
parent
227344631f
commit
ce6b44525f
5 changed files with 55 additions and 76 deletions
|
@ -2,11 +2,12 @@ defmodule Ash.Registry.ResourceValidations do
|
|||
@moduledoc """
|
||||
Adds some top level validations of resources present in a registry
|
||||
"""
|
||||
@transformers [
|
||||
Ash.Registry.ResourceValidations.Transformers.EnsureResourcesCompiled,
|
||||
Ash.Registry.ResourceValidations.Transformers.ValidateRelatedResourceInclusion,
|
||||
Ash.Registry.ResourceValidations.Transformers.EnsureNoEmbeds
|
||||
|
||||
@verifiers [
|
||||
Ash.Registry.ResourceValidations.Verifiers.EnsureResourcesCompiled,
|
||||
Ash.Registry.ResourceValidations.Verifiers.ValidateRelatedResourceInclusion,
|
||||
Ash.Registry.ResourceValidations.Verifiers.EnsureNoEmbeds
|
||||
]
|
||||
|
||||
use Spark.Dsl.Extension, transformers: @transformers
|
||||
use Spark.Dsl.Extension, verifiers: @verifiers
|
||||
end
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
defmodule Ash.Registry.ResourceValidations.Transformers.ValidateRelatedResourceInclusion do
|
||||
@moduledoc """
|
||||
Ensures that all related resources are included in an API.
|
||||
"""
|
||||
use Spark.Dsl.Transformer
|
||||
alias Spark.Dsl.Transformer
|
||||
|
||||
@impl true
|
||||
def after_compile?, do: true
|
||||
|
||||
@impl true
|
||||
def after?(Ash.Registry.ResourceValidations.Transformers.EnsureResourcesCompiled), do: true
|
||||
def after?(_), do: false
|
||||
|
||||
@impl true
|
||||
def transform(dsl) do
|
||||
resources =
|
||||
dsl
|
||||
|> Transformer.get_entities([:entries])
|
||||
|> Enum.map(& &1.entry)
|
||||
|
||||
resources
|
||||
|> Enum.flat_map(&get_all_related_resources(&1, resources))
|
||||
|> Enum.uniq()
|
||||
|> Enum.reject(&(&1 in resources))
|
||||
|> case do
|
||||
[] ->
|
||||
{:ok, dsl}
|
||||
|
||||
resources ->
|
||||
raise "Resources #{Enum.map_join(resources, ", ", &inspect/1)} must be included in the registry."
|
||||
end
|
||||
end
|
||||
|
||||
defp get_all_related_resources(resource, checked) do
|
||||
resource
|
||||
|> Ash.Resource.Info.relationships()
|
||||
|> Enum.reject(& &1.api)
|
||||
|> Enum.flat_map(fn
|
||||
%{type: :many_to_many} = relationship ->
|
||||
[relationship.through, relationship.destination]
|
||||
|
||||
relationship ->
|
||||
[relationship.destination]
|
||||
end)
|
||||
|> Enum.reject(&(&1 in checked))
|
||||
|> Enum.flat_map(fn resource ->
|
||||
[resource | get_all_related_resources(resource, [resource | checked])]
|
||||
end)
|
||||
end
|
||||
end
|
|
@ -1,22 +1,19 @@
|
|||
defmodule Ash.Registry.ResourceValidations.Transformers.EnsureNoEmbeds do
|
||||
defmodule Ash.Registry.ResourceValidations.Verifiers.EnsureNoEmbeds do
|
||||
@moduledoc """
|
||||
Ensures that all resources for a given registry are not embeds.
|
||||
"""
|
||||
use Spark.Dsl.Transformer
|
||||
alias Spark.Dsl.Transformer
|
||||
use Spark.Dsl.Verifier
|
||||
alias Spark.Dsl.Verifier
|
||||
|
||||
@impl true
|
||||
def after_compile?, do: true
|
||||
|
||||
@impl true
|
||||
def transform(dsl) do
|
||||
def verify(dsl) do
|
||||
dsl
|
||||
|> Transformer.get_entities([:entries])
|
||||
|> Verifier.get_entities([:entries])
|
||||
|> Enum.map(& &1.entry)
|
||||
|> Enum.filter(&Ash.Resource.Info.embedded?/1)
|
||||
|> case do
|
||||
[] ->
|
||||
{:ok, dsl}
|
||||
:ok
|
||||
|
||||
rejected ->
|
||||
{:error,
|
|
@ -1,19 +1,15 @@
|
|||
defmodule Ash.Registry.ResourceValidations.Transformers.EnsureResourcesCompiled do
|
||||
defmodule Ash.Registry.ResourceValidations.Verifiers.EnsureResourcesCompiled do
|
||||
@moduledoc """
|
||||
Ensures that all resources for a given registry are compiled.
|
||||
"""
|
||||
use Spark.Dsl.Transformer
|
||||
alias Spark.Dsl.Transformer
|
||||
use Spark.Dsl.Verifier
|
||||
alias Spark.Dsl.Verifier
|
||||
|
||||
require Logger
|
||||
|
||||
@impl true
|
||||
def after_compile?, do: true
|
||||
|
||||
@impl true
|
||||
def transform(dsl) do
|
||||
def verify(dsl) do
|
||||
dsl
|
||||
|> Transformer.get_entities([:entries])
|
||||
|> Verifier.get_entities([:entries])
|
||||
|> Enum.map(& &1.entry)
|
||||
|> Enum.map(fn resource ->
|
||||
try do
|
||||
|
@ -37,7 +33,7 @@ defmodule Ash.Registry.ResourceValidations.Transformers.EnsureResourcesCompiled
|
|||
|> Enum.filter(& &1)
|
||||
|> case do
|
||||
[] ->
|
||||
{:ok, dsl}
|
||||
:ok
|
||||
|
||||
rejected ->
|
||||
for {resource, error} <- rejected do
|
||||
|
@ -46,7 +42,7 @@ defmodule Ash.Registry.ResourceValidations.Transformers.EnsureResourcesCompiled
|
|||
)
|
||||
end
|
||||
|
||||
{:ok, dsl}
|
||||
:ok
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
defmodule Ash.Registry.ResourceValidations.Verifiers.ValidateRelatedResourceInclusion do
|
||||
@moduledoc """
|
||||
Ensures that all related resources are included in an API.
|
||||
"""
|
||||
use Spark.Dsl.Verifier
|
||||
alias Spark.Dsl.Verifier
|
||||
|
||||
@impl true
|
||||
def verify(dsl) do
|
||||
resources =
|
||||
dsl
|
||||
|> Verifier.get_entities([:entries])
|
||||
|> Enum.map(& &1.entry)
|
||||
|
||||
for resource <- resources do
|
||||
for relationship <- Ash.Resource.Info.relationships(resource) do
|
||||
unless relationship.api || relationship.destination in resources do
|
||||
raise """
|
||||
Could not determine api for #{inspect(resource)}.#{relationship.name}. Please do one of the following:
|
||||
|
||||
1. Add the resource to the registry `#{Verifier.get_persisted(dsl, :module)}`
|
||||
|
||||
2. Set the `api` option on the relationship, for example:
|
||||
|
||||
|
||||
#{relationship.type} :#{relationship.name}, #{inspect(relationship.destination)} do
|
||||
api SomeOtherApi
|
||||
end
|
||||
"""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue