Packages
absinthe
1.5.0-alpha.0
1.11.0
1.10.2
1.10.1
1.10.0
1.9.1
1.9.0
1.8.0
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.8
1.6.7
retired
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.6.0-rc.1
1.6.0-rc.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.5.0-rc.5
1.5.0-rc.4
1.5.0-rc.3
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.5.0-beta.2
1.5.0-beta.1
1.5.0-beta.0
1.5.0-alpha.4
1.5.0-alpha.3
1.5.0-alpha.2
1.5.0-alpha.1
1.5.0-alpha.0
1.4.16
1.4.15
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.4.9
1.4.8
retired
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.3
1.4.0-rc.2
1.4.0-rc.1
1.4.0-rc.0
1.4.0-beta.5
1.4.0-beta.4
1.4.0-beta.3
1.4.0-beta.2
1.4.0-beta.1
1.3.2
1.3.1
1.3.0
1.3.0-rc.0
1.3.0-beta.2
1.3.0-beta.1
1.3.0-beta.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.2.0-beta.0
1.2.0-alpha0
1.2.0-alpha.2
1.2.0-alpha.1
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.0
0.5.2
0.5.1
0.5.0
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.2.3
0.2.2
0.2.1
0.1.0
GraphQL for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/absinthe/phase/subscription/subscribe_self.ex
defmodule Absinthe.Phase.Subscription.SubscribeSelf do
use Absinthe.Phase
alias Absinthe.Phase
@moduledoc false
alias Absinthe.Blueprint
@spec run(any, Keyword.t()) :: {:ok, Blueprint.t()}
def run(blueprint, options) do
with %{type: :subscription} = op <- Blueprint.current_operation(blueprint) do
do_subscription(op, blueprint, options)
else
_ -> {:ok, blueprint}
end
end
def do_subscription(%{type: :subscription} = op, blueprint, options) do
context = blueprint.execution.context
pubsub = ensure_pubsub!(context)
hash = :erlang.phash2(blueprint)
doc_id = "__absinthe__:doc:#{hash}"
%{selections: [field]} = op
with {:ok, field_key} <- get_field_key(field, context) do
Absinthe.Subscription.subscribe(pubsub, field_key, doc_id, blueprint)
{:replace, blueprint, [{Phase.Subscription.Result, topic: doc_id}]}
else
{:error, error} ->
blueprint = update_in(blueprint.execution.validation_errors, &[error | &1])
error_pipeline = [
{Phase.Document.Result, options}
]
{:replace, blueprint, error_pipeline}
end
end
defp get_field_key(%{schema_node: schema_node, argument_data: argument_data} = field, context) do
name = schema_node.identifier
config =
case Absinthe.Type.function(schema_node, :config) do
fun when is_function(fun, 2) ->
apply(fun, [argument_data, %{context: context}])
fun when is_function(fun, 1) ->
IO.write(
:stderr,
"Warning: 1-arity topic functions are deprecated, upgrade to 2 arity before 1.4.0 release"
)
apply(fun, [argument_data])
nil ->
{:ok, topic: Atom.to_string(name)}
end
case config do
{:ok, config} ->
key = find_key!(config)
{:ok, {name, key}}
{:error, msg} ->
error = %Phase.Error{
phase: __MODULE__,
message: msg,
locations: [field.source_location]
}
{:error, error}
val ->
raise """
Invalid return from config function!
Config function must returne `{:ok, config}` or `{:error, msg}`. You returned:
#{inspect(val)}
"""
end
end
defp find_key!(config) do
topic =
config[:topic] ||
raise """
Subscription config must include a non null topic!
#{inspect(config)}
"""
to_string(topic)
end
defp ensure_pubsub!(context) do
case Absinthe.Subscription.extract_pubsub(context) do
{:ok, pubsub} ->
pubsub
_ ->
raise """
Pubsub not configured!
Subscriptions require a configured pubsub module.
"""
end
end
end