diff --git a/lib/domain/domain.ex b/lib/domain/domain.ex index a4b824de..69aa7f06 100644 --- a/lib/domain/domain.ex +++ b/lib/domain/domain.ex @@ -235,7 +235,8 @@ defmodule AshGraphql.Domain do |> Enum.flat_map(fn resource -> if AshGraphql.Resource in Spark.extensions(resource) do AshGraphql.Resource.type_definitions(resource, domain, all_domains, schema, relay_ids?) ++ - AshGraphql.Resource.mutation_types(resource, all_domains, schema) + AshGraphql.Resource.mutation_types(resource, all_domains, schema) ++ + AshGraphql.Resource.subscription_types(resource, all_domains, schema) else AshGraphql.Resource.no_graphql_types(resource, schema) end diff --git a/lib/graphql/resolver.ex b/lib/graphql/resolver.ex index 92474d82..76e8d859 100644 --- a/lib/graphql/resolver.ex +++ b/lib/graphql/resolver.ex @@ -508,7 +508,9 @@ defmodule AshGraphql.Graphql.Resolver do def resolve( %{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, name: name} = subscription, + _input?} ) do dbg(NOTIFICATION: notification) data = notification.data @@ -534,7 +536,9 @@ defmodule AshGraphql.Graphql.Resolver do tenant: Map.get(context, :tenant) ), domain, - resolution + resolution, + "#{name}_result", + [to_string(notification.action.type) <> "d"] ) case query |> Ash.read_one() do @@ -546,8 +550,12 @@ defmodule AshGraphql.Graphql.Resolver do ) {:ok, result} -> + dbg(result) + resolution - |> Absinthe.Resolution.put_result({:ok, result}) + |> Absinthe.Resolution.put_result( + {:ok, %{String.to_existing_atom(to_string(notification.action.type) <> "d") => result}} + ) {:error, error} -> resolution @@ -2260,6 +2268,10 @@ defmodule AshGraphql.Graphql.Resolver do String.to_atom("#{mutation_name}_result") end + defp subscription_result_type(subscription_name) do + String.to_atom("#{subscription_name}_result") + end + # sobelow_skip ["DOS.StringToAtom"] defp page_type(resource, strategy, relay?) do type = AshGraphql.Resource.Info.type(resource) @@ -2277,9 +2289,17 @@ defmodule AshGraphql.Graphql.Resolver do end @doc false - def select_fields(query_or_changeset, resource, resolution, type_override, nested \\ []) do + def select_fields( + query_or_changeset, + resource, + resolution, + type_override, + nested \\ [] + ) do subfields = get_select(resource, resolution, type_override, nested) + dbg(type_override: type_override, subfields: subfields, nested: nested) + case query_or_changeset do %Ash.Query{} = query -> query |> Ash.Query.select(subfields) @@ -2317,8 +2337,12 @@ defmodule AshGraphql.Graphql.Resolver do end defp fields(%Absinthe.Resolution{} = resolution, [], type) do + dbg("FIELDS") + dbg(type) + resolution - |> Absinthe.Resolution.project(type) + |> Absinthe.Resolution.project() + |> dbg() end defp fields(%Absinthe.Resolution{} = resolution, names, _type) do diff --git a/lib/resource/resource.ex b/lib/resource/resource.ex index 71535d4c..20c99f6e 100644 --- a/lib/resource/resource.ex +++ b/lib/resource/resource.ex @@ -1100,6 +1100,46 @@ defmodule AshGraphql.Resource do end) end + def subscription_types(resource, _all_domains, schema) do + resource + |> subscriptions() + |> Enum.map(fn %Subscription{name: name} -> + resource_type = AshGraphql.Resource.Info.type(resource) + + result_type = name |> to_string() |> then(&(&1 <> "_result")) |> String.to_atom() + + %Absinthe.Blueprint.Schema.ObjectTypeDefinition{ + module: schema, + identifier: result_type, + name: name |> to_string() |> then(&(&1 <> "_result")) |> Macro.camelize(), + fields: [ + %Absinthe.Blueprint.Schema.FieldDefinition{ + __reference__: ref(__ENV__), + identifier: :created, + module: schema, + name: "created", + type: resource_type + }, + %Absinthe.Blueprint.Schema.FieldDefinition{ + __reference__: ref(__ENV__), + identifier: :updated, + module: schema, + name: "updated", + type: resource_type + }, + %Absinthe.Blueprint.Schema.FieldDefinition{ + __reference__: ref(__ENV__), + identifier: :destroyed, + module: schema, + name: "destroyed", + type: resource_type + } + ], + __reference__: ref(__ENV__) + } + end) + end + defp id_translation_middleware(relay_id_translations, true) do [{{AshGraphql.Graphql.IdTranslator, :translate_relay_ids}, relay_id_translations}] end @@ -1152,6 +1192,8 @@ defmodule AshGraphql.Resource do resource |> subscriptions() |> Enum.map(fn %Subscription{name: name} = subscription -> + result_type = name |> to_string() |> then(&(&1 <> "_result")) |> String.to_atom() + %Absinthe.Blueprint.Schema.FieldDefinition{ arguments: args(:subscription, resource, nil, schema, nil), identifier: name, @@ -1168,7 +1210,7 @@ defmodule AshGraphql.Resource do [ {{AshGraphql.Graphql.Resolver, :resolve}, {api, resource, subscription, true}} ], - type: AshGraphql.Resource.Info.type(resource), + type: result_type, __reference__: ref(__ENV__) } end) diff --git a/lib/subscription/endpoint.ex b/lib/subscription/endpoint.ex index db6fc3ec..563e778d 100644 --- a/lib/subscription/endpoint.ex +++ b/lib/subscription/endpoint.ex @@ -22,11 +22,13 @@ defmodule AshGraphql.Subscription.Endpoint do Data: #{inspect(data)} """) + dbg(DATA: data) + case should_send?(data) do - true -> + false -> :ok - false -> + true -> :ok = pubsub.publish_subscription(topic, data) end rescue diff --git a/lib/subscriptions.ex b/lib/subscriptions.ex index 1bec15e5..1e8f935b 100644 --- a/lib/subscriptions.ex +++ b/lib/subscriptions.ex @@ -8,12 +8,23 @@ defmodule AshGraphql.Subscription do @doc """ Produce a query that will load the correct data for a subscription. """ - def query_for_subscription(query, domain, %{context: context} = resolution) do + def query_for_subscription( + query, + domain, + %{context: context} = resolution, + type_override \\ nil, + nested \\ [] + ) do query |> Ash.Query.new() |> Ash.Query.set_tenant(Map.get(context, :tenant)) |> Ash.Query.set_context(get_context(context)) - |> AshGraphql.Graphql.Resolver.select_fields(query.resource, resolution, nil) + |> AshGraphql.Graphql.Resolver.select_fields( + query.resource, + resolution, + type_override, + nested + ) |> AshGraphql.Graphql.Resolver.load_fields( [ domain: domain,