Packages

ash

2.6.2
3.29.3 3.29.2 3.29.1 3.29.0 3.28.0 3.27.8 3.27.7 3.27.6 3.27.5 3.27.4 3.27.3 3.27.2 3.27.1 3.27.0 3.26.0 3.25.2 3.25.1 3.25.0 retired 3.24.7 3.24.6 3.24.5 3.24.4 3.24.3 3.24.2 3.24.1 3.24.0 3.23.1 3.23.0 3.22.2 3.22.1 3.22.0 3.21.3 3.21.2 3.21.1 3.21.0 3.20.0 3.19.3 3.19.2 3.19.1 3.19.0 3.18.0 3.17.1 3.17.0 3.16.0 3.15.0 3.14.1 3.14.0 retired 3.13.2 3.13.1 3.13.0 3.12.0 3.11.3 3.11.2 3.11.1 3.11.0 3.10.1 3.10.0 3.9.0 3.8.0 3.7.6 3.7.5 3.7.4 3.7.3 3.7.2 3.7.1 3.7.0 retired 3.6.3 retired 3.6.2 3.6.1 3.6.0 3.5.43 3.5.42 3.5.41 3.5.40 3.5.39 3.5.38 3.5.37 3.5.36 3.5.35 3.5.34 3.5.33 3.5.32 3.5.31 3.5.30 3.5.29 3.5.28 3.5.27 3.5.26 3.5.25 3.5.24 3.5.23 3.5.22 3.5.21 3.5.20 3.5.19 3.5.18 3.5.17 3.5.16 3.5.15 3.5.14 3.5.13 3.5.12 3.5.11 3.5.10 3.5.9 3.5.8 3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.74 retired 3.4.73 3.4.72 3.4.71 3.4.70 3.4.69 3.4.68 3.4.67 3.4.66 3.4.65 3.4.64 3.4.63 3.4.62 3.4.61 3.4.60 3.4.59 3.4.58 3.4.57 3.4.56 3.4.55 3.4.54 3.4.53 3.4.52 3.4.51 3.4.50 3.4.49 3.4.48 3.4.47 3.4.46 3.4.45 3.4.44 3.4.43 3.4.42 3.4.41 3.4.40 3.4.39 3.4.38 3.4.37 3.4.36 3.4.35 3.4.34 3.4.33 3.4.32 3.4.31 3.4.30 3.4.29 3.4.28 3.4.27 3.4.26 3.4.25 3.4.24 3.4.23 3.4.22 3.4.21 3.4.20 3.4.19 3.4.18 3.4.17 3.4.16 3.4.15 3.4.14 3.4.13 3.4.12 3.4.11 3.4.10 3.4.9 3.4.8 3.4.7 3.4.6 3.4.5 3.4.4 3.4.3 3.4.2 3.4.1 3.4.0 3.3.3 3.3.2 3.3.1 3.3.0 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 3.2.0 3.1.8 3.1.7 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.16 3.0.15 3.0.14 3.0.13 3.0.12 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.4 3.0.3 3.0.2 3.0.1 3.0.0 3.0.0-rc.46 3.0.0-rc.45 3.0.0-rc.44 3.0.0-rc.43 3.0.0-rc.42 3.0.0-rc.41 3.0.0-rc.40 3.0.0-rc.39 3.0.0-rc.38 3.0.0-rc.37 3.0.0-rc.36 3.0.0-rc.35 3.0.0-rc.34 3.0.0-rc.33 3.0.0-rc.32 3.0.0-rc.31 3.0.0-rc.29 3.0.0-rc.28 3.0.0-rc.27 3.0.0-rc.26 3.0.0-rc.25 3.0.0-rc.24 3.0.0-rc.23 3.0.0-rc.22 3.0.0-rc.21 3.0.0-rc.20 3.0.0-rc.19 3.0.0-rc.18 3.0.0-rc.17 3.0.0-rc.16 3.0.0-rc.15 3.0.0-rc.14 3.0.0-rc.13 3.0.0-rc.12 3.0.0-rc.11 3.0.0-rc.10 3.0.0-rc.9 3.0.0-rc.8 3.0.0-rc.7 3.0.0-rc.6 3.0.0-rc.5 3.0.0-rc.4 3.0.0-rc.3 3.0.0-rc.1 3.0.0-rc.0 2.21.15 2.21.14 2.21.13 2.21.12 2.21.11 2.21.10 2.21.9 2.21.8 2.21.7 2.21.6 2.21.5 2.21.4 2.21.3 2.21.2 2.21.1 2.21.0 2.20.3 2.20.2 2.20.1 2.20.0 2.19.14 2.19.13 2.19.12 2.19.11 2.19.10 2.19.9 2.19.8 2.19.7 2.19.6 2.19.5 2.19.4 2.19.3 retired 2.19.2 retired 2.19.1 retired 2.19.0 retired 2.18.2 2.18.1 2.18.0 2.17.24 2.17.23 2.17.22 2.17.21 2.17.20 2.17.19 2.17.18 2.17.17 2.17.16 2.17.15 2.17.14 2.17.13 2.17.12 2.17.11 2.17.10 2.17.9 2.17.8 2.17.7 2.17.6 2.17.5 2.17.4 2.17.3 2.17.2 2.17.1 2.17.0 2.16.1 2.16.0 2.15.20 2.15.19 2.15.18 2.15.17 2.15.16 2.15.15 2.15.14 2.15.13 2.15.12 2.15.11 2.15.10 2.15.9 2.15.8 2.15.7 2.15.6 2.15.5 2.15.4 2.15.2 2.15.1 2.15.0 2.14.21 2.14.20 2.14.19 2.14.18 2.14.17 2.14.16 2.14.15 2.14.14 2.14.13 2.14.12 2.14.11 2.14.10 2.14.9 2.14.8 2.14.7 2.14.6 2.14.5 2.14.4 2.14.3 2.14.2 2.14.1 2.14.0 2.13.4 retired 2.13.3 2.13.2 2.13.1 2.13.0 2.12.1 2.12.0 2.11.11 2.11.10 2.11.9 2.11.8 2.11.7 2.11.6 2.11.5 2.11.4 2.11.3 2.11.2 2.11.1 2.11.0 2.11.0-rc.3 2.11.0-rc.2 2.11.0-rc.1 2.11.0-rc.0 2.10.2 2.10.1 2.10.0 2.9.29 2.9.28 2.9.27 2.9.26 2.9.25 2.9.24 2.9.23 2.9.22 2.9.21 2.9.20 2.9.19 2.9.18 2.9.17 2.9.16 2.9.15 2.9.14 2.9.13 2.9.12 2.9.11 2.9.10 2.9.9 2.9.8 2.9.7 2.9.6 2.9.5 2.9.4 2.9.3 2.9.2 2.9.1 2.9.0 2.8.1 2.8.0 2.7.1 2.7.0 2.6.31 2.6.30 2.6.29 2.6.28 2.6.27 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 2.6.2 2.6.1 2.6.0 2.5.16 2.5.15 2.5.14 2.5.13 2.5.12 2.5.11 2.5.10 2.5.9 2.5.8 2.5.7 2.5.6 2.5.5 2.5.4 2.5.3 2.5.2 2.5.1 2.5.0 2.5.0-rc.6 2.5.0-rc.5 2.5.0-rc.4 2.5.0-rc.3 2.5.0-rc.2 2.5.0-rc.1 2.5.0-rc.0 2.4.30 2.4.29 2.4.28 2.4.27 2.4.26 2.4.25 2.4.24 2.4.23 2.4.22 2.4.21 2.4.20 2.4.19 2.4.18 2.4.17 2.4.16 2.4.15 2.4.14 2.4.13 2.4.12 2.4.11 2.4.10 2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 2.3.0 2.2.0 2.1.0 2.0.0 2.0.0-rc.15 2.0.0-rc.14 2.0.0-rc.13 2.0.0-rc.12 2.0.0-rc.11 2.0.0-rc.10 2.0.0-rc.9 2.0.0-rc.8 2.0.0-rc.7 2.0.0-rc.6 2.0.0-rc.5 2.0.0-rc.4 2.0.0-rc.3 2.0.0-rc.2 2.0.0-rc.1 2.0.0-rc.0 2.0.0-pre.8 2.0.0-pre.7 2.0.0-pre.6 2.0.0-pre.5 2.0.0-pre.4 2.0.0-pre.3 2.0.0-pre.2 2.0.0-pre.1 2.0.0-pre.0 1.53.3 1.53.2 1.53.0 1.52.0-rc.22 1.52.0-rc.21 1.52.0-rc.20 1.52.0-rc.19 1.52.0-rc.18 1.52.0-rc.17 1.52.0-rc.16 1.52.0-rc.15 1.52.0-rc.14 1.52.0-rc.13 1.52.0-rc.12 1.52.0-rc.11 1.52.0-rc.10 1.52.0-rc.9 1.52.0-rc.8 1.52.0-rc.7 1.52.0-rc.6 1.52.0-rc.5 1.52.0-rc.4 1.52.0-rc.3 1.52.0-rc.2 1.52.0-rc.1 1.52.0-rc.0 1.51.2 1.51.1 retired 1.51.0 1.50.21 1.50.20 1.50.19 1.50.18 1.50.17 1.50.16 1.50.15 1.50.14 1.50.13 1.50.12 1.50.11 1.50.10 1.50.9 1.50.8 1.50.7 1.50.6 1.50.5 1.50.4 1.50.3 1.50.2 1.50.1 1.50.0 1.49.0 1.48.0-rc.30 1.48.0-rc.29 1.48.0-rc.28 1.48.0-rc.27 1.48.0-rc.26 1.48.0-rc.25 1.48.0-rc.24 1.48.0-rc.23 1.48.0-rc.22 1.48.0-rc.21 1.48.0-rc.20 1.48.0-rc.19 1.48.0-rc.18 1.48.0-rc.17 1.48.0-rc.16 1.48.0-rc.15 1.48.0-rc.14 1.48.0-rc.13 1.48.0-rc.12 1.48.0-rc.11 1.48.0-rc.10 1.48.0-rc.9 1.48.0-rc.8 1.48.0-rc.7 1.48.0-rc.6 1.48.0-rc.5 1.48.0-rc.4 1.48.0-rc.3 1.48.0-rc.2 1.48.0-rc.1 1.48.0-rc.0 1.47.12 1.47.11 1.47.10 1.47.9 1.47.8 1.47.7 1.47.6 1.47.5 1.47.4 1.47.3 1.47.2 1.47.1 1.47.0 1.46.13 1.46.12 1.46.11 1.46.10 1.46.9 1.46.8 1.46.7 1.46.6 1.46.5 1.46.4 1.46.3 1.46.2 1.46.1 1.46.0 1.45.0-rc9 1.45.0-rc8 1.45.0-rc7 1.45.0-rc6 1.45.0-rc5 1.45.0-rc4 1.45.0-rc3 1.45.0-rc20 1.45.0-rc2 1.45.0-rc19 1.45.0-rc18 1.45.0-rc17 1.45.0-rc16 1.45.0-rc15 1.45.0-rc14 1.45.0-rc13 1.45.0-rc12 1.45.0-rc11 1.45.0-rc10 1.45.0-rc1 1.45.0-rc0 1.44.13 1.44.12 1.44.11 1.44.10 1.44.9 1.44.8 1.44.7 1.44.6 1.44.5 1.44.4 1.44.3 1.44.2 1.44.1 1.44.0 1.43.12 1.43.11 1.43.10 1.43.9 1.43.8 1.43.7 1.43.6 1.43.5 1.43.4 1.43.3 1.43.2 1.43.1 1.43.0 1.42.0 1.41.12 1.41.11 1.41.10 1.41.9 1.41.8 1.41.7 1.41.6 1.41.5 1.41.4 1.41.3 1.41.2 1.41.1 1.41.0 1.40.0 1.39.7 1.39.6 1.39.5 1.39.4 1.39.3 1.39.2 1.39.1 1.39.0 1.38.0 1.37.2 1.37.1 1.37.0 1.36.22 1.36.21 1.36.19 1.36.18 1.36.17 1.36.16 1.36.15 1.36.14 1.36.13 1.36.12 1.36.11 1.36.10 1.36.9 1.36.8 1.36.7 1.36.6 1.36.5 1.36.4 1.36.3 1.36.2 1.36.0 1.35.1 1.35.0 1.34.9 1.34.8 1.34.7 1.34.6 1.34.5 1.34.4 1.34.3 1.34.2 1.34.1 1.34.0 1.33.0 1.32.2 1.32.1 1.32.0 1.31.1 1.31.0 1.30.2 1.30.1 1.29.0-rc1 1.29.0-rc0 1.28.1 1.28.0 1.27.1 1.27.0 1.26.13 1.26.12 1.26.11 1.26.10 1.26.9 1.26.8 1.26.7 1.26.6 1.26.5 1.26.4 1.26.2 1.26.1 1.26.0 1.25.8 1.25.7 1.25.6 1.25.5 1.25.4 1.25.3 1.25.2 1.25.1 1.25.0 1.24.2 1.24.1 1.24.0 1.23.3 1.23.2 1.23.1 1.23.0 1.22.1 1.22.0 1.20.1 1.20.0 1.19.1 1.19.0 1.18.1 1.18.0 1.17.1 1.17.0 1.16.2 1.15.1 1.15.0 1.14.0 1.13.4 1.13.3 1.13.2 1.13.1 1.13.0 1.12.0 1.11.1 1.11.0 1.10.0 1.9.0 1.8.0 1.7.0 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.1 1.5.0 1.4.1 1.4.0 1.3.1 1.3.0 1.2.1 1.2.0 1.1.3 1.1.2 1.1.0 1.0.3 1.0.2 1.0.1 1.0.0 0.13.1 0.13.0 0.12.0 0.10.0 0.9.1 0.9.0 0.8.0 0.7.0 0.6.5 0.6.4 0.6.3 0.6.2 0.6.1 0.6.0 0.5.2 0.5.1 0.5.0 0.4.0 0.3.0 0.2.0 0.1.9 0.1.8 0.1.3 0.1.1 0.1.0

A declarative, extensible framework for building Elixir applications.

Security advisory: This version has known vulnerabilities. View advisories

Current section

Files

Jump to
ash lib ash resource builder.ex
Raw

lib/ash/resource/builder.ex

defmodule Ash.Resource.Builder do
@moduledoc """
Tools for transforming resources in DSL Transformers.
"""
alias Spark.Dsl.Transformer
use Spark.Dsl.Builder
@doc """
Builds and adds a new action unless an action with that name already exists
"""
@spec add_new_action(
Spark.Dsl.Builder.input(),
type :: Ash.Resource.Actions.action_type(),
name :: atom,
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_new_action(dsl_state, type, name, opts \\ []) do
if Ash.Resource.Info.action(dsl_state, name) do
dsl_state
else
add_action(dsl_state, type, name, opts)
end
end
@doc """
Builds and adds an action
"""
@spec add_action(
Spark.Dsl.Builder.input(),
type :: Ash.Resource.Actions.action_type(),
name :: atom,
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_action(dsl_state, type, name, opts \\ []) do
with {:ok, action} <- build_action(type, name, opts) do
Transformer.add_entity(dsl_state, [:actions], action)
end
end
@doc """
Builds an action
"""
@spec build_action(
type :: Ash.Resource.Actions.action_type(),
name :: atom,
opts :: Keyword.t()
) ::
{:ok, Ash.Resource.Actions.action()} | {:error, term}
def build_action(type, name, opts \\ []) do
with {:ok, opts} <- handle_nested_builders(opts, [:changes, :arguments, :metadata]) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:actions],
type,
Keyword.merge(opts, name: name)
)
end
end
@doc """
Builds and adds a change
"""
@spec add_change(
Spark.Dsl.Builder.input(),
ref :: module | {module, Keyword.t()},
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_change(dsl_state, ref, opts \\ []) do
ref =
case ref do
{module, opts} -> {module, opts}
module -> {module, []}
end
with {:ok, change} <- build_change(ref, opts) do
Transformer.add_entity(dsl_state, [:changes], change)
end
end
@doc """
Builds a change
"""
@spec build_change(
ref :: module | {module, Keyword.t()},
opts :: Keyword.t()
) ::
{:ok, Ash.Resource.Change.t()} | {:error, term}
def build_change(ref, opts \\ []) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:changes],
:change,
Keyword.merge(opts, change: ref)
)
end
@doc """
Builds and adds a preparation
"""
@spec add_preparation(
Spark.Dsl.Builder.input(),
ref :: module | {module, Keyword.t()},
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_preparation(dsl_state, ref, opts \\ []) do
ref =
case ref do
{module, opts} -> {module, opts}
module -> {module, []}
end
with {:ok, preparation} <- build_preparation(ref, opts) do
Transformer.add_entity(dsl_state, [:preparations], preparation)
end
end
@doc """
Builds a preparation
"""
@spec build_preparation(
ref :: module | {module, Keyword.t()},
opts :: Keyword.t()
) ::
{:ok, Ash.Resource.Preparation.t()} | {:error, term}
def build_preparation(ref, opts \\ []) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:preparations],
:prepare,
Keyword.merge(opts, preparation: ref)
)
end
@doc """
Builds an action argument
"""
@spec build_action_argument(name :: atom, type :: Ash.Type.t(), opts :: Keyword.t()) ::
{:ok, Ash.Resource.Actions.Argument.t()} | {:error, term}
def build_action_argument(name, type, opts \\ []) do
Transformer.build_entity(
Ash.Resource.Dsl,
# All action types that support arguments have the same entity, so we just say `create` here
[:actions, :create],
:argument,
Keyword.merge(opts, name: name, type: type)
)
end
@doc """
Builds an action change
"""
@spec build_action_change(change :: Ash.Resource.Change.ref(), opts :: Keyword.t()) ::
{:ok, Ash.Resource.Change.t()} | {:error, term}
def build_action_change(change, opts \\ []) do
Transformer.build_entity(
Ash.Resource.Dsl,
# All action types that support changes have the same change entity, so we just say `create` here
[:actions, :create],
:change,
Keyword.put(opts, :change, change)
)
end
@doc """
Builds and adds an update_timestamp unless an update_timestamp with that name already exists
"""
@spec add_new_update_timestamp(Spark.Dsl.Builder.input(), name :: atom, opts :: Keyword.t()) ::
Spark.Dsl.Builder.result()
defbuilder add_new_update_timestamp(dsl_state, name, opts \\ []) do
if Ash.Resource.Info.attribute(dsl_state, name) do
dsl_state
else
add_update_timestamp(dsl_state, name, opts)
end
end
@doc """
Builds and adds an update_timestamp
"""
@spec add_update_timestamp(Spark.Dsl.Builder.input(), name :: atom, opts :: Keyword.t()) ::
Spark.Dsl.Builder.result()
defbuilder add_update_timestamp(dsl_state, name, opts \\ []) do
with {:ok, update_timestamp} <- build_update_timestamp(name, opts) do
Transformer.add_entity(dsl_state, [:attributes], update_timestamp)
end
end
@doc """
Builds an update_timestamp with the given name, type, and options
"""
@spec build_update_timestamp(name :: atom, opts :: Keyword.t()) ::
{:ok, Ash.Resource.Attribute.t()} | {:error, term}
def build_update_timestamp(name, opts \\ []) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:attributes],
:update_timestamp,
Keyword.merge(opts, name: name)
)
end
@doc """
Builds and adds a create_timestamp unless a create_timestamp with that name already exists
"""
@spec add_new_create_timestamp(Spark.Dsl.Builder.input(), name :: atom, opts :: Keyword.t()) ::
Spark.Dsl.Builder.result()
defbuilder add_new_create_timestamp(dsl_state, name, opts \\ []) do
if Ash.Resource.Info.attribute(dsl_state, name) do
dsl_state
else
add_create_timestamp(dsl_state, name, opts)
end
end
@doc """
Builds and adds a create_timestamp to a resource
"""
@spec add_create_timestamp(
Spark.Dsl.Builder.input(),
name :: atom,
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_create_timestamp(dsl_state, name, opts \\ []) do
with {:ok, create_timestamp} <- build_create_timestamp(name, opts) do
Transformer.add_entity(dsl_state, [:attributes], create_timestamp)
end
end
@doc """
Builds an create_timestamp with the given name, type, and options
"""
@spec build_create_timestamp(name :: atom, opts :: Keyword.t()) ::
{:ok, Ash.Resource.Attribute.t()} | {:error, term}
def build_create_timestamp(name, opts \\ []) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:attributes],
:create_timestamp,
Keyword.merge(opts, name: name)
)
end
@doc """
Builds and adds an attribute unless an attribute with that name already exists
"""
@spec add_new_attribute(
Spark.Dsl.Builder.input(),
name :: atom,
type :: Ash.Type.t(),
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_new_attribute(dsl_state, name, type, opts \\ []) do
if Ash.Resource.Info.attribute(dsl_state, name) do
{:ok, dsl_state}
else
add_attribute(dsl_state, name, type, opts)
end
end
@doc """
Builds and adds an attribute to a resource
"""
@spec add_attribute(
Spark.Dsl.Builder.input(),
name :: atom,
type :: Ash.Type.t(),
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_attribute(dsl_state, name, type, opts \\ []) do
with {:ok, attribute} <- build_attribute(name, type, opts) do
Transformer.add_entity(dsl_state, [:attributes], attribute)
end
end
@doc """
Builds an attribute with the given name, type, and options
"""
@spec build_attribute(name :: atom, type :: Ash.Type.t(), opts :: Keyword.t()) ::
{:ok, Ash.Resource.Attribute.t()} | {:error, term}
def build_attribute(name, type, opts \\ []) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:attributes],
:attribute,
Keyword.merge(opts, name: name, type: type)
)
end
@doc """
Builds and adds a calculation unless a calculation with that name already exists
"""
@spec add_new_calculation(
Spark.Dsl.Builder.input(),
name :: atom,
type :: Ash.Type.t(),
calculation :: module | {module, Keyword.t()},
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_new_calculation(dsl_state, name, type, calculation, opts \\ []) do
if Ash.Resource.Info.calculation(dsl_state, name) do
{:ok, dsl_state}
else
add_calculation(dsl_state, name, type, calculation, opts)
end
end
@doc """
Builds and adds a calculation to a resource
"""
@spec add_calculation(
Spark.Dsl.Builder.input(),
name :: atom,
type :: Ash.Type.t(),
calculation :: module | {module, Keyword.t()},
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_calculation(dsl_state, name, type, calculation, opts \\ []) do
with {:ok, calculation} <- build_calculation(name, type, calculation, opts) do
Transformer.add_entity(dsl_state, [:calculations], calculation)
end
end
@doc """
Builds a calculation with the given name, type, and options
"""
@spec build_calculation(
name :: atom,
type :: Ash.Type.t(),
calculation :: module | {module, Keyword.t()},
opts :: Keyword.t()
) ::
{:ok, Ash.Resource.Calculation.t()} | {:error, term}
def build_calculation(name, type, calculation, opts \\ []) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:calculations],
:calculate,
Keyword.merge(opts, name: name, type: type, calculation: calculation)
)
end
end