ash_graphql/lib/graphql/id_translator.ex

68 lines
1.9 KiB
Elixir
Raw Normal View History

defmodule AshGraphql.Graphql.IdTranslator do
@moduledoc false
def translate_relay_ids(%{state: :unresolved} = resolution, relay_id_translations) do
arguments =
Enum.reduce(relay_id_translations, resolution.arguments, &process/2)
%{resolution | arguments: arguments}
end
def translate_relay_ids(resolution, _relay_id_translations) do
resolution
end
defp process({field, nested_translations}, args) when is_list(nested_translations) do
case Map.get(args, field) do
subtree when is_map(subtree) ->
new_subtree = Enum.reduce(nested_translations, subtree, &process/2)
Map.put(args, field, new_subtree)
elements when is_list(elements) ->
new_elements =
Enum.map(elements, fn element ->
Enum.reduce(nested_translations, element, &process/2)
end)
Map.put(args, field, new_elements)
_ ->
args
end
end
defp process({field, type}, args) when is_atom(type) do
case Map.get(args, field) do
id when is_binary(id) ->
case AshGraphql.Resource.decode_relay_id(id) do
{:ok, %{type: ^type, id: decoded_id}} ->
Map.put(args, field, decoded_id)
_ ->
# If we fail to decode for the correct type, we just skip translation
# This will be marked as an invalid input down the line
args
end
[id | _] = ids when is_binary(id) ->
decoded_ids =
Enum.map(ids, fn id ->
case AshGraphql.Resource.decode_relay_id(id) do
{:ok, %{type: ^type, id: decoded_id}} ->
decoded_id
_ ->
# If we fail to decode for the correct type, we just skip translation
# This will be marked as an invalid input down the line
id
end
end)
Map.put(args, field, decoded_ids)
_ ->
args
end
end
end