This commit is contained in:
Zach Daniel 2022-03-25 17:17:01 -04:00
parent 867f9d5371
commit 3c47194d55
94 changed files with 6372 additions and 149 deletions

View file

@ -1,5 +1,5 @@
[
import_deps: [:ecto, :phoenix],
import_deps: [:ecto, :phoenix, :ash, :ash_postgres, :surface],
inputs: ["*.{ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{ex,exs}"],
subdirectories: ["priv/*/migrations"]
]

4
.gitignore vendored
View file

@ -32,3 +32,7 @@ ash_hq-*.tar
npm-debug.log
/assets/node_modules/
.elixir_ls
/indexes/*

33
Dockerfile Normal file
View file

@ -0,0 +1,33 @@
FROM hexpm/elixir:1.12.2-erlang-24.0.5-ubuntu-xenial-20210114
# install build dependencies
USER root
RUN apt-get update
RUN apt-get install -y git gcc g++ make curl
RUN apt-get install -y build-essential
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update
RUN apt-get install -y nodejs yarn
ENV MIX_ENV=prod
COPY ./assets/package.json assets/package.json
COPY ./assets/package-lock.json assets/package-lock.json
RUN npm install --prefix ./assets
COPY ./mix.exs .
COPY ./mix.lock .
COPY ./config/config.exs config/config.exs
COPY ./config/prod.exs config/prod.exs
RUN mix local.hex --force && \
mix local.rebar --force && \
mix deps.get && \
mix deps.compile
COPY ./config/runtime.exs config/runtime.exs
COPY ./lib ./lib
COPY ./priv ./priv
COPY ./assets ./assets
RUN mix assets.deploy
RUN mix compile
COPY ./rel ./rel
RUN mix release --overwrite
RUN mkdir indexes
CMD ["_build/prod/rel/ash_hq/bin/ash_hq", "start"]

View file

@ -1,6 +1,13 @@
/* This file is for your main application CSS */
@import "./phoenix.css";
@import "syntax.css";
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "@fontsource/fira-code";
.search-hit {
color: red
}
/* Alerts and form errors used by phx.new */
.alert {
padding: 15px;

File diff suppressed because one or more lines are too long

86
assets/css/syntax.css Normal file
View file

@ -0,0 +1,86 @@
.highlight .hll { background-color: #f1fa8c }
.highlight { background: #181920; color: #f8f8f2 }
.highlight .c { color: #6272a4 } /* Comment */
.highlight .err { color: #f8f8f2 } /* Error */
.highlight .g { color: #f8f8f2 } /* Generic */
.highlight .k { color: #ff79c6 } /* Keyword */
.highlight .l { color: #f8f8f2 } /* Literal */
.highlight .n { color: #f8f8f2 } /* Name */
.highlight .o { color: #ff79c6 } /* Operator */
.highlight .x { color: #f8f8f2 } /* Other */
.highlight .p { color: #f8f8f2 } /* Punctuation */
.highlight .ch { color: #6272a4 } /* Comment.Hashbang */
.highlight .cm { color: #6272a4 } /* Comment.Multiline */
.highlight .cp { color: #ff79c6 } /* Comment.Preproc */
.highlight .cpf { color: #6272a4 } /* Comment.PreprocFile */
.highlight .c1 { color: #6272a4 } /* Comment.Single */
.highlight .cs { color: #6272a4 } /* Comment.Special */
.highlight .gd { color: #8b080b } /* Generic.Deleted */
.highlight .ge { color: #f8f8f2; text-decoration: underline } /* Generic.Emph */
.highlight .gr { color: #f8f8f2 } /* Generic.Error */
.highlight .gh { color: #f8f8f2; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #f8f8f2; font-weight: bold } /* Generic.Inserted */
.highlight .go { color: #44475a } /* Generic.Output */
.highlight .gp { color: #f8f8f2 } /* Generic.Prompt */
.highlight .gs { color: #f8f8f2 } /* Generic.Strong */
.highlight .gu { color: #f8f8f2; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #f8f8f2 } /* Generic.Traceback */
.highlight .kc { color: #ff79c6 } /* Keyword.Constant */
.highlight .kd { color: #8be9fd; font-style: italic } /* Keyword.Declaration */
.highlight .kn { color: #ff79c6 } /* Keyword.Namespace */
.highlight .kp { color: #ff79c6 } /* Keyword.Pseudo */
.highlight .kr { color: #ff79c6 } /* Keyword.Reserved */
.highlight .kt { color: #8be9fd } /* Keyword.Type */
.highlight .ld { color: #f8f8f2 } /* Literal.Date */
.highlight .m { color: #bd93f9 } /* Literal.Number */
.highlight .s { color: #f1fa8c } /* Literal.String */
.highlight .na { color: #50fa7b } /* Name.Attribute */
.highlight .nb { color: #8be9fd; font-style: italic } /* Name.Builtin */
.highlight .nc { color: #50fa7b } /* Name.Class */
.highlight .no { color: #f8f8f2 } /* Name.Constant */
.highlight .nd { color: #f8f8f2 } /* Name.Decorator */
.highlight .ni { color: #f8f8f2 } /* Name.Entity */
.highlight .ne { color: #f8f8f2 } /* Name.Exception */
.highlight .nf { color: #50fa7b } /* Name.Function */
.highlight .nl { color: #8be9fd; font-style: italic } /* Name.Label */
.highlight .nn { color: #f8f8f2 } /* Name.Namespace */
.highlight .nx { color: #f8f8f2 } /* Name.Other */
.highlight .py { color: #f8f8f2 } /* Name.Property */
.highlight .nt { color: #ff79c6 } /* Name.Tag */
.highlight .nv { color: #8be9fd; font-style: italic } /* Name.Variable */
.highlight .ow { color: #ff79c6 } /* Operator.Word */
.highlight .w { color: #f8f8f2 } /* Text.Whitespace */
.highlight .mb { color: #bd93f9 } /* Literal.Number.Bin */
.highlight .mf { color: #bd93f9 } /* Literal.Number.Float */
.highlight .mh { color: #bd93f9 } /* Literal.Number.Hex */
.highlight .mi { color: #bd93f9 } /* Literal.Number.Integer */
.highlight .mo { color: #bd93f9 } /* Literal.Number.Oct */
.highlight .sa { color: #f1fa8c } /* Literal.String.Affix */
.highlight .sb { color: #f1fa8c } /* Literal.String.Backtick */
.highlight .sc { color: #f1fa8c } /* Literal.String.Char */
.highlight .dl { color: #f1fa8c } /* Literal.String.Delimiter */
.highlight .sd { color: #f1fa8c } /* Literal.String.Doc */
.highlight .s2 { color: #f1fa8c } /* Literal.String.Double */
.highlight .se { color: #f1fa8c } /* Literal.String.Escape */
.highlight .sh { color: #f1fa8c } /* Literal.String.Heredoc */
.highlight .si { color: #f1fa8c } /* Literal.String.Interpol */
.highlight .sx { color: #f1fa8c } /* Literal.String.Other */
.highlight .sr { color: #f1fa8c } /* Literal.String.Regex */
.highlight .s1 { color: #f1fa8c } /* Literal.String.Single */
.highlight .ss { color: #f1fa8c } /* Literal.String.Symbol */
.highlight .bp { color: #f8f8f2; font-style: italic } /* Name.Builtin.Pseudo */
.highlight .fm { color: #50fa7b } /* Name.Function.Magic */
.highlight .vc { color: #8be9fd; font-style: italic } /* Name.Variable.Class */
.highlight .vg { color: #8be9fd; font-style: italic } /* Name.Variable.Global */
.highlight .vi { color: #8be9fd; font-style: italic } /* Name.Variable.Instance */
.highlight .vm { color: #8be9fd; font-style: italic } /* Name.Variable.Magic */
.highlight .il { color: #bd93f9 } /* Literal.Number.Integer.Long */
/* pre.highlight code>span::before {
content: counter(listing) ". ";
display: inline-block;
width: 8em;
padding-left: auto;
margin-left: auto;
text-align: right;
} */

View file

@ -1,7 +1,3 @@
// We import the CSS which is extracted to its own file by esbuild.
// Remove this line if you add a your own CSS build pipeline (e.g postcss).
import "../css/app.css"
// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
// import "./user_socket.js"
@ -26,13 +22,68 @@ import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
import topbar from "../vendor/topbar"
window.matchMedia('(prefers-color-scheme: dark)').matches
const Hooks = {};
Hooks.ColorTheme = {
mounted() {
this.handleEvent('set_theme', (payload) => {
document.documentElement.classList.add(payload.theme);
if(payload.theme === "dark") {
document.documentElement.classList.remove("light");
} else {
document.documentElement.classList.remove("dark");
};
document.cookie = 'theme' + '=' + payload.theme + ';path=/';
})
}
}
Hooks.CmdK = {
mounted() {
window.addEventListener("keydown", (event) => {
if(event.metaKey && event.key === "k") {
document.getElementById("search-button").click()
}
})
window.addEventListener("keydown", (event) => {
if(event.key === "Escape") {
document.getElementById("close-search").click()
}
})
}
}
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
let liveSocket = new LiveSocket("/live", Socket, {
params: {_csrf_token: csrfToken},
hooks: Hooks,
metadata: {
keydown: (e) => {
return {
key: e.key,
metaKey: e.metaKey
}
}
}
});
// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
window.addEventListener("phx:page-loading-start", info => topbar.show())
window.addEventListener("phx:page-loading-stop", info => topbar.hide())
window.addEventListener("js:focus", e => e.target.focus())
window.addEventListener("js:noscroll-main", e => {
console.log(e.target.id)
if(e.target.style.display === "none") {
document.getElementById("main-container").classList.add("overflow-hidden")
} else {
document.getElementById("main-container").classList.remove("overflow-hidden")
}
})
// connect if there are any LiveViews on the page
liveSocket.connect()

2572
assets/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

15
assets/package.json Normal file
View file

@ -0,0 +1,15 @@
{
"scripts": {
"deploy": "NODE_ENV=production postcss css/app.css -o ../priv/static/assets/app.css"
},
"devDependencies": {
"autoprefixer": "^10.4.4",
"postcss": "^8.4.12",
"postcss-cli": "^9.1.0",
"postcss-import": "^14.0.2",
"tailwindcss": "^3.0.23"
},
"dependencies": {
"@fontsource/fira-code": "^4.5.5"
}
}

7
assets/postcss.config.js Normal file
View file

@ -0,0 +1,7 @@
module.exports = {
plugins: {
'postcss-import': {},
tailwindcss: {},
autoprefixer: {},
}
}

29
assets/tailwind.config.js Normal file
View file

@ -0,0 +1,29 @@
const colors = require('tailwindcss/colors')
module.exports = {
mode: "jit",
purge: ["./js/**/*.js", "../lib/*_web/**/*.*ex"],
darkMode: "class",
theme: {
extend: {
fontFamily: {
'code': ['Fira Code']
},
backgroundImage: {
'dark-grid': `linear-gradient(to bottom, rgb(24, 25, 32, 80%) 20%, rgb(24, 25, 32, 50%) 40%, rgb(24, 25, 32, 40%) 80%, rgb(24, 25, 32, 60%) 20%), url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ada3bf' fill-opacity='0.26'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`,
'light-grid': `linear-gradient(to bottom, rgb(255, 255, 255, 90%) 20%, rgb(255, 255, 255, 85%) 30%, rgb(255, 255, 255, 80%) 80%, rgb(255, 255, 255, 95%) 20%), url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23312a3b' fill-opacity='0.42'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");`
},
colors: {
'primary-black': '#181920',
'silver-phoenix': '#EAEBF3'
},
},
},
variants: {
extend: {
display: ['dark']
},
},
plugins: [],
};

View file

@ -0,0 +1,143 @@
require Logger
[name, version, file, branch] = System.argv()
if branch == "true" do
Mix.install([
{String.to_atom(name), github: "ash-project/#{name}", ref: version}
], force: true,
system_env: [
{"MIX_QUIET", "true"}
])
else
Mix.install([
{String.to_atom(name), "== #{version}"}
], system_env: [
{"MIX_QUIET", "true"}
])
end
defmodule Utils do
def try_apply(func, default \\ nil) do
func.()
rescue
_ ->
default
end
def build(extension) do
extension_name = extension.name
%{
name: extension_name,
target: extension[:target],
default_for_target: extension[:default_for_target?] || false,
type: extension[:type],
dsls: build_sections(extension.module.sections())
}
end
defp build_sections(sections, path \\ []) do
Enum.flat_map(sections, fn section ->
[%{
name: section.name,
options: schema(section.schema, path ++ [section.name]),
doc: section.describe,
type: :section,
examples: examples(section.examples),
path: path
}] ++
build_entities(section.entities, path ++ [section.name]) ++
build_sections(section.sections, path ++ [section.name])
end)
end
defp build_entities(entities, path) do
Enum.flat_map(entities, fn entity ->
[%{
name: entity.name,
recursive_as: Map.get(entity, :recursive_as),
examples: examples(entity.examples),
doc: entity.describe,
args: entity.args,
type: :entity,
path: path,
options: schema(entity.schema, path ++ [entity.name]),
}] ++ build_entities(List.flatten(Keyword.values(entity.entities)), path ++ [entity.name])
end)
end
defp examples(examples) do
Enum.map(examples, fn {title, example} ->
"#{title}<>\n<>#{example}"
example ->
example
end)
end
defp schema(schema, path) do
Enum.map(schema, fn {name, value} ->
%{
name: name,
path: path,
type: value[:type_name] || type(value[:type]),
doc: value[:doc],
required: value[:required] || false,
default: inspect(value[:default])
}
end)
end
defp type({:behaviour, mod}), do: Module.split(mod) |> List.last()
defp type({:ash_behaviour, mod}), do: Module.split(mod) |> List.last()
defp type({:ash_behaviour, mod, _builtins}), do: Module.split(mod) |> List.last()
defp type({:custom, _, _, _}), do: "any"
defp type(:ash_type), do: "Type"
defp type(:ash_resource), do: "Resource"
defp type(:any), do: "any"
defp type(:keyword_list), do: "Keyword List"
defp type({:keyword_list, _schema}), do: "Keyword List"
defp type(:non_empty_keyword_list), do: "Keyword List"
defp type(:atom), do: "Atom"
defp type(:string), do: "String"
defp type(:boolean), do: "Boolean"
defp type(:integer), do: "Integer"
defp type(:non_neg_integer), do: "Non Negative Integer"
defp type(:pos_integer), do: "Positive Integer"
defp type(:float), do: "Float"
defp type(:timeout), do: "Timeout"
defp type(:pid), do: "Pid"
defp type(:mfa), do: "MFA"
defp type(:mod_arg), do: "Module and Arguments"
defp type({:fun, arity}), do: "Function/#{arity}"
defp type({:one_of, choices}), do: type({:in, choices})
defp type({:in, choices}), do: Enum.map_join(choices, " | ", &inspect/1)
defp type({:or, subtypes}), do: Enum.map_join(subtypes, " | ", &type/1)
defp type({:list, subtype}), do: type(subtype) <> "[]"
end
dsls =
for [app] <- :ets.match(:ac_tab, {{:loaded, :"$1"}, :_}),
{:ok, modules} = :application.get_key(app, :modules),
module <- Enum.filter(modules, &Ash.Helpers.implements_behaviour?(&1, Ash.DocIndex)),
module.for_library() == name do
module
end
extensions =
dsls
|> Enum.flat_map(fn dsl ->
dsl.extensions()
end)
data =
extensions
|> Enum.reduce(%{}, fn extension, acc ->
acc
|> Map.put_new(:extensions, [])
|> Map.update!(:extensions, fn extensions ->
[Utils.build(extension) | extensions]
end)
end)
File.write!(file, Base.encode64(:erlang.term_to_binary(data)))

View file

@ -10,6 +10,22 @@ import Config
config :ash_hq,
ecto_repos: [AshHq.Repo]
config :elasticlunr,
storage: Elasticlunr.Storage.Disk
config :elasticlunr, Elasticlunr.Storage.Disk, directory: "/indexes/"
config :ash_hq, ash_apis: [AshHq.Docs]
config :ash_hq, AshHq.Docs,
resources: [
registry: AshHq.Docs.Registry
]
config :ash_hq, AshHq.Repo,
timeout: :timer.minutes(10),
ownership_timeout: :timer.minutes(10)
# Configures the endpoint
config :ash_hq, AshHqWeb.Endpoint,
url: [host: "localhost"],

View file

@ -25,7 +25,15 @@ config :ash_hq, AshHqWeb.Endpoint,
secret_key_base: "FxKFwVYhDFah3bLLXXqWdpdcLf5e5T1UyVM6XQp7kCt/Reg5yuAEI3upAVDRoP5e",
watchers: [
# Start the esbuild watcher by calling Esbuild.install_and_run(:default, args)
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]}
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]},
npx: [
"tailwindcss",
"--input=css/app.css",
"--output=../priv/static/assets/app.css",
"--postcss",
"--watch",
cd: Path.expand("../assets", __DIR__)
]
]
# ## SSL Support
@ -58,7 +66,7 @@ config :ash_hq, AshHqWeb.Endpoint,
patterns: [
~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
~r"priv/gettext/.*(po)$",
~r"lib/ash_hq_web/(live|views)/.*(ex)$",
~r"lib/ash_hq_web/(live|views|pages|components)/.*(ex)$",
~r"lib/ash_hq_web/templates/.*(eex)$"
]
]

View file

@ -20,13 +20,11 @@ if config_env() == :prod do
For example: ecto://USER:PASS@HOST/DATABASE
"""
maybe_ipv6 = if System.get_env("ECTO_IPV6"), do: [:inet6], else: []
config :ash_hq, AshHq.Repo,
# ssl: true,
ssl: false,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
socket_options: maybe_ipv6
socket_options: [:inet6]
# The secret key base is used to sign/encrypt cookies and other secrets.
# A default value is used in config/dev.exs and config/test.exs but you
@ -40,11 +38,11 @@ if config_env() == :prod do
You can generate one by calling: mix phx.gen.secret
"""
host = System.get_env("PHX_HOST") || "example.com"
host = System.get_env("PHX_HOST") || "ash-hq.com"
port = String.to_integer(System.get_env("PORT") || "4000")
config :ash_hq, AshHqWeb.Endpoint,
url: [host: host, port: 443],
url: [host: host, port: 80],
http: [
# Enable IPv6 and bind on all interfaces.
# Set it to {0, 0, 0, 0, 0, 0, 0, 1} for local network only access.

34
fly.toml Normal file
View file

@ -0,0 +1,34 @@
# fly.toml file generated for lodge-shares on 2022-03-20T23:03:53-04:00
app = "ash-hq"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[deploy]
release_command = "_build/prod/rel/ash_hq/bin/ash_hq eval 'AshHq.Release.migrate'"
[env]
[[services]]
internal_port = 4000
protocol = "tcp"
[services.concurrency]
hard_limit = 25
soft_limit = 20
[[services.ports]]
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[[services.tcp_checks]]
grace_period = "30s" # allow some time for startup
interval = "15s"
restart_limit = 6
timeout = "2s"

View file

@ -8,6 +8,7 @@ defmodule AshHq.Application do
@impl true
def start(_type, _args) do
children = [
{Finch, name: AshHq.Finch},
# Start the Ecto repository
AshHq.Repo,
# Start the Telemetry supervisor
@ -15,7 +16,8 @@ defmodule AshHq.Application do
# Start the PubSub system
{Phoenix.PubSub, name: AshHq.PubSub},
# Start the Endpoint (http/https)
AshHqWeb.Endpoint
AshHqWeb.Endpoint,
AshHq.Docs.Indexer
# Start a worker by calling: AshHq.Worker.start_link(arg)
# {AshHq.Worker, arg}
]

View file

@ -0,0 +1,28 @@
defmodule AshHq.Docs.Changes.AddArgToRelationship do
use Ash.Resource.Change
def change(changeset, opts, _) do
arg = opts[:arg]
rel = opts[:rel]
arg_value = Ash.Changeset.get_argument(changeset, arg)
relationship_value = Ash.Changeset.get_argument(changeset, rel)
new_value =
cond do
is_list(relationship_value) ->
Enum.map(relationship_value, fn val ->
Map.put(val, arg, arg_value)
end)
is_map(relationship_value) ->
Map.put(relationship_value, arg, arg_value)
true ->
relationship_value
end
Ash.Changeset.set_argument(changeset, rel, new_value)
end
end

View file

@ -0,0 +1,16 @@
defmodule AshHq.Docs.Preparations.LoadSearchData do
use Ash.Resource.Preparation
def prepare(query, _, _) do
query_string = Ash.Query.get_argument(query, :query)
if query_string do
query
|> Ash.Query.load(search_headline: [query: query_string])
|> Ash.Query.sort(match_rank: {:asc, %{query: query_string}})
|> Ash.Query.load(match_rank: [query: query_string])
else
query
end
end
end

3
lib/ash_hq/docs/docs.ex Normal file
View file

@ -0,0 +1,3 @@
defmodule AshHq.Docs do
use Ash.Api, otp_app: :ash_hq
end

View file

@ -0,0 +1,102 @@
defmodule AshHq.Docs.Importer do
@moduledoc """
Builds the documentation into term files in the `priv/docs` directory.
"""
alias AshHq.Docs.LibraryVersion
require Logger
def import() do
for %{name: name, latest_version: latest_version} = library <-
AshHq.Docs.Library.read!(load: :latest_version) do
latest_version =
if latest_version do
Version.parse!(latest_version)
end
versions =
Finch.build(:get, "https://hex.pm/api/packages/#{name}")
|> Finch.request(AshHq.Finch)
|> case do
{:ok, response} ->
Jason.decode!(response.body)
{:error, error} ->
raise "Something went wrong #{inspect(error)}"
end
|> Map.get("releases", [])
|> Enum.map(&Map.get(&1, "version"))
|> filter_by_version(latest_version)
|> Enum.reverse()
already_defined_versions =
AshHq.Docs.LibraryVersion.defined_for!(
library.id,
versions
)
# TODO: reenable this
# versions
# |> Enum.reject(fn version ->
# Enum.find(already_defined_versions, &(&1.version == version))
# end)
# |> Enum.concat(["master"])
# branches =
library.track_branches
|> Enum.map(&{&1, true})
|> Enum.each(fn version ->
{version, branch?} =
case version do
{version, true} -> {version, true}
_ -> {version, false}
end
file = Path.expand("./#{Ash.UUID.generate()}.json")
{_, 0} =
System.cmd("elixir", [
"./build_docs/build_dsl_docs.exs",
name,
version,
file,
to_string(branch?)
])
output = File.read!(file)
result = :erlang.binary_to_term(Base.decode64!(String.trim(output)))
File.rm!(file)
LibraryVersion.build!(library.id, version, result)
end)
end
for version <- LibraryVersion.unprocessed!() do
try do
LibraryVersion.process!(version)
rescue
e ->
Logger.error(
"Exception while importing: #{version.id}\n#{Exception.format(:error, e, __STACKTRACE__)}"
)
:ok
end
end
end
defp filter_by_version(versions, latest_version) do
if latest_version do
Enum.take_while(versions, fn version ->
Version.match?(Version.parse!(version), "> #{latest_version}")
end)
else
latest = Version.parse!(Enum.at(versions, 0))
Enum.take_while(versions, fn version ->
version = Version.parse!(version)
version.major == latest.major && version.minor == latest.minor
end)
end
end
end

View file

@ -0,0 +1,34 @@
defmodule AshHq.Docs.Indexer do
use GenServer
alias Elasticlunr.{Index, IndexManager, Pipeline}
def start_link(_) do
GenServer.start_link(__MODULE__, :ok)
end
def init(_) do
{:ok, %{}, {:continue, :index}}
end
def handle_continue(:index, state) do
index =
case IndexManager.get("docs") do
{:ok, index} ->
index
IO.inspect("it was started")
:not_running ->
pipeline = Pipeline.new(Pipeline.default_runners())
index = Index.new(pipeline: pipeline, store_documents: true)
IO.inspect("started it")
{:ok, _} = IndexManager.save(index)
index
end
IO.inspect(index)
{:noreply, state}
end
end

View file

@ -0,0 +1,12 @@
defmodule AshHq.Docs.Registry do
use Ash.Registry,
extensions: [Ash.Registry.ResourceValidations]
entries do
entry AshHq.Docs.Extension
entry AshHq.Docs.Dsl
entry AshHq.Docs.Library
entry AshHq.Docs.LibraryVersion
entry AshHq.Docs.Option
end
end

View file

@ -0,0 +1,129 @@
defmodule AshHq.Docs.Dsl do
use AshHq.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "dsls"
repo AshHq.Repo
end
code_interface do
define_for AshHq.Docs
define :search, args: [:query, :library_versions]
end
actions do
read :read do
primary? true
end
read :search do
argument :query, :string do
allow_nil? false
end
argument :library_versions, {:array, :uuid} do
allow_nil? false
end
prepare AshHq.Docs.Preparations.LoadSearchData
filter expr(matches(query: arg(:query)) and library_version_id in ^arg(:library_versions))
end
create :create do
argument :options, {:array, :map}
argument :library_version, :uuid
change {AshHq.Docs.Changes.AddArgToRelationship, arg: :library_version, rel: :options}
change manage_relationship(:options, type: :direct_control)
change manage_relationship(:library_version, type: :replace)
end
update :update do
argument :options, {:array, :map}
argument :library_version, :uuid
change {AshHq.Docs.Changes.AddArgToRelationship, arg: :library_version, rel: :options}
change manage_relationship(:options, type: :direct_control)
change manage_relationship(:library_version, type: :replace)
end
end
calculations do
calculate :search_headline,
:string,
expr(
fragment(
"ts_headline('english', ?, to_tsquery('english', ? || ':*'), 'MaxFragments=3, StartSel=\"<span class=\"\"search-hit\"\">\", StopSel=</span>')",
doc,
^arg(:query)
)
) do
argument :query, :string do
allow_nil? false
end
end
calculate :matches,
:boolean,
expr(
fragment("to_tsvector(? || ?) @@ to_tsquery(? || ':*')", name, doc, ^arg(:query))
) do
argument :query, :string do
allow_nil? false
end
end
calculate :match_rank,
:float,
expr(
fragment(
"ts_rank(setweight(to_tsvector(?), 'A') || setweight(to_tsvector(?), 'D'), to_tsquery(?))",
name,
doc,
^arg(:query)
)
) do
argument :query, :string do
allow_nil? false
end
end
end
attributes do
uuid_primary_key :id
attribute :name, :string do
allow_nil? false
end
attribute :doc, :string
attribute :examples, {:array, :string}
attribute :args, {:array, :string}
attribute :path, {:array, :string}
attribute :recursive_as, :string
attribute :type, :atom do
allow_nil? false
constraints one_of: [:entity, :section]
end
end
aggregates do
first :extension_type, :extension, :type
end
relationships do
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
end
belongs_to :extension, AshHq.Docs.Extension do
required? true
end
belongs_to :dsl, __MODULE__
has_many :options, AshHq.Docs.Option
has_many :dsls, __MODULE__
end
end

View file

@ -0,0 +1,60 @@
defmodule AshHq.Docs.Extension do
use AshHq.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "extensions"
repo AshHq.Repo
end
identities do
identity :unique_name_by_library_version, [:name, :library_version_id]
end
code_interface do
define_for AshHq.Docs
define :import, args: [:library_version]
define :destroy
end
actions do
create :import do
argument :library_version, :uuid do
allow_nil? false
end
argument :dsls, {:array, :map}
change manage_relationship(:library_version, type: :replace)
change {AshHq.Docs.Changes.AddArgToRelationship, arg: :library_version, rel: :dsls}
change manage_relationship(:dsls, type: :direct_control)
end
end
attributes do
uuid_primary_key :id
attribute :name, :string do
allow_nil? false
end
attribute :target, :string
attribute :default_for_target, :boolean do
default false
end
attribute :type, :string do
allow_nil? false
end
end
relationships do
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
end
has_many :dsls, AshHq.Docs.Dsl
end
end

View file

@ -0,0 +1,39 @@
defmodule AshHq.Docs.Library do
use AshHq.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "libraries"
repo AshHq.Repo
end
code_interface do
define_for AshHq.Docs
define :read
define :create
end
attributes do
uuid_primary_key :id
attribute :name, :string do
allow_nil? false
end
attribute :track_branches, {:array, :string} do
default []
end
end
aggregates do
first :latest_version, :versions, :version do
sort version: :desc
filter expr(version != "master")
end
end
relationships do
has_many :versions, AshHq.Docs.LibraryVersion
end
end

View file

@ -0,0 +1,45 @@
defmodule AshHq.Docs.LibraryVersion.Changes.ProcessLibraryVersion do
use Ash.Resource.Change
alias AshHq.Docs
alias AshHq.Docs.{Extension}
def change(changeset, _, _) do
Ash.Changeset.before_action(changeset, fn changeset ->
if changeset.data.processed do
changeset
else
notifications = process(changeset.data, Ash.Changeset.get_attribute(changeset, :data))
{Ash.Changeset.force_change_attribute(changeset, :processed, true),
%{notifications: notifications}}
end
end)
end
defp process(library_version, data) do
library_version = Docs.load!(library_version, :extensions)
process_extensions(library_version, data["extensions"] || [])
end
defp process_extensions(library_version, extensions) do
{extensions, notifications} =
Enum.reduce(extensions, {[], []}, fn config, {extensions, notifications} ->
{extension, new_notifications} =
Extension.import!(library_version.id, config,
upsert?: true,
upsert_identity: :unique_name_by_library_version,
return_notifications?: true
)
{[extension | extensions], notifications ++ new_notifications}
end)
destroy_notifications =
library_version.extensions
|> Enum.reject(fn extension -> Enum.any?(extensions, &(&1.name == extension.name)) end)
|> Enum.flat_map(&Extension.destroy!(&1, return_notifications?: true))
notifications ++ destroy_notifications
end
end

View file

@ -0,0 +1,84 @@
defmodule AshHq.Docs.LibraryVersion do
use AshHq.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "library_versions"
repo AshHq.Repo
end
code_interface do
define_for AshHq.Docs
define :build, args: [:library, :version, :data]
define :defined_for, args: [:library, :versions]
define :unprocessed
define :process
end
actions do
read :read do
primary? true
end
create :build do
argument :library, :uuid do
allow_nil? false
end
change manage_relationship(:library, type: :replace)
end
read :defined_for do
argument :library, :uuid do
allow_nil? false
end
argument :versions, {:array, :string} do
allow_nil? false
end
filter expr(version in ^arg(:versions) and library_id == ^arg(:library))
end
read :unprocessed do
filter expr(processed == false)
end
update :process do
change AshHq.Docs.LibraryVersion.Changes.ProcessLibraryVersion
end
end
attributes do
uuid_primary_key :id
attribute :version, :string do
allow_nil? false
end
attribute :data, :map
attribute :processed, :boolean do
default false
writable? false
end
end
calculations do
calculate :sortable_version,
{:array, :string},
expr(fragment("string_to_array(?, '.')", version))
end
preparations do
prepare AshHq.Docs.LibraryVersion.Preparations.SortBySortableVersionInstead
end
relationships do
belongs_to :library, AshHq.Docs.Library do
required? true
end
has_many :extensions, AshHq.Docs.Extension
end
end

View file

@ -0,0 +1,13 @@
defmodule AshHq.Docs.LibraryVersion.Preparations.SortBySortableVersionInstead do
use Ash.Resource.Preparation
def prepare(query, _, _) do
%{query | sort: replace_sort(query.sort)}
end
defp replace_sort(nil), do: nil
defp replace_sort(:version), do: :version
defp replace_sort({:version, order}), do: {:version, order}
defp replace_sort(list) when is_list(list), do: Enum.map(list, &replace_sort/1)
defp replace_sort(other), do: other
end

View file

@ -0,0 +1,120 @@
defmodule AshHq.Docs.Option do
use AshHq.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "options"
repo AshHq.Repo
end
code_interface do
define_for AshHq.Docs
define :search, args: [:query, :library_versions]
end
attributes do
uuid_primary_key :id
attribute :name, :string do
allow_nil? false
end
attribute :type, :string do
allow_nil? false
end
attribute :doc, :string
attribute :required, :boolean do
allow_nil? false
default false
end
attribute :default, :string
attribute :path, {:array, :string}
end
actions do
read :read do
primary? true
end
read :search do
argument :query, :string do
allow_nil? false
end
argument :library_versions, {:array, :uuid} do
allow_nil? false
end
prepare AshHq.Docs.Preparations.LoadSearchData
filter expr(matches(query: arg(:query)) and library_version_id in ^arg(:library_versions))
end
create :create do
argument :library_version, :uuid
change manage_relationship(:library_version, type: :replace)
end
end
calculations do
calculate :search_headline,
:string,
expr(
fragment(
"ts_headline('english', ?, to_tsquery('english', ? || ':*'), 'MaxFragments=3, StartSel=\"<span class=\"\"search-hit\"\">\", StopSel=</span>')",
doc,
^arg(:query)
)
) do
argument :query, :string do
allow_nil? false
end
end
calculate :matches,
:boolean,
expr(
fragment(
"setweight(to_tsvector(?), 'A') || setweight(to_tsvector(?), 'D') @@ to_tsquery(? || ':*')",
name,
doc,
^arg(:query)
)
) do
argument :query, :string do
allow_nil? false
end
end
calculate :match_rank,
:float,
expr(
fragment(
"ts_rank(setweight(to_tsvector(?), 'A') || setweight(to_tsvector(?), 'D'), to_tsquery(?))",
name,
doc,
^arg(:query)
)
) do
argument :query, :string do
allow_nil? false
end
end
end
aggregates do
first :extension_type, [:dsl, :extension], :type
end
relationships do
belongs_to :dsl, AshHq.Docs.Dsl do
required? true
end
belongs_to :library_version, AshHq.Docs.LibraryVersion do
required? true
end
end
end

View file

@ -0,0 +1,13 @@
defmodule AshHq.Docs.Types.Doc do
use Ash.Type
def cast_input(nil, _), do: nil
def cast_input(value, _) when is_binary(value) do
{:ok, Earmark.as_html!(value)}
end
def cast_stored(value, _), do: {:ok, value}
def dump_to_native(value, _), do: {:ok, value}
end

View file

@ -0,0 +1,10 @@
defmodule Mix.Tasks.AshHq.BuildDocs do
@moduledoc "The hello mix task: `mix help hello`"
use Mix.Task
@shortdoc "Builds documentation for any versions"
def run(_) do
Mix.Task.run("app.start")
AshHq.Docs.Importer.Builder.build()
end
end

42
lib/ash_hq/release.ex Normal file
View file

@ -0,0 +1,42 @@
defmodule AshHq.Release do
@moduledoc """
Houses tasks that need to be executed in the released application (because mix is not present in releases).
"""
@app :ash_hq
def migrate do
load_app()
for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
end
end
def migrate_all do
load_app()
migrate()
end
def rollback(repo, version) do
load_app()
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
end
defp repos do
apis()
|> Enum.flat_map(fn api ->
api
|> Ash.Api.resources()
|> Enum.map(&AshPostgres.repo/1)
end)
|> Enum.uniq()
end
defp apis do
Application.fetch_env!(@app, :ash_apis)
end
defp load_app do
Application.load(@app)
end
end

View file

@ -1,5 +1,4 @@
defmodule AshHq.Repo do
use Ecto.Repo,
otp_app: :ash_hq,
adapter: Ecto.Adapters.Postgres
use AshPostgres.Repo,
otp_app: :ash_hq
end

31
lib/ash_hq/resource.ex Normal file
View file

@ -0,0 +1,31 @@
defmodule AshHq.Resource do
defmacro __using__(opts) do
opts =
if opts[:notifiers] && Ash.Notifier.PubSub in opts[:notifiers] do
opts
else
opts
|> Keyword.put_new(:notifiers, [])
|> Keyword.update!(:notifiers, &[Ash.Notifier.PubSub | &1])
end
quote do
use Ash.Resource, unquote(opts)
pub_sub do
module AshHqWeb.Endpoint
prefix Module.split(__MODULE__)
|> Enum.reverse()
|> Enum.take(2)
|> Enum.reverse()
|> Enum.map(&Macro.underscore/1)
|> Enum.join(".")
publish_all :create, ["created"]
publish_all :update, ["updated"]
publish_all :destroy, ["destroyed"]
end
end
end
end

View file

@ -0,0 +1,13 @@
defmodule AshHqWeb.Components.CalloutText do
use Surface.Component
slot default, required: true
def render(assigns) do
~F"""
<span class="text-orange-600 dark:text-orange-400 font-bold typed-out-container">
<#slot />
</span>
"""
end
end

View file

@ -0,0 +1,86 @@
defmodule AshHqWeb.Components.CodeExample do
use Surface.LiveComponent
prop text, :string, required: true
prop class, :css_class
prop title, :string
prop start_collapsed, :boolean, default: false
prop collapsable, :boolean, default: false
data collapsed, :string, default: false
def render(assigns) do
~F"""
<div class={"rounded-xl bg-primary-black border border-gray-400 text-sm border-b", @class}>
<div class={"flex flex-row justify-between py-2 pl-2 pr-8", "border-b border-gray-600": !@collapsed}>
<div class="flex flex-row justify-start space-x-1">
<div class="w-3 h-3 bg-gray-600 rounded-full"/>
<div class="w-3 h-3 bg-gray-600 rounded-full"/>
<div class="w-3 h-3 bg-gray-600 rounded-full"/>
</div>
{#if @title}
<div class="justify-self-end text-white">{@title}</div>
<div>
{#if @collapsable}
<button class="hover:bg-gray-700" :on-click="fold">
{#if @collapsed}
<Heroicons.Solid.ChevronDoubleDownIcon class="w-4 h-4"/>
{#else}
<Heroicons.Solid.ChevronDoubleUpIcon class="w-4 h-4"/>
{/if}
</button>
{/if}
</div>
{/if}
</div>
<div class={"pl-1 pt-2", "h-0": @collapsed}>
{#for {line, no} <- to_code(@text)}
<div class={"flex flex-row font-code mr-4", "invisible h-0": @collapsed}>
<div class="sm:hidden md:block mr-8 text-gray-600"><pre>{no}</pre></div>{Phoenix.HTML.raw(line)}
</div>
{/for}
</div>
</div>
"""
end
def handle_event("fold", _, socket) do
{:noreply, assign(socket, :collapsed, !socket.assigns.collapsed)}
end
def update(assigns, socket) do
if assigns.start_collapsed && assigns.collapsable do
{:ok, socket |> assign(assigns) |> assign(:collapsed, true)}
else
{:ok, socket |> assign(assigns) |> assign(:collapsed, false)}
end
end
defp to_code(text) do
# TODO: do this at compile time
lines =
text
# this is pretty naive, won't handle things like block comments
|> String.split("\n")
|> Enum.reverse()
|> Enum.drop_while(&(&1 in [""]))
|> Enum.reverse()
|> Enum.map(fn
"" ->
"<br>"
line ->
Makeup.highlight(line)
end)
count = Enum.count(lines)
padding = String.length(to_string(count))
lines
|> Enum.with_index()
|> Enum.map(fn {line, index} ->
{line, String.pad_leading(to_string(index + 1), padding, " ")}
end)
end
end

View file

@ -0,0 +1,193 @@
defmodule AshHqWeb.Components.Search do
use Surface.LiveComponent
require Ash.Query
alias Surface.Components.Form
alias Surface.Components.Form.{Label, Select}
prop open, :boolean, default: false
prop close, :event, required: true
data versions, :map, default: %{}
data selected_versions, :map, default: %{}
data search, :string, default: ""
data results, :map, default: %{}
data libraries, :list, default: []
# style={"display: none;"}
def render(assigns) do
~F"""
<div id={@id} class="transition absolute flex justify-center align-middle w-screen h-screen backdrop-blur-sm pb-8 bg-white bg-opacity-10" phx-hook="CmdK">
<div
:on-click-away={AshHqWeb.AppViewLive.toggle_search()}
class="dark:text-white absolute rounded-xl left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 w-1/2 h-3/4 bg-white dark:bg-primary-black border-2 dark:border-gray-900"
>
<div class="h-full px-6 my-6">
<div class="w-full flex flex-row justify-start sticky top-0 pb-3 border-b border-gray-600">
<Heroicons.Outline.SearchIcon class="h-6 w-6 mr-4 ml-4" />
<div class="flex flex-row justify-between w-full">
<Form for={:search} change="search" class="w-full">
<input id="search-input" name="search" class="text-lg bg-primary-black grow ring-0 outline-none w-full" />
</Form>
<button id="close-search" class="mr-4 ml-4 h-6 w-6 hover:text-gray-400" :on-click={@close}>
<Heroicons.Outline.XIcon class="h-6 w-6" />
</button>
</div>
</div>
<div class="grid grid-cols-6 h-[82%] mt-3">
<div class="border-r border-gray-600">
<Form for={:versions} change="change_versions">
{#for library <- @libraries}
<Label field={library.id}>
{library.name}
</Label>
<div>
<Select class="text-black" name={"versions[#{library.id}]"} options={Enum.map(library.versions, &{&1.version, &1.id})} />
</div>
{/for}
</Form>
</div>
<div class="col-span-5 pl-4 overflow-y-auto">
{render_results(assigns, @results)}
</div>
</div>
</div>
</div>
</div>
"""
end
defp render_results(assigns, results) do
~F"""
{#for {group, result} <- @results}
<div>
{group}
</div>
{/for}
"""
end
def mount(socket) do
socket =
AshPhoenix.LiveView.keep_live(
socket,
:libraries,
fn _socket ->
versions_query =
AshHq.Docs.LibraryVersion
|> Ash.Query.sort(version: :desc)
|> Ash.Query.filter(processed == true)
AshHq.Docs.Library.read!(load: [versions: versions_query])
end,
after_fetch: fn results, socket ->
socket
|> assign(
:selected_versions,
Map.new(results, fn library ->
version = Enum.at(library.versions, 0)
{library.id, version && version.id}
end)
)
|> search()
end
)
{:ok, socket}
end
def handle_event("change_versions", %{"versions" => versions}, socket) do
{:noreply,
socket
|> assign(:selected_versions, versions)
|> search()}
end
def handle_event("search", %{"search" => search}, socket) do
{:noreply, socket |> assign(:search, search) |> search()}
end
defp search(socket) do
if socket.assigns[:search] in [nil, ""] || socket.assigns[:selected_versions] in [nil, %{}] do
assign(socket, :results, %{})
else
docs =
AshHq.Docs.Dsl.search!(
socket.assigns.search,
Map.values(socket.assigns.selected_versions),
query: Ash.Query.limit(AshHq.Docs.Dsl, 10),
load: [:extension_type]
)
results =
AshHq.Docs.Option.search!(
socket.assigns.search,
Map.values(socket.assigns.selected_versions),
query: Ash.Query.limit(AshHq.Docs.Option, 10),
load: [:extension_type]
)
|> Enum.concat(docs)
|> tap(fn items ->
Enum.map(items, & &1.match_rank) |> IO.inspect()
end)
|> Enum.group_by(& &1.extension_type)
|> Enum.sort_by(fn {_type, items} ->
items
|> Enum.map(& &1.match_rank)
|> Enum.max()
|> Kernel.*(-1)
end)
|> tap(fn stuff ->
stuff
|> Enum.map(fn {_type, items} ->
items
|> Enum.map(& &1.match_rank)
|> Enum.max()
# |> Kernel.*(-1)
end)
|> IO.inspect()
end)
|> Enum.map(fn {type, items} ->
{type, group_by_paths(items)}
end)
assign(socket, :results, results)
end
end
defp group_by_paths(items) do
items
|> Enum.map(&{&1.path, &1})
|> do_group_by_paths()
end
defp do_group_by_paths(items, path_acc \\ []) do
{items_for_group, further} =
Enum.split_with(items, fn
{[], _} ->
true
_ ->
false
end)
further_items =
further
|> Enum.group_by(
fn {[next | _rest], _item} ->
next
end,
fn {[_next | rest], item} ->
{rest, item}
end
)
|> Enum.map(fn {nested, items} ->
{nested, do_group_by_paths(items, path_acc ++ [nested])}
end)
%{path: path_acc, items: items_for_group, further: further_items}
end
end

View file

@ -0,0 +1,22 @@
defmodule AshHqWeb.SessionPlug do
@moduledoc false
@behaviour Plug
@cookies_to_replicate [
"theme"
]
def init(_), do: []
def call(conn, _) do
Enum.reduce(@cookies_to_replicate, conn, fn cookie, conn ->
case conn.req_cookies[cookie] do
value when value in [nil, "", "null"] ->
Plug.Conn.put_session(conn, cookie, nil)
value ->
Plug.Conn.put_session(conn, cookie, value)
end
end)
end
end

View file

@ -8,6 +8,7 @@ defmodule AshHqWeb.Router do
plug :put_root_layout, {AshHqWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug AshHqWeb.SessionPlug
end
pipeline :api do
@ -17,7 +18,9 @@ defmodule AshHqWeb.Router do
scope "/", AshHqWeb do
pipe_through :browser
get "/", PageController, :index
live_session :main, root_layout: {AshHqWeb.LayoutView, "root.html"} do
live "/", AppViewLive
end
end
# Other scopes may use custom stacks.

View file

@ -1,30 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" class={"h-full #{@configured_theme || "dark"}"}>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<%= csrf_meta_tag() %>
<%= live_title_tag assigns[:page_title] || "AshHq", suffix: " · Phoenix Framework" %>
<%= live_title_tag assigns[:page_title] || "Ash Framework" %>
<link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/assets/app.css")}/>
<script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/app.js")}></script>
</head>
<body>
<header>
<section class="container">
<nav>
<ul>
<li><a href="https://hexdocs.pm/phoenix/overview.html">Get Started</a></li>
<%= if function_exported?(Routes, :live_dashboard_path, 2) do %>
<li><%= link "LiveDashboard", to: Routes.live_dashboard_path(@conn, :home) %></li>
<% end %>
</ul>
</nav>
<a href="https://phoenixframework.org/" class="phx-logo">
<img src={Routes.static_path(@conn, "/images/phoenix.png")} alt="Phoenix Framework Logo"/>
</a>
</section>
</header>
<body class="h-full">
<%= @inner_content %>
</body>
</html>

View file

@ -0,0 +1,271 @@
defmodule AshHqWeb.AppViewLive do
use Surface.LiveView,
container: {:div, class: "h-full"}
alias AshHqWeb.Components.{CalloutText, CodeExample, Search}
alias Phoenix.LiveView.JS
data configured_theme, :string, default: :system
data searching, :boolean, default: false
def render(assigns) do
~F"""
<div
id="app"
class={"h-full font-sans": true, "#{@configured_theme}": true}
phx-hook="ColorTheme"
>
<div id="main-container" class="h-full bg-white dark:bg-primary-black dark:text-silver-phoenix">
<Search id="search-box" close={close_search()} />
<div class="flex justify-between pt-4 px-4">
<div class="flex flex-row align-baseline">
<img class="h-10 hidden dark:block" src="/images/ash-framework-dark.png"/>
<img class="h-10 dark:hidden" src="/images/ash-framework-light.png"/>
</div>
<div class="flex flex-row">
<button phx-click="toggle_theme">
{#case @configured_theme}
{#match "light"}
<Heroicons.Outline.SunIcon class="w-10 h-10"/>
{#match _}
<Heroicons.Outline.MoonIcon class="w-10 h-10"/>
{/case}
</button>
</div>
</div>
<div>
<div class="mt-4 dark:bg-primary-black dark:bg-dark-grid bg-light-grid px-12 pt-12 flex flex-col items-center">
<div class="text-5xl font-bold max-w-5xl mx-auto mt-2 text-center">
Build <CalloutText>powerful</CalloutText> and <CalloutText>extensible</CalloutText> Elixir applications with a next generation tool-chain.
</div>
<div class="text-xl font-light text-gray-700 dark:text-gray-400 max-w-4xl mx-auto mt-4 text-center">
A declarative foundation for modern applications. Use extensions like <CalloutText>Ash GraphQL</CalloutText> and <CalloutText>Ash Json Api</CalloutText> to add APIs in minutes,
or build your own extensions. Plug-and-play with other excellent tools like <CalloutText>Phoenix</CalloutText> and <CalloutText>Absinthe</CalloutText>.
</div>
<button id="search-button" class="w-96 button hide xl:block border border-gray-400 bg-gray-200 dark:border-gray-700 rounded-lg dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 mt-4" phx-click={toggle_search()}>
<div class="flex flex-row justify-between items-center px-4">
<div class="h-12 flex flex-row justify-start items-center text-center space-x-4">
<Heroicons.Outline.SearchIcon class="w-4 h-4" />
<div>Search Documentation</div>
</div>
<div> K</div>
</div>
</button>
<div class="pt-6 pb-6 w-full hidden md:block">
<div class="flex flex-row justify-center space-x-24 xl:space-x-32">
<CodeExample id="define-a-resource" class="grow min-w-fit" text={post_example()} title="Define a resource" />
<div class="flex flex-col space-y-8">
<CodeExample class="w-auto" collapsable id="use-it-programatically" text={changeset_example()} title="Use it programatically" />
<CodeExample class="w-auto" collapsable id="graphql-interface" text={graphql_example()} title="Add a GraphQL interface" />
<CodeExample class="w-auto" collapsable start_collapsed id="authorization-policies" text={policies_example()} title="Add authorization policies" />
<CodeExample class="w-auto" collapsable start_collapsed id="aggregates" text={aggregate_example()} title="Define aggregates and calculations" />
<CodeExample class="w-auto" collapsable start_collapsed id="pubsub" text={notifier_example()} title="Broadcast changes over Phoenix PubSub" />
<CodeExample class="w-auto" collapsable start_collapsed id="live-view" text={live_view_example()} title="Use it with Phoenix LiveView" />
</div>
</div>
</div>
</div>
</div>
<div class="bg-primary-black">
</div>
</div>
</div>
"""
end
def mount(_params, session, socket) do
configured_theme = session["theme"] || "dark"
{:ok, assign(socket, configured_theme: configured_theme)}
end
def toggle_search(js \\ %JS{}) do
js
|> JS.dispatch("js:noscroll-main", to: "#search-box")
|> JS.toggle(
in: "fade-in duration-100",
out: "fade-out duration-100",
to: "#search-box",
time: 100
)
|> JS.dispatch("js:focus", to: "#search-input")
end
def close_search(js \\ %JS{}) do
js
|> JS.dispatch("js:noscroll-main", to: "#search-box")
|> JS.hide(
transition: "fade-out duration-100",
to: "#search-box",
time: 100
)
|> JS.dispatch("js:focus", to: "#search-input")
end
def handle_event("toggle_theme", _, socket) do
theme =
case socket.assigns.configured_theme do
"light" ->
"dark"
"dark" ->
"light"
end
{:noreply,
socket
|> assign(:configured_theme, theme)
|> push_event("set_theme", %{theme: theme})}
end
defp changeset_example() do
"""
post = Example.Post.create!(%{
text: "Declarative programming is fun!"
})
Example.Post.react!(post, %{type: :like})
Example.Post
|> Ash.Query.filter(likes > 10)
|> Ash.Query.sort(likes: :desc)
|> Example.read!()
"""
end
defp live_view_example() do
"""
def mount(_params, _session, socket) do
form = AshPhoenix.Form.for_create(Example.Post, :create)
{:ok, assign(socket, :form, form}}
end
def handle_event("validate", %{"form" => input}, socket) do
form = AshPhoenix.Form.validate(socket.assigns.form, input)
{:ok, assign(socket, :form, form)}
end
def handle_event("submit", _, socket) do
case AshPhoenix.Form.submit(socket.assigns.form) do
{:ok, post} ->
{:ok, redirect_to_post(socket, post)}
{:error, form_with_errors} ->
{:noreply, assign(socket, :form, form_with_errors)}
end
end
"""
end
defp graphql_example() do
"""
graphql do
type :post
queries do
get :get_post, :read
list :feed, :read
end
mutations do
create :create_post, :create
update :react_to_post, :react
end
end
"""
end
defp policies_example() do
"""
policies do
policy action_type(:read) do
authorize_if expr(visibility == :everyone)
authorize_if relates_to_actor_via([:author, :friends])
end
end
"""
end
defp notifier_example() do
"""
pub_sub do
module ExampleEndpoint
prefix "post"
publish_all :create, ["created"]
publish :react, ["reaction", :id] event: "reaction"
end
"""
end
defp aggregate_example() do
"""
aggregates do
count :likes, :reactions do
filter expr(type == :like)
end
count :dislikes, :reactions do
filter expr(type == :dislike)
end
end
calculations do
calculate :like_ratio, :float do
expr(likes / likes + dislikes)
end
end
"""
end
defp post_example() do
"""
defmodule Example.Post do
use AshHq.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "posts"
repo Example.Repo
end
attributes do
attribute :text, :string do
allow_nil? false
end
attribute :visibility, :atom do
constraints [
one_of: [:friends, :everyone]
]
end
end
actions do
update :react do
argument :type, Example.Types.ReactionType do
allow_nil? false
end
change manage_relationship(
:type,
:reactions,
type: :append
)
end
end
relationships do
belongs_to :author, Example.User do
required? true
end
has_many :reactions, Example.Reaction
end
end
"""
end
end

26
mix.exs
View file

@ -33,6 +33,17 @@ defmodule AshHq.MixProject do
# Type `mix help deps` for examples and options.
defp deps do
[
# {:ash, github: "ash-project/ash", override: true},
{:ash, path: "../ash", override: true},
{:ash_postgres, github: "ash-project/ash_postgres"},
{:ash_phoenix, github: "ash-project/ash_phoenix"},
{:elasticlunr, "~> 0.6.6"},
{:earmark, "~> 1.4"},
{:ecto, git: "https://github.com/elixir-ecto/ecto.git", override: true},
{:surface, "~> 0.7.3"},
{:surface_heroicons, "~> 0.6.0"},
{:makeup, "~> 1.1"},
{:makeup_elixir, "~> 0.16.0"},
{:phoenix, "~> 1.6.6"},
{:phoenix_ecto, "~> 4.4"},
{:ecto_sql, "~> 3.6"},
@ -40,6 +51,8 @@ defmodule AshHq.MixProject do
{:phoenix_html, "~> 3.0"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_view, "~> 0.17.5"},
{:nimble_options, "~> 0.4.0", override: true},
{:finch, "~> 0.10.2"},
{:floki, ">= 0.30.0", only: :test},
{:phoenix_live_dashboard, "~> 0.6"},
{:esbuild, "~> 0.3", runtime: Mix.env() == :dev},
@ -60,11 +73,16 @@ defmodule AshHq.MixProject do
# See the documentation for `Mix` for more info on aliases.
defp aliases do
[
setup: ["deps.get", "ecto.setup"],
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
seed: ["run priv/repo/seeds.exs"],
setup: ["ash_postgres.create", "ash_postgres.migrate", "seed"],
reset: ["drop", "setup"],
drop: ["ash_postgres.drop"],
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
"assets.deploy": ["esbuild default --minify", "phx.digest"]
"assets.deploy": [
"cmd --cd assets npm run deploy",
"esbuild default --minify",
"phx.digest"
]
]
end
end

View file

@ -1,20 +1,44 @@
%{
"castore": {:hex, :castore, "0.1.15", "dbb300827d5a3ec48f396ca0b77ad47058578927e9ebe792abd99fcbc3324326", [:mix], [], "hexpm", "c69379b907673c7e6eb229f09a0a09b60bb27cfb9625bcb82ea4c04ba82a8442"},
"ash": {:git, "https://github.com/ash-project/ash.git", "880a17f197873eb1c8dc8d81a8b4d6d9cb570b3f", []},
"ash_phoenix": {:git, "https://github.com/ash-project/ash_phoenix.git", "9de0ff87780bd16d06dcde1bac6a8e041a31659d", []},
"ash_postgres": {:git, "https://github.com/ash-project/ash_postgres.git", "ed8d4f29f2eb6e667a568f3b373f90ace93cc3f4", []},
"castore": {:hex, :castore, "0.1.16", "2675f717adc700475345c5512c381ef9273eb5df26bdd3f8c13e2636cf4cc175", [:mix], [], "hexpm", "28ed2c43d83b5c25d35c51bc0abf229ac51359c170cba76171a462ced2e4b651"},
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"},
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
"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"},
"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"},
"ecto": {:hex, :ecto, "3.7.2", "44c034f88e1980754983cc4400585970b4206841f6f3780967a65a9150ef09a8", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a600da5772d1c31abbf06f3e4a1ffb150e74ed3e2aa92ff3cee95901657a874e"},
"earmark": {:hex, :earmark, "1.4.24", "1923e201c3742af421860b983560967cc3e3deacc59c12966bc991a5435565e6", [:mix], [{:earmark_parser, "~> 1.4.25", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "9724242f241f2ad634756d8f2bb57a3d0992cedd10c51842fa655703b4da7c67"},
"earmark_parser": {:hex, :earmark_parser, "1.4.25", "2024618731c55ebfcc5439d756852ec4e85978a39d0d58593763924d9a15916f", [:mix], [], "hexpm", "56749c5e1c59447f7b7a23ddb235e4b3defe276afc220a6227237f3efe83f51e"},
"ecto": {:git, "https://github.com/elixir-ecto/ecto.git", "cda1172063753dea764e9c8ad80757dae5d1a4a7", []},
"ecto_sql": {:hex, :ecto_sql, "3.7.2", "55c60aa3a06168912abf145c6df38b0295c34118c3624cf7a6977cd6ce043081", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0 or ~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c218ea62f305dcaef0b915fb56583195e7b91c91dcfb006ba1f669bfacbff2a"},
"elasticlunr": {:hex, :elasticlunr, "0.6.6", "937a41a7293040e060f880817abac8e025ac9e146554e24042aaf8fbe94a0d1f", [:mix], [{:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: false]}, {:stemmer, "~> 1.0", [hex: :stemmer, repo: "hexpm", optional: false]}, {:uuid, "~> 1.1", [hex: :uuid, repo: "hexpm", optional: false]}], "hexpm", "d02244cb10c46b82bbc1e68477be296aa78f2d6ecf70355722ce916ff24f6958"},
"elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"},
"esbuild": {:hex, :esbuild, "0.4.0", "9f17db148aead4cf1e6e6a584214357287a93407b5fb51a031f122b61385d4c2", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "b61e4e6b92ffe45e4ee4755a22de6211a67c67987dc02afb35a425a0add1d447"},
"ets": {:hex, :ets, "0.8.1", "8ff9bcda5682b98493f8878fc9dbd990e48d566cba8cce59f7c2a78130da29ea", [:mix], [], "hexpm", "6be41b50adb5bc5c43626f25ea2d0af1f4a242fb3fad8d53f0c67c20b78915cc"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"finch": {:hex, :finch, "0.10.2", "9ad27d68270d879f73f26604bb2e573d40f29bf0e907064a9a337f90a16a0312", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dd8b11b282072cec2ef30852283949c248bd5d2820c88d8acc89402b81db7550"},
"floki": {:hex, :floki, "0.32.0", "f915dc15258bc997d49be1f5ef7d3992f8834d6f5695270acad17b41f5bcc8e2", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "1c5a91cae1fd8931c26a4826b5e2372c284813904c8bacb468b5de39c7ececbd"},
"gettext": {:hex, :gettext, "0.19.1", "564953fd21f29358e68b91634799d9d26989f8d039d7512622efb3c3b1c97892", [:mix], [], "hexpm", "10c656c0912b8299adba9b061c06947511e3f109ab0d18b44a866a4498e77222"},
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
"hpax": {:hex, :hpax, "0.1.1", "2396c313683ada39e98c20a75a82911592b47e5c24391363343bde74f82396ca", [:mix], [], "hexpm", "0ae7d5a0b04a8a60caf7a39fcf3ec476f35cc2cc16c05abea730d3ce6ac6c826"},
"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"},
"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_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mint": {:hex, :mint, "1.4.1", "49b3b6ea35a9a38836d2ad745251b01ca9ec062f7cb66f546bf22e6699137126", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "cd261766e61011a9079cccf8fa9d826e7a397c24fbedf0e11b49312bea629b58"},
"nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"phoenix": {:hex, :phoenix, "1.6.6", "281c8ce8dccc9f60607346b72cdfc597c3dde134dd9df28dff08282f0b751754", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "807bd646e64cd9dc83db016199715faba72758e6db1de0707eef0a2da4924364"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
"phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"},
@ -23,13 +47,25 @@
"phoenix_live_view": {:hex, :phoenix_live_view, "0.17.7", "05a42377075868a678d446361effba80cefef19ab98941c01a7a4c7560b29121", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.9 or ~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "25eaf41028eb351b90d4f69671874643a09944098fefd0d01d442f40a6091b6f"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
"phoenix_view": {:hex, :phoenix_view, "1.1.2", "1b82764a065fb41051637872c7bd07ed2fdb6f5c3bd89684d4dca6e10115c95a", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "7ae90ad27b09091266f6adbb61e1d2516a7c3d7062c6789d46a7554ec40f3a56"},
"picosat_elixir": {:hex, :picosat_elixir, "0.2.1", "407dcb90755167fd9e3311b60565ff32ed0d234010363406c07cdb4175b95bc5", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "68f4bdb2ac3b594209e54625d3d58c9e2e98b90f2ec8e03235f66e88c9eda5fe"},
"plug": {:hex, :plug, "1.13.4", "addb6e125347226e3b11489e23d22a60f7ab74786befb86c14f94fb5f23ca9a4", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "06114c1f2a334212fe3ae567dbb3b1d29fd492c1a09783d52f3d489c1a6f4cf2"},
"plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"},
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
"postgrex": {:hex, :postgrex, "0.16.2", "0f83198d0e73a36e8d716b90f45f3bde75b5eebf4ade4f43fa1f88c90a812f74", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "a9ea589754d9d4d076121090662b7afe155b374897a6550eb288f11d755acfa0"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"req": {:hex, :req, "0.2.1", "5d4ee7bc6666cd4d77e95f89ce75ca0ca73b6a25eeebbe2e7bc60cdd56d73865", [:mix], [{:finch, "~> 0.9.1", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}], "hexpm", "ababd5c8a334848bde2bc3c2f518df22211c8533d863d15bfefa04796abc3633"},
"sourceror": {:hex, :sourceror, "0.10.0", "a6a85d8acc874df59bedb7497374f8f7517e4d54a5805da903ff31aaee14a1a7", [:mix], [], "hexpm", "ddd94d23d96ac949696616eb89cecac977dfed7ecdfac6bbd3f83617e4daea28"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"stemmer": {:hex, :stemmer, "1.1.0", "71221331ced40832b47e6989a12dd9de1b15c982043d1014742be83c34ec9e79", [:mix], [], "hexpm", "0cb5faf73476b84500e371ff39fd9a494f60ab31d991689c1cd53b920556228f"},
"surface": {:hex, :surface, "0.7.3", "104dbb22d828a63a9ef45edf65c1f47fa4aedbcfb5478f2cafbe649586b02a58", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.17.4", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.9", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "ab4aa36f767042dc822b28ba0fb455bfa2cca054c7305a6cc113597ab81726e2"},
"surface_heroicons": {:hex, :surface_heroicons, "0.6.0", "04e171843439d2d52c868f8adf5294c49505f504a74a0200179e49c447d6f354", [:mix], [{:surface, ">= 0.5.0", [hex: :surface, repo: "hexpm", optional: false]}], "hexpm", "1136c88a8de44a63c050cec9b0b64f771127dfd96feabab4cd0bde8b6b727ba2"},
"swoosh": {:hex, :swoosh, "1.6.3", "598d3f07641004bedb3eede40057760ae18be1073cff72f079ca1e1fc9cd97b9", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "81ff9d7c7c4005a57465a7eb712edd71db51829aef94c8a34c30c5b9e9964adf"},
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
"telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"},
"timex": {:hex, :timex, "3.7.7", "3ed093cae596a410759104d878ad7b38e78b7c2151c6190340835515d4a46b8a", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "0ec4b09f25fe311321f9fc04144a7e3affe48eb29481d7a5583849b6c4dfa0a7"},
"typable": {:hex, :typable, "0.3.0", "0431e121d124cd26f312123e313d2689b9a5322b15add65d424c07779eaa3ca1", [:mix], [], "hexpm", "880a0797752da1a4c508ac48f94711e04c86156f498065a83d160eef945858f8"},
"tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
"uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm", "c790593b4c3b601f5dc2378baae7efaf5b3d73c4c6456ba85759905be792f2ac"},
}

BIN
priv/docs/ash/1.51.0 Normal file

Binary file not shown.

BIN
priv/docs/ash/1.51.1 Normal file

Binary file not shown.

BIN
priv/docs/ash/1.51.2 Normal file

Binary file not shown.

BIN
priv/docs/ash/master Normal file

Binary file not shown.

View file

@ -1,4 +0,0 @@
[
import_deps: [:ecto_sql],
inputs: ["*.exs"]
]

View file

@ -0,0 +1,71 @@
defmodule AshHq.Repo.Migrations.MigrateResources1 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
create table(:sections, primary_key: false) do
add :id, :uuid, null: false, primary_key: true
add :name, :text, null: false
end
create table(:library_versions, primary_key: false) do
add :id, :uuid, null: false, primary_key: true
add :version, :text, null: false
add :library_id, :uuid, null: false
end
create table(:libraries, primary_key: false) do
add :id, :uuid, null: false, primary_key: true
end
alter table(:library_versions) do
modify :library_id,
references(:libraries,
column: :id,
name: "library_versions_library_id_fkey",
type: :uuid
)
end
alter table(:libraries) do
add :name, :text, null: false
end
create table(:extensions, primary_key: false) do
add :id, :uuid, null: false, primary_key: true
add :name, :text, null: false
end
create table(:entities, primary_key: false) do
add :id, :uuid, null: false, primary_key: true
add :name, :text, null: false
end
end
def down do
drop table(:entities)
drop table(:extensions)
alter table(:libraries) do
remove :name
end
drop constraint(:library_versions, "library_versions_library_id_fkey")
alter table(:library_versions) do
modify :library_id, :uuid
end
drop table(:libraries)
drop table(:library_versions)
drop table(:sections)
end
end

View file

@ -0,0 +1,21 @@
defmodule AshHq.Repo.Migrations.MigrateResources2 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(:library_versions) do
add :data, :map
end
end
def down do
alter table(:library_versions) do
remove :data
end
end
end

View file

@ -0,0 +1,21 @@
defmodule AshHq.Repo.Migrations.MigrateResources3 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(:library_versions) do
add :processed, :boolean, default: false
end
end
def down do
alter table(:library_versions) do
remove :processed
end
end
end

View file

@ -0,0 +1,29 @@
defmodule AshHq.Repo.Migrations.MigrateResources4 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(:extensions) do
add :library_version_id,
references(:library_versions,
column: :id,
name: "extensions_library_version_id_fkey",
type: :uuid
),
null: false
end
end
def down do
drop constraint(:extensions, "extensions_library_version_id_fkey")
alter table(:extensions) do
remove :library_version_id
end
end
end

View file

@ -0,0 +1,31 @@
defmodule AshHq.Repo.Migrations.MigrateResources5 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(:extensions) do
add :target, :text
add :default_for_target, :boolean, default: false
end
create unique_index(:extensions, [:library_version_id, :name],
name: "extensions_unique_name_by_library_version_index"
)
end
def down do
drop_if_exists unique_index(:extensions, [:library_version_id, :name],
name: "extensions_unique_name_by_library_version_index"
)
alter table(:extensions) do
remove :default_for_target
remove :target
end
end
end

View file

@ -0,0 +1,21 @@
defmodule AshHq.Repo.Migrations.MigrateResources6 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(:libraries) do
add :track_branches, {:array, :text}, default: []
end
end
def down do
alter table(:libraries) do
remove :track_branches
end
end
end

View file

@ -0,0 +1,82 @@
defmodule AshHq.Repo.Migrations.MigrateResources7 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
create table(:options, primary_key: false) do
add :id, :uuid, null: false, primary_key: true
add :name, :text, null: false
add :type, :text, null: false
add :doc, :text
add :required, :boolean, null: false, default: false
add :default, :text
add :dsl_id, :uuid, null: false
end
create table(:dsls, primary_key: false) do
add :id, :uuid, null: false, primary_key: true
end
alter table(:options) do
modify :dsl_id, references(:dsls, column: :id, name: "options_dsl_id_fkey", type: :uuid)
end
alter table(:dsls) do
add :name, :text, null: false
add :doc, :text
add :examples, {:array, :text}
add :args, {:array, :text}
add :path, {:array, :text}
add :type, :text, null: false
add :library_version_id,
references(:library_versions,
column: :id,
name: "dsls_library_version_id_fkey",
type: :uuid
),
null: false
add :extension_id,
references(:extensions, column: :id, name: "dsls_extension_id_fkey", type: :uuid),
null: false
add :dsl_id, references(:dsls, column: :id, name: "dsls_dsl_id_fkey", type: :uuid)
end
end
def down do
drop constraint(:dsls, "dsls_dsl_id_fkey")
drop constraint(:dsls, "dsls_extension_id_fkey")
drop constraint(:dsls, "dsls_library_version_id_fkey")
alter table(:dsls) do
remove :dsl_id
remove :extension_id
remove :library_version_id
remove :type
remove :path
remove :args
remove :examples
remove :doc
remove :name
end
drop constraint(:options, "options_dsl_id_fkey")
alter table(:options) do
modify :dsl_id, :uuid
end
drop table(:dsls)
drop table(:options)
end
end

View file

@ -0,0 +1,21 @@
defmodule AshHq.Repo.Migrations.MigrateResources8 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(:dsls) do
add :recursive_as, :text
end
end
def down do
alter table(:dsls) do
remove :recursive_as
end
end
end

View file

@ -0,0 +1,25 @@
defmodule AshHq.Repo.Migrations.MigrateResources9 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
add :library_version_id,
references(:dsls, column: :id, name: "options_library_version_id_fkey", type: :uuid),
null: false
end
end
def down do
drop constraint(:options, "options_library_version_id_fkey")
alter table(:options) do
remove :library_version_id
end
end
end

View file

@ -0,0 +1,31 @@
defmodule AshHq.Repo.Migrations.MigrateResources10 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
drop constraint(:options, "options_library_version_id_fkey")
alter table(:options) do
modify :library_version_id,
references(:library_versions,
column: :id,
name: "options_library_version_id_fkey",
type: :uuid
)
end
end
def down do
drop constraint(:options, "options_library_version_id_fkey")
alter table(:options) do
modify :library_version_id,
references(:dsls, column: :id, name: "options_library_version_id_fkey", type: :uuid)
end
end
end

View file

@ -0,0 +1,21 @@
defmodule AshHq.Repo.Migrations.MigrateResources11 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
add :path, {:array, :text}
end
end
def down do
alter table(:options) do
remove :path
end
end
end

View file

@ -0,0 +1,21 @@
defmodule AshHq.Repo.Migrations.MigrateResources12 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(:extensions) do
add :type, :text, null: false
end
end
def down do
alter table(:extensions) do
remove :type
end
end
end

View file

@ -9,3 +9,6 @@
#
# We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong.
AshHq.Docs.Library.create!(%{name: "ash", track_branches: ["main"]})
# AshHq.Docs.Library.create!(%{name: "ash_postgres", track_branches: ["master"]})

View file

@ -0,0 +1,165 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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": "doc",
"type": "text"
},
{
"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?": 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": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_library_version_id_fkey",
"on_delete": null,
"on_update": null,
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_extension_id_fkey",
"on_delete": null,
"on_update": null,
"table": "extensions"
},
"size": null,
"source": "extension_id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_dsl_id_fkey",
"on_delete": null,
"on_update": null,
"table": "dsls"
},
"size": null,
"source": "dsl_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "781AFEF8BB0319AA4EDC5AE608AAAFD90BDC2FEC0C28CA2DE53475C669642D67",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "dsls"
}

View file

@ -0,0 +1,175 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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": "doc",
"type": "text"
},
{
"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": "type",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_library_version_id_fkey",
"on_delete": null,
"on_update": null,
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_extension_id_fkey",
"on_delete": null,
"on_update": null,
"table": "extensions"
},
"size": null,
"source": "extension_id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "dsls_dsl_id_fkey",
"on_delete": null,
"on_update": null,
"table": "dsls"
},
"size": null,
"source": "dsl_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "0316B91DC28F757F8FE72CC0E55C080D3AAB9430E9D1A27E143F88AA1BC17DDB",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "dsls"
}

View file

@ -0,0 +1,37 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "7B7D050A2B9C48844F978326DCE3C22BDC038BBA77712A7AEDDFAAF76163A9B7",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "entities"
}

View file

@ -0,0 +1,37 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "7BFE7E7CC16AA00CE78C90AD42304AABBFB21A5A73D150A030B8A26189FF0E6B",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "extensions"
}

View file

@ -0,0 +1,60 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "extensions_library_version_id_fkey",
"on_delete": null,
"on_update": null,
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "82FD37547E06CC3763E82E53E135C5C4D77781C0C0AECEE69117725D6352407B",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "extensions"
}

View file

@ -0,0 +1,90 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "extensions_library_version_id_fkey",
"on_delete": null,
"on_update": null,
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "D9477565F8EA2F8293CA0C880A3B0653FC886DD3BDDE02AFC60C99C9D1305EFF",
"identities": [
{
"base_filter": null,
"index_name": "extensions_unique_name_by_library_version_index",
"keys": [
"library_version_id",
"name"
],
"name": "unique_name_by_library_version"
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "extensions"
}

View file

@ -0,0 +1,100 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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": "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": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "extensions_library_version_id_fkey",
"on_delete": null,
"on_update": null,
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "1938D48EE8054F9FC51FA6300D4460725D5155B2AA1DEE80A333AD8FBC5EABD9",
"identities": [
{
"base_filter": null,
"index_name": "extensions_unique_name_by_library_version_index",
"keys": [
"library_version_id",
"name"
],
"name": "unique_name_by_library_version"
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "extensions"
}

View file

@ -0,0 +1,37 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "587B80401AF883E576A1303EE8FAE786DC54B2D5909C92293D4ADF06D927619B",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "libraries"
}

View file

@ -0,0 +1,50 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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": "[]",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "track_branches",
"type": [
"array",
"text"
]
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "673FCBFE159EFAF55C65B9E6795359ECF6B5B1344A30F8CE9C688E0EE0881EBD",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "libraries"
}

View file

@ -0,0 +1,60 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "library_versions_library_id_fkey",
"on_delete": null,
"on_update": null,
"table": "libraries"
},
"size": null,
"source": "library_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "1923B17B390C75BB5D67CFA14A2EFD523A449CEDE0336BF012FC27D36D83C862",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "library_versions"
}

View file

@ -0,0 +1,70 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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": null,
"size": null,
"source": "data",
"type": "map"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "library_versions_library_id_fkey",
"on_delete": null,
"on_update": null,
"table": "libraries"
},
"size": null,
"source": "library_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "78522A8E956E59BD4C57FBB26FE68BEF7CA7D51F48867A06F1F507E82BE82E33",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "library_versions"
}

View file

@ -0,0 +1,80 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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": null,
"size": null,
"source": "data",
"type": "map"
},
{
"allow_nil?": true,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "processed",
"type": "boolean"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "library_versions_library_id_fkey",
"on_delete": null,
"on_update": null,
"table": "libraries"
},
"size": null,
"source": "library_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "8BF507A6047D503DBB4B89DF6A0D919984C2E8032AE06A68AE9F5C2E9F9E9D99",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "library_versions"
}

View file

@ -0,0 +1,100 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"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": "default",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_dsl_id_fkey",
"on_delete": null,
"on_update": null,
"table": "dsls"
},
"size": null,
"source": "dsl_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "F5150BA878A12A92AAB78AE98A2161EE1185AD6AD3D8CBF589CE95B653FE4D49",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "options"
}

View file

@ -0,0 +1,123 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"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": "default",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_dsl_id_fkey",
"on_delete": null,
"on_update": null,
"table": "dsls"
},
"size": null,
"source": "dsl_id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_library_version_id_fkey",
"on_delete": null,
"on_update": null,
"table": "dsls"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "0D111F3BC67FEBF0F2B10FA081D7152176123EBD9C8F53183826958B6403E226",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "options"
}

View file

@ -0,0 +1,123 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"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": "default",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_dsl_id_fkey",
"on_delete": null,
"on_update": null,
"table": "dsls"
},
"size": null,
"source": "dsl_id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_library_version_id_fkey",
"on_delete": null,
"on_update": null,
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "D44FA3166AA71B076F44642988CAC885E62FFD2A1B025D9FAF378FA99DBE5D9B",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "options"
}

View file

@ -0,0 +1,136 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "doc",
"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": "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": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_dsl_id_fkey",
"on_delete": null,
"on_update": null,
"table": "dsls"
},
"size": null,
"source": "dsl_id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"destination_field": "id",
"destination_field_default": null,
"destination_field_generated": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "options_library_version_id_fkey",
"on_delete": null,
"on_update": null,
"table": "library_versions"
},
"size": null,
"source": "library_version_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "DDF54A71D09EED13508CDC5952D0F563A3CEC4B90058F3A4C997F6EB249F42B6",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "options"
}

View file

@ -0,0 +1,37 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "nil",
"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"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"has_create_action": true,
"hash": "89DDB6E45E575E42FE0BC9515C81B55652E40D9B1608624C3131CF72B1F7E2B0",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshHq.Repo",
"table": "sections"
}

BIN
priv/static/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,5 @@
# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
#
# To ban all spiders from the entire site uncomment the next two lines:
# User-agent: *
# Disallow: /

BIN
priv/static/robots.txt.gz Normal file

Binary file not shown.

5
rel/env.bat.eex Normal file
View file

@ -0,0 +1,5 @@
@echo off
rem Set the release to work across nodes.
rem RELEASE_DISTRIBUTION must be "sname" (local), "name" (distributed) or "none".
rem set RELEASE_DISTRIBUTION=name
rem set RELEASE_NODE=<%= @release.name %>

6
rel/env.sh.eex Normal file
View file

@ -0,0 +1,6 @@
#!/bin/sh
ip=$(grep fly-local-6pn /etc/hosts | cut -f 1)
export RELEASE_DISTRIBUTION=name
export RELEASE_NODE=$FLY_APP_NAME@$ip
export ELIXIR_ERL_OPTIONS="-proto_dist inet6_tcp"

11
rel/remote.vm.args.eex Normal file
View file

@ -0,0 +1,11 @@
## Customize flags given to the VM: https://erlang.org/doc/man/erl.html
## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here
## Number of dirty schedulers doing IO work (file, sockets, and others)
##+SDio 5
## Increase number of concurrent ports/sockets
##+Q 65536
## Tweak GC to run more often
##-env ERL_FULLSWEEP_AFTER 10

11
rel/vm.args.eex Normal file
View file

@ -0,0 +1,11 @@
## Customize flags given to the VM: https://erlang.org/doc/man/erl.html
## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here
## Number of dirty schedulers doing IO work (file, sockets, and others)
##+SDio 5
## Increase number of concurrent ports/sockets
##+Q 65536
## Tweak GC to run more often
##-env ERL_FULLSWEEP_AFTER 10