feat: Switch away from escript as the method, just use the app directory
This commit is contained in:
parent
bc1526316f
commit
7d9715d1bd
11 changed files with 168 additions and 106 deletions
|
@ -7,7 +7,6 @@ pages:
|
|||
- mix deps.get
|
||||
- mix esbuild.install --if-missing
|
||||
- mix tailwind.install --if-missing
|
||||
- mix tree_sitter.install --if-missing
|
||||
- (cd tree-sitter/_parsers/;git clone https://github.com/elixir-lang/tree-sitter-elixir; git clone https://github.com/camdencheek/tree-sitter-dockerfile)
|
||||
- mix assets.build
|
||||
- mix lain.build
|
||||
|
@ -20,15 +19,15 @@ pages:
|
|||
# I wish we could just depend on the pages:deploy job that GitLab inserts, but apparently we can't reference it.
|
||||
wait:
|
||||
needs:
|
||||
- "pages"
|
||||
- "pages"
|
||||
script:
|
||||
- sleep 10
|
||||
- sleep 10
|
||||
ping:
|
||||
needs:
|
||||
- "wait"
|
||||
- "wait"
|
||||
script:
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get
|
||||
- mix compile
|
||||
- mix lain.ping
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get
|
||||
- mix compile
|
||||
- mix lain.ping
|
||||
|
|
|
@ -25,11 +25,6 @@ config :esbuild,
|
|||
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
|
||||
]
|
||||
|
||||
config :tree_sitter,
|
||||
version: "0.20.8",
|
||||
config_directory: "tree-sitter",
|
||||
cacerts_path: Path.join([File.cwd!(), "_build", "castore.pem"])
|
||||
|
||||
config :lain,
|
||||
host: "pre.hn",
|
||||
base: "https://pre.hn/"
|
||||
|
|
124
lib/lain.ex
124
lib/lain.ex
|
@ -12,8 +12,6 @@ defmodule Lain do
|
|||
alias Lain.Frontmatter
|
||||
alias Lain.Markdown
|
||||
|
||||
@base_caller __ENV__
|
||||
|
||||
def read(path) do
|
||||
path
|
||||
|> File.read!()
|
||||
|
@ -53,9 +51,19 @@ defmodule Lain do
|
|||
end)
|
||||
end
|
||||
|
||||
def run(path) do
|
||||
TreeSitter.install_and_run(["-V"])
|
||||
def serve(path) do
|
||||
Application.put_env(:lain, :serve_endpoints, true, persistent: true)
|
||||
|
||||
Application.put_env(:lain, :built_path, Path.join(Path.expand(path), "build"),
|
||||
persistent: true
|
||||
)
|
||||
|
||||
run(path)
|
||||
|
||||
:timer.sleep(:infinity)
|
||||
end
|
||||
|
||||
def run(path) do
|
||||
posts =
|
||||
path
|
||||
|> Path.join("**/*.md")
|
||||
|
@ -77,7 +85,7 @@ defmodule Lain do
|
|||
|
||||
make_feed(posts, path)
|
||||
make_sitemap(posts, path)
|
||||
index = make_index(posts)
|
||||
index = make_index(posts, path)
|
||||
|
||||
Lain.LinkLog.run(path)
|
||||
Lain.Static.run(path)
|
||||
|
@ -91,7 +99,12 @@ defmodule Lain do
|
|||
|> Enum.into(%{})
|
||||
end
|
||||
|
||||
def make_index(posts) do
|
||||
def make_index(posts, root_path) do
|
||||
posts =
|
||||
Enum.filter(posts, fn %{path: path} ->
|
||||
String.starts_with?(path, Path.join(root_path, "posts"))
|
||||
end)
|
||||
|
||||
assigns = %{posts: posts}
|
||||
|
||||
body =
|
||||
|
@ -123,29 +136,31 @@ defmodule Lain do
|
|||
EEx.eval_string(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<title>pre.hn</title>
|
||||
<subtitle>Robert Prehn's personal blog.</subtitle>
|
||||
<link rel="alternative" type="text/html">https://pre.hn</link>
|
||||
<link rel="self" type="application/rss+xml">https://pre.hn/feed.rss</link>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<id>https://pre.hn/feed.rss</id>
|
||||
<updated><%= DateTime.utc_now() |> DateTime.to_iso8601() %></updated>
|
||||
<title>pre.hn</title>
|
||||
<subtitle>Robert Prehn's personal blog.</subtitle>
|
||||
<link href="https://pre.hn/feed.rss" rel="self" type="application/rss+xml"></link>
|
||||
|
||||
<%= for post <- @posts do %>
|
||||
<entry>
|
||||
<title><%= HtmlSanitizeEx.strip_tags(post.title) %></title>
|
||||
<content type="xhtml" xml:lang="en"
|
||||
xml:base="https://pre.hn/"><![CDATA[<html><body>
|
||||
<%= post.body %>
|
||||
</body></html>]]>
|
||||
</description>
|
||||
<content type="html"><%= post.body |> sanitize_html_for_rss.() |> xml_escape.() %>
|
||||
</content>
|
||||
<published><%= rss_date_format.(post.date) %></published>
|
||||
<updated><%= rss_date_format.(post[:updated_at] || post.date) %></updated>
|
||||
<author><name>Robert Prehn</name></author>
|
||||
<id><%= @base %><%= post.slug %>/</id>
|
||||
<link rel="alternate" type="text/html"><%= @base %><%= post.slug %>/</link>
|
||||
<link type="text/html" href="<%= @base %><%= post.slug %>/"></link>
|
||||
</entry>
|
||||
<% end %>
|
||||
</feed>
|
||||
""",
|
||||
assigns: assigns,
|
||||
rss_date_format: &rss_date_format/1
|
||||
rss_date_format: &rss_date_format/1,
|
||||
sanitize_html_for_rss: &sanitize_html_for_rss/1,
|
||||
xml_escape: &xml_escape/1
|
||||
)
|
||||
|
||||
File.mkdir_p!(Path.join([path, "build"]))
|
||||
|
@ -179,11 +194,33 @@ defmodule Lain do
|
|||
}
|
||||
def rss_date_format(date_string) do
|
||||
date = Date.from_iso8601!(date_string)
|
||||
{:ok, datetime} = DateTime.new(date, %Time{hour: 0, minute: 0, second: 0})
|
||||
|
||||
day = Map.get(@days_of_week, Date.day_of_week(date))
|
||||
month = Map.get(@months, date.month)
|
||||
DateTime.to_iso8601(datetime)
|
||||
end
|
||||
|
||||
"#{day}, #{date.day} #{month} #{date.year} 00:00:00 -0600"
|
||||
def sanitize_html_for_rss(body_string) do
|
||||
html = Floki.parse_fragment!(body_string)
|
||||
|
||||
Floki.traverse_and_update(html, fn
|
||||
{"iframe", _attrs, _children} = node ->
|
||||
[src | _] = Floki.attribute(node, "src")
|
||||
[title | _] = Floki.attribute(node, "title")
|
||||
{"a", [{"href", src || "#"}], [title]}
|
||||
|
||||
other ->
|
||||
other
|
||||
end)
|
||||
|> Floki.raw_html()
|
||||
end
|
||||
|
||||
def xml_escape(xml_string) do
|
||||
xml_string
|
||||
|> String.replace("&", "&")
|
||||
|> String.replace("<", "<")
|
||||
|> String.replace(">", ">")
|
||||
|> String.replace("\"", """)
|
||||
|> String.replace("'", "'")
|
||||
end
|
||||
|
||||
def make_sitemap(posts, path) do
|
||||
|
@ -202,6 +239,15 @@ defmodule Lain do
|
|||
|> Stream.run()
|
||||
end
|
||||
|
||||
def render_template(path, assigns) do
|
||||
EEx.eval_file(path, [assigns: assigns],
|
||||
engine: Phoenix.LiveView.TagEngine,
|
||||
tag_handler: Phoenix.LiveView.HTMLEngine,
|
||||
caller: __ENV__,
|
||||
source: File.read!(path)
|
||||
)
|
||||
end
|
||||
|
||||
attr(:path, :string, required: true)
|
||||
attr(:title, :string, required: true)
|
||||
attr(:slug, :string, required: true)
|
||||
|
@ -218,24 +264,13 @@ defmodule Lain do
|
|||
|
||||
assigns = %{assigns | inner_block: inner_block}
|
||||
|
||||
EEx.eval_file(path, [assigns: assigns],
|
||||
engine: Phoenix.LiveView.TagEngine,
|
||||
tag_handler: Phoenix.LiveView.HTMLEngine,
|
||||
caller: __ENV__,
|
||||
source: File.read!(path)
|
||||
)
|
||||
render_template(path, assigns)
|
||||
end
|
||||
|
||||
def menu(assigns) do
|
||||
~H"""
|
||||
<nav class="text-light flex justify-center">
|
||||
<div class="container flex">
|
||||
<a class={"box rounded-tr !mt-[28px] !-mb-[2px] !border-b-light #{if @slug == "index", do: "current"}"} href="/">About Me</a>
|
||||
<a class={"box rounded-tr !mt-[28px] !-mb-[2px] !border-b-light #{if @slug == "blog", do: "current"}"} href="/blog">Blog</a>
|
||||
<a class={"box rounded-tr !mt-[28px] !-mb-[2px] !border-b-light #{if @slug == "link-log", do: "current"}"} href="/link-log">Link Log</a>
|
||||
</div>
|
||||
</nav>
|
||||
"""
|
||||
def menu(%{path: root_path} = assigns) do
|
||||
path = Path.join([root_path, "templates", "menu.html.heex"])
|
||||
|
||||
render_template(path, assigns)
|
||||
end
|
||||
|
||||
def write_page(%{slug: slug} = assigns, root_path) do
|
||||
|
@ -248,16 +283,11 @@ defmodule Lain do
|
|||
Path.join([root_path, "build", slug, "index.html"])
|
||||
end
|
||||
|
||||
~H"""
|
||||
<.layout path={root_path} title={@title} slug={@slug} description={assigns[:description]}>
|
||||
<main class="container mx-auto z-10 relative">
|
||||
<section class="box border border-light">
|
||||
<h1><%= @title %></h1>
|
||||
<%= {:safe, @body} %>
|
||||
</section>
|
||||
</main>
|
||||
</.layout>
|
||||
"""
|
||||
assigns = Map.put(assigns, :root_path, root_path)
|
||||
|
||||
root_path
|
||||
|> Path.join("templates/page.html.heex")
|
||||
|> render_template(assigns)
|
||||
|> rendered_to_string()
|
||||
|> then(&File.write!(path, &1))
|
||||
end
|
||||
|
|
|
@ -10,30 +10,34 @@ defmodule Lain.CLI do
|
|||
@cacerts File.read!(@certpath)
|
||||
|
||||
def main([command, path]) do
|
||||
Application.put_env(
|
||||
:tree_sitter,
|
||||
:cacerts_path,
|
||||
Path.join([File.cwd!(), "_build", "castore.pem"])
|
||||
)
|
||||
|
||||
Application.put_env(
|
||||
:tailwind,
|
||||
:cacerts_path,
|
||||
Path.join([File.cwd!(), "_build", "castore.pem"])
|
||||
)
|
||||
|
||||
Application.ensure_all_started([:castore, :inets, :ssl, :tailwind])
|
||||
|
||||
args = [
|
||||
tailwind_args = [
|
||||
"--config=#{Path.join(Path.expand(path), "tailwind.config.js")}",
|
||||
"--input=#{Path.join(Path.expand(path), "assets/app.css")}",
|
||||
"--output=#{Path.join(Path.expand(path), "build/assets/app.css")}",
|
||||
"--minify"
|
||||
]
|
||||
|
||||
Application.put_all_env(
|
||||
tailwind: [
|
||||
version: "3.2.7",
|
||||
default: [
|
||||
args: tailwind_args,
|
||||
cd: Path.expand(path)
|
||||
]
|
||||
]
|
||||
)
|
||||
|
||||
Application.ensure_all_started([:castore, :inets, :ssl, :tailwind, :autumn])
|
||||
|
||||
File.write!(Path.join("_build", "castore.pem"), @cacerts)
|
||||
|
||||
Tailwind.install_and_run(:default, args)
|
||||
Tailwind.install_and_run(:default, tailwind_args)
|
||||
|
||||
case command do
|
||||
"build" ->
|
||||
|
@ -41,6 +45,9 @@ defmodule Lain.CLI do
|
|||
|
||||
"clean" ->
|
||||
Lain.clean(path)
|
||||
|
||||
"serve" ->
|
||||
Lain.serve(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule PreDotDn.DevServer do
|
|||
|
||||
plug(Plug.Logger)
|
||||
plug(:rewrite_dirs)
|
||||
plug(Plug.Static, at: "", from: "priv/static")
|
||||
plug(Plug.Static, at: "", from: {PreDotDn.DevServer, :path, []})
|
||||
|
||||
get "/health" do
|
||||
conn |> resp(200, "ok") |> halt()
|
||||
|
@ -12,6 +12,10 @@ defmodule PreDotDn.DevServer do
|
|||
plug(:match)
|
||||
plug(:dispatch)
|
||||
|
||||
def path() do
|
||||
Application.get_env(:lain, :built_path)
|
||||
end
|
||||
|
||||
def rewrite_dirs(conn, _) do
|
||||
is_directory =
|
||||
case Enum.reverse(conn.path_info) do
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
defmodule Lain.LinkLog do
|
||||
alias Lain.Markdown
|
||||
use Phoenix.Component
|
||||
import Phoenix.LiveViewTest, only: [rendered_to_string: 1]
|
||||
|
||||
|
@ -8,8 +7,10 @@ defmodule Lain.LinkLog do
|
|||
|
||||
make_feed(links, path)
|
||||
|
||||
make_stylesheet(path)
|
||||
|
||||
links
|
||||
|> make_index()
|
||||
|> make_index(path)
|
||||
|> Lain.write_page(path)
|
||||
end
|
||||
|
||||
|
@ -51,25 +52,42 @@ defmodule Lain.LinkLog do
|
|||
assigns: assigns
|
||||
)
|
||||
|
||||
path = Path.join([path, "build", "link-log", "feed.rss"])
|
||||
dir_path = Path.join([path, "build", "link-log"])
|
||||
File.mkdir_p!(dir_path)
|
||||
path = Path.join([dir_path, "feed.rss"])
|
||||
|
||||
File.write!(path, body)
|
||||
end
|
||||
|
||||
def make_index(links) do
|
||||
assigns = %{links: links}
|
||||
def make_stylesheet(path) do
|
||||
tailwind_args = [
|
||||
"--config=#{Path.join(Path.expand(path), "tailwind.config.js")}",
|
||||
"--input=#{Path.join(Path.expand(path), "assets/app.css")}",
|
||||
"--output=#{Path.join(Path.expand(path), "build/assets/app.css")}",
|
||||
"--minify"
|
||||
]
|
||||
|
||||
Application.put_all_env(
|
||||
tailwind: [
|
||||
version: "3.2.7",
|
||||
default: [
|
||||
args: tailwind_args,
|
||||
cd: Path.expand(path)
|
||||
]
|
||||
]
|
||||
)
|
||||
|
||||
Tailwind.install_and_run(:default, tailwind_args)
|
||||
end
|
||||
|
||||
def make_index(links, path) do
|
||||
path = Path.join([path, "templates", "link.html.heex"])
|
||||
assigns = %{links: links, path: path}
|
||||
|
||||
body =
|
||||
~H"""
|
||||
<%= for link <- @links do %>
|
||||
<div style="margin-bottom: 1rem">
|
||||
<a class="text-ellipsis overflow-hidden inline-block" style="padding-left: 2rem;text-indent: -2rem;" href={link["url"]}>
|
||||
<%= link["emoji"] || "🔗"%> <%= link["name"] %>
|
||||
</a>
|
||||
<div class="link-log-body">
|
||||
<%= {:safe, Markdown.render(link["summary"])} %>
|
||||
</div>
|
||||
</div>
|
||||
<%= Lain.render_template(@path, %{link: link}) %>
|
||||
<% end %>
|
||||
"""
|
||||
|> rendered_to_string()
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
defmodule Lain.Markdown do
|
||||
@default_opts [pure_links: true, wikilinks: true, inner_html: false]
|
||||
@default_opts [
|
||||
pure_links: true,
|
||||
wikilinks: true,
|
||||
inner_html: false,
|
||||
escape: false,
|
||||
math: true,
|
||||
smartypants: true
|
||||
]
|
||||
|
||||
def render(source, opts \\ []) do
|
||||
opts = Keyword.merge(@default_opts, opts, fn _key, _default_value, value -> value end)
|
||||
|
@ -17,7 +24,12 @@ defmodule Lain.Markdown do
|
|||
other ->
|
||||
other
|
||||
end
|
||||
|> Earmark.Transform.transform()
|
||||
|> Earmark.Transform.transform(%{
|
||||
initial_indent: 0,
|
||||
indent: 2,
|
||||
compact_output: false,
|
||||
escape: false
|
||||
})
|
||||
end
|
||||
|
||||
defp transformer({"a", attrs, ignored, meta}) do
|
||||
|
@ -60,14 +72,9 @@ defmodule Lain.Markdown do
|
|||
defp highlight([text], lang), do: highlight(text, lang)
|
||||
|
||||
defp highlight(text, lang) do
|
||||
{:ok, highlight} = TreeSitter.highlight_html(text, lang || "plain")
|
||||
highlight = Autumn.highlight!(text, language: lang || "plain")
|
||||
|
||||
[_preamble, rest] = String.split(highlight, "<table>")
|
||||
[tbody, _rest] = String.split(rest, "</table>")
|
||||
|
||||
table = "<table>\n#{tbody}\n</table>"
|
||||
|
||||
{"code", [], [table], %{verbatim: true}}
|
||||
{"div", [], [highlight], %{verbatim: true}}
|
||||
end
|
||||
|
||||
def floki2earmark(list) when is_list(list) do
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
defmodule Lain.Static do
|
||||
def run(path) do
|
||||
path
|
||||
|> Path.expand()
|
||||
|> Path.join("static/**/*")
|
||||
|> Path.wildcard()
|
||||
|> Enum.each(fn path ->
|
||||
build_path = String.replace(path, "site", "priv")
|
||||
build_path = String.replace(path, "static", "build")
|
||||
|
||||
if File.dir?(path) do
|
||||
File.mkdir_p!(build_path)
|
||||
|
|
|
@ -2,7 +2,6 @@ defmodule Mix.Tasks.Lain.DevServer do
|
|||
use Mix.Task
|
||||
|
||||
def run(_args) do
|
||||
Application.put_env(:lain, :serve_endpoints, true, persistent: true)
|
||||
Mix.Tasks.Run.run(["--no-halt"])
|
||||
Lain.serve(".")
|
||||
end
|
||||
end
|
||||
|
|
13
mix.exs
13
mix.exs
|
@ -9,7 +9,7 @@ defmodule Lain.MixProject do
|
|||
start_permanent: Mix.env() == :prod,
|
||||
aliases: aliases(),
|
||||
deps: deps(),
|
||||
escript: [main_module: Lain.CLI, include_priv_for: [:castore]]
|
||||
escript: [main_module: Lain.CLI, include_priv_for: [:castore, :autumn]]
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -17,21 +17,21 @@ defmodule Lain.MixProject do
|
|||
def application do
|
||||
[
|
||||
mod: {Lain.Application, []},
|
||||
extra_applications: [:castore, :logger]
|
||||
extra_applications: [:castore, :logger, :autumn]
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help deps" to learn about dependencies.
|
||||
defp deps do
|
||||
[
|
||||
{:autumn, path: "~/projects/autumn"},
|
||||
{:yaml_elixir, "~> 2.9.0"},
|
||||
{:esbuild, "~> 0.7.1"},
|
||||
{:tailwind, "~> 0.2.1"},
|
||||
{:phoenix_live_view, "~> 1.0.0"},
|
||||
{:rustler, "~> 0.29.1"},
|
||||
{:tree_sitter, "~> 0.0.3"},
|
||||
{:earmark_parser, "~> 1.4"},
|
||||
{:earmark, "~> 1.4"},
|
||||
{:earmark_parser, "~> 1.4.43"},
|
||||
{:earmark, "~> 1.4.43"},
|
||||
{:floki, "~> 0.36"},
|
||||
{:html_sanitize_ex, "~> 1.4"},
|
||||
{:phoenix_html, "~> 3.3.2"},
|
||||
|
@ -47,7 +47,8 @@ defmodule Lain.MixProject do
|
|||
def aliases() do
|
||||
[
|
||||
"assets.build": ["esbuild default --minify", "tailwind default --minify"],
|
||||
serve: ["do esbuild serve --serve + tailwind default --watch"]
|
||||
serve: ["do esbuild serve --serve + tailwind default --watch"],
|
||||
install: ["escript.build", "escript.install"]
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
7
mix.lock
7
mix.lock
|
@ -1,8 +1,9 @@
|
|||
%{
|
||||
"autumn": {:hex, :autumn, "0.3.0", "5498696364c726563fc93f5f6d4bfc3739916cd29a63df8cbac3e957d00f53ac", [:mix], [{:rustler, "~> 0.29", [hex: :rustler, repo: "hexpm", optional: false]}, {:rustler_precompiled, "~> 0.6", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "cf78e150315cbe4b194f6ef1cfd9007db95ce47013c9a7e4305297ef3f17cbb0"},
|
||||
"bandit": {:hex, :bandit, "1.6.4", "59cbc8e02f84fcad967bfed6b8a8261821c93a7ec4f835b46d1846b1120a91ec", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "8e156c009a77bb100fd78d5408684d01df1526f549c42614f8f9f27f44f1f7a7"},
|
||||
"castore": {:hex, :castore, "1.0.11", "4bbd584741601eb658007339ea730b082cc61f3554cf2e8f39bf693a11b49073", [:mix], [], "hexpm", "e03990b4db988df56262852f20de0f659871c35154691427a5047f4967a16a62"},
|
||||
"castore": {:hex, :castore, "1.0.12", "053f0e32700cbec356280c0e835df425a3be4bc1e0627b714330ad9d0f05497f", [:mix], [], "hexpm", "3dca286b2186055ba0c9449b4e95b97bf1b57b47c1f2644555879e659960c224"},
|
||||
"earmark": {:hex, :earmark, "1.4.43", "2024a0e9fe9bd5ef78fb9c87517de6c6d7deaf1cffdf6572fac3dd49cb34c433", [:mix], [], "hexpm", "958011ea938bc4018797bda3f8d0c871ab04621785bedc1e7188fb079dea2f5b"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.35", "437773ca9384edf69830e26e9e7b2e0d22d2596c4a6b17094a3b29f01ea65bb8", [:mix], [], "hexpm", "8652ba3cb85608d0d7aa2d21b45c6fad4ddc9a1f9a1f1b30ca3a246f0acc33f6"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.43", "34b2f401fe473080e39ff2b90feb8ddfeef7639f8ee0bbf71bb41911831d77c5", [:mix], [], "hexpm", "970a3cd19503f5e8e527a190662be2cee5d98eed1ff72ed9b3d1a3d466692de8"},
|
||||
"esbuild": {:hex, :esbuild, "0.7.1", "fa0947e8c3c3c2f86c9bf7e791a0a385007ccd42b86885e8e893bdb6631f5169", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "66661cdf70b1378ee4dc16573fcee67750b59761b2605a0207c267ab9d19f13c"},
|
||||
"floki": {:hex, :floki, "0.37.0", "b83e0280bbc6372f2a403b2848013650b16640cd2470aea6701f0632223d719e", [:mix], [], "hexpm", "516a0c15a69f78c47dc8e0b9b3724b29608aa6619379f91b1ffa47109b5d0dd3"},
|
||||
"hpax": {:hex, :hpax, "1.0.2", "762df951b0c399ff67cc57c3995ec3cf46d696e41f0bba17da0518d94acd4aac", [:mix], [], "hexpm", "2f09b4c1074e0abd846747329eaa26d535be0eb3d189fa69d812bfb8bfefd32f"},
|
||||
|
@ -18,12 +19,12 @@
|
|||
"plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
|
||||
"rustler": {:hex, :rustler, "0.29.1", "880f20ae3027bd7945def6cea767f5257bc926f33ff50c0d5d5a5315883c084d", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "109497d701861bfcd26eb8f5801fe327a8eef304f56a5b63ef61151ff44ac9b6"},
|
||||
"rustler_precompiled": {:hex, :rustler_precompiled, "0.8.2", "5f25cbe220a8fac3e7ad62e6f950fcdca5a5a5f8501835d2823e8c74bf4268d5", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:rustler, "~> 0.23", [hex: :rustler, repo: "hexpm", optional: true]}], "hexpm", "63d1bd5f8e23096d1ff851839923162096364bac8656a4a3c00d1fff8e83ee0a"},
|
||||
"sitemapper": {:hex, :sitemapper, "0.7.0", "4aee7930327a9a01b1c9b81d1d42f60c1a295e9f420108eb2d130c317415abd7", [:mix], [{:ex_aws_s3, "~> 2.0", [hex: :ex_aws_s3, repo: "hexpm", optional: true]}, {:xml_builder, "~> 2.1", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "60f7a684e5e9fe7f10ac5b69f48b0be2bcbba995afafcb3c143fc0c8ef1f223f"},
|
||||
"tailwind": {:hex, :tailwind, "0.2.1", "83d8eadbe71a8e8f67861fe7f8d51658ecfb258387123afe4d9dc194eddc36b0", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "e8a13f6107c95f73e58ed1b4221744e1eb5a093cd1da244432067e19c8c9a277"},
|
||||
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
|
||||
"thousand_island": {:hex, :thousand_island, "1.3.9", "095db3e2650819443e33237891271943fad3b7f9ba341073947581362582ab5a", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "25ab4c07badadf7f87adb4ab414e0ed374e5f19e72503aa85132caa25776e54f"},
|
||||
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
|
||||
"tree_sitter": {:hex, :tree_sitter, "0.0.2", "33218eeb40bf897f84d163a07b2373742db7dfee2e6601a60b5733fc6f33656f", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.9", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "8bf71f50a7b1d0ac4b8936fc55d50a21386b8b319f3ceb6f59f1377314e8bb5d"},
|
||||
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
||||
"websock_adapter": {:hex, :websock_adapter, "0.5.8", "3b97dc94e407e2d1fc666b2fb9acf6be81a1798a2602294aac000260a7c4a47d", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "315b9a1865552212b5f35140ad194e67ce31af45bcee443d4ecb96b5fd3f3782"},
|
||||
"xml_builder": {:hex, :xml_builder, "2.2.0", "cc5f1eeefcfcde6e90a9b77fb6c490a20bc1b856a7010ce6396f6da9719cbbab", [:mix], [], "hexpm", "9d66d52fb917565d358166a4314078d39ef04d552904de96f8e73f68f64a62c9"},
|
||||
|
|
Loading…
Reference in a new issue