Skip to content

Instantly share code, notes, and snippets.

@vorce
Last active December 6, 2022 16:24
Show Gist options
  • Save vorce/2c2012c720ef3766aeceaddf0795893f to your computer and use it in GitHub Desktop.
Save vorce/2c2012c720ef3766aeceaddf0795893f to your computer and use it in GitHub Desktop.
Absinthe import_fields from module
defmodule AbsintheHelper do
@moduledoc """
A way to `import_fields` from a specific module.
The idea is to make it more explicit in your schema where
object fields are coming from at a glance.
Usage in your schema:
```
require AbsintheHelper
alias AbsintheHelper
import_types(__MODULE__.MyModule)
query(name: "Foo") do
AbsintheHelper.import_fields_from(
{__MODULE__.MyModule, :my_object}
)
end
```
"""
import Absinthe.Schema.Notation
defp expand_ast(ast, env) do
Macro.prewalk(ast, fn
{_, _, _} = node ->
Macro.expand(node, env)
node ->
node
end)
end
defp lookup_object(module, identifier) do
first_schema = List.first(module.__absinthe_blueprint__().schema_definitions)
Enum.find(first_schema.type_definitions, fn object_type ->
Enum.find(object_type.fields, fn field -> field.identifier == identifier end)
end)
end
defmacro import_fields_from({module, object}, opts \\ []) do
expanded_module = expand_ast(module, __CALLER__)
object_lookup = lookup_object(expanded_module, object)
if object_lookup == nil,
do: raise("Module #{inspect(expanded_module)} does not contain object #{inspect(object)}")
quote do
import_fields(unquote(object), unquote(opts))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment