mirror of
https://github.com/ash-project/ash_graphql.git
synced 2024-09-20 13:24:14 +12:00
handle filter
This commit is contained in:
parent
df7dd8284b
commit
0064d8d2b1
6 changed files with 33 additions and 25 deletions
|
@ -507,15 +507,28 @@ defmodule AshGraphql.Graphql.Resolver do
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve(
|
def resolve(
|
||||||
%{arguments: _arguments, context: context, root_value: data} = resolution,
|
%{arguments: arguments, context: context, root_value: notification} = resolution,
|
||||||
{domain, resource, %AshGraphql.Resource.Subscription{read_action: read_action}, _input?}
|
{domain, resource, %AshGraphql.Resource.Subscription{read_action: read_action}, _input?}
|
||||||
) do
|
) do
|
||||||
|
dbg(NOTIFICATION: notification)
|
||||||
|
data = notification.data
|
||||||
|
|
||||||
read_action =
|
read_action =
|
||||||
read_action || Ash.Resource.Info.primary_action!(resource, :read).name
|
read_action || Ash.Resource.Info.primary_action!(resource, :read).name
|
||||||
|
|
||||||
|
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 =
|
query =
|
||||||
AshGraphql.Subscription.query_for_subscription(
|
AshGraphql.Subscription.query_for_subscription(
|
||||||
resource
|
query
|
||||||
|> Ash.Query.for_read(read_action, %{},
|
|> 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)
|
||||||
|
@ -524,13 +537,6 @@ defmodule AshGraphql.Graphql.Resolver do
|
||||||
resolution
|
resolution
|
||||||
)
|
)
|
||||||
|
|
||||||
query =
|
|
||||||
Ash.Resource.Info.primary_key(resource)
|
|
||||||
|> Enum.reduce(query, fn key, query ->
|
|
||||||
value = Map.get(data, key)
|
|
||||||
Ash.Query.filter(query, ^ref(key) == ^value)
|
|
||||||
end)
|
|
||||||
|
|
||||||
case query |> Ash.read_one() do
|
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
|
# should only happen if a resource is created/updated and the subscribed user is not allowed to see it
|
||||||
{:ok, nil} ->
|
{:ok, nil} ->
|
||||||
|
@ -1641,9 +1647,9 @@ defmodule AshGraphql.Graphql.Resolver do
|
||||||
end)}
|
end)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp massage_filter(_resource, nil), do: nil
|
def massage_filter(_resource, nil), do: nil
|
||||||
|
|
||||||
defp massage_filter(resource, filter) when is_map(filter) do
|
def massage_filter(resource, filter) when is_map(filter) do
|
||||||
Map.new(filter, fn {key, value} ->
|
Map.new(filter, fn {key, value} ->
|
||||||
cond do
|
cond do
|
||||||
rel = Ash.Resource.Info.relationship(resource, key) ->
|
rel = Ash.Resource.Info.relationship(resource, key) ->
|
||||||
|
@ -1658,7 +1664,7 @@ defmodule AshGraphql.Graphql.Resolver do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp massage_filter(_resource, other), do: other
|
def massage_filter(_resource, other), do: other
|
||||||
|
|
||||||
defp calc_input(key, value) do
|
defp calc_input(key, value) do
|
||||||
case Map.fetch(value, :input) do
|
case Map.fetch(value, :input) do
|
||||||
|
|
|
@ -1163,9 +1163,7 @@ defmodule AshGraphql.Resource do
|
||||||
|> subscriptions()
|
|> subscriptions()
|
||||||
|> Enum.map(fn %Subscription{name: name} = subscription ->
|
|> Enum.map(fn %Subscription{name: name} = subscription ->
|
||||||
%Absinthe.Blueprint.Schema.FieldDefinition{
|
%Absinthe.Blueprint.Schema.FieldDefinition{
|
||||||
arguments:
|
arguments: args(:subscription, resource, nil, schema, nil),
|
||||||
args(:subscription, resource, nil, schema, nil)
|
|
||||||
|> IO.inspect(label: "args"),
|
|
||||||
identifier: name,
|
identifier: name,
|
||||||
name: to_string(name),
|
name: to_string(name),
|
||||||
config:
|
config:
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
defmodule AshGraphql.Resource.Subscription.Actor do
|
defmodule AshGraphql.Resource.Subscription.Actor do
|
||||||
|
# I'd like to have the typespsay that actor can be anything
|
||||||
|
# but that the input and output must be the same
|
||||||
@callback author(actor :: any) :: actor :: any
|
@callback author(actor :: any) :: actor :: any
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,8 @@ defmodule AshGraphql.Subscription.Config do
|
||||||
|
|
||||||
actor =
|
actor =
|
||||||
if is_function(@subscription.actor) do
|
if is_function(@subscription.actor) do
|
||||||
|
# might be nice to also pass in the subscription, that way you could potentially
|
||||||
|
# deduplicate on an action basis as well if you wanted to
|
||||||
@subscription.actor.(context[:actor])
|
@subscription.actor.(context[:actor])
|
||||||
else
|
else
|
||||||
context[:actor]
|
context[:actor]
|
||||||
|
@ -26,6 +28,10 @@ defmodule AshGraphql.Subscription.Config do
|
||||||
case Ash.can(
|
case Ash.can(
|
||||||
@resource
|
@resource
|
||||||
|> Ash.Query.new()
|
|> Ash.Query.new()
|
||||||
|
# not sure if we need this here
|
||||||
|
|> Ash.Query.do_filter(
|
||||||
|
AshGraphql.Graphql.Resolver.massage_filter(@resource, Map.get(args, :filter))
|
||||||
|
)
|
||||||
|> Ash.Query.set_tenant(context[:tenant])
|
|> Ash.Query.set_tenant(context[:tenant])
|
||||||
|> Ash.Query.for_read(read_action),
|
|> Ash.Query.for_read(read_action),
|
||||||
actor,
|
actor,
|
||||||
|
|
|
@ -7,13 +7,11 @@ defmodule AshGraphql.Subscription.Endpoint do
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
def run_docset(pubsub, docs_and_topics, mutation_result) do
|
def run_docset(pubsub, docs_and_topics, notification) do
|
||||||
dbg(mutation_result, structs: false)
|
|
||||||
|
|
||||||
for {topic, key_strategy, doc} <- docs_and_topics do
|
for {topic, key_strategy, doc} <- docs_and_topics do
|
||||||
try do
|
try do
|
||||||
pipeline =
|
pipeline =
|
||||||
Absinthe.Subscription.Local.pipeline(doc, mutation_result.data)
|
Absinthe.Subscription.Local.pipeline(doc, notification)
|
||||||
|
|
||||||
{:ok, %{result: data}, _} = Absinthe.Pipeline.run(doc.source, pipeline)
|
{:ok, %{result: data}, _} = Absinthe.Pipeline.run(doc.source, pipeline)
|
||||||
|
|
||||||
|
@ -43,12 +41,12 @@ defmodule AshGraphql.Subscription.Endpoint do
|
||||||
# return any data we do not send the error to the client
|
# return any data we do not send the error to the client
|
||||||
# because it would just expose unnecessary information
|
# because it would just expose unnecessary information
|
||||||
# and the user can not really do anything usefull with it
|
# and the user can not really do anything usefull with it
|
||||||
errors
|
not (errors
|
||||||
|> List.wrap()
|
|> List.wrap()
|
||||||
|> Enum.any?(fn error -> Map.get(error, :code) in ["forbidden", "not_found"] end)
|
|> Enum.any?(fn error -> Map.get(error, :code) in ["forbidden", "not_found"] end))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp is_forbidden(_), do: false
|
defp should_send?(_), do: true
|
||||||
|
|
||||||
defp get_filter(topic) do
|
defp get_filter(topic) do
|
||||||
[_, rest] = String.split(topic, "__absinthe__:doc:")
|
[_, rest] = String.split(topic, "__absinthe__:doc:")
|
||||||
|
|
|
@ -6,8 +6,6 @@ defmodule AshGraphql.Subscription.Notifier do
|
||||||
def notify(notification) do
|
def notify(notification) do
|
||||||
pub_sub = Info.subscription_pubsub(notification.resource)
|
pub_sub = Info.subscription_pubsub(notification.resource)
|
||||||
|
|
||||||
dbg(notification, structs: false)
|
|
||||||
|
|
||||||
for subscription <- AshGraphql.Resource.Info.subscriptions(notification.resource) do
|
for subscription <- AshGraphql.Resource.Info.subscriptions(notification.resource) do
|
||||||
if is_nil(subscription.actions) or
|
if is_nil(subscription.actions) or
|
||||||
notification.action.name in List.wrap(subscription.actions) do
|
notification.action.name in List.wrap(subscription.actions) do
|
||||||
|
|
Loading…
Reference in a new issue