defmodule Ash.Resource.Transformers.ValidateAccept do @moduledoc "Validates that accept and reject lists only contain valid attributes" use Spark.Dsl.Transformer alias Spark.Dsl.Transformer alias Spark.Error.DslError @impl true def after_compile?, do: true @impl true def transform(dsl_state) do {private_attributes, public_attributes} = dsl_state |> Transformer.get_entities([:attributes]) |> Enum.split_with(& &1.private?) public_attribute_names = MapSet.new(public_attributes, & &1.name) private_attribute_names = MapSet.new(private_attributes, & &1.name) Transformer.get_entities(dsl_state, [:actions]) |> Enum.each(fn %{name: action_name, accept: accept, reject: reject} -> validate_attribute_name = fn attribute_name, type -> cond do MapSet.member?(private_attribute_names, attribute_name) -> raise DslError, path: [:actions, action_name, type, attribute_name], message: "#{attribute_name} is a private attribute" MapSet.member?(public_attribute_names, attribute_name) -> :ok true -> raise DslError, path: [:actions, action_name, type, attribute_name], message: "#{attribute_name} is not an attribute" end end Enum.each( accept, &validate_attribute_name.( &1, :accept ) ) Enum.each( reject, &validate_attribute_name.( &1, :reject ) ) _ -> :ok end) :ok end end