Skip to content

Commit

Permalink
improvement: WIP on open api resource generator
Browse files Browse the repository at this point in the history
improvement: update ash
  • Loading branch information
zachdaniel committed Sep 25, 2023
1 parent de000a8 commit 418de7a
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 64 deletions.
2 changes: 0 additions & 2 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import Config

config :ash, :use_all_identities_in_manage_relationship?, false

if Mix.env() == :dev do
config :git_ops,
mix_project: AshJsonApiWrapper.MixProject,
Expand Down
17 changes: 14 additions & 3 deletions lib/data_layer/data_layer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,10 @@ defmodule AshJsonApiWrapper.DataLayer do
AshJsonApiWrapper.Helpers.put_at_path(query, field, value)

{:place_in_list, path, value}, query ->
update_in!(query, path, [], &[value | &1])
update_in!(query, path, [value], &[value | &1])

{:place_in_csv_list, path, value}, query ->
update_in!(query, path, "#{value}", &"#{&1},#{value}")
end)

{:ok,
Expand Down Expand Up @@ -404,7 +407,16 @@ defmodule AshJsonApiWrapper.DataLayer do
AshJsonApiWrapper.Filter.find_place_in_list_filter(
filter,
field.name,
path
path,
:place_in_list
)

{:place_in_csv_list, path} ->
AshJsonApiWrapper.Filter.find_place_in_list_filter(
filter,
field.name,
path,
:place_in_csv_list
)
end

Expand Down Expand Up @@ -800,7 +812,6 @@ defmodule AshJsonApiWrapper.DataLayer do
else
case endpoint.entity_path do
nil ->
IO.inspect(endpoint)
{:ok, List.wrap(body)}

path ->
Expand Down
2 changes: 1 addition & 1 deletion lib/data_layer/transformers/set_endpoint_defaults.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule AshJsonApiWrapper.DataLayer.Transformers.SetEndpointDefaults do
def transform(dsl) do
base_entity_path = AshJsonApiWrapper.DataLayer.Info.base_entity_path(dsl)
base_paginator = AshJsonApiWrapper.DataLayer.Info.base_paginator(dsl)
base_fields = AshJsonApiWrapper.DataLayer.Info.fields(dsl) |> IO.inspect()
base_fields = AshJsonApiWrapper.DataLayer.Info.fields(dsl)

dsl
|> AshJsonApiWrapper.DataLayer.Info.endpoints()
Expand Down
2 changes: 1 addition & 1 deletion lib/endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule AshJsonApiWrapper.Endpoint do
def schema do
[
action: [
type: :atom,
type: {:wrap_list, :atom},
required: true,
doc: "The action this path is for"
],
Expand Down
1 change: 1 addition & 0 deletions lib/field.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ defmodule AshJsonApiWrapper.Field do
* `:simple` - Sets the value directly into the query params.
* `{:simple, "key" | ["path", "to", "key"]}` - Sets the value directly into the query params using the provided key.
* `{:place_in_list, ["path", "to", "list"]}` - Supports `or equals` and `in` filters over the given field, by placing their values in the provided list.
* `{:place_in_csv_list, ["path", "to", "list"]}` - Supports `or equals` and `in` filters over the given field, by placing their values in the provided list.
"""
]
]
Expand Down
29 changes: 20 additions & 9 deletions lib/filter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,26 @@ defmodule AshJsonApiWrapper.Filter do
filter,
field,
path,
type,
context \\ %{in_an_or?: false, other_branch_instructions: nil}
)

def find_place_in_list_filter(nil, _, _, _), do: {:ok, nil}
def find_place_in_list_filter(nil, _, _, _, _), do: {:ok, nil}

def find_place_in_list_filter(%Ash.Filter{expression: expression}, field, path, context) do
find_place_in_list_filter(expression, field, path, context)
def find_place_in_list_filter(%Ash.Filter{expression: expression}, field, path, type, context) do
find_place_in_list_filter(expression, field, path, type, context)
end

def find_place_in_list_filter(
%Ash.Query.BooleanExpression{op: op, left: left, right: right} = expr,
field,
path,
type,
context
) do
case find_place_in_list_filter(left, field, path, context) do
case find_place_in_list_filter(left, field, path, type, context) do
{:ok, nil} ->
case find_place_in_list_filter(right, field, path, context) do
case find_place_in_list_filter(right, field, path, type, context) do
{:ok, nil} ->
{:ok, expr, []}

Expand Down Expand Up @@ -124,18 +126,20 @@ defmodule AshJsonApiWrapper.Filter do
%Ash.Query.Operator.Eq{left: left, right: %Ash.Query.Ref{} = right} = op,
field,
path,
type,
context
) do
find_place_in_list_filter(%{op | right: left, left: right}, field, path, context)
find_place_in_list_filter(%{op | right: left, left: right}, field, path, type, context)
end

def find_place_in_list_filter(
%Ash.Query.Operator.In{left: left, right: %Ash.Query.Ref{} = right} = op,
field,
path,
type,
context
) do
find_place_in_list_filter(%{op | right: left, left: right}, field, path, context)
find_place_in_list_filter(%{op | right: left, left: right}, field, path, type, context)
end

def find_place_in_list_filter(
Expand All @@ -144,6 +148,7 @@ defmodule AshJsonApiWrapper.Filter do
},
field,
_path,
_type,
_context
)
when name != field do
Expand All @@ -156,6 +161,7 @@ defmodule AshJsonApiWrapper.Filter do
},
field,
_path,
_type,
_context
)
when name != field do
Expand All @@ -169,9 +175,10 @@ defmodule AshJsonApiWrapper.Filter do
},
field,
path,
type,
_context
) do
{:ok, {nil, [{:place_in_list, path, value}]}}
{:ok, {nil, [{type, path, value}]}}
end

def find_place_in_list_filter(
Expand All @@ -181,9 +188,10 @@ defmodule AshJsonApiWrapper.Filter do
},
field,
path,
type,
_context
) do
{:ok, {nil, Enum.map(values, &{:place_in_list, path, &1})}}
{:ok, {nil, Enum.map(values, &{type, path, &1})}}
end

def find_filter_that_uses_get_endpoint(
Expand Down Expand Up @@ -259,6 +267,9 @@ defmodule AshJsonApiWrapper.Filter do
{Ash.Query.BooleanExpression.new(:and, left, right_remaining), uses_endpoint,
add_templates([right_templates, templates])}}
end

{:ok, nil} ->
{:ok, {Ash.Query.BooleanExpression.new(:and, left, right), uses_endpoint, nil}}
end

{:error, error} ->
Expand Down
11 changes: 4 additions & 7 deletions lib/open_api/resource_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ defmodule AshJsonApiWrapper.OpenApi.ResourceGenerator do
endpoints =
json
|> operations(config)
|> Enum.take(1)
|> Enum.map_join("\n\n", fn {path, method, operation} ->
|> Enum.map_join("\n\n", fn {path, _method, operation} ->
entity_path =
if config[:entity_path] do
"entity_path \"#{config[:entity_path]}\""
Expand All @@ -23,14 +22,13 @@ defmodule AshJsonApiWrapper.OpenApi.ResourceGenerator do
actions =
json
|> operations(config)
|> Enum.take(1)
|> Enum.map_join("\n\n", fn
{path, "get", config} ->
{_path, "get", config} ->
"""
read :#{operation_id(config)}
"""

{path, "post", config} ->
{_path, "post", config} ->
"""
create :#{operation_id(config)}
"""
Expand Down Expand Up @@ -78,7 +76,7 @@ defmodule AshJsonApiWrapper.OpenApi.ResourceGenerator do
|> Enum.map_join("\n\n", fn {name, property} ->
type =
case property do
%{"enum" => values} ->
%{"enum" => _values} ->
":atom"

%{"format" => "date-time"} ->
Expand Down Expand Up @@ -181,7 +179,6 @@ defmodule AshJsonApiWrapper.OpenApi.ResourceGenerator do

{resource, code}
end)
|> Enum.take(1)
end

defp operation_id(%{"operationId" => operationId}) do
Expand Down
8 changes: 4 additions & 4 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},
"earmark_parser": {:hex, :earmark_parser, "1.4.16", "607709303e1d4e3e02f1444df0c821529af1c03b8578dfc81bb9cf64553d02b9", [:mix], [], "hexpm", "69fcf696168f5a274dd012e3e305027010658b2d1630cef68421d6baaeaccead"},
"ecto": {:hex, :ecto, "3.10.2", "6b887160281a61aa16843e47735b8a266caa437f80588c3ab80a8a960e6abe37", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6a895778f0d7648a4b34b486af59a1c8009041fbdf2b17f1ac215eb829c60235"},
"ecto": {:hex, :ecto, "3.10.3", "eb2ae2eecd210b4eb8bece1217b297ad4ff824b4384c0e3fdd28aaf96edd6135", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "44bec74e2364d491d70f7e42cd0d690922659d329f6465e89feb8a34e8cd3433"},
"elixir_make": {:hex, :elixir_make, "0.7.7", "7128c60c2476019ed978210c245badf08b03dbec4f24d05790ef791da11aa17c", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bc19fff950fad52bbe5f211b12db9ec82c6b34a9647da0c2224b8b8464c7e6c"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ets": {:hex, :ets, "0.8.1", "8ff9bcda5682b98493f8878fc9dbd990e48d566cba8cce59f7c2a78130da29ea", [:mix], [], "hexpm", "6be41b50adb5bc5c43626f25ea2d0af1f4a242fb3fad8d53f0c67c20b78915cc"},
Expand All @@ -24,7 +24,7 @@
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
Expand All @@ -39,8 +39,8 @@
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"picosat_elixir": {:hex, :picosat_elixir, "0.2.3", "bf326d0f179fbb3b706bb2c15fbc367dacfa2517157d090fdfc32edae004c597", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f76c9db2dec9d2561ffaa9be35f65403d53e984e8cd99c832383b7ab78c16c66"},
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
"sourceror": {:hex, :sourceror, "0.12.3", "a2ad3a1a4554b486d8a113ae7adad5646f938cad99bf8bfcef26dc0c88e8fade", [:mix], [], "hexpm", "4d4e78010ca046524e8194ffc4683422f34a96f6b82901abbb45acc79ace0316"},
"spark": {:hex, :spark, "1.1.18", "349ad7ec69b389294fd3f17a4e49e772cafbbb71d3571add652a80f7b3c44990", [:mix], [{:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "964b46866e01b39810a82f9ee538f7f25d450cb3223af58b0f4717ce69d6f167"},
"sourceror": {:hex, :sourceror, "0.14.0", "b6b8552d0240400d66b6f107c1bab7ac1726e998efc797f178b7b517e928e314", [:mix], [], "hexpm", "809c71270ad48092d40bbe251a133e49ae229433ce103f762a2373b7a10a8d8b"},
"spark": {:hex, :spark, "1.1.39", "f143b84a5b796bf2d83ec8fb4793ee9e66e67510c40d785f9a67050bb88e7677", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "d71bc26014c7e7abcdcf553f4cf7c5a5ff96f8365b1e20be3768ce503aafb203"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"stream_data": {:hex, :stream_data, "0.5.0", "b27641e58941685c75b353577dc602c9d2c12292dd84babf506c2033cd97893e", [:mix], [], "hexpm", "012bd2eec069ada4db3411f9115ccafa38540a3c78c4c0349f151fc761b9e271"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
Expand Down
45 changes: 8 additions & 37 deletions test/open_api_test.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule AshJsonApiWrapper.Hackernews.Test do
defmodule AshJsonApiWrapper.OpenApiTest do
use ExUnit.Case

require Ash.Query
Expand All @@ -25,34 +25,13 @@ defmodule AshJsonApiWrapper.Hackernews.Test do
entity_path: "objects",
fields: [
guid: [
filter_handler: {:place_in_list, ["guid"]}
# {
# "name": "guid",
# "in": "query",
# "required": false,
# "description": "Comma separated account_guids to list accounts for.",
# "schema": {
# "type": "string"
# }
# },
# {
# "name": "bank_guid",
# "in": "query",
# "required": false,
# "description": "Comma separated bank_guids to list accounts for.",
# "schema": {
# "type": "string"
# }
# },
# {
# "name": "customer_guid",
# "in": "query",
# "required": false,
# "description": "Comma separated customer_guids to list accounts for.",
# "schema": {
# "type": "string"
# }
# }
filter_handler: {:place_in_csv_list, ["guid"]}
],
bank_guid: [
filter_handler: {:place_in_csv_list, ["bank_guid"]}
],
customer_guid: [
filter_handler: {:place_in_csv_list, ["customer_guid"]}
]
]
]
Expand All @@ -71,16 +50,8 @@ defmodule AshJsonApiWrapper.Hackernews.Test do
@json
|> AshJsonApiWrapper.OpenApi.ResourceGenerator.generate(@config)
|> Enum.map(fn {resource, code} ->
IO.puts(code)
Code.eval_string(code)
resource
end)

Cybrid.Account
|> Ash.Query.for_read(:list_accounts)
|> Ash.Query.filter(guid == "1c96166bfa20e434962d6f08a96e69ad")
# |> Ash.Query.filter(type == :fee)
|> Api.read!()
|> IO.inspect()
end
end

0 comments on commit 418de7a

Please sign in to comment.