improvement: lots of docs fixes!

This commit is contained in:
Zach Daniel 2022-09-15 18:35:33 -04:00
parent 101004ecb0
commit fa07573511
38 changed files with 1902 additions and 183 deletions

View file

@ -1,9 +1,15 @@
[
import_deps: [:ecto, :phoenix, :ash, :ash_postgres, :surface],
inputs: ["*.{ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{ex,exs}"],
import_deps: [:ecto, :phoenix, :ash, :ash_postgres, :ash_graphql, :surface],
inputs: [
"*.{ex,exs}",
"priv/*/seeds.exs",
"priv/scripts/**/*.{ex,exs}",
"{config,lib,test}/**/*.{ex,exs}"
],
subdirectories: ["priv/*/migrations"],
plugins: [Spark.Formatter],
plugins: [Spark.Formatter, Surface.Formatter.Plugin],
locals_without_parens: [
auto_sanitize_name_attribute?: 1,
name_attribute: 1,
library_version_attribute: 1,
load_for_search: 1,

View file

@ -3,10 +3,11 @@
## Getting Started
1. Fork and clone this repository.
2. Set up the project by running `mix do deps.get, deps.compile, setup` (the import may take a while).
3. Install the frontend assets by running `npm i --prefix assets`.
4. Run the server with `iex -S mix phx.server`
5. Open [http://localhost:4000](http://localhost:4000)
2. Set up the project by running `mix do deps.get, deps.compile, setup`
3. Run `mix import` to import the latest dependencies from hex (this may take a while)
4. Install the frontend assets by running `npm i --prefix assets`.
5. Run the server with `iex -S mix phx.server`
6. Open [http://localhost:4000](http://localhost:4000)
## A Bit of History

View file

@ -373,6 +373,10 @@
background-color: #d2d2d2
}
.light .not-prose > .code-pre {
background-color: inherit
}
.light .inline {
background-color: #d2d2d2;
border-radius: 0.1rem;

View file

@ -2,7 +2,10 @@ defmodule AshHq.Docs do
@moduledoc """
Handles documentation data.
"""
use Ash.Api, otp_app: :ash_hq
use Ash.Api,
extensions: [
AshGraphql.Api
]
execution do
timeout 30_000

View file

@ -12,6 +12,8 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown.Changes.RenderMarkdown do
source = Ash.Changeset.get_attribute(changeset, opts[:source])
text = remove_ash_hq_hidden_content(source)
attribute = Ash.Resource.Info.attribute(changeset.resource, opts[:destination])
changeset =
if text != source do
Ash.Changeset.force_change_attribute(changeset, opts[:source], text)
@ -38,11 +40,29 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown.Changes.RenderMarkdown do
html_doc = AshHq.Docs.Extensions.RenderMarkdown.Highlighter.highlight(html_doc)
html_doc =
case attribute.type do
{:array, _} ->
List.wrap(html_doc)
_ ->
html_doc
end
Ash.Changeset.force_change_attribute(changeset, opts[:destination], html_doc)
{:ok, html_doc, _} ->
html_doc = AshHq.Docs.Extensions.RenderMarkdown.Highlighter.highlight(html_doc)
html_doc =
case attribute.type do
{:array, _} ->
List.wrap(html_doc)
_ ->
html_doc
end
Ash.Changeset.force_change_attribute(changeset, opts[:destination], html_doc)
end
else
@ -53,6 +73,10 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown.Changes.RenderMarkdown do
defp remove_ash_hq_hidden_content(nil), do: nil
defp remove_ash_hq_hidden_content(strings) when is_list(strings) do
Enum.map(strings, &remove_ash_hq_hidden_content/1)
end
defp remove_ash_hq_hidden_content(string) do
string
|> String.split(~r/\<\!---.*ash-hq-hide-start.*--\>/)

View file

@ -6,6 +6,10 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown.Highlighter do
@doc """
Highlights all code block in an already generated HTML document.
"""
def highlight(html) when is_list(html) do
Enum.map(html, &highlight/1)
end
def highlight(html) do
Regex.replace(
~r/<pre><code(?:\s+class="(\w*)")?>([^<]*)<\/code><\/pre>/,
@ -16,7 +20,6 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown.Highlighter do
defp highlight_code_block(full_block, lang, code) do
case pick_language_and_lexer(lang) do
{_language, nil, _opts} -> full_block
{language, lexer, opts} -> render_code(language, lexer, opts, code)
end
end
@ -31,17 +34,21 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown.Highlighter do
end
defp render_code(lang, lexer, lexer_opts, code) do
highlighted =
code
|> unescape_html()
|> IO.iodata_to_binary()
|> Makeup.highlight_inner_html(
lexer: lexer,
lexer_options: lexer_opts,
formatter_options: [highlight_tag: "span"]
)
if lexer do
highlighted =
code
|> unescape_html()
|> IO.iodata_to_binary()
|> Makeup.highlight_inner_html(
lexer: lexer,
lexer_options: lexer_opts,
formatter_options: [highlight_tag: "span"]
)
~s(<pre class="code-pre"><code class="makeup #{lang} highlight">#{highlighted}</code></pre>)
~s(<pre class="code-pre"><code class="makeup #{lang} highlight">#{highlighted}</code></pre>)
else
~s(<pre class="code-pre"><code class="makeup #{lang} text-black dark:text-white">#{code}</code></pre>)
end
end
entities = [{"&amp;", ?&}, {"&lt;", ?<}, {"&gt;", ?>}, {"&quot;", ?"}, {"&#39;", ?'}]

View file

@ -38,7 +38,15 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown do
Map.get(record, render_attributes(resource)[key])
on_demand? ->
as_html!(Map.get(record, key) || "", header_ids?(resource))
case Map.get(record, key) do
value when is_list(value) ->
Enum.map(value, fn value ->
as_html!(value || "", header_ids?(resource))
end)
value ->
as_html!(value || "", header_ids?(resource))
end
true ->
raise "#{resource} dos not render #{key} as markdown. Pass the `on_demand?` argument as `true` to render it dynamically."
@ -55,12 +63,35 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown do
""
end
def as_html!(text, add_ids?) when is_list(text) do
Enum.map(text, &as_html!(&1, add_ids?))
end
def as_html!(text, add_ids?) do
text
|> Earmark.as_html!(opts(add_ids?))
|> AshHq.Docs.Extensions.RenderMarkdown.Highlighter.highlight()
end
def as_html(text, add_ids?) when is_list(text) do
Enum.reduce_while(text, {:ok, [], []}, fn text, {:ok, list, errors} ->
case as_html(text, add_ids?) do
{:ok, text, new_errors} ->
{:cont, {:ok, [text | list], errors ++ new_errors}}
other ->
{:halt, other}
end
end)
|> case do
{:ok, list, errors} ->
{:ok, Enum.reverse(list), errors}
other ->
other
end
end
def as_html(text, add_ids?) do
text
|> Earmark.as_html(opts(add_ids?))

View file

@ -48,9 +48,41 @@ defmodule AshHq.Docs.Extensions.Search.Transformers.AddSearchStructure do
|> add_matches_calculation(config)
|> add_indexes(config)
|> add_html_for_calculation(config)
|> add_additional_html_calculations(config)
|> add_match_rank_calculation(config)}
end
defp add_additional_html_calculations(dsl_state, config) do
dsl_state
|> Transformer.get_option([:render_markdown], :render_attributes)
|> List.wrap()
|> Enum.reject(fn {source, _} ->
config.doc_attribute == source
end)
|> Enum.reduce(dsl_state, fn {_, dest}, dsl_state ->
name = :"#{dest}_for"
type = Ash.Resource.Info.attribute(dsl_state, dest).type
dsl_state
|> Transformer.add_entity(
[:calculations],
Transformer.build_entity!(Ash.Resource.Dsl, [:calculations], :calculate,
name: name,
type: type,
arguments: [html_for_argument()],
calculation:
Ash.Query.expr(
if ^ref(config.show_docs_on) == ^arg(:for) do
^ref(dest)
else
nil
end
)
)
)
end)
end
defp add_html_for_calculation(dsl_state, config) do
if config.doc_attribute do
html_for_attribute =

View file

@ -4,92 +4,92 @@ defmodule AshHq.Docs.Search do
use Ash.Flow, otp_app: :ash_hq
flow do
api AshHq.Docs
api(AshHq.Docs)
description """
description("""
Runs a search over all searchable items.
"""
""")
argument :query, :string do
allow_nil? false
constraints trim?: false, allow_empty?: true
allow_nil?(false)
constraints(trim?: false, allow_empty?: true)
end
argument :library_versions, {:array, :uuid} do
allow_nil? false
allow_nil?(false)
end
argument :types, {:array, :string}
argument(:types, {:array, :string})
returns :build_results
returns(:build_results)
end
steps do
custom :options, AshHq.Docs.Search.Steps.SearchResource do
input %{
input(%{
query: arg(:query),
library_versions: arg(:library_versions),
types: arg(:types),
resource: AshHq.Docs.Option
}
})
end
custom :dsls, AshHq.Docs.Search.Steps.SearchResource do
input %{
input(%{
query: arg(:query),
library_versions: arg(:library_versions),
types: arg(:types),
resource: AshHq.Docs.Dsl
}
})
end
custom :guides, AshHq.Docs.Search.Steps.SearchResource do
input %{
input(%{
query: arg(:query),
library_versions: arg(:library_versions),
types: arg(:types),
resource: AshHq.Docs.Guide
}
})
end
custom :library_versions, AshHq.Docs.Search.Steps.SearchResource do
input %{
input(%{
query: arg(:query),
library_versions: arg(:library_versions),
types: arg(:types),
resource: AshHq.Docs.LibraryVersion
}
})
end
custom :extensions, AshHq.Docs.Search.Steps.SearchResource do
input %{
input(%{
query: arg(:query),
library_versions: arg(:library_versions),
types: arg(:types),
resource: AshHq.Docs.Extension
}
})
end
custom :functions, AshHq.Docs.Search.Steps.SearchResource do
input %{
input(%{
query: arg(:query),
library_versions: arg(:library_versions),
types: arg(:types),
resource: AshHq.Docs.Function
}
})
end
custom :modules, AshHq.Docs.Search.Steps.SearchResource do
input %{
input(%{
query: arg(:query),
library_versions: arg(:library_versions),
types: arg(:types),
resource: AshHq.Docs.Module
}
})
end
custom :build_results, AshHq.Docs.Search.Steps.BuildResults do
input %{
input(%{
dsls: result(:dsls),
options: result(:options),
guides: result(:guides),
@ -97,7 +97,7 @@ defmodule AshHq.Docs.Search do
extensions: result(:extensions),
functions: result(:functions),
modules: result(:modules)
}
})
end
end
end

View file

@ -53,16 +53,40 @@ defmodule AshHq.Docs.Importer do
|> Enum.each(fn version ->
file = Path.expand("./#{Ash.UUID.generate()}.json")
# Just throwing in a bunch of things here to see if it fixes the issue
# don't actually think they matter, but might as well try
env_to_unset = [
"RELEASE_BOOT_SCRIPT",
"RELEASE_MODE",
"RELEASE_COMMAND",
"BINDIR",
"RELEASE_REMOTE_VM_ARGS",
"RELEASE_ROOT",
"ROOTDIR",
"RELEASE_NODE",
"RELEASE_VSN",
"RELEASE_PROG",
"RELEASE_TMP",
"RELEASE_SYS_CONFIG",
"RELEASE_NAME",
"RELEASE_RELEASE_VM_ARGS",
"RELEASE_COOKIE"
]
result =
try do
with_retry(fn ->
{_, 0} =
System.cmd("elixir", [
Path.join([:code.priv_dir(:ash_hq), "scripts", "build_dsl_docs.exs"]),
name,
version,
file
])
System.cmd(
"elixir",
[
Path.join([:code.priv_dir(:ash_hq), "scripts", "build_dsl_docs.exs"]),
name,
version,
file
],
env: Map.new(env_to_unset, &{&1, nil})
)
output = File.read!(file)
:erlang.binary_to_term(Base.decode64!(String.trim(output)))

View file

@ -112,11 +112,11 @@ defmodule AshHq.Docs.Dsl do
relationships do
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
allow_nil? true
end
belongs_to :extension, AshHq.Docs.Extension do
required? true
allow_nil? true
end
belongs_to :dsl, __MODULE__

View file

@ -93,7 +93,7 @@ defmodule AshHq.Docs.Extension do
relationships do
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
allow_nil? true
end
has_many :dsls, AshHq.Docs.Dsl

View file

@ -10,7 +10,7 @@ defmodule AshHq.Docs.Function do
end
render_markdown do
render_attributes doc: :doc_html
render_attributes doc: :doc_html, heads: :heads_html
header_ids? false
end
@ -53,7 +53,7 @@ defmodule AshHq.Docs.Function do
end
attribute :type, :atom do
constraints one_of: [:function, :macro, :callback]
constraints one_of: [:function, :macro, :callback, :type]
allow_nil? false
end
@ -61,6 +61,10 @@ defmodule AshHq.Docs.Function do
default []
end
attribute :heads_html, {:array, :string} do
default []
end
attribute :doc, :string do
allow_nil? false
constraints trim?: false, allow_empty?: true
@ -102,11 +106,11 @@ defmodule AshHq.Docs.Function do
relationships do
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
allow_nil? true
end
belongs_to :module, AshHq.Docs.Module do
required? true
allow_nil? true
end
end
end

View file

@ -2,7 +2,10 @@ defmodule AshHq.Docs.Guide do
@moduledoc false
use AshHq.Resource,
data_layer: AshPostgres.DataLayer,
extensions: [AshHq.Docs.Extensions.Search, AshHq.Docs.Extensions.RenderMarkdown]
extensions: [
AshHq.Docs.Extensions.Search,
AshHq.Docs.Extensions.RenderMarkdown
]
resource do
description "Represents a markdown guide exposed by a library"
@ -18,7 +21,7 @@ defmodule AshHq.Docs.Guide do
load_for_search library_version: [:library_name, :library_display_name]
show_docs_on :route
sanitized_name_attribute :route
auto_sanitize_name_attribute?(false)
auto_sanitize_name_attribute? false
end
code_interface do
@ -27,6 +30,13 @@ defmodule AshHq.Docs.Guide do
actions do
defaults [:create, :read, :update, :destroy]
read :paginate do
pagination do
countable true
keyset? true
end
end
end
changes do
@ -76,7 +86,7 @@ defmodule AshHq.Docs.Guide do
relationships do
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
allow_nil? true
end
end
end

View file

@ -120,7 +120,7 @@ defmodule AshHq.Docs.LibraryVersion do
relationships do
belongs_to :library, AshHq.Docs.Library do
required? true
allow_nil? true
end
has_many :extensions, AshHq.Docs.Extension

View file

@ -90,7 +90,7 @@ defmodule AshHq.Docs.Module do
relationships do
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
allow_nil? true
end
has_many :functions, AshHq.Docs.Function

View file

@ -111,15 +111,15 @@ defmodule AshHq.Docs.Option do
relationships do
belongs_to :dsl, AshHq.Docs.Dsl do
required? true
allow_nil? true
end
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
allow_nil? true
end
belongs_to :extension, AshHq.Docs.Extension do
required? true
allow_nil? true
end
end
end

View file

@ -17,30 +17,58 @@ defmodule AshHqWeb.Components.Docs.Functions do
{#case Enum.filter(@functions, &(&1.type == @type))}
{#match []}
{#match functions}
<h1>{@header}</h1>
<h3>{@header}</h3>
{#for function <- functions}
<div
id={"#{@type}-#{function.sanitized_name}-#{function.arity}"}
class="nav-anchor rounded-lg bg-base-dark-400 dark:bg-base-dark-700 bg-opacity-50 px-2"
>
<p class="">
<div class="">
<div class="flex flex-row items-baseline">
<a href={"##{@type}-#{function.sanitized_name}-#{function.arity}"}>
<Heroicons.Outline.LinkIcon class="h-3 m-3" />
</a>
<div class="text-xl font-semibold mb-2">{function.name}/{function.arity} <SourceLink module_or_function={function} library={@library} library_version={@library_version} />
</div>
<div id={"#{@type}-#{function.sanitized_name}-#{function.arity}"} class="nav-anchor mb-8">
<div class="bg-base-light-200 dark:bg-base-dark-700 w-full rounded-lg">
<div class="flex flex-row items-center bg-opacity-50 py-1 rounded-t-lg bg-base-light-300 dark:bg-base-dark-800 w-full">
<a href={"##{@type}-#{function.sanitized_name}-#{function.arity}"}>
<Heroicons.Outline.LinkIcon class="h-3 m-3" />
</a>
<div class="flex flex-row items-center justify-between w-full pr-2">
<div class="text-xl w-full font-semibold">{function.name}/{function.arity}</div>
<SourceLink module_or_function={function} library={@library} library_version={@library_version} />
</div>
{#for head <- function.heads}
<code class="makeup elixir">{head}</code>
{/for}
{raw(render_replacements(@libraries, @selected_versions, function.html_for))}
</div>
</p>
<div class="p-4">
{raw(rendered(@libraries, @selected_versions, function.html_for))}
</div>
</div>
</div>
{/for}
{/case}
"""
end
defp rendered(libraries, selected_versions, html_for) do
libraries
|> render_replacements(selected_versions, html_for)
|> String.split("<!--- heads-end -->")
|> case do
[] ->
""
[string] ->
string
[heads, docs] ->
if String.trim(docs) == "" do
"""
<div class="not-prose">
#{heads}
</div>
#{docs}
"""
else
"""
<div class="not-prose border-b pb-2">
#{heads}
</div>
#{docs}
"""
end
end
end
end

View file

@ -15,6 +15,16 @@ defmodule AshHqWeb.Components.RightNav do
<a id="right-nav-module-docs" class="hover:text-primary-light-300 right-nav" href="#module-docs">
{@module}
</a>
{#for %{type: :type} = function <- @functions}
<a
id={"right-nav-callback-#{function.sanitized_name}-#{function.arity}"}
class="hover:text-primary-light-300 right-nav"
href={"#type-#{function.sanitized_name}-#{function.arity}"}
>
{"#{function.name}/#{function.arity}"}
</a>
{/for}
{#for %{type: :callback} = function <- @functions}
<a
id={"right-nav-callback-#{function.sanitized_name}-#{function.arity}"}

View file

@ -140,7 +140,25 @@ defmodule AshHqWeb.Components.Search do
defp render_item_type(assigns, item) do
case item_type(item) do
type when type in ["Module", "Function"] ->
"Function" ->
case item.type do
type when type in [:function, :macro] ->
~F"""
<Heroicons.Outline.CodeIcon class="h-4 w-4" />
"""
:callback ->
~F"""
<Heroicons.Outline.AtSymbolIcon class="h-4 w-4" />
"""
:type ->
~F"""
<Heroicons.Outline.InformationCircleIcon class="h-4 w-4" />
"""
end
"Module" ->
~F"""
<Heroicons.Outline.CodeIcon class="h-4 w-4" />
"""

View file

@ -116,6 +116,15 @@ defmodule AshHqWeb.Pages.Docs do
{/if}
</div>
{#if @module}
<Functions
header="Types"
type={:type}
functions={@module.functions}
library={@library}
library_version={@library_version}
libraries={@libraries}
selected_versions={@selected_versions}
/>
<Functions
header="Callbacks"
type={:callback}
@ -442,20 +451,34 @@ defmodule AshHqWeb.Pages.Docs do
defp load_docs_for(query, nil), do: query
defp load_docs_for(query, []), do: query
defp load_docs_for(query, true) do
query.resource
|> AshHq.Docs.Extensions.RenderMarkdown.render_attributes()
|> Enum.reduce(query, fn {source, target}, query ->
Ash.Query.select(query, [source, target])
end)
defp load_docs_for(_query, true) do
raise "unreachable"
end
defp load_docs_for(query, name) when is_list(name) do
Ash.Query.load(query, html_for: %{for: Enum.join(name, "/")})
name = Enum.join(name, "/")
load_docs_for(query, name)
end
defp load_docs_for(query, name) do
Ash.Query.load(query, html_for: %{for: name})
query
|> Ash.Query.load(html_for: %{for: name})
|> load_additional_docs(name)
end
defp load_additional_docs(query, name) do
query.resource
|> AshHq.Docs.Extensions.RenderMarkdown.render_attributes()
|> Enum.reduce(query, fn {source, dest}, query ->
doc_source = AshHq.Docs.Extensions.Search.doc_attribute(query.resource)
if doc_source && source == doc_source do
query
else
load = String.to_existing_atom("#{dest}_for")
Ash.Query.load(query, [{load, %{for: name}}])
end
end)
end
defp deselect_doc_attributes(query) do

View file

@ -491,7 +491,7 @@ defmodule AshHqWeb.Pages.Home do
relationships do
belongs_to :author, Example.User do
required? true
allow_nil? true
end
has_many :reactions, Example.Reaction

View file

@ -66,6 +66,16 @@ defmodule AshHqWeb.Router do
end
end
## Api routes
scope "/" do
forward "/gql", Absinthe.Plug, schema: AshHqWeb.Schema
forward "/playground",
Absinthe.Plug.GraphiQL,
schema: AshHqWeb.Schema,
interface: :playground
end
## Authentication routes
scope "/", AshHqWeb do

22
lib/ash_hq_web/schema.ex Normal file
View file

@ -0,0 +1,22 @@
defmodule AshHqWeb.Schema do
use Absinthe.Schema
# The registry must be included alongside the api to ensure the schema is properly recompiled on changes.
@apis [{AshHq.Docs, AshHq.Docs.Registry}]
use AshGraphql, apis: @apis
query do
end
# mutation do
# end
def context(ctx) do
AshGraphql.add_context(ctx, @apis)
end
def plugins() do
[Absinthe.Middleware.Dataloader | Absinthe.Plugin.defaults()]
end
end

14
mix.exs
View file

@ -33,11 +33,15 @@ defmodule AshHq.MixProject do
# Type `mix help deps` for examples and options.
defp deps do
[
{:ash, "~> 2.0.0-rc.4"},
# {:ash, path: "../ash", override: true},
{:ash_postgres, "~> 1.0.0-rc.3"},
# {:ash, "~> 2.0.0-rc.5"},
{:ash, path: "../ash", override: true},
# {:ash_postgres, "~> 1.0.0-rc.3"},
{:ash_postgres, github: "ash-project/ash_postgres"},
# {:ash_postgres, path: "../ash_postgres"},
{:ash_phoenix, "~> 1.0.0-rc.0"},
# {:ash_phoenix, "~> 1.0.0-rc.0"},
{:ash_phoenix, github: "ash-project/ash_phoenix"},
{:ash_graphql, github: "ash-project/ash_graphql"},
{:absinthe_plug, "~> 1.5"},
# {:ash_phoenix, github: "ash-project/ash_phoenix", branch: "ash-2.0", override: true},
# {:ash_livebook, path: "../ash_livebook", only: [:dev]},
{:spark, "~> 0.1"},
@ -102,7 +106,7 @@ defmodule AshHq.MixProject do
# See the documentation for `Mix` for more info on aliases.
defp aliases do
[
seed: ["run priv/repo/seeds.exs", "import"],
seed: ["run priv/repo/seeds.exs"],
setup: ["ash_postgres.create", "ash_postgres.migrate", "seed"],
reset: ["drop", "setup"],
credo: "credo --strict",

View file

@ -1,7 +1,10 @@
%{
"ash": {:hex, :ash, "2.0.0-rc.4", "6c184706a5de2fab19f3b51b07cf81e6d157a7d7884d0e1bc57fe3c8ae535cc5", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: true]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:spark, "~> 0.1 and >= 0.1.9", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.5.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b6e5a34aa924feda8ac9bbaaa67faf38c9bf09a970ef6872cb3b56a88588b2ca"},
"ash_phoenix": {:hex, :ash_phoenix, "1.0.0-rc.0", "7c5d780c6ebf239977ec0a3f40675ee3f3a5d6eaa4f28a95b4bc6701b61bbd67", [:mix], [{:ash, "~> 2.0.0-rc.0", [hex: :ash, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5.6 or ~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.15", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "e47246d2c7630b68a0d78d12824d73cd57d0948fe59dab736c26f79bb68b0ff3"},
"ash_postgres": {:hex, :ash_postgres, "1.0.0-rc.3", "e18e7a1c1d601e8a73b91e6f75e8f4f99f4ca58083c29354dee19942ccb0f9f7", [:mix], [{:ash, "~> 2.0.0-rc.3", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.8", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.8", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "92691ab7f2cf773aa1d5b0a79050b32549eb9de8203baf6b787b3d5681b6a1d1"},
"absinthe": {:hex, :absinthe, "1.7.0", "36819e7b1fd5046c9c734f27fe7e564aed3bda59f0354c37cd2df88fd32dd014", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0 or ~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "566a5b5519afc9b29c4d367f0c6768162de3ec03e9bf9916f9dc2bcbe7c09643"},
"absinthe_plug": {:hex, :absinthe_plug, "1.5.8", "38d230641ba9dca8f72f1fed2dfc8abd53b3907d1996363da32434ab6ee5d6ab", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bbb04176647b735828861e7b2705465e53e2cf54ccf5a73ddd1ebd855f996e5a"},
"ash": {:hex, :ash, "2.0.0-rc.5", "f5f852415d31d0f9624fd7510429abd7d3c5e271f23e553a8bdba01cf8d1df42", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: true]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:spark, "~> 0.1 and >= 0.1.9", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.5.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "93a272f0fd7c73189dfdb19221c9a2099a5bf9ab0dd11c26bd462a670d18d390"},
"ash_graphql": {:git, "https://github.com/ash-project/ash_graphql.git", "b2b9e22f7cfc70d48ec5beba46b5d588ea9e247b", []},
"ash_phoenix": {:git, "https://github.com/ash-project/ash_phoenix.git", "b64cd1394137713d1b407b49264fe88b3b7b6ebf", []},
"ash_postgres": {:git, "https://github.com/ash-project/ash_postgres.git", "11561ea163f60a4b32ee895b36005be24c8ab3d4", []},
"bcrypt_elixir": {:hex, :bcrypt_elixir, "3.0.1", "9be815469e6bfefec40fa74658ecbbe6897acfb57614df1416eeccd4903f602c", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "486bb95efb645d1efc6794c1ddd776a186a9a713abf06f45708a6ce324fb96cf"},
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
"castore": {:hex, :castore, "0.1.18", "deb5b9ab02400561b6f5708f3e7660fc35ca2d51bfc6a940d2f513f89c2975fc", [:mix], [], "hexpm", "61bbaf6452b782ef80b33cdb45701afbcf0a918a45ebe7e73f1130d661e66a06"},
@ -13,6 +16,7 @@
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"credo": {:hex, :credo, "1.6.6", "f51f8d45db1af3b2e2f7bee3e6d3c871737bda4a91bff00c5eec276517d1a19c", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "625520ce0984ee0f9f1f198165cd46fa73c1e59a17ebc520038b8fce056a5bdc"},
"dataloader": {:hex, :dataloader, "1.0.10", "a42f07641b1a0572e0b21a2a5ae1be11da486a6790f3d0d14512d96ff3e3bbe9", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0 or ~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "54cd70cec09addf4b2ace14cc186a283a149fd4d3ec5475b155951bf33cd963f"},
"db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"dialyxir": {:hex, :dialyxir, "1.2.0", "58344b3e87c2e7095304c81a9ae65cb68b613e28340690dfe1a5597fd08dec37", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "61072136427a851674cab81762be4dbeae7679f85b1272b6d25c3a839aff8463"},
@ -42,7 +46,7 @@
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"},
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
"libgraph": {:hex, :libgraph, "0.13.3", "20732b7bafb933dcf7351c479e03076ebd14a85fd3202c67a1c197f4f7c2466b", [:mix], [], "hexpm", "78f2576eef615440b46f10060b1de1c86640441422832052686df53dc3c148c6"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_eex": {:hex, :makeup_eex, "0.1.1", "89352d5da318d97ae27bbcc87201f274504d2b71ede58ca366af6a5fbed9508d", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.16", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_html, "~> 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d111a0994eaaab09ef1a4b3b313ef806513bb4652152c26c0d7ca2be8402a964"},
@ -80,7 +84,7 @@
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
"sourceror": {:hex, :sourceror, "0.11.2", "549ce48be666421ac60cfb7f59c8752e0d393baa0b14d06271d3f6a8c1b027ab", [:mix], [], "hexpm", "9ab659118896a36be6eec68ff7b0674cba372fc8e210b1e9dc8cf2b55bb70dfb"},
"spark": {:hex, :spark, "0.1.19", "f4093755f74423c4dfc64f308d16ac00c7c4e69fc186329aae9ffd3b4b062ffa", [:mix], [{:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "5a34859c8a8aa36a1633270117f64ecabd92596cf68943650306c31af0013e58"},
"spark": {:hex, :spark, "0.1.21", "2a8929f2c894d159a0b079f932944da63fae601538806567c444b45b00b17322", [:mix], [{:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "ca4bd4c2578018bb647ce7e675b592c729aba25a35c59454eb7dd0e2e2a4cc0f"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"stream_data": {:hex, :stream_data, "0.5.0", "b27641e58941685c75b353577dc602c9d2c12292dd84babf506c2033cd97893e", [:mix], [], "hexpm", "012bd2eec069ada4db3411f9115ccafa38540a3c78c4c0349f151fc761b9e271"},
"surface": {:hex, :surface, "0.8.1", "3228df8a82fea8daf8daefaa343b30be04d524ae41c657f5c5bb9ea4f711fc28", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.17.6", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.9", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "8a824660bc7a4cc4dd77ca986591b2935f27f6de01332df41ec3f5335213d114"},

View file

@ -8,24 +8,14 @@ defmodule AshHq.Repo.Migrations.MigrateResources23 do
use Ecto.Migration
def up do
# alter table(:modules) do
# Attribute removal has been commented out to avoid data loss. See the migration generator documentation for more
# If you uncomment this, be sure to also uncomment the corresponding attribute *addition* in the `down` migration
# remove :category_index
#
# end
#
alter table(:modules) do
remove :category_index
end
end
def down do
# alter table(:modules) do
# This is the `down` migration of the statement:
#
# remove :category_index
#
#
# add :category_index, :bigint, null: false, default: 0
# end
#
alter table(:modules) do
add :category_index, :bigint, null: false, default: 0
end
end
end
end

View file

@ -12,8 +12,6 @@ defmodule AshHq.Repo.Migrations.InstallPgStatStatements do
end
def down do
# Uncomment this if you actually want to uninstall the extensions
# when this migration is rolled back:
# execute("DROP EXTENSION IF EXISTS \"pg_stat_statements\"")
execute("DROP EXTENSION IF EXISTS \"pg_stat_statements\"")
end
end
end

View file

@ -12,8 +12,6 @@ defmodule AshHq.Repo.Migrations.InstallSslinfo do
end
def down do
# Uncomment this if you actually want to uninstall the extensions
# when this migration is rolled back:
# execute("DROP EXTENSION IF EXISTS \"sslinfo\"")
execute("DROP EXTENSION IF EXISTS \"sslinfo\"")
end
end
end

View file

@ -0,0 +1,79 @@
defmodule AshHq.Repo.Migrations.MigrateResources25 do
@moduledoc """
Updates resources based on their most recent snapshots.
This file was autogenerated with `mix ash_postgres.generate_migrations`
"""
use Ecto.Migration
def up do
alter table(:options) do
modify :extension_id, :uuid, null: true
modify :library_version_id, :uuid, null: true
modify :dsl_id, :uuid, null: true
end
alter table(:modules) do
modify :library_version_id, :uuid, null: true
end
alter table(:library_versions) do
modify :library_id, :uuid, null: true
end
alter table(:guides) do
modify :library_version_id, :uuid, null: true
end
alter table(:functions) do
modify :module_id, :uuid, null: true
modify :library_version_id, :uuid, null: true
add :heads_html, {:array, :text}
end
alter table(:extensions) do
modify :library_version_id, :uuid, null: true
end
alter table(:dsls) do
modify :extension_id, :uuid, null: true
modify :library_version_id, :uuid, null: true
end
end
def down do
alter table(:dsls) do
modify :library_version_id, :uuid, null: false
modify :extension_id, :uuid, null: false
end
alter table(:extensions) do
modify :library_version_id, :uuid, null: false
end
alter table(:functions) do
remove :heads_html
modify :library_version_id, :uuid, null: false
modify :module_id, :uuid, null: false
end
alter table(:guides) do
modify :library_version_id, :uuid, null: false
end
alter table(:library_versions) do
modify :library_id, :uuid, null: false
end
alter table(:modules) do
modify :library_version_id, :uuid, null: false
end
alter table(:options) do
modify :dsl_id, :uuid, null: false
modify :library_version_id, :uuid, null: false
modify :extension_id, :uuid, null: false
end
end
end

View file

@ -0,0 +1,252 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "sanitized_path",
"type": "text"
},
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v4()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "name",
"type": "text"
},
{
"allow_nil?": false,
"default": "\"\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc_html",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "imports",
"type": [
"array",
"text"
]
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "links",
"type": "map"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "examples",
"type": [
"array",
"text"
]
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "args",
"type": [
"array",
"text"
]
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "path",
"type": [
"array",
"text"
]
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "recursive_as",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "order",
"type": "bigint"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "type",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_library_version_id_fkey",
"on_delete": "delete",
"on_update": null,
"schema": "public",
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_extension_id_fkey",
"on_delete": null,
"on_update": null,
"schema": "public",
"table": "extensions"
},
"size": null,
"source": "extension_id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_dsl_id_fkey",
"on_delete": null,
"on_update": null,
"schema": "public",
"table": "dsls"
},
"size": null,
"source": "dsl_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [
{
"code?": false,
"down": "DROP INDEX dsls_name_lower_index;",
"name": "name_index",
"up": "CREATE INDEX dsls_name_lower_index ON dsls(lower(name));\n"
},
{
"code?": false,
"down": "DROP INDEX dsls_name_trigram_index;",
"name": "trigram_index",
"up": "CREATE INDEX dsls_name_trigram_index ON dsls USING GIST (name gist_trgm_ops);\n"
},
{
"code?": false,
"down": "DROP INDEX dsls_search_index;",
"name": "search_index",
"up": "CREATE INDEX dsls_search_index ON dsls USING GIN((\n setweight(to_tsvector('english', name), 'A') ||\n setweight(to_tsvector('english', doc), 'D')\n));\n"
}
],
"has_create_action": true,
"hash": "9BD57BFBB171CE02A79A04D0674A196C28015935B303B840C7E8B201DC486F20",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"schema": null,
"table": "dsls"
}

View file

@ -0,0 +1,162 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "sanitized_name",
"type": "text"
},
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v4()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "name",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "target",
"type": "text"
},
{
"allow_nil?": true,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "default_for_target",
"type": "boolean"
},
{
"allow_nil?": false,
"default": "\"\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc_html",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "type",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "order",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "extensions_library_version_id_fkey",
"on_delete": "delete",
"on_update": null,
"schema": "public",
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [
{
"code?": false,
"down": "DROP INDEX extensions_name_lower_index;",
"name": "name_index",
"up": "CREATE INDEX extensions_name_lower_index ON extensions(lower(name));\n"
},
{
"code?": false,
"down": "DROP INDEX extensions_name_trigram_index;",
"name": "trigram_index",
"up": "CREATE INDEX extensions_name_trigram_index ON extensions USING GIST (name gist_trgm_ops);\n"
},
{
"code?": false,
"down": "DROP INDEX extensions_search_index;",
"name": "search_index",
"up": "CREATE INDEX extensions_search_index ON extensions USING GIN((\n setweight(to_tsvector('english', name), 'A') ||\n setweight(to_tsvector('english', doc), 'D')\n));\n"
}
],
"has_create_action": true,
"hash": "8371230D65675BF8F2AC383F03E47F6F96277D18EA018F2575E41E836D8F0597",
"identities": [
{
"base_filter": null,
"index_name": "extensions_unique_name_by_library_version_index",
"keys": [
"name",
"library_version_id"
],
"name": "unique_name_by_library_version"
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"schema": null,
"table": "extensions"
}

View file

@ -0,0 +1,212 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "sanitized_name",
"type": "text"
},
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v4()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "name",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "file",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "line",
"type": "bigint"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "arity",
"type": "bigint"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "type",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "heads",
"type": [
"array",
"text"
]
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "heads_html",
"type": [
"array",
"text"
]
},
{
"allow_nil?": false,
"default": "\"\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc_html",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "order",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "functions_library_version_id_fkey",
"on_delete": "delete",
"on_update": null,
"schema": "public",
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "functions_module_id_fkey",
"on_delete": null,
"on_update": null,
"schema": "public",
"table": "modules"
},
"size": null,
"source": "module_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [
{
"code?": false,
"down": "DROP INDEX functions_name_lower_index;",
"name": "name_index",
"up": "CREATE INDEX functions_name_lower_index ON functions(lower(name));\n"
},
{
"code?": false,
"down": "DROP INDEX functions_name_trigram_index;",
"name": "trigram_index",
"up": "CREATE INDEX functions_name_trigram_index ON functions USING GIST (name gist_trgm_ops);\n"
},
{
"code?": false,
"down": "DROP INDEX functions_search_index;",
"name": "search_index",
"up": "CREATE INDEX functions_search_index ON functions USING GIN((\n setweight(to_tsvector('english', name), 'A') ||\n setweight(to_tsvector('english', doc), 'D')\n));\n"
}
],
"has_create_action": true,
"hash": "DB6CB68A2EE0BEC31244E8AE62DB729CE6047B053BD923967971E7752B1516AE",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"schema": null,
"table": "functions"
}

View file

@ -0,0 +1,132 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v4()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "order",
"type": "bigint"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "name",
"type": "text"
},
{
"allow_nil?": false,
"default": "\"\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "text",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "text_html",
"type": "text"
},
{
"allow_nil?": false,
"default": "\"Topics\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "category",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "route",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "guides_library_version_id_fkey",
"on_delete": "delete",
"on_update": null,
"schema": "public",
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [
{
"code?": false,
"down": "DROP INDEX guides_name_lower_index;",
"name": "name_index",
"up": "CREATE INDEX guides_name_lower_index ON guides(lower(name));\n"
},
{
"code?": false,
"down": "DROP INDEX guides_name_trigram_index;",
"name": "trigram_index",
"up": "CREATE INDEX guides_name_trigram_index ON guides USING GIST (name gist_trgm_ops);\n"
},
{
"code?": false,
"down": "DROP INDEX guides_search_index;",
"name": "search_index",
"up": "CREATE INDEX guides_search_index ON guides USING GIN((\n setweight(to_tsvector('english', name), 'A') ||\n setweight(to_tsvector('english', text), 'D')\n));\n"
}
],
"has_create_action": true,
"hash": "13FBAE11094D53482AB4F2A367CBAFDFCF1C6791E5BEDA2A5D322A5976577F43",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"schema": null,
"table": "guides"
}

View file

@ -0,0 +1,102 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "sanitized_version",
"type": "text"
},
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v4()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "version",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "library_versions_library_id_fkey",
"on_delete": null,
"on_update": null,
"schema": "public",
"table": "libraries"
},
"size": null,
"source": "library_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [
{
"code?": false,
"down": "DROP INDEX library_versions_name_lower_index;",
"name": "name_index",
"up": "CREATE INDEX library_versions_name_lower_index ON library_versions(lower(version));\n"
},
{
"code?": false,
"down": "DROP INDEX library_versions_name_trigram_index;",
"name": "trigram_index",
"up": "CREATE INDEX library_versions_name_trigram_index ON library_versions USING GIST (version gist_trgm_ops);\n"
},
{
"code?": false,
"down": "DROP INDEX library_versions_search_index;",
"name": "search_index",
"up": "CREATE INDEX library_versions_search_index ON library_versions USING GIN((\n to_tsvector('english', version)\n));\n"
}
],
"has_create_action": true,
"hash": "6955BC52938CEFCD5655D441140DA7C3B3E61CC7CE4871106F18BADF11788EC3",
"identities": [
{
"base_filter": null,
"index_name": "library_versions_unique_version_for_library_index",
"keys": [
"version",
"library_id"
],
"name": "unique_version_for_library"
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"schema": null,
"table": "library_versions"
}

View file

@ -0,0 +1,142 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "sanitized_name",
"type": "text"
},
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v4()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "name",
"type": "text"
},
{
"allow_nil?": false,
"default": "\"Misc\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "category",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "file",
"type": "text"
},
{
"allow_nil?": false,
"default": "\"\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc_html",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "order",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "modules_library_version_id_fkey",
"on_delete": "delete",
"on_update": null,
"schema": "public",
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [
{
"code?": false,
"down": "DROP INDEX modules_name_lower_index;",
"name": "name_index",
"up": "CREATE INDEX modules_name_lower_index ON modules(lower(name));\n"
},
{
"code?": false,
"down": "DROP INDEX modules_name_trigram_index;",
"name": "trigram_index",
"up": "CREATE INDEX modules_name_trigram_index ON modules USING GIST (name gist_trgm_ops);\n"
},
{
"code?": false,
"down": "DROP INDEX modules_search_index;",
"name": "search_index",
"up": "CREATE INDEX modules_search_index ON modules USING GIN((\n setweight(to_tsvector('english', name), 'A') ||\n setweight(to_tsvector('english', doc), 'D')\n));\n"
}
],
"has_create_action": true,
"hash": "7895D447D0C831745B52B021C8223D873BE351C25740E7F7F7A39F1BFAC2327F",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"schema": null,
"table": "modules"
}

View file

@ -0,0 +1,233 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "sanitized_path",
"type": "text"
},
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v4()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "name",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "type",
"type": "text"
},
{
"allow_nil?": false,
"default": "\"\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc_html",
"type": "text"
},
{
"allow_nil?": false,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "required",
"type": "boolean"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "argument_index",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "links",
"type": "map"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "default",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "path",
"type": [
"array",
"text"
]
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "order",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_dsl_id_fkey",
"on_delete": null,
"on_update": null,
"schema": "public",
"table": "dsls"
},
"size": null,
"source": "dsl_id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_library_version_id_fkey",
"on_delete": "delete",
"on_update": null,
"schema": "public",
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_extension_id_fkey",
"on_delete": null,
"on_update": null,
"schema": "public",
"table": "extensions"
},
"size": null,
"source": "extension_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [
{
"code?": false,
"down": "DROP INDEX options_name_lower_index;",
"name": "name_index",
"up": "CREATE INDEX options_name_lower_index ON options(lower(name));\n"
},
{
"code?": false,
"down": "DROP INDEX options_name_trigram_index;",
"name": "trigram_index",
"up": "CREATE INDEX options_name_trigram_index ON options USING GIST (name gist_trgm_ops);\n"
},
{
"code?": false,
"down": "DROP INDEX options_search_index;",
"name": "search_index",
"up": "CREATE INDEX options_search_index ON options USING GIN((\n setweight(to_tsvector('english', name), 'A') ||\n setweight(to_tsvector('english', doc), 'D')\n));\n"
}
],
"has_create_action": true,
"hash": "280876F64475A9D0C93AF6595B70F7486AD49B2A729E55441416C936F1BE63E4",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"schema": null,
"table": "options"
}

View file

@ -3,12 +3,75 @@ require Logger
Application.put_env(:dsl, :name, name)
Mix.install([
{String.to_atom(name), "== #{version}"}
], force: true, system_env: [
{"MIX_QUIET", "true"}
])
Mix.install(
[
{String.to_atom(name), "== #{version}"}
],
force: true,
system_env: [
{"MIX_QUIET", "true"}
]
)
defmodule Types do
def for_module(module) do
{:ok, types} = Code.Typespec.fetch_types(module)
types
rescue
_ ->
[]
end
def callbacks_for_module(module) do
{:ok, callbacks} = Code.Typespec.fetch_callbacks(module)
callbacks
rescue
_ ->
[]
end
def specs_for_module(module) do
{:ok, specs} = Code.Typespec.fetch_specs(module)
specs
rescue
_ ->
[]
end
def additional_heads_for(specs, name, arity) do
specs
|> Enum.flat_map(fn
{{^name, ^arity}, contents} ->
contents
_ ->
[]
end)
|> Enum.map(fn body ->
name
|> Code.Typespec.spec_to_quoted(body)
|> Macro.to_string()
end)
end
def code_for(types, name, arity) do
case Enum.find_value(types, fn
{:type, {^name, _, args} = type} ->
if Enum.count(args) == arity do
type
end
_other ->
false
end) do
nil ->
""
type ->
type |> Code.Typespec.type_to_quoted() |> Macro.to_string()
end
end
end
defmodule Utils do
def try_apply(func, default \\ nil) do
@ -36,19 +99,21 @@ defmodule Utils do
sections
|> Enum.with_index()
|> Enum.flat_map(fn {section, index} ->
[%{
name: section.name,
options: schema(section.schema, path ++ [section.name]),
doc: section.describe || "No documentation",
links: Map.new(section.links || []),
imports: Enum.map(section.imports, &inspect/1),
type: :section,
order: index,
examples: examples(section.examples),
path: path
}] ++
build_entities(section.entities, path ++ [section.name]) ++
build_sections(section.sections, path ++ [section.name])
[
%{
name: section.name,
options: schema(section.schema, path ++ [section.name]),
doc: section.describe || "No documentation",
links: Map.new(section.links || []),
imports: Enum.map(section.imports, &inspect/1),
type: :section,
order: index,
examples: examples(section.examples),
path: path
}
] ++
build_entities(section.entities, path ++ [section.name]) ++
build_sections(section.sections, path ++ [section.name])
end)
end
@ -56,19 +121,21 @@ defmodule Utils do
entities
|> Enum.with_index()
|> Enum.flat_map(fn {entity, index} ->
[%{
name: entity.name,
recursive_as: Map.get(entity, :recursive_as),
examples: examples(entity.examples),
order: index,
doc: entity.describe || "No documentation",
imports: [],
links: Map.new(entity.links || []),
args: entity.args,
type: :entity,
path: path,
options: add_argument_indices(schema(entity.schema, path ++ [entity.name]), entity.args),
}] ++ build_entities(List.flatten(Keyword.values(entity.entities)), path ++ [entity.name])
[
%{
name: entity.name,
recursive_as: Map.get(entity, :recursive_as),
examples: examples(entity.examples),
order: index,
doc: entity.describe || "No documentation",
imports: [],
links: Map.new(entity.links || []),
args: entity.args,
type: :entity,
path: path,
options: add_argument_indices(schema(entity.schema, path ++ [entity.name]), entity.args)
}
] ++ build_entities(List.flatten(Keyword.values(entity.entities)), path ++ [entity.name])
end)
end
@ -89,8 +156,9 @@ defmodule Utils do
end
defp examples(examples) do
Enum.map(examples, fn {title, example} ->
"#{title}<>\n<>#{example}"
Enum.map(examples, fn
{title, example} ->
"#{title}<>\n<>#{example}"
example ->
example
@ -118,28 +186,106 @@ defmodule Utils do
{:docs_v1, _, :elixir, _, %{"en" => docs}, _, _} = Code.fetch_docs(module)
docs
rescue
_ -> "No Documentation"
_ -> ""
end
def build_function({{type, name, arity}, line, heads, %{"en" => docs}, _}, file, order) when not(is_nil(type)) and not(is_nil(name)) and not(is_nil(arity)) do
[%{
name: to_string(name),
type: type,
file: file,
line: line,
arity: arity,
order: order,
heads: heads,
doc: docs || "No documentation"
}]
def build_function({_, _, _, :hidden, _}, _, _, _, _, _), do: []
def build_function(
{{type, name, arity}, line, heads, docs, _},
file,
types,
callbacks,
specs,
order
)
when not is_nil(type) and not is_nil(name) and not is_nil(arity) do
docs =
case docs do
%{"en" => en} ->
en
_ ->
""
end
heads = List.wrap(heads)
heads =
case type do
:type ->
case Types.code_for(types, name, arity) do
"" ->
heads
head ->
[head | heads]
end
:callback ->
heads ++ Types.additional_heads_for(callbacks, name, arity)
:function ->
heads ++ Types.additional_heads_for(specs, name, arity)
:macro ->
heads ++ Types.additional_heads_for(specs, name, arity)
_ ->
heads
end
heads =
heads
|> Enum.map(fn head ->
head
|> Code.format_string!(line_length: 68)
|> IO.iodata_to_binary()
end)
|> case do
[] ->
["#{name}/#{arity}"]
heads ->
heads
end
docs = """
```elixir
#{Enum.join(heads, "\n")}
```
<!--- heads-end -->
#{docs}
"""
[
%{
name: to_string(name),
type: type,
file: file,
line: line,
arity: arity,
order: order,
doc: docs || "No documentation"
}
]
end
def build_function(_, _, _), do: []
def build_function(_, _, _, _, _, _), do: []
def build_module(module, category, order) do
{:docs_v1, _, :elixir, _, %{
"en" => module_doc
}, _, defs} = Code.fetch_docs(module)
{:docs_v1, _, :elixir, _, docs, _, defs} = Code.fetch_docs(module)
module_doc =
case docs do
%{"en" => en} ->
en
_ ->
""
end
module_info =
try do
@ -151,19 +297,27 @@ defmodule Utils do
file = file(module_info[:source])
types = Types.for_module(module)
callbacks = Types.callbacks_for_module(module)
typespecs = Types.specs_for_module(module)
%{
name: inspect(module),
doc: module_doc,
file: file,
order: order,
category: category,
functions: defs |> Enum.with_index() |> Enum.flat_map(fn {definition, i} ->
build_function(definition, file, i)
end)
functions:
defs
|> Enum.with_index()
|> Enum.flat_map(fn {definition, i} ->
build_function(definition, file, types, callbacks, typespecs, i)
end)
}
end
defp file(nil), do: nil
defp file(path) do
this_path = Path.split(__ENV__.file)
compile_path = Path.split(path)
@ -219,7 +373,8 @@ defmodule Utils do
defp type({:spark_type, type, _, _}), do: inspect(type)
def doc_index?(module) do
Spark.implements_behaviour?(module, Spark.DocIndex) && module.for_library() == Application.get_env(:dsl, :name)
Spark.implements_behaviour?(module, Spark.DocIndex) &&
module.for_library() == Application.get_env(:dsl, :name)
end
end
@ -247,7 +402,7 @@ case Enum.at(dsls, 0) do
Utils.try_apply(fn -> dsl.guides() end, [])
|> Enum.with_index()
|> Enum.reduce(acc, fn {guide, order}, acc ->
Map.update!(acc, :guides, fn guides ->
Map.update!(acc, :guides, fn guides ->
[Map.put(guide, :order, order) | guides]
end)
end)
@ -275,6 +430,5 @@ case Enum.at(dsls, 0) do
end)
end)
File.write!(file, Base.encode64(:erlang.term_to_binary(data)))
end