use trace and handle arguments

This commit is contained in:
Barnabas Jovanovics 2024-08-15 15:15:47 +02:00
parent 45ca5cc9c0
commit 46ac0136f3
2 changed files with 92 additions and 47 deletions

View file

@ -507,62 +507,98 @@ defmodule AshGraphql.Graphql.Resolver do
end end
def resolve( def resolve(
%{arguments: arguments, context: context, root_value: notification} = resolution, %{arguments: args, context: context, root_value: notification} = resolution,
{domain, resource, {domain, resource,
%AshGraphql.Resource.Subscription{read_action: read_action, name: name} = subscription, %AshGraphql.Resource.Subscription{read_action: read_action, name: name}, _input?}
_input?}
) do ) do
dbg(NOTIFICATION: notification) case handle_arguments(resource, read_action, args) do
data = notification.data {:ok, args} ->
metadata = %{
read_action = domain: domain,
read_action || Ash.Resource.Info.primary_action!(resource, :read).name resource: resource,
resource_short_name: Ash.Resource.Info.short_name(resource),
query =
Ash.Resource.Info.primary_key(resource)
|> Enum.reduce(resource, fn key, query ->
value = Map.get(data, key)
Ash.Query.filter(query, ^ref(key) == ^value)
end)
query =
Ash.Query.do_filter(query, massage_filter(query.resource, Map.get(arguments, :filter)))
query =
AshGraphql.Subscription.query_for_subscription(
query
|> Ash.Query.for_read(read_action, %{},
actor: Map.get(context, :actor), actor: Map.get(context, :actor),
tenant: Map.get(context, :tenant) tenant: Map.get(context, :tenant),
), action: read_action,
domain, source: :graphql,
resolution, subscription: name,
"#{name}_result", authorize?: AshGraphql.Domain.Info.authorize?(domain)
[to_string(notification.action.type) <> "d"] }
)
case query |> Ash.read_one() do trace domain,
# should only happen if a resource is created/updated and the subscribed user is not allowed to see it resource,
{:ok, nil} -> :gql_subscription,
resolution name,
|> Absinthe.Resolution.put_result( metadata do
{:error, to_errors([Ash.Error.Query.NotFound.exception()], context, domain)} opts = [
) actor: Map.get(context, :actor),
action: read_action,
authorize?: AshGraphql.Domain.Info.authorize?(domain),
tenant: Map.get(context, :tenant)
]
{:ok, result} -> data = notification.data
dbg(result)
resolution read_action =
|> Absinthe.Resolution.put_result( read_action || Ash.Resource.Info.primary_action!(resource, :read).name
{:ok, %{String.to_existing_atom(to_string(notification.action.type) <> "d") => result}}
) query =
Ash.Resource.Info.primary_key(resource)
|> Enum.reduce(resource, fn key, query ->
value = Map.get(data, key)
Ash.Query.filter(query, ^ref(key) == ^value)
end)
query =
Ash.Query.do_filter(
query,
massage_filter(query.resource, Map.get(args, :filter))
)
query =
AshGraphql.Subscription.query_for_subscription(
query
|> Ash.Query.for_read(read_action, %{}, opts),
domain,
resolution,
"#{name}_result",
[subcription_field_from_action_type(notification.action.type)]
)
case query |> Ash.read_one() do
# should only happen if a resource is created/updated and the subscribed user is not allowed to see it
{:ok, nil} ->
resolution
|> Absinthe.Resolution.put_result(
{:error, to_errors([Ash.Error.Query.NotFound.exception()], context, domain)}
)
{:ok, result} ->
resolution
|> Absinthe.Resolution.put_result(
{:ok,
%{
String.to_existing_atom(
subcription_field_from_action_type(notification.action.type)
) => result
}}
)
{:error, error} ->
resolution
|> Absinthe.Resolution.put_result({:error, to_errors([error], context, domain)})
end
end
{:error, error} -> {:error, error} ->
resolution {:error, error}
|> Absinthe.Resolution.put_result({:error, to_errors([error], context, domain)})
end end
end end
defp subcription_field_from_action_type(:create), do: "created"
defp subcription_field_from_action_type(:update), do: "updated"
defp subcription_field_from_action_type(:destroy), do: "destroyed"
defp read_one_query(resource, args) do defp read_one_query(resource, args) do
case Map.fetch(args, :filter) do case Map.fetch(args, :filter) do
{:ok, filter} when filter != %{} -> {:ok, filter} when filter != %{} ->

View file

@ -1110,18 +1110,27 @@ defmodule AshGraphql.Resource do
end) end)
end end
@doc false
# sobelow_skip ["DOS.StringToAtom"]
def subscription_types(resource, _all_domains, schema) do def subscription_types(resource, _all_domains, schema) do
resource resource
|> subscriptions() |> subscriptions()
|> Enum.map(fn %Subscription{name: name} -> |> Enum.map(fn %Subscription{name: name} ->
resource_type = AshGraphql.Resource.Info.type(resource) resource_type = AshGraphql.Resource.Info.type(resource)
result_type = name |> to_string() |> then(&(&1 <> "_result")) |> String.to_atom() result_type_name =
name
|> to_string()
|> then(&(&1 <> "_result"))
result_type =
result_type_name
|> String.to_atom()
%Absinthe.Blueprint.Schema.ObjectTypeDefinition{ %Absinthe.Blueprint.Schema.ObjectTypeDefinition{
module: schema, module: schema,
identifier: result_type, identifier: result_type,
name: name |> to_string() |> then(&(&1 <> "_result")) |> Macro.camelize(), name: result_type_name,
fields: [ fields: [
%Absinthe.Blueprint.Schema.FieldDefinition{ %Absinthe.Blueprint.Schema.FieldDefinition{
__reference__: ref(__ENV__), __reference__: ref(__ENV__),