Current section
Files
Jump to
Current section
Files
lib/extract_metadata.ex
defmodule Bastion.ExtractMetadata do
@moduledoc """
An `Absinthe.Phase.t` that extracts the metadata for the fields in the passed `Absinthe.Blueprint.t`
"""
alias Absinthe.Blueprint
use Absinthe.Phase
@type id :: atom
@type metadata :: map
@type extracted_metadata :: {id, metadata}
@spec run(Blueprint.t, Keyword.t) :: {:ok, [extracted_metadata]}
def run(blueprint, _opts \\ []) do
extracted =
blueprint
|> parse_selected_field_metadata()
{:ok, extracted}
end
@spec parse_selected_field_metadata(Blueprint.t) :: [Blueprint.Document.Field.t]
defp parse_selected_field_metadata(blueprint) do
blueprint.operations
|> Stream.flat_map(&flatten_selections(&1.selections))
|> Enum.map(&field_to_meta/1)
end
@spec flatten_selections([Blueprint.Document.Field.t] | Blueprint.Document.Field.t) :: [Blueprint.Document.Field.t]
defp flatten_selections([]), do: []
defp flatten_selections([%Blueprint.Document.Field{} | _] = selections), do:
selections |> Enum.flat_map(&flatten_selections/1)
defp flatten_selections(%Blueprint.Document.Field{} = selection), do:
[selection | flatten_selections(selection.selections)]
@spec field_to_meta(Blueprint.Document.Field.t) :: Keyword.t
defp field_to_meta(%Blueprint.Document.Field{schema_node: %Absinthe.Type.Field{__private__: private}}) do
case Keyword.fetch(private, :meta) do
:error ->
[]
{:ok, meta} ->
meta
end
end
end