zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

hydrate.ex (6373B)


      1 defmodule Absinthe.Phase.Schema.Hydrate do
      2   @moduledoc false
      3   @behaviour Absinthe.Schema.Hydrator
      4 
      5   use Absinthe.Phase
      6   alias Absinthe.Blueprint
      7 
      8   @hydrate [
      9     Blueprint.Schema.DirectiveDefinition,
     10     Blueprint.Schema.EnumTypeDefinition,
     11     Blueprint.Schema.EnumValueDefinition,
     12     Blueprint.Schema.FieldDefinition,
     13     Blueprint.Schema.InputObjectTypeDefinition,
     14     Blueprint.Schema.InputValueDefinition,
     15     Blueprint.Schema.InterfaceTypeDefinition,
     16     Blueprint.Schema.ObjectTypeDefinition,
     17     Blueprint.Schema.ScalarTypeDefinition,
     18     Blueprint.Schema.SchemaDefinition,
     19     Blueprint.Schema.UnionTypeDefinition
     20   ]
     21 
     22   @impl Absinthe.Phase
     23   def run(blueprint, opts \\ []) do
     24     {:ok, schema} = Keyword.fetch(opts, :schema)
     25     hydrator = Keyword.get(opts, :hydrator, __MODULE__)
     26     blueprint = Blueprint.prewalk(blueprint, &handle_node(&1, [], schema, hydrator))
     27     {:ok, blueprint}
     28   end
     29 
     30   defp handle_node(%Blueprint{} = node, ancestors, schema, hydrator) do
     31     node
     32     |> hydrate_node(ancestors, schema, hydrator)
     33     |> set_children(ancestors, schema, hydrator)
     34   end
     35 
     36   defp handle_node(%node_module{} = node, ancestors, schema, hydrator)
     37        when node_module in @hydrate do
     38     node
     39     |> hydrate_node(ancestors, schema, hydrator)
     40     |> set_children(ancestors, schema, hydrator)
     41   end
     42 
     43   defp handle_node(node, ancestors, schema, hydrator) do
     44     set_children(node, ancestors, schema, hydrator)
     45   end
     46 
     47   defp set_children(parent, ancestors, schema, hydrator) do
     48     Blueprint.prewalk(parent, fn
     49       ^parent -> parent
     50       child -> {:halt, handle_node(child, [parent | ancestors], schema, hydrator)}
     51     end)
     52   end
     53 
     54   defp hydrate_node(%{} = node, ancestors, schema, hydrator) do
     55     hydrations = schema.hydrate(node, ancestors)
     56     apply_hydrations(node, hydrations, hydrator)
     57   end
     58 
     59   defp apply_hydrations(node, hydrations, hydrator) do
     60     hydrations
     61     |> List.wrap()
     62     |> Enum.reduce(node, fn hydration, node ->
     63       hydrator.apply_hydration(node, hydration)
     64     end)
     65   end
     66 
     67   @impl Absinthe.Schema.Hydrator
     68 
     69   def apply_hydration(
     70         node,
     71         {:meta, keyword_list}
     72       )
     73       when is_list(keyword_list) do
     74     %{node | __private__: Keyword.put(node.__private__, :meta, keyword_list)}
     75   end
     76 
     77   def apply_hydration(
     78         node,
     79         {:description, text}
     80       ) do
     81     %{node | description: text}
     82   end
     83 
     84   def apply_hydration(
     85         %Blueprint.Schema.FieldDefinition{} = node,
     86         {:resolve, resolver}
     87       ) do
     88     %{node | middleware: [{Absinthe.Resolution, resolver}]}
     89   end
     90 
     91   def apply_hydration(
     92         %Blueprint.Schema.FieldDefinition{} = node,
     93         {:middleware, {_module, _opts} = middleware}
     94       ) do
     95     %{node | middleware: [middleware]}
     96   end
     97 
     98   def apply_hydration(
     99         %Blueprint.Schema.FieldDefinition{} = node,
    100         {:complexity, complexity}
    101       )
    102       when is_integer(complexity) do
    103     %{node | complexity: complexity}
    104   end
    105 
    106   def apply_hydration(
    107         %Blueprint.Schema.ScalarTypeDefinition{} = node,
    108         {:parse, parse}
    109       )
    110       when is_function(parse) do
    111     %{node | parse: parse}
    112   end
    113 
    114   def apply_hydration(
    115         %Blueprint.Schema.ScalarTypeDefinition{} = node,
    116         {:serialize, serialize}
    117       )
    118       when is_function(serialize) do
    119     %{node | serialize: serialize}
    120   end
    121 
    122   def apply_hydration(
    123         %Blueprint.Schema.InterfaceTypeDefinition{} = node,
    124         {:resolve_type, resolve_type}
    125       )
    126       when is_function(resolve_type) do
    127     %{node | resolve_type: resolve_type}
    128   end
    129 
    130   def apply_hydration(
    131         %Blueprint.Schema.UnionTypeDefinition{} = node,
    132         {:resolve_type, resolve_type}
    133       )
    134       when is_function(resolve_type) do
    135     %{node | resolve_type: resolve_type}
    136   end
    137 
    138   def apply_hydration(
    139         %Blueprint.Schema.ObjectTypeDefinition{} = node,
    140         {:is_type_of, is_type_of}
    141       )
    142       when is_function(is_type_of) do
    143     %{node | is_type_of: is_type_of}
    144   end
    145 
    146   def apply_hydration(
    147         %Blueprint.Schema.EnumValueDefinition{} = node,
    148         {:as, value}
    149       ) do
    150     %{node | value: value}
    151   end
    152 
    153   @hydration_level1 [
    154     Blueprint.Schema.DirectiveDefinition,
    155     Blueprint.Schema.EnumTypeDefinition,
    156     Blueprint.Schema.InputObjectTypeDefinition,
    157     Blueprint.Schema.InterfaceTypeDefinition,
    158     Blueprint.Schema.ObjectTypeDefinition,
    159     Blueprint.Schema.ScalarTypeDefinition,
    160     Blueprint.Schema.UnionTypeDefinition
    161   ]
    162 
    163   @hydration_level2 [
    164     Blueprint.Schema.FieldDefinition,
    165     Blueprint.Schema.EnumValueDefinition
    166   ]
    167 
    168   @hydration_level3 [
    169     Blueprint.Schema.InputValueDefinition
    170   ]
    171 
    172   def apply_hydration(%Absinthe.Blueprint{} = root, %{} = sub_hydrations) do
    173     {root, _} =
    174       Blueprint.prewalk(root, nil, fn
    175         %module{identifier: ident} = node, nil when module in @hydration_level1 ->
    176           case Map.fetch(sub_hydrations, ident) do
    177             :error ->
    178               {node, nil}
    179 
    180             {:ok, type_hydrations} ->
    181               {apply_hydrations(node, type_hydrations, __MODULE__), nil}
    182           end
    183 
    184         node, nil ->
    185           {node, nil}
    186       end)
    187 
    188     root
    189   end
    190 
    191   def apply_hydration(%module{} = root, %{} = sub_hydrations)
    192       when module in @hydration_level1 do
    193     {root, _} =
    194       Blueprint.prewalk(root, nil, fn
    195         %module{identifier: ident} = node, nil when module in @hydration_level2 ->
    196           case Map.fetch(sub_hydrations, ident) do
    197             :error ->
    198               {node, nil}
    199 
    200             {:ok, type_hydrations} ->
    201               {apply_hydrations(node, type_hydrations, __MODULE__), nil}
    202           end
    203 
    204         node, nil ->
    205           {node, nil}
    206       end)
    207 
    208     root
    209   end
    210 
    211   def apply_hydration(%module{} = root, %{} = sub_hydrations)
    212       when module in @hydration_level2 do
    213     {root, _} =
    214       Blueprint.prewalk(root, nil, fn
    215         %module{identifier: ident} = node, nil when module in @hydration_level3 ->
    216           case Map.fetch(sub_hydrations, ident) do
    217             :error ->
    218               {node, nil}
    219 
    220             {:ok, type_hydrations} ->
    221               {apply_hydrations(node, type_hydrations, __MODULE__), nil}
    222           end
    223 
    224         node, nil ->
    225           {node, nil}
    226       end)
    227 
    228     root
    229   end
    230 
    231   def apply_hydration(root, result) do
    232     raise ArgumentError, """
    233     Invalid hydration!
    234 
    235     #{inspect(result)}
    236 
    237     is not a valid way to hydrate
    238 
    239     #{inspect(root)}
    240     """
    241   end
    242 end