Packages
Codec for generating Absinthe JSON schemas in a deterministic format with alphabetically ordered type definitions
Current section
Files
Jump to
Current section
Files
lib/absinthe_sorting_codec.ex
defmodule AbsintheSortingCodec do
@moduledoc """
Convert the JSON output of an introspection query into deterministic JSON with types ordered alphabetically.
## Example
```
AbsintheSortingCodec.encode!(Jason.decode!("swapi.json"))
```
Can be used to convert an Absinthe schema to a sorted, deterministic ordering
by using AbsintheSortingCodec as the JSON encoder.
## Example
```bash
mix absinthe.schema.json --schema MySchema --json-codec AbsintheSortingCodec --pretty true
```
"""
@doc """
Generates a JSON GraphQL schema in a deterministic format, with lists of objects sorted by their `name` property,
if they have one.
`schema` is the Elixir representation of the JSON result of an introspection query (as generated by Absinthe).
Uses [Jason](https://github.com/michalmuskala/jason) for encoding into JSON.
"""
def encode(schema, opts \\ []) do
schema
|> sorted_objects()
|> Jason.encode(opts)
end
def encode!(schema, opts \\ []) do
case encode(schema, opts) do
{:ok, content} -> content
{:error, reason} -> raise reason
end
end
defp sorted_objects(value)
defp sorted_objects(map) when is_map(map) do
for {key, val} <- map, into: %{}, do: {key, sorted_objects(val)}
end
defp sorted_objects(list) when is_list(list) do
list
|> Enum.sort_by(&list_sorting_value/1)
|> Enum.map(&sorted_objects/1)
end
defp sorted_objects(value), do: value
defp list_sorting_value(%{name: name}), do: name
defp list_sorting_value(%{"name" => name}), do: name
defp list_sorting_value(value), do: value
end