improvement: WIP on open api resource generator

improvement: update ash
This commit is contained in:
Zach Daniel 2023-09-25 10:16:47 -04:00
parent de000a859c
commit 418de7a1bd
9 changed files with 53 additions and 64 deletions

View file

@ -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,

View file

@ -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,
@ -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
@ -800,7 +812,6 @@ defmodule AshJsonApiWrapper.DataLayer do
else
case endpoint.entity_path do
nil ->
IO.inspect(endpoint)
{:ok, List.wrap(body)}
path ->

View file

@ -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()

View file

@ -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"
],

View file

@ -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.
"""
]
]

View file

@ -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, []}
@ -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(
@ -144,6 +148,7 @@ defmodule AshJsonApiWrapper.Filter do
},
field,
_path,
_type,
_context
)
when name != field do
@ -156,6 +161,7 @@ defmodule AshJsonApiWrapper.Filter do
},
field,
_path,
_type,
_context
)
when name != field do
@ -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(
@ -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(
@ -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} ->

View file

@ -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]}\""
@ -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)}
"""
@ -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"} ->
@ -181,7 +179,6 @@ defmodule AshJsonApiWrapper.OpenApi.ResourceGenerator do
{resource, code}
end)
|> Enum.take(1)
end
defp operation_id(%{"operationId" => operationId}) do

View file

@ -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"},
@ -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"},
@ -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"},

View file

@ -1,4 +1,4 @@
defmodule AshJsonApiWrapper.Hackernews.Test do
defmodule AshJsonApiWrapper.OpenApiTest do
use ExUnit.Case
require Ash.Query
@ -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"]}
]
]
]
@ -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