mirror of
https://github.com/ash-project/ash_json_api_wrapper.git
synced 2024-09-19 12:53:10 +12:00
improvement: support 3.0
This commit is contained in:
parent
19e6de356e
commit
c7bce0db6f
10 changed files with 59 additions and 46 deletions
7
.github/ISSUE_TEMPLATE/proposal.md
vendored
7
.github/ISSUE_TEMPLATE/proposal.md
vendored
|
@ -1,10 +1,9 @@
|
||||||
---
|
---
|
||||||
name: Proposal
|
name: Proposal
|
||||||
about: Suggest an idea for this project
|
about: Suggest an idea for this project
|
||||||
title: ''
|
title: ""
|
||||||
labels: enhancement, needs review
|
labels: enhancement, needs review
|
||||||
assignees: ''
|
assignees: ""
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
@ -29,7 +28,7 @@ For example
|
||||||
Or
|
Or
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
Api.read(:resource, bar: 10) # <- Adding `bar` here would cause <x>
|
Ash.read(..., bar: 10) # <- Adding `bar` here would cause <x>
|
||||||
```
|
```
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
erlang 26.0.2
|
|
||||||
elixir 1.15.4-otp-26
|
|
|
@ -133,7 +133,7 @@ defmodule AshJsonApiWrapper.DataLayer do
|
||||||
defmodule Query do
|
defmodule Query do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
defstruct [
|
defstruct [
|
||||||
:api,
|
:domain,
|
||||||
:context,
|
:context,
|
||||||
:headers,
|
:headers,
|
||||||
:action,
|
:action,
|
||||||
|
@ -206,8 +206,8 @@ defmodule AshJsonApiWrapper.DataLayer do
|
||||||
def can?(_, _), do: false
|
def can?(_, _), do: false
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def resource_to_query(resource, api \\ nil) do
|
def resource_to_query(resource, domain \\ nil) do
|
||||||
%Query{path: AshJsonApiWrapper.DataLayer.Info.endpoint_base(resource), api: api}
|
%Query{path: AshJsonApiWrapper.DataLayer.Info.endpoint_base(resource), domain: domain}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -341,7 +341,7 @@ defmodule AshJsonApiWrapper.DataLayer do
|
||||||
query
|
query
|
||||||
| query_params: params,
|
| query_params: params,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
api: query.api,
|
domain: query.domain,
|
||||||
action: action,
|
action: action,
|
||||||
endpoint: AshJsonApiWrapper.DataLayer.Info.endpoint(resource, action.name),
|
endpoint: AshJsonApiWrapper.DataLayer.Info.endpoint(resource, action.name),
|
||||||
context: context
|
context: context
|
||||||
|
@ -667,7 +667,7 @@ defmodule AshJsonApiWrapper.DataLayer do
|
||||||
if is_nil(query.runtime_filter) do
|
if is_nil(query.runtime_filter) do
|
||||||
{:ok, results}
|
{:ok, results}
|
||||||
else
|
else
|
||||||
Ash.Filter.Runtime.filter_matches(query.api, results, query.runtime_filter)
|
Ash.Filter.Runtime.filter_matches(query.domain, results, query.runtime_filter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
defmodule AshJsonApiWrapper.Errors.InvalidData do
|
defmodule AshJsonApiWrapper.Errors.InvalidData do
|
||||||
@moduledoc "Used when an invalid value is present in the response for a given attribute"
|
@moduledoc "Used when an invalid value is present in the response for a given attribute"
|
||||||
use Ash.Error.Exception
|
|
||||||
|
|
||||||
def_ash_error([:field, :value], class: :invalid)
|
use Splode.Error, fields: [:field, :value], class: :invalid
|
||||||
|
|
||||||
defimpl Ash.ErrorKind do
|
def message(error) do
|
||||||
def id(_), do: Ash.UUID.generate()
|
"Invalid value provided#{for_field(error)}: #{inspect(error.value)}"
|
||||||
|
|
||||||
def code(_), do: "invalid_data"
|
|
||||||
|
|
||||||
def message(error) do
|
|
||||||
"Invalid value provided#{for_field(error)}: #{inspect(error.value)}"
|
|
||||||
end
|
|
||||||
|
|
||||||
defp for_field(%{field: field}) when not is_nil(field), do: " for #{field}"
|
|
||||||
defp for_field(_), do: ""
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp for_field(%{field: field}) when not is_nil(field), do: " for #{field}"
|
||||||
|
defp for_field(_), do: ""
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ defmodule AshJsonApiWrapper.OpenApi.ResourceGenerator do
|
||||||
@moduledoc "Generates resources from an open api specification"
|
@moduledoc "Generates resources from an open api specification"
|
||||||
|
|
||||||
# sobelow_skip ["DOS.StringToAtom"]
|
# sobelow_skip ["DOS.StringToAtom"]
|
||||||
def generate(json, main_config) do
|
def generate(json, domain, main_config) do
|
||||||
main_config[:resources]
|
main_config[:resources]
|
||||||
|> Enum.map(fn {resource, config} ->
|
|> Enum.map(fn {resource, config} ->
|
||||||
endpoints =
|
endpoints =
|
||||||
|
@ -158,7 +158,7 @@ defmodule AshJsonApiWrapper.OpenApi.ResourceGenerator do
|
||||||
code =
|
code =
|
||||||
"""
|
"""
|
||||||
defmodule #{resource} do
|
defmodule #{resource} do
|
||||||
use Ash.Resource, data_layer: AshJsonApiWrapper.DataLayer
|
use Ash.Resource, domain: #{inspect(domain)}, data_layer: AshJsonApiWrapper.DataLayer
|
||||||
|
|
||||||
json_api_wrapper do
|
json_api_wrapper do
|
||||||
#{tesla}
|
#{tesla}
|
||||||
|
|
|
@ -72,8 +72,9 @@ defmodule AshJsonApiWrapper.CustomPagination.Test do
|
||||||
|
|
||||||
defmodule Users do
|
defmodule Users do
|
||||||
use Ash.Resource,
|
use Ash.Resource,
|
||||||
|
domain: AshJsonApiWrapper.CustomPagination.Test.Domain,
|
||||||
data_layer: AshJsonApiWrapper.DataLayer,
|
data_layer: AshJsonApiWrapper.DataLayer,
|
||||||
validate_api_inclusion?: false
|
validate_domain_inclusion?: false
|
||||||
|
|
||||||
json_api_wrapper do
|
json_api_wrapper do
|
||||||
tesla(TestingTesla)
|
tesla(TestingTesla)
|
||||||
|
@ -112,8 +113,8 @@ defmodule AshJsonApiWrapper.CustomPagination.Test do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defmodule Api do
|
defmodule Domain do
|
||||||
use Ash.Api, validate_config_inclusion?: false
|
use Ash.Domain, validate_config_inclusion?: false
|
||||||
|
|
||||||
resources do
|
resources do
|
||||||
allow_unregistered?(true)
|
allow_unregistered?(true)
|
||||||
|
@ -160,12 +161,12 @@ defmodule AshJsonApiWrapper.CustomPagination.Test do
|
||||||
Users
|
Users
|
||||||
|> Ash.Query.for_read(:list_users)
|
|> Ash.Query.for_read(:list_users)
|
||||||
# |> Ash.Query.limit(2)
|
# |> Ash.Query.limit(2)
|
||||||
|> Api.read!(page: [limit: 2, offset: 0])
|
|> Ash.read!(page: [limit: 2, offset: 0])
|
||||||
|
|
||||||
users2 =
|
users2 =
|
||||||
Users
|
Users
|
||||||
|> Ash.Query.for_read(:list_users)
|
|> Ash.Query.for_read(:list_users)
|
||||||
|> Api.read!(page: [limit: 2, offset: 1])
|
|> Ash.read!(page: [limit: 2, offset: 1])
|
||||||
|
|
||||||
users_count = users.results |> Enum.count()
|
users_count = users.results |> Enum.count()
|
||||||
users2_count = users2.results |> Enum.count()
|
users2_count = users2.results |> Enum.count()
|
||||||
|
|
|
@ -6,8 +6,9 @@ defmodule AshJsonApiWrapper.Hackernews.Test do
|
||||||
defmodule TopStory do
|
defmodule TopStory do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use Ash.Resource,
|
use Ash.Resource,
|
||||||
|
domain: AshJsonApiWrapper.Hackernews.Test.Domain,
|
||||||
data_layer: AshJsonApiWrapper.DataLayer,
|
data_layer: AshJsonApiWrapper.DataLayer,
|
||||||
validate_api_inclusion?: false
|
validate_domain_inclusion?: false
|
||||||
|
|
||||||
json_api_wrapper do
|
json_api_wrapper do
|
||||||
endpoints do
|
endpoints do
|
||||||
|
@ -44,7 +45,7 @@ defmodule AshJsonApiWrapper.Hackernews.Test do
|
||||||
|
|
||||||
defmodule ShortUrl do
|
defmodule ShortUrl do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use Ash.Calculation
|
use Ash.Resource.Calculation
|
||||||
|
|
||||||
def calculate(records, _, _) do
|
def calculate(records, _, _) do
|
||||||
Enum.map(records, fn record ->
|
Enum.map(records, fn record ->
|
||||||
|
@ -60,8 +61,9 @@ defmodule AshJsonApiWrapper.Hackernews.Test do
|
||||||
defmodule Story do
|
defmodule Story do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use Ash.Resource,
|
use Ash.Resource,
|
||||||
|
domain: AshJsonApiWrapper.Hackernews.Test.Domain,
|
||||||
data_layer: AshJsonApiWrapper.DataLayer,
|
data_layer: AshJsonApiWrapper.DataLayer,
|
||||||
validate_api_inclusion?: false
|
validate_domain_inclusion?: false
|
||||||
|
|
||||||
calculations do
|
calculations do
|
||||||
calculate(:short_url, :string, ShortUrl)
|
calculate(:short_url, :string, ShortUrl)
|
||||||
|
@ -112,8 +114,9 @@ defmodule AshJsonApiWrapper.Hackernews.Test do
|
||||||
defmodule User do
|
defmodule User do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use Ash.Resource,
|
use Ash.Resource,
|
||||||
|
domain: AshJsonApiWrapper.Hackernews.Test.Domain,
|
||||||
data_layer: AshJsonApiWrapper.DataLayer,
|
data_layer: AshJsonApiWrapper.DataLayer,
|
||||||
validate_api_inclusion?: false
|
validate_domain_inclusion?: false
|
||||||
|
|
||||||
attributes do
|
attributes do
|
||||||
attribute :id, :string do
|
attribute :id, :string do
|
||||||
|
@ -143,9 +146,9 @@ defmodule AshJsonApiWrapper.Hackernews.Test do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defmodule Api do
|
defmodule Domain do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use Ash.Api, validate_config_inclusion?: false
|
use Ash.Domain, validate_config_inclusion?: false
|
||||||
|
|
||||||
resources do
|
resources do
|
||||||
allow_unregistered?(true)
|
allow_unregistered?(true)
|
||||||
|
@ -157,7 +160,7 @@ defmodule AshJsonApiWrapper.Hackernews.Test do
|
||||||
TopStory
|
TopStory
|
||||||
|> Ash.Query.limit(1)
|
|> Ash.Query.limit(1)
|
||||||
|> Ash.Query.load(story: :user)
|
|> Ash.Query.load(story: :user)
|
||||||
|> Api.read!()
|
|> Domain.read!()
|
||||||
|> Enum.map(& &1.story)
|
|> Enum.map(& &1.story)
|
||||||
|
|
||||||
assert is_binary(top_story.url)
|
assert is_binary(top_story.url)
|
||||||
|
|
|
@ -38,9 +38,18 @@ defmodule AshJsonApiWrapper.OpenApi.CybridTest do
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
defmodule Domain do
|
||||||
|
use Ash.Domain,
|
||||||
|
validate_config_inclusion?: false
|
||||||
|
|
||||||
|
resources do
|
||||||
|
allow_unregistered? true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "it does stuff" do
|
test "it does stuff" do
|
||||||
@json
|
@json
|
||||||
|> AshJsonApiWrapper.OpenApi.ResourceGenerator.generate(@config)
|
|> AshJsonApiWrapper.OpenApi.ResourceGenerator.generate(Domain, @config)
|
||||||
|> Enum.map(fn {resource, code} ->
|
|> Enum.map(fn {resource, code} ->
|
||||||
Code.eval_string(code)
|
Code.eval_string(code)
|
||||||
resource
|
resource
|
||||||
|
|
|
@ -31,9 +31,18 @@ defmodule AshJsonApiWrapper.OpenApi.PetstoreTest do
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
defmodule Domain do
|
||||||
|
use Ash.Domain,
|
||||||
|
validate_config_inclusion?: false
|
||||||
|
|
||||||
|
resources do
|
||||||
|
allow_unregistered? true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "it does stuff" do
|
test "it does stuff" do
|
||||||
@json
|
@json
|
||||||
|> AshJsonApiWrapper.OpenApi.ResourceGenerator.generate(@config)
|
|> AshJsonApiWrapper.OpenApi.ResourceGenerator.generate(Domain, @config)
|
||||||
|> Enum.map(fn {resource, code} ->
|
|> Enum.map(fn {resource, code} ->
|
||||||
Code.eval_string(code)
|
Code.eval_string(code)
|
||||||
resource
|
resource
|
||||||
|
|
|
@ -11,7 +11,8 @@ defmodule AshJsonApiWrapper.Petstore.Test do
|
||||||
defmodule Petstore do
|
defmodule Petstore do
|
||||||
use Ash.Resource,
|
use Ash.Resource,
|
||||||
data_layer: AshJsonApiWrapper.DataLayer,
|
data_layer: AshJsonApiWrapper.DataLayer,
|
||||||
validate_api_inclusion?: false
|
domain: AshJsonApiWrapper.Petstore.Test.Domain,
|
||||||
|
validate_domain_inclusion?: false
|
||||||
|
|
||||||
json_api_wrapper do
|
json_api_wrapper do
|
||||||
tesla(TestingTesla)
|
tesla(TestingTesla)
|
||||||
|
@ -68,8 +69,8 @@ defmodule AshJsonApiWrapper.Petstore.Test do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defmodule Api do
|
defmodule Domain do
|
||||||
use Ash.Api, validate_config_inclusion?: false
|
use Ash.Domain, validate_config_inclusion?: false
|
||||||
|
|
||||||
resources do
|
resources do
|
||||||
allow_unregistered?(true)
|
allow_unregistered?(true)
|
||||||
|
@ -80,16 +81,16 @@ defmodule AshJsonApiWrapper.Petstore.Test do
|
||||||
Petstore
|
Petstore
|
||||||
|> Ash.Query.for_read(:find_pets_by_status)
|
|> Ash.Query.for_read(:find_pets_by_status)
|
||||||
|> Ash.Query.filter(status == "pending")
|
|> Ash.Query.filter(status == "pending")
|
||||||
|> Api.read!()
|
|> Ash.read!()
|
||||||
|
|
||||||
Petstore
|
Petstore
|
||||||
|> Ash.Query.for_read(:by_status)
|
|> Ash.Query.for_read(:by_status)
|
||||||
|> Ash.Query.filter(status == "available")
|
|> Ash.Query.filter(status == "available")
|
||||||
|> Api.read!()
|
|> Ash.read!()
|
||||||
|
|
||||||
Petstore
|
Petstore
|
||||||
|> Ash.Query.for_read(:pet)
|
|> Ash.Query.for_read(:pet)
|
||||||
|> Ash.Query.filter(id == 10)
|
|> Ash.Query.filter(id == 10)
|
||||||
|> Api.read!()
|
|> Ash.read!()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue