Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render improvements #780

Merged
merged 4 commits into from
Sep 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/absinthe/pipeline.ex
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ defmodule Absinthe.Pipeline do
# This phase is run once now because a lot of other
# validations aren't possible if type references are invalid.
Phase.Schema.Validation.NoCircularFieldImports,
Phase.Schema.Validation.Result,
{Phase.Schema.Validation.Result, pass: :initial},
Phase.Schema.FieldImports,
Phase.Schema.Validation.KnownDirectives,
{Phase.Schema.Arguments.Parse, options},
Expand All @@ -149,7 +149,7 @@ defmodule Absinthe.Pipeline do
Phase.Schema.Validation.QueryTypeMustBeObject,
Phase.Schema.RegisterTriggers,
# This phase is run again now after additional validations
Phase.Schema.Validation.Result,
{Phase.Schema.Validation.Result, pass: :final},
Phase.Schema.Build,
Phase.Schema.InlineFunctions,
{Phase.Schema.Compile, options}
Expand Down Expand Up @@ -252,7 +252,7 @@ defmodule Absinthe.Pipeline do
# Whether a phase configuration is for a given phase
@spec match_phase?(Phase.t(), phase_config_t) :: boolean
defp match_phase?(phase, phase), do: true
defp match_phase?(phase, {phase, _}), do: true
defp match_phase?(phase, {phase, _}) when is_atom(phase), do: true
defp match_phase?(_, _), do: false

@doc """
Expand All @@ -263,7 +263,7 @@ defmodule Absinthe.Pipeline do
iex> Pipeline.upto([A, B, C], B)
[A, B]
"""
@spec upto(t, atom) :: t
@spec upto(t, phase_config_t) :: t
def upto(pipeline, phase) do
beginning = before(pipeline, phase)
item = get_in(pipeline, [Access.at(length(beginning))])
Expand Down
53 changes: 38 additions & 15 deletions lib/absinthe/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule Absinthe.Schema do

## Custom Schema Manipulation (in progress)
In Absinthe 1.5 schemas are built using the same process by which queries are
executed. All the fancy macros build up an intermediary tree of structs in the
executed. All the macros in this module and in `Notation` build up an intermediary tree of structs in the
`%Absinthe.Blueprint{}` namespace, which we generally call "Blueprint structs".

At the top you've got a `%Blueprint{}` struct which holds onto some schema
Expand Down Expand Up @@ -67,7 +67,7 @@ defmodule Absinthe.Schema do
Pipeline.insert_after(pipeline, Phase.Schema.TypeImports, __MODULE__)
end

# Here's the blueprint of the schema, let's do whatever we want with it.
# Here's the blueprint of the schema, do whatever you want with it.
def run(blueprint, _) do
{:ok, blueprint}
end
Expand Down Expand Up @@ -105,6 +105,7 @@ defmodule Absinthe.Schema do
import unquote(__MODULE__), only: :macros

@after_compile unquote(__MODULE__)
@before_compile unquote(__MODULE__)

defdelegate __absinthe_type__(name), to: __MODULE__.Compiled
defdelegate __absinthe_directive__(name), to: __MODULE__.Compiled
Expand Down Expand Up @@ -287,26 +288,34 @@ defmodule Absinthe.Schema do
Absinthe.Schema.Notation.record!(env, @object_type, :subscription, attrs, block)
end

defmacro __before_compile__(_) do
quote do
@doc false
def __absinthe_pipeline_modifiers__ do
@pipeline_modifier
end
end
end

defp apply_modifiers(pipeline, schema) do
Enum.reduce(schema.__absinthe_pipeline_modifiers__, pipeline, fn
{module, function}, pipeline ->
apply(module, function, [pipeline])

module, pipeline ->
module.pipeline(pipeline)
end)
end

def __after_compile__(env, _) do
prototype_schema =
env.module
|> Module.get_attribute(:prototype_schema)

pipeline =
Absinthe.Pipeline.for_schema(env.module,
prototype_schema: prototype_schema
)

pipeline =
env.module
|> Module.get_attribute(:pipeline_modifier)
|> Enum.reduce(pipeline, fn
{module, function}, pipeline ->
apply(module, function, [pipeline])

module, pipeline ->
module.pipeline(pipeline)
end)
|> Absinthe.Pipeline.for_schema(prototype_schema: prototype_schema)
|> apply_modifiers(env.module)

env.module.__absinthe_blueprint__
|> Absinthe.Pipeline.run(pipeline)
Expand Down Expand Up @@ -544,6 +553,20 @@ defmodule Absinthe.Schema do
|> Enum.map(&lookup_directive(schema, &1))
end

def to_sdl(schema) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice function to have!

We should use it in Mix.Tasks.Absinthe.Schema.Sdl as well

https://github.com/absinthe-graphql/absinthe/blob/master/lib/mix/tasks/absinthe.schema.sdl.ex#L76-L82

pipeline =
schema
|> Absinthe.Pipeline.for_schema()
|> Absinthe.Pipeline.upto({Absinthe.Phase.Schema.Validation.Result, pass: :final})
|> apply_modifiers(schema)

# we can be assertive here, since this same pipeline was already used to
# successfully compile the schema.
{:ok, bp, _} = Absinthe.Pipeline.run(schema.__absinthe_blueprint__, pipeline)

inspect(bp, pretty: true)
end

@doc """
List all implementors of an interface on a schema
"""
Expand Down
Loading