improvement: deduplicate map types across domains (#164)

Allow having common NewType maps that are used in multiple domains and are
correctly deduplicated
This commit is contained in:
Riccardo Binetti 2024-05-23 18:11:28 +02:00 committed by GitHub
parent 7ec1cfe84e
commit 31d29e178f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 117 additions and 6 deletions

View file

@ -182,6 +182,9 @@ defmodule AshGraphql do
unquote(relay_ids?)
)
global_maps =
AshGraphql.global_maps(unquote(ash_resources), unquote(schema), __ENV__)
global_enums =
AshGraphql.global_enums(unquote(ash_resources), unquote(schema), __ENV__)
@ -199,6 +202,7 @@ defmodule AshGraphql do
unquote(define_relay_types?),
unquote(relay_ids?)
) ++
global_maps ++
global_enums ++
global_unions ++
embedded_types,
@ -237,6 +241,12 @@ defmodule AshGraphql do
end
end
def global_maps(resources, schema, env) do
resources
|> Enum.flat_map(&AshGraphql.Resource.map_definitions(&1, schema, env))
|> Enum.uniq_by(& &1.identifier)
end
def global_enums(resources, schema, env) do
resources
|> Enum.flat_map(&all_attributes_and_arguments/1)
@ -660,8 +670,7 @@ defmodule AshGraphql do
schema
)
] ++
AshGraphql.Resource.enum_definitions(embedded_type, schema, __ENV__) ++
AshGraphql.Resource.map_definitions(embedded_type, schema, __ENV__)
AshGraphql.Resource.enum_definitions(embedded_type, schema, __ENV__)
else
[]
end

View file

@ -1700,14 +1700,12 @@ defmodule AshGraphql.Resource do
List.wrap(page_of(resource, schema)) ++
List.wrap(relay_page(resource, schema)) ++
List.wrap(keyset_page_of(resource, schema)) ++
map_definitions(resource, schema, __ENV__) ++
enum_definitions(resource, schema, __ENV__) ++
managed_relationship_definitions(resource, schema)
end
def no_graphql_types(resource, schema) do
map_definitions(resource, schema, __ENV__) ++
enum_definitions(resource, schema, __ENV__) ++
enum_definitions(resource, schema, __ENV__) ++
managed_relationship_definitions(resource, schema)
end

View file

@ -0,0 +1,16 @@
defmodule AshGraphql.Test.OtherDomain do
@moduledoc false
# This domain and its resource serves the purpose of testing deduplication of
# common map types
use Ash.Domain,
extensions: [
AshGraphql.Domain
],
otp_app: :ash_graphql
resources do
resource(AshGraphql.Test.OtherResource)
end
end

View file

@ -0,0 +1,48 @@
defmodule AshGraphql.Test.OtherResource do
@moduledoc false
alias AshGraphql.Test.CommonMap
use Ash.Resource,
domain: AshGraphql.Test.OtherDomain,
data_layer: Ash.DataLayer.Ets,
extensions: [AshGraphql.Resource]
graphql do
type :other_resource
queries do
get :get_other_resource, :read
list :list_other_resources, :read
end
mutations do
create :create_other_resource_with_common_map, :create_with_common_map
end
end
actions do
read :read do
primary?(true)
end
create :create_with_common_map do
argument(:common_map_arg, {:array, CommonMap})
end
end
attributes do
uuid_primary_key(:id)
attribute :common_map_attribute, CommonMap do
public?(true)
end
end
calculations do
calculate :common_map_calculation, CommonMap do
public?(true)
calculation(fn records, _ -> {:ok, []} end)
end
end
end

View file

@ -128,6 +128,7 @@ end
defmodule AshGraphql.Test.Post do
@moduledoc false
alias AshGraphql.Test.Comment
alias AshGraphql.Test.CommonMap
alias AshGraphql.Test.SponsoredComment
use Ash.Resource,
@ -198,6 +199,7 @@ defmodule AshGraphql.Test.Post do
create :create_post, :create_confirm
create :upsert_post, :upsert, upsert?: true
create :create_post_with_common_map, :create_with_common_map
create :create_post_bar_with_foo, :create_bar_with_foo
create :create_post_bar_with_baz, :create_bar_with_baz
@ -247,6 +249,10 @@ defmodule AshGraphql.Test.Post do
argument(:bar, BarWithBaz)
end
create :create_with_common_map do
argument(:common_map_arg, {:array, CommonMap})
end
create :create_with_error do
change(RaiseResourceError)
end
@ -434,12 +440,21 @@ defmodule AshGraphql.Test.Post do
public?(true)
end
attribute :common_map_attribute, CommonMap do
public?(true)
end
create_timestamp(:created_at, public?: true)
end
calculations do
calculate(:static_calculation, :string, AshGraphql.Test.StaticCalculation, public?: true)
calculate :common_map_calculation, CommonMap do
public?(true)
calculation(fn records, _ -> {:ok, []} end)
end
calculate(:private_calculation, AshGraphql.Test.Embed, fn records, _ ->
records
|> Enum.map(fn

View file

@ -3,7 +3,7 @@ defmodule AshGraphql.Test.Schema do
use Absinthe.Schema
@domains [AshGraphql.Test.Domain]
@domains [AshGraphql.Test.Domain, AshGraphql.Test.OtherDomain]
use AshGraphql, domains: @domains

View file

@ -0,0 +1,25 @@
defmodule AshGraphql.Test.CommonMap do
@moduledoc false
use Ash.Type.NewType,
subtype_of: :map,
constraints: [
fields: [
some: [
type: :string,
allow_nil?: false
],
stuff: [
type: :string,
allow_nil?: false
]
]
]
use AshGraphql.Type
@impl true
def graphql_type(_), do: :common_map
@impl true
def graphql_input_type(_), do: :common_map_input
end