improvement: support new struct types in type generation

This commit is contained in:
Zach Daniel 2024-08-09 17:42:24 -04:00
parent 190a7a1f75
commit f349a5aeaa
6 changed files with 48 additions and 6 deletions

View file

@ -31,6 +31,8 @@ defmodule AshGraphql.DefaultErrorHandler do
end)
end
def stringified_value(value) when is_list(value), do: "[#{value |> Enum.map(&stringified_value(&1)) |> Enum.join(", ")}]"
def stringified_value(value) when is_list(value),
do: "[#{value |> Enum.map_join(", ", &stringified_value(&1))}]"
def stringified_value(value), do: to_string(value)
end

View file

@ -3108,9 +3108,14 @@ defmodule AshGraphql.Resource do
{types, fields} =
Enum.reduce(constraints[:fields], {[], []}, fn {name, attribute}, {types, fields} ->
map_type? =
attribute[:type] in [:map, Ash.Type.Map] ||
attribute[:type] in [:map, Ash.Type.Map, :struct, Ash.Type.Struct] ||
(Ash.Type.NewType.new_type?(attribute[:type]) &&
Ash.Type.NewType.subtype_of(attribute[:type]) in [:map, Ash.Type.Map])
Ash.Type.NewType.subtype_of(attribute[:type]) in [
:map,
Ash.Type.Map,
:struct,
Ash.Type.Struct
])
if map_type? && attribute[:constraints] not in [nil, []] do
nested_type_name =
@ -3354,7 +3359,7 @@ defmodule AshGraphql.Resource do
|> AshGraphql.all_attributes_and_arguments(all_domains, [], false)
|> Enum.map(&unnest/1)
|> Enum.filter(
&(Ash.Type.NewType.subtype_of(&1.type) == Ash.Type.Map &&
&(Ash.Type.NewType.subtype_of(&1.type) in [Ash.Type.Map, Ash.Type.Struct] &&
!Enum.empty?(Ash.Type.NewType.constraints(&1.type, &1.constraints)[:fields] || []) &&
define_type?(&1.type, &1.constraints))
)

View file

@ -3,7 +3,6 @@
"absinthe_plug": {:hex, :absinthe_plug, "1.5.8", "38d230641ba9dca8f72f1fed2dfc8abd53b3907d1996363da32434ab6ee5d6ab", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bbb04176647b735828861e7b2705465e53e2cf54ccf5a73ddd1ebd855f996e5a"},
"ash": {:hex, :ash, "3.3.3", "1e4047c867e064fe5edabd86c7366dbf3e094a91a2f5269ee0169eb310931e7c", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.3.11 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.9", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.8 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0486ec2185deeca68d617eb016d22e598af0e44e7512453f959124f4345ae9df"},
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"},
"credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"},
@ -43,7 +42,6 @@
"splode": {:hex, :splode, "0.2.4", "71046334c39605095ca4bed5d008372e56454060997da14f9868534c17b84b53", [:mix], [], "hexpm", "ca3b95f0d8d4b482b5357954fec857abd0fa3ea509d623334c1328e7382044c2"},
"stream_data": {:hex, :stream_data, "1.1.1", "fd515ca95619cca83ba08b20f5e814aaf1e5ebff114659dc9731f966c9226246", [:mix], [], "hexpm", "45d0cd46bd06738463fd53f22b70042dbb58c384bb99ef4e7576e7bb7d3b8c8c"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"typable": {:hex, :typable, "0.3.0", "0431e121d124cd26f312123e313d2689b9a5322b15add65d424c07779eaa3ca1", [:mix], [], "hexpm", "880a0797752da1a4c508ac48f94711e04c86156f498065a83d160eef945858f8"},
"ucwidth": {:hex, :ucwidth, "0.2.0", "1f0a440f541d895dff142275b96355f7e91e15bca525d4a0cc788ea51f0e3441", [:mix], [], "hexpm", "c1efd1798b8eeb11fb2bec3cafa3dd9c0c3647bee020543f0340b996177355bf"},
"yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"},
"yaml_elixir": {:hex, :yaml_elixir, "2.11.0", "9e9ccd134e861c66b84825a3542a1c22ba33f338d82c07282f4f1f52d847bd50", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "53cc28357ee7eb952344995787f4bb8cc3cecbf189652236e9b163e8ce1bc242"},

View file

@ -2,6 +2,7 @@ defmodule AshGraphql.Test.OtherResource do
@moduledoc false
alias AshGraphql.Test.CommonMap
alias AshGraphql.Test.CommonMapStruct
use Ash.Resource,
domain: AshGraphql.Test.OtherDomain,
@ -37,6 +38,10 @@ defmodule AshGraphql.Test.OtherResource do
attribute :common_map_attribute, CommonMap do
public?(true)
end
attribute :common_map_struct_attribute, CommonMapStruct do
public?(true)
end
end
calculations do

View file

@ -129,6 +129,7 @@ defmodule AshGraphql.Test.Post do
@moduledoc false
alias AshGraphql.Test.Comment
alias AshGraphql.Test.CommonMap
alias AshGraphql.Test.CommonMapStruct
alias AshGraphql.Test.SponsoredComment
use Ash.Resource,
@ -464,6 +465,10 @@ defmodule AshGraphql.Test.Post do
public?(true)
end
attribute :common_map_struct_attribute, CommonMapStruct do
public?(true)
end
create_timestamp(:created_at, public?: true)
end

View file

@ -0,0 +1,27 @@
defmodule AshGraphql.Test.CommonMapStruct do
defstruct [:some, :stuff]
@moduledoc false
use Ash.Type.NewType,
subtype_of: :struct,
constraints: [
instance_of: __MODULE__,
fields: [
some: [
type: :string,
allow_nil?: false
],
stuff: [
type: :string,
allow_nil?: false
]
]
]
use AshGraphql.Type
@impl true
def graphql_type(_), do: :common_map_struct
@impl true
def graphql_input_type(_), do: :common_map_struct_input
end