Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ defmodule AshTypescript.Rpc.Codegen.FunctionGenerators.FunctionCore do
{updated_fields, true,
"Fields extends #{rpc_action_name_pascal}Fields | undefined = undefined"}

{:ok, :unconstrained_map, _} ->
{:ok, type, _} when type in [:unconstrained_map, :array_of_unconstrained_map] ->
# Unconstrained maps don't support field selection
{config_fields, false, nil}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ defmodule AshTypescript.Rpc.Codegen.Helpers.ActionIntrospection do
- `{:ok, :typed_struct, {module, fields}}` - Type with field constraints (TypedStruct or similar)
- `{:ok, :array_of_typed_struct, {module, fields}}` - Array of types with field constraints
- `{:ok, :unconstrained_map, nil}` - Map without field constraints
- `{:ok, :array_of_unconstrained_map, nil}` - Array of maps without field constraints
- `{:error, :not_generic_action}` - Not a generic action
- `{:error, reason}` - Other errors
"""
Expand Down Expand Up @@ -197,7 +198,11 @@ defmodule AshTypescript.Rpc.Codegen.Helpers.ActionIntrospection do
end

:unconstrained_map ->
{:ok, :unconstrained_map, nil}
if is_array do
{:ok, :array_of_unconstrained_map, nil}
else
{:ok, :unconstrained_map, nil}
end

{:error, reason} ->
{:error, reason}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,11 @@ defmodule AshTypescript.Rpc.Codegen.TypeGenerators.ResultTypes do
export type Infer#{rpc_action_name_pascal}Result = Record<string, any>;
"""

{:ok, :array_of_unconstrained_map, _} ->
"""
export type Infer#{rpc_action_name_pascal}Result = Array<Record<string, any>>;
"""

_ ->
if action.returns do
return_type = get_ts_type(%{type: action.returns, constraints: action.constraints})
Expand Down
15 changes: 10 additions & 5 deletions lib/ash_typescript/rpc/pipeline.ex
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ defmodule AshTypescript.Rpc.Pipeline do
when type in [:typed_map, :array_of_typed_map, :typed_struct, :array_of_typed_struct] ->
format_generic_action_output(data, action, formatter)

{:ok, :unconstrained_map, _} ->
{:ok, type, _} when type in [:unconstrained_map, :array_of_unconstrained_map] ->
format_field_names(data, formatter)

_ ->
Expand All @@ -1000,7 +1000,7 @@ defmodule AshTypescript.Rpc.Pipeline do

defp unconstrained_map_action?(action) do
case ActionIntrospection.action_returns_field_selectable_type?(action) do
{:ok, :unconstrained_map, _} -> true
{:ok, type, _} when type in [:unconstrained_map, :array_of_unconstrained_map] -> true
_ -> false
end
end
Expand All @@ -1019,9 +1019,14 @@ defmodule AshTypescript.Rpc.Pipeline do

:action ->
case ActionIntrospection.action_returns_field_selectable_type?(action) do
{:ok, :unconstrained_map, _} -> false
{:ok, _, _} -> true
_ -> false
{:ok, type, _} when type in [:unconstrained_map, :array_of_unconstrained_map] ->
false

{:ok, _, _} ->
true

_ ->
false
end

_ ->
Expand Down
40 changes: 40 additions & 0 deletions test/ash_typescript/rpc/rpc_run_action_generic_actions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,46 @@
end
end

describe "get_custom_data_list action (array of unconstrained maps)" do
setup do
conn = TestHelpers.build_rpc_conn()
%{conn: conn}
end

test "returns array of maps", %{conn: conn} do
result =
Rpc.run_action(:ash_typescript, conn, %{
"action" => "get_custom_data_list_todo"
})

assert result["success"] == true
data = result["data"]

assert is_list(data)
assert length(data) == 2

[first, second] = data
assert first["userId"] == "123e4567-e89b-12d3-a456-426614174000"
assert first["status"] == "active"
assert second["userId"] == "223e4567-e89b-12d3-a456-426614174001"
assert second["status"] == "pending"
end

test "generated result type is Array<Record<string, any>>" do

Check failure on line 532 in test/ash_typescript/rpc/rpc_run_action_generic_actions_test.exs

View workflow job for this annotation

GitHub Actions / ash-ci / mix test

test get_custom_data_list action (array of unconstrained maps) generated result type is Array<Record<string, any>> (AshTypescript.Rpc.RpcRunActionGenericActionsTest)
{:ok, typescript} = AshTypescript.Rpc.Codegen.generate_typescript_types(:ash_typescript)

assert typescript =~
"export type InferGetCustomDataListTodoResult = Array<Record<string, any>>;"
end

test "non-array unconstrained map result type remains Record<string, any>" do

Check failure on line 539 in test/ash_typescript/rpc/rpc_run_action_generic_actions_test.exs

View workflow job for this annotation

GitHub Actions / ash-ci / mix test

test get_custom_data_list action (array of unconstrained maps) non-array unconstrained map result type remains Record<string, any> (AshTypescript.Rpc.RpcRunActionGenericActionsTest)
{:ok, typescript} = AshTypescript.Rpc.Codegen.generate_typescript_types(:ash_typescript)

assert typescript =~
"export type InferGetCustomDataTodoResult = Record<string, any>;"
end
end

describe "complex return type validation" do
setup do
conn = TestHelpers.build_rpc_conn()
Expand Down
1 change: 1 addition & 0 deletions test/support/domain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ defmodule AshTypescript.Test.Domain do
rpc_action :get_keyword_options_todo, :get_keyword_options
rpc_action :get_coordinates_info_todo, :get_coordinates_info
rpc_action :get_custom_data_todo, :get_custom_data
rpc_action :get_custom_data_list_todo, :get_custom_data_list
rpc_action :destroy_todo, :destroy
rpc_action :assign_to_user_todo, :assign_to_user
rpc_action :assign_to_users_todo, :assign_to_users
Expand Down
10 changes: 10 additions & 0 deletions test/support/resources/todo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,16 @@ defmodule AshTypescript.Test.Todo do
end
end

action :get_custom_data_list, {:array, :map} do
run fn _input, _context ->
{:ok,
[
%{user_id: "123e4567-e89b-12d3-a456-426614174000", status: "active"},
%{user_id: "223e4567-e89b-12d3-a456-426614174001", status: "pending"}
]}
end
end

# Additional read action with different pagination configuration for testing
read :search_paginated do
argument :query, :string, allow_nil?: false
Expand Down
Loading