defmodule Grapix.SchemaBuilder do defp gen_quoted_preamble_block() do quote do use(Absinthe.Schema) import_types(Absinthe.Type.Custom) end end defp gen_types_block(api_list) do block = api_list |> Enum.map(fn api -> {decls, []} = Code.eval_string("#{to_string(api)}.QuotedDeclarations.types()") decls end) |> Enum.filter(&(&1 != {:__block__, [], []})) {:__block__, [], block} end defp gen_fields_block(api_list) do block = api_list |> Enum.map(fn api -> {decls, []} = Code.eval_string("#{to_string(api)}.QuotedDeclarations.fields()") decls end) |> Enum.filter(&(&1 != {:__block__, [], []})) {:__block__, [], block} end defp gen_root_imports_statements(root_operation, api_list) do api_list |> Enum.map(fn api -> {imports, []} = Code.eval_string( "#{to_string(api)}.QuotedDeclarations.root_field_imports(:#{root_operation})" ) imports end) |> Enum.filter(&(&1 != {:__block__, [], []})) end defp gen_root_operation_block(root_operation, api_list) do case gen_root_imports_statements(root_operation, api_list) do [] -> nil block -> {root_operation, [], [[name: Macro.camelize(to_string(root_operation))], [do: {:__block__, [], block}]]} end end defmacro inject_schema_def(modules) do {api_list, []} = Code.eval_quoted(modules) block = [ gen_quoted_preamble_block(), gen_types_block(api_list), gen_fields_block(api_list), gen_root_operation_block(:query, api_list), gen_root_operation_block(:mutation, api_list), gen_root_operation_block(:subscription, api_list) ] |> Enum.filter(&(not is_nil(&1))) ast = {:__block__, [], block} Macro.to_string(ast) ast end end