improvement: builder & typespec improvements

This commit is contained in:
Zach Daniel 2023-03-20 23:11:04 -04:00
parent 6f6e820b21
commit 3c464b863f
3 changed files with 84 additions and 2 deletions

View file

@ -120,6 +120,8 @@ defmodule Ash.Resource.Actions.Read do
offset?: false
]
@type t :: %__MODULE__{}
def transform(pagination) do
if pagination.keyset? or pagination.offset? do
{:ok, pagination}
@ -131,7 +133,11 @@ defmodule Ash.Resource.Actions.Read do
def transform(read) do
if read.pagination do
{:ok, %{read | pagination: List.last(read.pagination) || false}}
if is_list(read.pagination) do
{:ok, %{read | pagination: List.last(read.pagination) || false}}
else
{:ok, %{read | pagination: read.pagination}}
end
else
{:ok, %{read | pagination: false}}
end

View file

@ -50,7 +50,8 @@ defmodule Ash.Resource.Builder do
) ::
{: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
with {:ok, opts} <-
handle_nested_builders(opts, [:changes, :arguments, :metadata, :pagination]) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:actions],
@ -60,6 +61,63 @@ defmodule Ash.Resource.Builder do
end
end
@doc """
Builds and adds a new relationship unless a relationship with that name already exists
"""
@spec add_new_relationship(
Spark.Dsl.Builder.input(),
type :: Ash.Resource.Relationships.type(),
name :: atom,
destination :: module,
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_new_relationship(dsl_state, type, name, destination, opts \\ []) do
if Ash.Resource.Info.relationship(dsl_state, name) do
dsl_state
else
add_relationship(dsl_state, type, name, destination, opts)
end
end
@doc """
Builds and adds an action
"""
@spec add_relationship(
Spark.Dsl.Builder.input(),
type :: Ash.Resource.Relationships.type(),
name :: atom,
destination :: module,
opts :: Keyword.t()
) ::
Spark.Dsl.Builder.result()
defbuilder add_relationship(dsl_state, type, name, destination, opts \\ []) do
with {:ok, relationship} <- build_relationship(type, name, destination, opts) do
Transformer.add_entity(dsl_state, [:relationships], relationship)
end
end
@doc """
Builds an action
"""
@spec build_relationship(
type :: Ash.Resource.Relationships.type(),
name :: atom,
destination :: module,
opts :: Keyword.t()
) ::
{:ok, Ash.Resource.Relationships.relationship()} | {:error, term}
def build_relationship(type, name, destination, opts \\ []) do
with {:ok, opts} <- handle_nested_builders(opts, [:changes, :arguments, :metadata]) do
Transformer.build_entity(
Ash.Resource.Dsl,
[:relationships],
type,
Keyword.merge(opts, name: name, destination: destination)
)
end
end
@doc """
Builds and adds a change
"""
@ -136,6 +194,21 @@ defmodule Ash.Resource.Builder do
)
end
@doc """
Builds a pagination object
"""
@spec build_pagination(pts :: Keyword.t()) ::
{:ok, Ash.Resource.Actions.Read.Pagination.t()} | {:error, term}
def build_pagination(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, :read],
:pagination,
opts
)
end
@doc """
Builds an action argument
"""
@ -341,6 +414,8 @@ defmodule Ash.Resource.Builder do
) ::
{:ok, Ash.Resource.Calculation.t()} | {:error, term}
def build_calculation(name, type, calculation, opts \\ []) do
opts = Keyword.put_new(opts, :arguments, [])
Transformer.build_entity(
Ash.Resource.Dsl,
[:calculations],

View file

@ -3,5 +3,6 @@ defmodule Ash.Resource.Relationships do
alias Ash.Resource.Relationships.{BelongsTo, HasMany, HasOne, ManyToMany}
@type relationship :: HasOne.t() | BelongsTo.t() | HasMany.t() | ManyToMany.t()
@type type :: :has_many | :has_one | :belongs_to | :many_to_many
@type cardinality :: :many | :one
end