2020-05-02 04:32:56 +12:00
|
|
|
defmodule AshGraphql do
|
|
|
|
@moduledoc """
|
2020-08-14 10:55:34 +12:00
|
|
|
AshGraphql is a graphql front extension for the Ash framework.
|
|
|
|
|
2020-09-24 13:32:45 +12:00
|
|
|
See the [getting started guide](/getting_started.md) for information on setting it up, and
|
2020-08-14 10:55:34 +12:00
|
|
|
see the `AshGraphql.Resource` documentation for docs on its DSL
|
2020-05-02 04:32:56 +12:00
|
|
|
"""
|
|
|
|
|
2020-08-14 09:39:59 +12:00
|
|
|
defmacro __using__(opts) do
|
2020-09-24 12:54:57 +12:00
|
|
|
quote bind_quoted: [apis: opts[:apis], api: opts[:api]] do
|
|
|
|
apis =
|
|
|
|
api
|
|
|
|
|> List.wrap()
|
|
|
|
|> Kernel.++(List.wrap(apis))
|
|
|
|
|> Enum.map(&{&1, false})
|
|
|
|
|> List.update_at(0, fn {api, _} -> {api, true} end)
|
|
|
|
|
|
|
|
for {api, first?} <- apis do
|
|
|
|
defmodule Module.concat(api, AshTypes) do
|
|
|
|
@moduledoc false
|
|
|
|
alias Absinthe.{Blueprint, Phase, Pipeline}
|
|
|
|
|
|
|
|
def pipeline(pipeline) do
|
|
|
|
Pipeline.insert_before(
|
|
|
|
pipeline,
|
|
|
|
Phase.Schema.Validation.QueryTypeMustBeObject,
|
|
|
|
__MODULE__
|
|
|
|
)
|
|
|
|
end
|
2020-08-17 19:00:13 +12:00
|
|
|
|
2020-09-24 12:54:57 +12:00
|
|
|
def run(blueprint, _opts) do
|
|
|
|
api = unquote(api)
|
|
|
|
|
|
|
|
case Code.ensure_compiled(api) do
|
|
|
|
{:module, _} ->
|
|
|
|
blueprint_with_queries =
|
|
|
|
api
|
|
|
|
|> AshGraphql.Api.queries(__MODULE__)
|
|
|
|
|> Enum.reduce(blueprint, fn query, blueprint ->
|
|
|
|
Absinthe.Blueprint.add_field(blueprint, "RootQueryType", query)
|
|
|
|
end)
|
|
|
|
|
|
|
|
blueprint_with_mutations =
|
|
|
|
api
|
|
|
|
|> AshGraphql.Api.mutations(__MODULE__)
|
|
|
|
|> Enum.reduce(blueprint_with_queries, fn mutation, blueprint ->
|
|
|
|
Absinthe.Blueprint.add_field(blueprint, "RootMutationType", mutation)
|
|
|
|
end)
|
|
|
|
|
|
|
|
new_defs =
|
|
|
|
List.update_at(blueprint_with_mutations.schema_definitions, 0, fn schema_def ->
|
|
|
|
%{
|
|
|
|
schema_def
|
2020-11-06 14:59:06 +13:00
|
|
|
| imports: [{Absinthe.Type.Custom, []} | List.wrap(schema_def.imports)],
|
|
|
|
type_definitions:
|
2020-09-24 12:54:57 +12:00
|
|
|
schema_def.type_definitions ++
|
|
|
|
AshGraphql.Api.type_definitions(api, __MODULE__, unquote(first?))
|
|
|
|
}
|
|
|
|
end)
|
|
|
|
|
|
|
|
{:ok, %{blueprint_with_mutations | schema_definitions: new_defs}}
|
|
|
|
|
|
|
|
{:error, _} ->
|
|
|
|
# Something else will fail here, so we don't need to
|
|
|
|
{:ok, blueprint}
|
|
|
|
end
|
2020-08-17 19:00:13 +12:00
|
|
|
end
|
2020-08-14 09:39:59 +12:00
|
|
|
end
|
2020-05-02 04:32:56 +12:00
|
|
|
|
2020-09-24 12:54:57 +12:00
|
|
|
@pipeline_modifier Module.concat(api, AshTypes)
|
|
|
|
end
|
2020-08-14 09:39:59 +12:00
|
|
|
end
|
2020-05-02 04:32:56 +12:00
|
|
|
end
|
2020-08-15 02:20:47 +12:00
|
|
|
|
2020-09-24 12:54:57 +12:00
|
|
|
def add_context(ctx, apis) do
|
|
|
|
dataloader =
|
|
|
|
apis
|
|
|
|
|> List.wrap()
|
|
|
|
|> Enum.reduce(Dataloader.new(), fn api, dataloader ->
|
|
|
|
Dataloader.add_source(
|
|
|
|
dataloader,
|
|
|
|
api,
|
|
|
|
AshGraphql.Dataloader.new(api)
|
|
|
|
)
|
|
|
|
end)
|
|
|
|
|
2020-10-28 19:16:16 +13:00
|
|
|
Map.put(ctx, :loader, dataloader)
|
2020-08-15 02:20:47 +12:00
|
|
|
end
|
2020-05-02 04:32:56 +12:00
|
|
|
end
|