Compare commits
4 Commits
32d9fdf328
...
1abac25a0e
Author | SHA1 | Date |
---|---|---|
Ryan Rix | 1abac25a0e | |
Ryan Rix | 22de64460f | |
Ryan Rix | 2b8356513f | |
Ryan Rix | 20ea44391e |
|
@ -0,0 +1,109 @@
|
|||
:PROPERTIES:
|
||||
:ID: 20230303T100429.248407
|
||||
:END:
|
||||
#+TITLE: Arcology Elixir Backend Logic
|
||||
|
||||
#+AUTO_TANGLE: t
|
||||
|
||||
* Setting up the =Arcology= elixir module
|
||||
|
||||
This is a module, the submodules are where the interesting things happen. The module doc says what it does:
|
||||
|
||||
#+begin_src text :noweb-ref arcology.moduledoc
|
||||
Arcology keeps the contexts that define your domain
|
||||
and business logic.
|
||||
|
||||
Contexts are also responsible for managing your data, regardless
|
||||
if it comes from the database, an external API or others.
|
||||
#+end_src
|
||||
|
||||
#+begin_src elixir :tangle lib/arcology.ex :noweb yes
|
||||
defmodule Arcology do
|
||||
@moduledoc """
|
||||
<<arcology.moduledoc>>
|
||||
"""
|
||||
end
|
||||
#+end_src
|
||||
|
||||
* =Arcology.Application= Elixir Application Startup
|
||||
|
||||
#+begin_src elixir :tangle lib/arcology/application.ex :noweb yes
|
||||
defmodule Arcology.Application do
|
||||
@moduledoc false
|
||||
|
||||
use Application
|
||||
|
||||
<<start_2>>
|
||||
|
||||
<<config_change_3>>
|
||||
end
|
||||
#+end_src
|
||||
|
||||
So =Arcology.Application.start/2= is the entrypoint of the Phoenix [[https://hexdocs.pm/elixir/Application.html][OTP application]], it starts up a bunch of other *Supervised*[fn:1] Elixir processes and makes sure they keep running.
|
||||
|
||||
** =Arcology.Application.start/2=
|
||||
|
||||
We start the Ecto repository [[roam:Arcology.Repo]]:
|
||||
|
||||
#+begin_src elixir :noweb-ref app-children
|
||||
Arcology.Repo
|
||||
#+end_src
|
||||
|
||||
We start the PubSub messaging system:
|
||||
|
||||
#+begin_src elixir :noweb-ref app-children
|
||||
{Phoenix.PubSub, name: Arcology.PubSub}
|
||||
#+end_src
|
||||
|
||||
We start [[https://github.com/sneako/finch][Finch]], an HTTP client:
|
||||
|
||||
#+begin_src elixir :noweb-ref app-children
|
||||
{Finch, name: Arcology.Finch}
|
||||
#+end_src
|
||||
|
||||
We start the [[roam:ArcologyWeb.Endpoint]] which handles HTTP requests from the web.
|
||||
|
||||
#+begin_src elixir :noweb-ref app-children
|
||||
ArcologyWeb.Endpoint
|
||||
#+end_src
|
||||
|
||||
We will also start the =ArcologyWeb.Telemetry= server provided by Phoenix [n.b. this code block isn't directly included so that i can generate decent list-syntax without relying on metaprogramming or not being able to detangle this to my heart's content]
|
||||
|
||||
This supervisor is configured to only restart a single process when the process dies; for other applications you may want it to restart *all* children, or to only restart "younger" processes which may rely on state within the dead process. This is pretty simple for now. Check out [[https://hexdocs.pm/elixir/Supervisor.html][the docs]] if you care.
|
||||
|
||||
#+begin_src elixir :noweb-ref start_2 :noweb yes
|
||||
@impl true
|
||||
def start(_type, _args) do
|
||||
children = [
|
||||
ArcologyWeb.Telemetry
|
||||
, <<app-children>>
|
||||
]
|
||||
|
||||
opts = [strategy: :one_for_one, name: Arcology.Supervisor]
|
||||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
#+end_src
|
||||
|
||||
This =config_change= function is a stub that sends new configuration to the =ArcologyWeb.Endpoint= process when the appication is upgraded. I'll probably just restart the thing in place, but for highly-available OTP applications this sort of stuff is bread-and-butter.
|
||||
|
||||
#+begin_src elixir :noweb-ref config_change_3
|
||||
@impl true
|
||||
def config_change(changed, _new, removed) do
|
||||
ArcologyWeb.Endpoint.config_change(changed, removed)
|
||||
:ok
|
||||
end
|
||||
#+end_src
|
||||
|
||||
* =Arcology.Mailer=
|
||||
|
||||
This is a stub for now -- maybe i'll send mails for new posts in the future but *shrug*:
|
||||
|
||||
#+begin_src elixir :tangle lib/arcology/mailer.ex
|
||||
defmodule Arcology.Mailer do
|
||||
use Swoosh.Mailer, otp_app: :arcology
|
||||
end
|
||||
#+end_src
|
||||
|
||||
* Footnotes
|
||||
|
||||
[fn:1] Elixir is built on Erlang, and Erlang has a process-based Actor model, you can send messages to processes whose IDs you have. The Supervisor is responsible for starting and managing the lifecycle of these processes. See [[https://www.erlang.org/doc/design_principles/sup_princ.html][the OTP Design Principles]] doc.
|
|
@ -0,0 +1,177 @@
|
|||
:PROPERTIES:
|
||||
:ID: 20230303T095957.835101
|
||||
:ROAM_ALIASES: ArcologyWeb
|
||||
:END:
|
||||
#+TITLE: Arcology Web Elixir Application
|
||||
|
||||
* Setting up the =ArcologyWeb= module
|
||||
:PROPERTIES:
|
||||
:ID: 20230303T114356.700426
|
||||
:ROAM_ALIASES: ArcologyWeb
|
||||
:END:
|
||||
|
||||
Much of this is boilerplate which I include here only to understand and take apart how Phoenix operates. There's not a whole lot hiding "under the hood" compared to, say, Ruby on Rails, which I really appreciate, to be honest.
|
||||
|
||||
So starting with the moduledoc:
|
||||
|
||||
#+begin_src text :noweb-ref ArcologyWeb.moduledoc
|
||||
The entrypoint for defining your web interface, such
|
||||
as controllers, components, channels, and so on.
|
||||
|
||||
This can be used in your application as:
|
||||
|
||||
use ArcologyWeb, :controller
|
||||
use ArcologyWeb, :html
|
||||
|
||||
The definitions below will be executed for every controller,
|
||||
component, etc, so keep them short and clean, focused
|
||||
on imports, uses and aliases.
|
||||
|
||||
Do NOT define functions inside the quoted expressions
|
||||
below. Instead, define additional modules and import
|
||||
those modules here.
|
||||
#+end_src
|
||||
|
||||
This is pretty straightforward, right? Our controllers and views can include a bunch of standard behavior (auth, logging, rate limiting, etc) by invoking those =use= statements. There are a bunch of functions defined below which will be exposed in that fashion using this "magic" =__using__= macro:
|
||||
|
||||
#+begin_src elixir :noweb-ref ArcologyWeb.__using__
|
||||
@doc """
|
||||
When used, dispatch to the appropriate controller/view/etc.
|
||||
"""
|
||||
defmacro __using__(which) when is_atom(which) do
|
||||
apply(__MODULE__, which, [])
|
||||
end
|
||||
#+end_src
|
||||
|
||||
Some of the helpers include some extra helpers shared among them by "unquoting" a function which returns "quoted" =import= and =alias= statements -- this is the sort of indirection which makes sense in my Lisp brain, but it can be really off-putting to people who aren't exposed to this sort of pattern. The basic idea here is to provide those statements in the function which is "used in" rather than in the private helpers where they would be executed were they not quoted.
|
||||
|
||||
These functions import functionality for HTML rendering, [[https://hexdocs.pm/phoenix/1.7.0-rc.0/Phoenix.VerifiedRoutes.html][compile-time Verified Route]] generation, and translations:
|
||||
|
||||
#+begin_src elixir :noweb-ref quoted-helpers
|
||||
defp html_helpers do
|
||||
quote do
|
||||
# HTML escaping functionality
|
||||
import Phoenix.HTML
|
||||
# Core UI components and translation
|
||||
import ArcologyWeb.CoreComponents
|
||||
import ArcologyWeb.Gettext
|
||||
|
||||
# Shortcut for generating JS commands
|
||||
alias Phoenix.LiveView.JS
|
||||
|
||||
# Routes generation with the ~p sigil
|
||||
unquote(verified_routes())
|
||||
end
|
||||
end
|
||||
|
||||
def verified_routes do
|
||||
quote do
|
||||
use Phoenix.VerifiedRoutes,
|
||||
endpoint: ArcologyWeb.Endpoint,
|
||||
router: ArcologyWeb.Router,
|
||||
statics: ArcologyWeb.static_paths()
|
||||
end
|
||||
end
|
||||
#+end_src
|
||||
|
||||
Use'ing =:router= in [[roam:ArcologyWeb.Router]] lets me customize the behavior of the router by introducing [[https://hexdocs.pm/plug/readme.html][Plugs]]; I'll be adding a Plug to attempt to load Arcology pages rather than using a "greedy" route which I used in (for example) the FastAPI [[id:20220225T175638.482695][Arcology Domain Router]].
|
||||
|
||||
#+begin_src elixir :noweb-ref helpers
|
||||
def router do
|
||||
quote do
|
||||
use Phoenix.Router, helpers: false
|
||||
|
||||
# Import common connection and controller functions to use in pipelines
|
||||
import Plug.Conn
|
||||
import Phoenix.Controller
|
||||
import Phoenix.LiveView.Router
|
||||
end
|
||||
end
|
||||
#+end_src
|
||||
|
||||
Routing, controlling, viewing, etc, can all be skipped for =static_paths=, these are files that can just be served out of the filesystem where the application is built and bundled:
|
||||
|
||||
#+begin_src elixir :noweb-ref helpers
|
||||
def static_paths, do: ~w(assets fonts images favicon.ico robots.txt)
|
||||
#+end_src
|
||||
|
||||
The =:controller= helper sets up rendering rules, provides access to translations
|
||||
|
||||
#+begin_src elixir :noweb-ref helpers
|
||||
def controller do
|
||||
quote do
|
||||
use Phoenix.Controller,
|
||||
formats: [:html, :json],
|
||||
layouts: [html: ArcologyWeb.Layouts]
|
||||
|
||||
import Plug.Conn
|
||||
import ArcologyWeb.Gettext
|
||||
|
||||
unquote(verified_routes())
|
||||
end
|
||||
end
|
||||
#+end_src
|
||||
|
||||
The =:live_view=, =:live_component=, and =:html= helpers set up HTML rendering and dynamic LiveView components using the quoted helpers described above.
|
||||
|
||||
#+begin_src elixir :noweb-ref helpers
|
||||
def live_view do
|
||||
quote do
|
||||
use Phoenix.LiveView,
|
||||
layout: {ArcologyWeb.Layouts, :app}
|
||||
|
||||
unquote(html_helpers())
|
||||
end
|
||||
end
|
||||
|
||||
def live_component do
|
||||
quote do
|
||||
use Phoenix.LiveComponent
|
||||
|
||||
unquote(html_helpers())
|
||||
end
|
||||
end
|
||||
|
||||
def html do
|
||||
quote do
|
||||
use Phoenix.Component
|
||||
|
||||
# Import convenience functions from controllers
|
||||
import Phoenix.Controller,
|
||||
only: [get_csrf_token: 0, view_module: 1, view_template: 1]
|
||||
|
||||
# Include general helpers for rendering HTML
|
||||
unquote(html_helpers())
|
||||
end
|
||||
end
|
||||
|
||||
#+end_src
|
||||
|
||||
The =:channel= helper will provide =Phoenix.Channel= helpers to PubSub channels, if I decide to use them.
|
||||
|
||||
#+begin_src elixir :noweb-ref helpers
|
||||
def channel do
|
||||
quote do
|
||||
use Phoenix.Channel
|
||||
end
|
||||
end
|
||||
#+end_src
|
||||
|
||||
#+begin_src elixir :noweb yes :tangle lib/arcology_web.ex
|
||||
defmodule ArcologyWeb do
|
||||
@moduledoc """
|
||||
<<ArcologyWeb.moduledoc>>
|
||||
"""
|
||||
|
||||
<<helpers>>
|
||||
|
||||
<<quoted_helpers>>
|
||||
|
||||
<<ArcologyWeb.__using__>>
|
||||
end
|
||||
#+end_src
|
||||
|
||||
* =ArcologyWeb.Endpoint= helpers
|
||||
:PROPERTIES:
|
||||
:ID: 20230303T104626.041201
|
||||
:END:
|
|
@ -0,0 +1,51 @@
|
|||
# This file is responsible for configuring your application
|
||||
# and its dependencies with the aid of the Config module.
|
||||
#
|
||||
# This configuration file is loaded before any dependency and
|
||||
# is restricted to this project.
|
||||
|
||||
# General application configuration
|
||||
import Config
|
||||
|
||||
config :arcology,
|
||||
ecto_repos: [Arcology.Repo]
|
||||
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
url: [host: "localhost"],
|
||||
render_errors: [
|
||||
formats: [html: ArcologyWeb.ErrorHTML, json: ArcologyWeb.ErrorJSON],
|
||||
layout: false
|
||||
],
|
||||
pubsub_server: Arcology.PubSub,
|
||||
live_view: [signing_salt: "OgcteMC0"]
|
||||
|
||||
config :arcology, Arcology.Mailer, adapter: Swoosh.Adapters.Local
|
||||
|
||||
config :esbuild,
|
||||
version: "0.14.41",
|
||||
default: [
|
||||
args:
|
||||
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
|
||||
cd: Path.expand("../assets", __DIR__),
|
||||
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
|
||||
]
|
||||
|
||||
# Configure tailwind (the version is required)
|
||||
config :tailwind,
|
||||
version: "3.2.4",
|
||||
default: [
|
||||
args: ~w(
|
||||
--config=tailwind.config.js
|
||||
--input=css/app.css
|
||||
--output=../priv/static/assets/app.css
|
||||
),
|
||||
cd: Path.expand("../assets", __DIR__)
|
||||
]
|
||||
|
||||
config :logger, :console,
|
||||
format: "$time $metadata[$level] $message\n",
|
||||
metadata: [:request_id]
|
||||
|
||||
config :phoenix, :json_library, Jason
|
||||
|
||||
import_config "#{config_env()}.exs"
|
|
@ -0,0 +1,39 @@
|
|||
import Config
|
||||
|
||||
config :arcology, Arcology.Repo,
|
||||
database: Path.expand("../arcology.db", Path.dirname(__ENV__.file)),
|
||||
pool_size: 5,
|
||||
stacktrace: true,
|
||||
show_sensitive_data_on_connection_error: true
|
||||
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
# Binding to loopback ipv4 address prevents access from other machines.
|
||||
# Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
|
||||
http: [ip: {127, 0, 0, 1}, port: 4000],
|
||||
check_origin: false,
|
||||
code_reloader: true,
|
||||
debug_errors: true,
|
||||
secret_key_base: "PkJnuIpBpXQpUqGrc7ynUHYyXvAB40b03rjay/9WuKmzEN9H9GaELBdGOok2GQih",
|
||||
watchers: [
|
||||
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]},
|
||||
tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}
|
||||
]
|
||||
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
live_reload: [
|
||||
patterns: [
|
||||
~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
|
||||
~r"priv/gettext/.*(po)$",
|
||||
~r"lib/arcology_web/(controllers|live|components)/.*(ex|heex)$"
|
||||
]
|
||||
]
|
||||
|
||||
config :arcology, dev_routes: true
|
||||
|
||||
config :logger, :console, format: "[$level] $message\n"
|
||||
|
||||
config :phoenix, :stacktrace_depth, 20
|
||||
|
||||
config :phoenix, :plug_init_mode, :runtime
|
||||
|
||||
config :swoosh, :api_client, false
|
|
@ -0,0 +1,21 @@
|
|||
import Config
|
||||
|
||||
# For production, don't forget to configure the url host
|
||||
# to something meaningful, Phoenix uses this information
|
||||
# when generating URLs.
|
||||
|
||||
# Note we also include the path to a cache manifest
|
||||
# containing the digested version of static files. This
|
||||
# manifest is generated by the `mix phx.digest` task,
|
||||
# which you should run after static files are built and
|
||||
# before starting your production server.
|
||||
config :arcology, ArcologyWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json"
|
||||
|
||||
# Configures Swoosh API Client
|
||||
config :swoosh, api_client: Swoosh.ApiClient.Finch, finch_name: Arcology.Finch
|
||||
|
||||
# Do not print debug messages in production
|
||||
config :logger, level: :info
|
||||
|
||||
# Runtime production configuration, including reading
|
||||
# of environment variables, is done on config/runtime.exs.
|
|
@ -0,0 +1,36 @@
|
|||
if System.get_env("PHX_SERVER") do
|
||||
config :arcology, ArcologyWeb.Endpoint, server: true
|
||||
end
|
||||
|
||||
if config_env() == :prod do
|
||||
|
||||
database_path =
|
||||
System.get_env("DATABASE_PATH") ||
|
||||
raise """
|
||||
environment variable DATABASE_PATH is missing.
|
||||
For example: /etc/arcology/arcology.db
|
||||
"""
|
||||
|
||||
config :arcology, Arcology.Repo,
|
||||
database: database_path,
|
||||
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "5")
|
||||
|
||||
secret_key_base =
|
||||
System.get_env("SECRET_KEY_BASE") ||
|
||||
raise """
|
||||
environment variable SECRET_KEY_BASE is missing.
|
||||
You can generate one by calling: mix phx.gen.secret
|
||||
"""
|
||||
|
||||
host = System.get_env("PHX_HOST") || "example.com"
|
||||
port = String.to_integer(System.get_env("PORT") || "4000")
|
||||
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
url: [host: host, port: 443, scheme: "https"],
|
||||
http: [
|
||||
ip: {127, 0, 0, 1},
|
||||
port: port
|
||||
],
|
||||
secret_key_base: secret_key_base
|
||||
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
import Config
|
||||
|
||||
# Configure your database
|
||||
#
|
||||
# The MIX_TEST_PARTITION environment variable can be used
|
||||
# to provide built-in test partitioning in CI environment.
|
||||
# Run `mix help test` for more information.
|
||||
config :arcology, Arcology.Repo,
|
||||
database: Path.expand("../arcology_test.db", Path.dirname(__ENV__.file)),
|
||||
pool_size: 5,
|
||||
pool: Ecto.Adapters.SQL.Sandbox
|
||||
|
||||
# We don't run a server during test. If one is required,
|
||||
# you can enable the server option below.
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
http: [ip: {127, 0, 0, 1}, port: 4002],
|
||||
secret_key_base: "4EDyvZHi6tCmgax6tx/v9e6L9kQmXt8qnhsqYE78k7P82uy71Ge7Zl6jPMolA+RR",
|
||||
server: false
|
||||
|
||||
# In test we don't send emails.
|
||||
config :arcology, Arcology.Mailer, adapter: Swoosh.Adapters.Test
|
||||
|
||||
# Disable swoosh api client as it is only required for production adapters.
|
||||
config :swoosh, :api_client, false
|
||||
|
||||
# Print only warnings and errors during test
|
||||
config :logger, level: :warning
|
||||
|
||||
# Initialize plugs at runtime for faster test compilation
|
||||
config :phoenix, :plug_init_mode, :runtime
|
|
@ -0,0 +1,9 @@
|
|||
defmodule Arcology do
|
||||
@moduledoc """
|
||||
Arcology keeps the contexts that define your domain
|
||||
and business logic.
|
||||
|
||||
Contexts are also responsible for managing your data, regardless
|
||||
if it comes from the database, an external API or others.
|
||||
"""
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
defmodule Arcology.Application do
|
||||
@moduledoc false
|
||||
|
||||
use Application
|
||||
|
||||
@impl true
|
||||
def start(_type, _args) do
|
||||
children = [
|
||||
ArcologyWeb.Telemetry
|
||||
, Arcology.Repo
|
||||
, {Phoenix.PubSub, name: Arcology.PubSub}
|
||||
, {Finch, name: Arcology.Finch}
|
||||
, ArcologyWeb.Endpoint
|
||||
]
|
||||
|
||||
opts = [strategy: :one_for_one, name: Arcology.Supervisor]
|
||||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def config_change(changed, _new, removed) do
|
||||
ArcologyWeb.Endpoint.config_change(changed, removed)
|
||||
:ok
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
defmodule Arcology.Mailer do
|
||||
use Swoosh.Mailer, otp_app: :arcology
|
||||
end
|
|
@ -0,0 +1,113 @@
|
|||
defmodule ArcologyWeb do
|
||||
@moduledoc """
|
||||
The entrypoint for defining your web interface, such
|
||||
as controllers, components, channels, and so on.
|
||||
|
||||
This can be used in your application as:
|
||||
|
||||
use ArcologyWeb, :controller
|
||||
use ArcologyWeb, :html
|
||||
|
||||
The definitions below will be executed for every controller,
|
||||
component, etc, so keep them short and clean, focused
|
||||
on imports, uses and aliases.
|
||||
|
||||
Do NOT define functions inside the quoted expressions
|
||||
below. Instead, define additional modules and import
|
||||
those modules here.
|
||||
"""
|
||||
|
||||
def static_paths, do: ~w(assets fonts images favicon.ico robots.txt)
|
||||
|
||||
def router do
|
||||
quote do
|
||||
use Phoenix.Router, helpers: false
|
||||
|
||||
# Import common connection and controller functions to use in pipelines
|
||||
import Plug.Conn
|
||||
import Phoenix.Controller
|
||||
import Phoenix.LiveView.Router
|
||||
end
|
||||
end
|
||||
|
||||
def channel do
|
||||
quote do
|
||||
use Phoenix.Channel
|
||||
end
|
||||
end
|
||||
|
||||
def controller do
|
||||
quote do
|
||||
use Phoenix.Controller,
|
||||
formats: [:html, :json],
|
||||
layouts: [html: ArcologyWeb.Layouts]
|
||||
|
||||
import Plug.Conn
|
||||
import ArcologyWeb.Gettext
|
||||
|
||||
unquote(verified_routes())
|
||||
end
|
||||
end
|
||||
|
||||
def live_view do
|
||||
quote do
|
||||
use Phoenix.LiveView,
|
||||
layout: {ArcologyWeb.Layouts, :app}
|
||||
|
||||
unquote(html_helpers())
|
||||
end
|
||||
end
|
||||
|
||||
def live_component do
|
||||
quote do
|
||||
use Phoenix.LiveComponent
|
||||
|
||||
unquote(html_helpers())
|
||||
end
|
||||
end
|
||||
|
||||
def html do
|
||||
quote do
|
||||
use Phoenix.Component
|
||||
|
||||
# Import convenience functions from controllers
|
||||
import Phoenix.Controller,
|
||||
only: [get_csrf_token: 0, view_module: 1, view_template: 1]
|
||||
|
||||
# Include general helpers for rendering HTML
|
||||
unquote(html_helpers())
|
||||
end
|
||||
end
|
||||
|
||||
defp html_helpers do
|
||||
quote do
|
||||
# HTML escaping functionality
|
||||
import Phoenix.HTML
|
||||
# Core UI components and translation
|
||||
import ArcologyWeb.CoreComponents
|
||||
import ArcologyWeb.Gettext
|
||||
|
||||
# Shortcut for generating JS commands
|
||||
alias Phoenix.LiveView.JS
|
||||
|
||||
# Routes generation with the ~p sigil
|
||||
unquote(verified_routes())
|
||||
end
|
||||
end
|
||||
|
||||
def verified_routes do
|
||||
quote do
|
||||
use Phoenix.VerifiedRoutes,
|
||||
endpoint: ArcologyWeb.Endpoint,
|
||||
router: ArcologyWeb.Router,
|
||||
statics: ArcologyWeb.static_paths()
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
When used, dispatch to the appropriate controller/view/etc.
|
||||
"""
|
||||
defmacro __using__(which) when is_atom(which) do
|
||||
apply(__MODULE__, which, [])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,61 @@
|
|||
defmodule Arcology.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :arcology,
|
||||
version: "0.1.0",
|
||||
elixir: "~> 1.14",
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
start_permanent: Mix.env() == :prod,
|
||||
aliases: aliases(),
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
mod: {Arcology.Application, []},
|
||||
extra_applications: [:logger, :runtime_tools]
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
defp elixirc_paths(:test), do: ["lib", "test/support"]
|
||||
defp elixirc_paths(_), do: ["lib"]
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:phoenix, "~> 1.7.1"},
|
||||
{:phoenix_ecto, "~> 4.4"},
|
||||
{:ecto_sql, "~> 3.6"},
|
||||
{:ecto_sqlite3, ">= 0.0.0"},
|
||||
{:phoenix_html, "~> 3.3"},
|
||||
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
||||
{:phoenix_live_view, "~> 0.18.16"},
|
||||
{:floki, ">= 0.30.0", only: :test},
|
||||
{:phoenix_live_dashboard, "~> 0.7.2"},
|
||||
{:esbuild, "~> 0.5", runtime: Mix.env() == :dev},
|
||||
{:tailwind, "~> 0.1.8", runtime: Mix.env() == :dev},
|
||||
{:swoosh, "~> 1.3"},
|
||||
{:finch, "~> 0.13"},
|
||||
{:telemetry_metrics, "~> 0.6"},
|
||||
{:telemetry_poller, "~> 1.0"},
|
||||
{:gettext, "~> 0.20"},
|
||||
{:jason, "~> 1.2"},
|
||||
{:plug_cowboy, "~> 2.5"}
|
||||
]
|
||||
end
|
||||
|
||||
defp aliases do
|
||||
[
|
||||
setup: ["deps.get", "ecto.setup", "assets.setup", "assets.build"],
|
||||
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
|
||||
"ecto.reset": ["ecto.drop", "ecto.setup"],
|
||||
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
|
||||
"assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"],
|
||||
"assets.build": ["tailwind default", "esbuild default"],
|
||||
"assets.deploy": ["tailwind default --minify", "esbuild default --minify", "phx.digest"]
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
%{
|
||||
"castore": {:hex, :castore, "0.1.22", "4127549e411bedd012ca3a308dede574f43819fe9394254ca55ab4895abfa1a2", [:mix], [], "hexpm", "c17576df47eb5aa1ee40cc4134316a99f5cad3e215d5c77b8dd3cfef12a22cac"},
|
||||
"cc_precompiler": {:hex, :cc_precompiler, "0.1.6", "68894618428c8a4e7fcbc0b2e2dda0c19ca13f98b2507a2fcf813a72ca5a0723", [:mix], [{:elixir_make, "~> 0.7.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "238b56c19dfe679a371e604ef33d0371a858a414eeca3a2e09af8bd74178e00c"},
|
||||
"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.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"},
|
||||
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
|
||||
"ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [: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", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 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", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"},
|
||||
"ecto_sqlite3": {:hex, :ecto_sqlite3, "0.9.1", "6cb740afcb0af882cf9dfbac7ff8db863600d3bb24454c840d506e05b1508d6e", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:exqlite, "~> 0.9", [hex: :exqlite, repo: "hexpm", optional: false]}], "hexpm", "cc7664d9210c232370e67e89331056cf0a35e74862cd57e893e7035eacbd4afc"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.7.5", "784cc00f5fa24239067cc04d449437dcc5f59353c44eb08f188b2b146568738a", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "c3d63e8d5c92fa3880d89ecd41de59473fa2e83eeb68148155e25e8b95aa2887"},
|
||||
"esbuild": {:hex, :esbuild, "0.6.1", "a774bfa7b4512a1211bf15880b462be12a4c48ed753a170c68c63b2c95888150", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "569f7409fb5a932211573fc20e2a930a0d5cf3377c5b4f6506c651b1783a1678"},
|
||||
"expo": {:hex, :expo, "0.4.0", "bbe4bf455e2eb2ebd2f1e7d83530ce50fb9990eb88fc47855c515bfdf1c6626f", [:mix], [], "hexpm", "a8ed1683ec8b7c7fa53fd7a41b2c6935f539168a6bb0616d7fd6b58a36f3abf2"},
|
||||
"exqlite": {:hex, :exqlite, "0.13.5", "2904bdf1fe5fcb5c7e0d2e991178bb2b7c534c339bfa3e4966bf40e34fadf512", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "32fe5badecc3491975dbc39b1104e77cde35c23a9e1cb47ce9ee3b4945c90666"},
|
||||
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
|
||||
"finch": {:hex, :finch, "0.14.0", "619bfdee18fc135190bf590356c4bf5d5f71f916adb12aec94caa3fa9267a4bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5459acaf18c4fdb47a8c22fb3baff5d8173106217c8e56c5ba0b93e66501a8dd"},
|
||||
"floki": {:hex, :floki, "0.34.2", "5fad07ef153b3b8ec110b6b155ec3780c4b2c4906297d0b4be1a7162d04a7e02", [:mix], [], "hexpm", "26b9d50f0f01796bc6be611ca815c5e0de034d2128e39cc9702eee6b66a4d1c8"},
|
||||
"gettext": {:hex, :gettext, "0.22.1", "e7942988383c3d9eed4bdc22fc63e712b655ae94a672a27e4900e3d4a2c43581", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "ad105b8dab668ee3f90c0d3d94ba75e9aead27a62495c101d94f2657a190ac5d"},
|
||||
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
|
||||
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
|
||||
"mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"},
|
||||
"mint": {:hex, :mint, "1.5.0", "fa2d1ea301f5cc42f45c3fabbd268742a932be49c11c0f054af1dd67d3f7515e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "8a61c2d469c657f6cb76ea547d523c3a593d24901b1d97bf92bf4a83eaa2517b"},
|
||||
"nimble_options": {:hex, :nimble_options, "0.5.2", "42703307b924880f8c08d97719da7472673391905f528259915782bb346e0a1b", [:mix], [], "hexpm", "4da7f904b915fd71db549bcdc25f8d56f378ef7ae07dc1d372cbe72ba950dce0"},
|
||||
"nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
|
||||
"phoenix": {:hex, :phoenix, "1.7.1", "a029bde19d9c3b559e5c3d06c78b76e81396bedd456a6acedb42f9c7b2e535a9", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [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]}, {:websock_adapter, "~> 0.4", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "ea9d4a85c3592e37efa07d0dc013254fda445885facaefddcbf646375c116457"},
|
||||
"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.3.1", "4788757e804a30baac6b3fc9695bf5562465dd3f1da8eb8460ad5b404d9a2178", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bed1906edd4906a15fd7b412b85b05e521e1f67c9a85418c55999277e553d0d3"},
|
||||
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.7.2", "97cc4ff2dba1ebe504db72cb45098cb8e91f11160528b980bd282cc45c73b29c", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0e5fdf063c7a3b620c566a30fcf68b7ee02e5e46fe48ee46a6ec3ba382dc05b7"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.4.1", "2aff698f5e47369decde4357ba91fc9c37c6487a512b41732818f2204a8ef1d3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "9bffb834e7ddf08467fe54ae58b5785507aaba6255568ae22b4d46e2bb3615ab"},
|
||||
"phoenix_live_view": {:hex, :phoenix_live_view, "0.18.16", "781c6a3ac49e0451ca403848b40807171caea400896fe8ed8e5ddd6106ad5580", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "09e6ae2babe62f74bfcd1e3cac1a9b0e2c262557cc566300a843425c9cb6842a"},
|
||||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"},
|
||||
"phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"},
|
||||
"plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [: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", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"},
|
||||
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
|
||||
"swoosh": {:hex, :swoosh, "1.9.1", "0a5d7bf9954eb41d7e55525bc0940379982b090abbaef67cd8e1fd2ed7f8ca1a", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, 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", "76dffff3ffcab80f249d5937a592eaef7cc49ac6f4cdd27e622868326ed6371e"},
|
||||
"tailwind": {:hex, :tailwind, "0.1.10", "21ed80ae1f411f747ee513470578acaaa1d0eb40170005350c5b0b6d07e2d624", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "e0fc474dfa8ed7a4573851ac69c5fd3ca70fbb0a5bada574d1d657ebc6f2f1f1"},
|
||||
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
||||
"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"},
|
||||
"websock": {:hex, :websock, "0.4.3", "184ac396bdcd3dfceb5b74c17d221af659dd559a95b1b92041ecb51c9b728093", [:mix], [], "hexpm", "5e4dd85f305f43fd3d3e25d70bec4a45228dfed60f0f3b072d8eddff335539cf"},
|
||||
"websock_adapter": {:hex, :websock_adapter, "0.4.5", "30038a3715067f51a9580562c05a3a8d501126030336ffc6edb53bf57d6d2d26", [:mix], [{:bandit, "~> 0.6", [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.4", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "1d9812dc7e703c205049426fd4fe0852a247a825f91b099e53dc96f68bafe4c8"},
|
||||
}
|
|
@ -0,0 +1,584 @@
|
|||
{ lib, beamPackages, overrides ? (x: y: {}) }:
|
||||
|
||||
let
|
||||
buildRebar3 = lib.makeOverridable beamPackages.buildRebar3;
|
||||
buildMix = lib.makeOverridable beamPackages.buildMix;
|
||||
buildErlangMk = lib.makeOverridable beamPackages.buildErlangMk;
|
||||
|
||||
self = packages // (overrides self packages);
|
||||
|
||||
packages = with beamPackages; with self; {
|
||||
castore = buildMix rec {
|
||||
name = "castore";
|
||||
version = "0.1.22";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1b1cl89fzkykimxwgm8mwb9wmxcrd8qk8hfc83pa2npb8zgpcxf1";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
cc_precompiler = buildMix rec {
|
||||
name = "cc_precompiler";
|
||||
version = "0.1.6";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0370g10xg2xg14p3mjpf2jj5ia3i0cyz6kk03qvrlrzykp0md2r3";
|
||||
};
|
||||
|
||||
beamDeps = [ elixir_make ];
|
||||
};
|
||||
|
||||
connection = buildMix rec {
|
||||
name = "connection";
|
||||
version = "1.1.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1746n8ba11amp1xhwzp38yfii2h051za8ndxlwdykyqqljq1wb3j";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
cowboy = buildErlangMk rec {
|
||||
name = "cowboy";
|
||||
version = "2.9.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1phv0a1zbgk7imfgcm0dlacm7hbjcdygb0pqmx4s26jf9f9rywic";
|
||||
};
|
||||
|
||||
beamDeps = [ cowlib ranch ];
|
||||
};
|
||||
|
||||
cowboy_telemetry = buildRebar3 rec {
|
||||
name = "cowboy_telemetry";
|
||||
version = "0.4.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1pn90is3k9dq64wbijvzkqb6ldfqvwiqi7ymc8dx6ra5xv0vm63x";
|
||||
};
|
||||
|
||||
beamDeps = [ cowboy telemetry ];
|
||||
};
|
||||
|
||||
cowlib = buildRebar3 rec {
|
||||
name = "cowlib";
|
||||
version = "2.11.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1ac6pj3x4vdbsa8hvmbzpdfc4k0v1p102jbd39snai8wnah9sgib";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
db_connection = buildMix rec {
|
||||
name = "db_connection";
|
||||
version = "2.4.3";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "04iwywfqf8k125yfvm084l1mp0bcv82mwih7xlpb7kx61xdw29y1";
|
||||
};
|
||||
|
||||
beamDeps = [ connection telemetry ];
|
||||
};
|
||||
|
||||
decimal = buildMix rec {
|
||||
name = "decimal";
|
||||
version = "2.0.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0xzm8hfhn8q02rmg8cpgs68n5jz61wvqg7bxww9i1a6yanf6wril";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
ecto = buildMix rec {
|
||||
name = "ecto";
|
||||
version = "3.9.4";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0xgfz1pzylj22k0qa8zh4idvd4139b1lwnmq33na8fia2j69hpyy";
|
||||
};
|
||||
|
||||
beamDeps = [ decimal jason telemetry ];
|
||||
};
|
||||
|
||||
ecto_sql = buildMix rec {
|
||||
name = "ecto_sql";
|
||||
version = "3.9.2";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0w1zplm8ndf10dwxffg60iwzvbz3hyyiy761x91cvnwg6nsfxd8y";
|
||||
};
|
||||
|
||||
beamDeps = [ db_connection ecto telemetry ];
|
||||
};
|
||||
|
||||
ecto_sqlite3 = buildMix rec {
|
||||
name = "ecto_sqlite3";
|
||||
version = "0.9.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1z2apnn5w0z7jgl5gkb293kka2ngaq8372bywrq268qc47cn8xnc";
|
||||
};
|
||||
|
||||
beamDeps = [ decimal ecto ecto_sql exqlite ];
|
||||
};
|
||||
|
||||
elixir_make = buildMix rec {
|
||||
name = "elixir_make";
|
||||
version = "0.7.5";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "11r8maaqnpp2an0i8s7b7vla4gs7b7g43kcyv203iyljbj6kxmn3";
|
||||
};
|
||||
|
||||
beamDeps = [ castore ];
|
||||
};
|
||||
|
||||
esbuild = buildMix rec {
|
||||
name = "esbuild";
|
||||
version = "0.6.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0y0n79wb2lf60rjlynvw6zrmq38ajcm0xhizaw8j54sszc4p97sn";
|
||||
};
|
||||
|
||||
beamDeps = [ castore ];
|
||||
};
|
||||
|
||||
expo = buildMix rec {
|
||||
name = "expo";
|
||||
version = "0.4.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1wmbycv8mdfngxnn3c3bi8b3kx9md4n1p96p7yjpyz4bxj1idvd8";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
exqlite = buildMix rec {
|
||||
name = "exqlite";
|
||||
version = "0.13.5";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0rh6r52ljfzfx5yb874y7b13bpkwww2136y3vdsijjf3xjnmpzij";
|
||||
};
|
||||
|
||||
beamDeps = [ cc_precompiler db_connection elixir_make ];
|
||||
};
|
||||
|
||||
file_system = buildMix rec {
|
||||
name = "file_system";
|
||||
version = "0.2.10";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1p0myxmnjjds8bbg69dd6fvhk8q3n7lb78zd4qvmjajnzgdmw6a1";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
finch = buildMix rec {
|
||||
name = "finch";
|
||||
version = "0.14.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1pd805jyd4qbpb2md3kw443325yqynpkpyr2iixb9zf432psqnal";
|
||||
};
|
||||
|
||||
beamDeps = [ castore mime mint nimble_options nimble_pool telemetry ];
|
||||
};
|
||||
|
||||
floki = buildMix rec {
|
||||
name = "floki";
|
||||
version = "0.34.2";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1j6ilik6pviff34rrqr8456h7pp0qlash731pv36ny811w7xbf96";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
gettext = buildMix rec {
|
||||
name = "gettext";
|
||||
version = "0.22.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0pdcj2hmf9jgv40w3594lqksvbp9fnx98g8d1kwy73k6mf6mn45d";
|
||||
};
|
||||
|
||||
beamDeps = [ expo ];
|
||||
};
|
||||
|
||||
hpax = buildMix rec {
|
||||
name = "hpax";
|
||||
version = "0.1.2";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "04wci9ifsfyd2pbcrnpgh2aq0a8fi1lpkrzb91kz3x93b8yq91rc";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
jason = buildMix rec {
|
||||
name = "jason";
|
||||
version = "1.4.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0891p2yrg3ri04p302cxfww3fi16pvvw1kh4r91zg85jhl87k8vr";
|
||||
};
|
||||
|
||||
beamDeps = [ decimal ];
|
||||
};
|
||||
|
||||
mime = buildMix rec {
|
||||
name = "mime";
|
||||
version = "2.0.3";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0szzdfalafpawjrrwbrplhkgxjv8837mlxbkpbn5xlj4vgq0p8r7";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
mint = buildMix rec {
|
||||
name = "mint";
|
||||
version = "1.5.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0ysilbm86jmzjazrf78vj0j3sn9s7i97sm7afv5zcmy6d7ac4qca";
|
||||
};
|
||||
|
||||
beamDeps = [ castore hpax ];
|
||||
};
|
||||
|
||||
nimble_options = buildMix rec {
|
||||
name = "nimble_options";
|
||||
version = "0.5.2";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1q6wa2ljprybfb9w2zg0gbppiwsnimgw5kcvakdp3z8mp42gk9sd";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
nimble_pool = buildMix rec {
|
||||
name = "nimble_pool";
|
||||
version = "0.2.6";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0gv59waa505mz2gi956sj1aa6844c65w2dp2qh2jfgsx15am0w8w";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
phoenix = buildMix rec {
|
||||
name = "phoenix";
|
||||
version = "1.7.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0mv425f3fipnrgfyzjpshmc49njg4l9w03bxl3pkfbjrqf2lm7ga";
|
||||
};
|
||||
|
||||
beamDeps = [ castore jason phoenix_pubsub phoenix_template plug plug_cowboy plug_crypto telemetry websock_adapter ];
|
||||
};
|
||||
|
||||
phoenix_ecto = buildMix rec {
|
||||
name = "phoenix_ecto";
|
||||
version = "4.4.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1h9wnjmxns8y8dsr0r41ks66gscaqm7ivk4gsh5y07nkiralx1h9";
|
||||
};
|
||||
|
||||
beamDeps = [ ecto phoenix_html plug ];
|
||||
};
|
||||
|
||||
phoenix_html = buildMix rec {
|
||||
name = "phoenix_html";
|
||||
version = "3.3.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1lyhagjpg4lran6431csgkvf28g50mdvh4mlsxgs21j9vmp91ldy";
|
||||
};
|
||||
|
||||
beamDeps = [ plug ];
|
||||
};
|
||||
|
||||
phoenix_live_dashboard = buildMix rec {
|
||||
name = "phoenix_live_dashboard";
|
||||
version = "0.7.2";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1dq5vj1a6fzclr3fwj7y8rg2xq3yigvgqc3aaq664fvs7h3dypqf";
|
||||
};
|
||||
|
||||
beamDeps = [ ecto mime phoenix_live_view telemetry_metrics ];
|
||||
};
|
||||
|
||||
phoenix_live_reload = buildMix rec {
|
||||
name = "phoenix_live_reload";
|
||||
version = "1.4.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1aqm6sxy4ijd5gi8lmjmcaxal1smg2smibjlzrkq9w6xwwsbizwv";
|
||||
};
|
||||
|
||||
beamDeps = [ file_system phoenix ];
|
||||
};
|
||||
|
||||
phoenix_live_view = buildMix rec {
|
||||
name = "phoenix_live_view";
|
||||
version = "0.18.16";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0al4nsf5qhj3m0066mncawjjcb0fkcdaqg0yrnzp8bz6mcmsxrh9";
|
||||
};
|
||||
|
||||
beamDeps = [ jason phoenix phoenix_html phoenix_template telemetry ];
|
||||
};
|
||||
|
||||
phoenix_pubsub = buildMix rec {
|
||||
name = "phoenix_pubsub";
|
||||
version = "2.1.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1nfqrmbrq45if9pgk6g6vqiply2sxc40is3bfanphn7a3rnpqdl1";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
phoenix_template = buildMix rec {
|
||||
name = "phoenix_template";
|
||||
version = "1.0.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1vlkd4z2bxinczwcysydidpnh49rpxjihb5k3k4k8qr2yrwc0z8m";
|
||||
};
|
||||
|
||||
beamDeps = [ phoenix_html ];
|
||||
};
|
||||
|
||||
plug = buildMix rec {
|
||||
name = "plug";
|
||||
version = "1.14.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "056wkb1b17mh5h9ncs2vbswvpjsm2iqc580nmyrvgznlqwr080mz";
|
||||
};
|
||||
|
||||
beamDeps = [ mime plug_crypto telemetry ];
|
||||
};
|
||||
|
||||
plug_cowboy = buildMix rec {
|
||||
name = "plug_cowboy";
|
||||
version = "2.6.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "19jgv5dm53hv5aqgxxzr3fnrpgfll9ics199swp6iriwfl5z4g07";
|
||||
};
|
||||
|
||||
beamDeps = [ cowboy cowboy_telemetry plug ];
|
||||
};
|
||||
|
||||
plug_crypto = buildMix rec {
|
||||
name = "plug_crypto";
|
||||
version = "1.2.3";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "18plj2idhp3f0nmqyjjf2rzj849l3br0797m8ln20p5dqscj0rxm";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
ranch = buildRebar3 rec {
|
||||
name = "ranch";
|
||||
version = "1.8.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1rfz5ld54pkd2w25jadyznia2vb7aw9bclck21fizargd39wzys9";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
swoosh = buildMix rec {
|
||||
name = "swoosh";
|
||||
version = "1.9.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "07ipsrp34s18c9zd5kglqsdc8z7gxa9aadsrklj0zf6azzrzzpvn";
|
||||
};
|
||||
|
||||
beamDeps = [ cowboy finch jason mime plug_cowboy telemetry ];
|
||||
};
|
||||
|
||||
tailwind = buildMix rec {
|
||||
name = "tailwind";
|
||||
version = "0.1.10";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1wgiyb3fnmyns5sabbav1axhz9rwzp2nkb2i71bs9mwfz96lgz70";
|
||||
};
|
||||
|
||||
beamDeps = [ castore ];
|
||||
};
|
||||
|
||||
telemetry = buildRebar3 rec {
|
||||
name = "telemetry";
|
||||
version = "1.2.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1mgyx9zw92g6w8fp9pblm3b0bghwxwwcbslrixq23ipzisfwxnfs";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
telemetry_metrics = buildMix rec {
|
||||
name = "telemetry_metrics";
|
||||
version = "0.6.1";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1iilk2n75kn9i95fdp8mpxvn3rcn3ghln7p77cijqws13j3y1sbv";
|
||||
};
|
||||
|
||||
beamDeps = [ telemetry ];
|
||||
};
|
||||
|
||||
telemetry_poller = buildRebar3 rec {
|
||||
name = "telemetry_poller";
|
||||
version = "1.0.0";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "0vjgxkxn9ll1gc6xd8jh4b0ldmg9l7fsfg7w63d44gvcssplx8mk";
|
||||
};
|
||||
|
||||
beamDeps = [ telemetry ];
|
||||
};
|
||||
|
||||
websock = buildMix rec {
|
||||
name = "websock";
|
||||
version = "0.4.3";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1krralrzzpcf5l3kn3qgsvz8s8j59bn0pmr57qyzshsz61gxhkay";
|
||||
};
|
||||
|
||||
beamDeps = [];
|
||||
};
|
||||
|
||||
websock_adapter = buildMix rec {
|
||||
name = "websock_adapter";
|
||||
version = "0.4.5";
|
||||
|
||||
src = fetchHex {
|
||||
pkg = "${name}";
|
||||
version = "${version}";
|
||||
sha256 = "1j74my5zd5nwafg0j6zr4nl4g8jj13zd8vs295820g3hgvf1560x";
|
||||
};
|
||||
|
||||
beamDeps = [ plug plug_cowboy websock ];
|
||||
};
|
||||
};
|
||||
in self
|
||||
|
451
setup.org
451
setup.org
|
@ -2,6 +2,7 @@
|
|||
:ID: 20230302T132603.040866
|
||||
:END:
|
||||
#+TITLE: Arcology Phoenix Setup
|
||||
#+filetags: :Project:
|
||||
|
||||
#+ARCOLOGY_KEY: arcology/phx/setup
|
||||
#+ARCOLOGY_ALLOW_CRAWL: t
|
||||
|
@ -138,3 +139,453 @@ mixNixDeps = import ./mix.nix {
|
|||
});
|
||||
};
|
||||
#+end_src
|
||||
|
||||
* =mix.exs= project configuration
|
||||
|
||||
#+begin_src elixir :noweb-ref project
|
||||
def project do
|
||||
[
|
||||
app: :arcology,
|
||||
version: "0.1.0",
|
||||
elixir: "~> 1.14",
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
start_permanent: Mix.env() == :prod,
|
||||
aliases: aliases(),
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
#+end_src
|
||||
|
||||
This instructs Mix to load [[roam:Arcology.Application]] as the entrypoint:
|
||||
|
||||
#+begin_src elixir :noweb-ref application
|
||||
def application do
|
||||
[
|
||||
mod: {Arcology.Application, []},
|
||||
extra_applications: [:logger, :runtime_tools]
|
||||
]
|
||||
end
|
||||
#+end_src
|
||||
|
||||
Specifies which paths to compile per environment.
|
||||
|
||||
#+begin_src elixir :noweb-ref paths
|
||||
|
||||
defp elixirc_paths(:test), do: ["lib", "test/support"]
|
||||
defp elixirc_paths(_), do: ["lib"]
|
||||
#+end_src
|
||||
|
||||
Here's what we depend on:
|
||||
|
||||
#+begin_src elixir :noweb-ref deps
|
||||
defp deps do
|
||||
[
|
||||
{:phoenix, "~> 1.7.1"},
|
||||
{:phoenix_ecto, "~> 4.4"},
|
||||
{:ecto_sql, "~> 3.6"},
|
||||
{:ecto_sqlite3, ">= 0.0.0"},
|
||||
{:phoenix_html, "~> 3.3"},
|
||||
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
||||
{:phoenix_live_view, "~> 0.18.16"},
|
||||
{:floki, ">= 0.30.0", only: :test},
|
||||
{:phoenix_live_dashboard, "~> 0.7.2"},
|
||||
{:esbuild, "~> 0.5", runtime: Mix.env() == :dev},
|
||||
{:tailwind, "~> 0.1.8", runtime: Mix.env() == :dev},
|
||||
{:swoosh, "~> 1.3"},
|
||||
{:finch, "~> 0.13"},
|
||||
{:telemetry_metrics, "~> 0.6"},
|
||||
{:telemetry_poller, "~> 1.0"},
|
||||
{:gettext, "~> 0.20"},
|
||||
{:jason, "~> 1.2"},
|
||||
{:plug_cowboy, "~> 2.5"}
|
||||
]
|
||||
end
|
||||
#+end_src
|
||||
|
||||
Aliases are shortcuts or tasks specific to the current project.
|
||||
For example, to install project dependencies and perform other setup tasks, run [[shell:mix setup]]. See [[https://hexdocs.pm/mix/1.12/Mix.html#module-aliases][the documentation]] for `Mix` for more info on aliases.
|
||||
|
||||
#+begin_src elixir :noweb-ref aliases
|
||||
defp aliases do
|
||||
[
|
||||
setup: ["deps.get", "ecto.setup", "assets.setup", "assets.build"],
|
||||
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
|
||||
"ecto.reset": ["ecto.drop", "ecto.setup"],
|
||||
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
|
||||
"assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"],
|
||||
"assets.build": ["tailwind default", "esbuild default"],
|
||||
"assets.deploy": ["tailwind default --minify", "esbuild default --minify", "phx.digest"]
|
||||
]
|
||||
end
|
||||
#+end_src
|
||||
|
||||
#+begin_src elixir :tangle mix.exs :noweb yes
|
||||
defmodule Arcology.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
<<project>>
|
||||
|
||||
<<application>>
|
||||
|
||||
<<paths>>
|
||||
|
||||
<<deps>>
|
||||
|
||||
<<aliases>>
|
||||
end
|
||||
#+end_src
|
||||
|
||||
* Runtime Project Configuration
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
# This file is responsible for configuring your application
|
||||
# and its dependencies with the aid of the Config module.
|
||||
#
|
||||
# This configuration file is loaded before any dependency and
|
||||
# is restricted to this project.
|
||||
|
||||
# General application configuration
|
||||
import Config
|
||||
#+end_src
|
||||
|
||||
Tell Phoenix to load [[roam:Arcology.Repo]]
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
config :arcology,
|
||||
ecto_repos: [Arcology.Repo]
|
||||
#+end_src
|
||||
|
||||
Configure [[id:20230303T104626.041201][=ArcologyWeb.Endpoint=]], instruct it to use =Arcology.PubSub= as its message-passing layer.
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
url: [host: "localhost"],
|
||||
render_errors: [
|
||||
formats: [html: ArcologyWeb.ErrorHTML, json: ArcologyWeb.ErrorJSON],
|
||||
layout: false
|
||||
],
|
||||
pubsub_server: Arcology.PubSub,
|
||||
live_view: [signing_salt: "OgcteMC0"]
|
||||
#+end_src
|
||||
|
||||
Configures the mailer
|
||||
|
||||
By default it uses the "Local" adapter which stores the emails
|
||||
locally. You can see the emails in your browser, at "/dev/mailbox".
|
||||
|
||||
For production it's recommended to configure a different adapter
|
||||
at the `config/runtime.exs`.
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
config :arcology, Arcology.Mailer, adapter: Swoosh.Adapters.Local
|
||||
#+end_src
|
||||
|
||||
Configure =esbuild= for Javascript packaging. Sure beats a webpack setup!! I hope!!!!
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
config :esbuild,
|
||||
version: "0.14.41",
|
||||
default: [
|
||||
args:
|
||||
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
|
||||
cd: Path.expand("../assets", __DIR__),
|
||||
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
|
||||
]
|
||||
#+end_src
|
||||
|
||||
Configure Tailwind for components CSS; I might just ship the same 40 CSS rules I've been using for a while, though, tbh. This stuff is auto-generated:
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
# Configure tailwind (the version is required)
|
||||
config :tailwind,
|
||||
version: "3.2.4",
|
||||
default: [
|
||||
args: ~w(
|
||||
--config=tailwind.config.js
|
||||
--input=css/app.css
|
||||
--output=../priv/static/assets/app.css
|
||||
),
|
||||
cd: Path.expand("../assets", __DIR__)
|
||||
]
|
||||
#+end_src
|
||||
|
||||
Configures Elixir's Logger:
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
config :logger, :console,
|
||||
format: "$time $metadata[$level] $message\n",
|
||||
metadata: [:request_id]
|
||||
#+end_src
|
||||
|
||||
Use [[https://github.com/michalmuskala/jason][Jason]] for JSON parsing in Phoenix; in the past I used Poison which require a NIF, but this seems like a good middle-ground between fast and cheap.
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
config :phoenix, :json_library, Jason
|
||||
#+end_src
|
||||
|
||||
Import environment specific config. This must remain at the bottom of this file so it overrides the configuration defined above.
|
||||
|
||||
#+begin_src elixir :tangle config/config.exs
|
||||
import_config "#{config_env()}.exs"
|
||||
#+end_src
|
||||
|
||||
** Dev
|
||||
|
||||
This will override the code in the parent =config.exs=.
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
import Config
|
||||
#+end_src
|
||||
|
||||
In production this will read an environment variable, but in dev we can just use the local directory to store the [[id:arcology/arroyo-page][Arroyo Arcology Generator]]'s DB.
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
config :arcology, Arcology.Repo,
|
||||
database: Path.expand("../arcology.db", Path.dirname(__ENV__.file)),
|
||||
pool_size: 5,
|
||||
stacktrace: true,
|
||||
show_sensitive_data_on_connection_error: true
|
||||
#+end_src
|
||||
|
||||
Dev build will bind to [[http://localhost:4000]] and have debug helpers installed code reloading enabled for Elixir, CSS, and Javascript.
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
# Binding to loopback ipv4 address prevents access from other machines.
|
||||
# Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
|
||||
http: [ip: {127, 0, 0, 1}, port: 4000],
|
||||
check_origin: false,
|
||||
code_reloader: true,
|
||||
debug_errors: true,
|
||||
secret_key_base: "PkJnuIpBpXQpUqGrc7ynUHYyXvAB40b03rjay/9WuKmzEN9H9GaELBdGOok2GQih",
|
||||
watchers: [
|
||||
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]},
|
||||
tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}
|
||||
]
|
||||
#+end_src
|
||||
|
||||
Phoenix's LiveReload is pretty slick -- it will automatically reload your browser page if CSS, JS, or Elixir Web modules, etc are changed:
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
live_reload: [
|
||||
patterns: [
|
||||
~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
|
||||
~r"priv/gettext/.*(po)$",
|
||||
~r"lib/arcology_web/(controllers|live|components)/.*(ex|heex)$"
|
||||
]
|
||||
]
|
||||
#+end_src
|
||||
|
||||
Enable dev routes for dashboard and mailbox
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
config :arcology, dev_routes: true
|
||||
#+end_src
|
||||
|
||||
Do not include metadata nor timestamps in development logs
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
config :logger, :console, format: "[$level] $message\n"
|
||||
#+end_src
|
||||
|
||||
Set a higher stacktrace during development. The auto-generated comment says "Avoid configuring such in production as building large stacktraces may be expensive."
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
config :phoenix, :stacktrace_depth, 20
|
||||
#+end_src
|
||||
|
||||
Initialize plugs at runtime for faster development compilation:
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
config :phoenix, :plug_init_mode, :runtime
|
||||
#+end_src
|
||||
|
||||
Disable [[https://github.com/swoosh/swoosh][swoosh]] api client as it is only required for production adapters, this is for the Mailer, and I probably don't care to set this up in prod, but yanno...
|
||||
|
||||
#+begin_src elixir :tangle config/dev.exs
|
||||
config :swoosh, :api_client, false
|
||||
#+end_src
|
||||
|
||||
** Test
|
||||
|
||||
I promise myself I'll figure out how to write tests for Arcology this time around.............
|
||||
|
||||
#+begin_src elixir :tangle config/test.exs
|
||||
import Config
|
||||
|
||||
# Configure your database
|
||||
#
|
||||
# The MIX_TEST_PARTITION environment variable can be used
|
||||
# to provide built-in test partitioning in CI environment.
|
||||
# Run `mix help test` for more information.
|
||||
config :arcology, Arcology.Repo,
|
||||
database: Path.expand("../arcology_test.db", Path.dirname(__ENV__.file)),
|
||||
pool_size: 5,
|
||||
pool: Ecto.Adapters.SQL.Sandbox
|
||||
|
||||
# We don't run a server during test. If one is required,
|
||||
# you can enable the server option below.
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
http: [ip: {127, 0, 0, 1}, port: 4002],
|
||||
secret_key_base: "4EDyvZHi6tCmgax6tx/v9e6L9kQmXt8qnhsqYE78k7P82uy71Ge7Zl6jPMolA+RR",
|
||||
server: false
|
||||
|
||||
# In test we don't send emails.
|
||||
config :arcology, Arcology.Mailer, adapter: Swoosh.Adapters.Test
|
||||
|
||||
# Disable swoosh api client as it is only required for production adapters.
|
||||
config :swoosh, :api_client, false
|
||||
|
||||
# Print only warnings and errors during test
|
||||
config :logger, level: :warning
|
||||
|
||||
# Initialize plugs at runtime for faster test compilation
|
||||
config :phoenix, :plug_init_mode, :runtime
|
||||
#+end_src
|
||||
|
||||
** NEXT Prod
|
||||
|
||||
This is mostly overridden by the runtime configuration below.
|
||||
|
||||
#+begin_src elixir :tangle config/prod.exs
|
||||
import Config
|
||||
|
||||
# For production, don't forget to configure the url host
|
||||
# to something meaningful, Phoenix uses this information
|
||||
# when generating URLs.
|
||||
|
||||
# Note we also include the path to a cache manifest
|
||||
# containing the digested version of static files. This
|
||||
# manifest is generated by the `mix phx.digest` task,
|
||||
# which you should run after static files are built and
|
||||
# before starting your production server.
|
||||
config :arcology, ArcologyWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json"
|
||||
|
||||
# Configures Swoosh API Client
|
||||
config :swoosh, api_client: Swoosh.ApiClient.Finch, finch_name: Arcology.Finch
|
||||
|
||||
# Do not print debug messages in production
|
||||
config :logger, level: :info
|
||||
|
||||
# Runtime production configuration, including reading
|
||||
# of environment variables, is done on config/runtime.exs.
|
||||
#+end_src
|
||||
|
||||
** Runtime
|
||||
|
||||
These helpers are used to set up the process with environment variables at runtime. These will be important when it comes to deploying Arcology on [[id:20211120T220054.226284][the Wobserver]].
|
||||
|
||||
Only start the web server if =PHX_SERVER= is set; this is done automatically by the =bin/server= wrapper script installed by =mix phx.gen.release=.
|
||||
|
||||
#+begin_src elixir :tangle config/runtime.exs
|
||||
if System.get_env("PHX_SERVER") do
|
||||
config :arcology, ArcologyWeb.Endpoint, server: true
|
||||
end
|
||||
#+end_src
|
||||
|
||||
Only =prod= is runtime configured:
|
||||
|
||||
#+begin_src elixir :tangle config/runtime.exs
|
||||
if config_env() == :prod do
|
||||
#+end_src
|
||||
|
||||
The database is pointed to with =DATABASE_PATH=:
|
||||
|
||||
#+begin_src elixir :tangle config/runtime.exs
|
||||
database_path =
|
||||
System.get_env("DATABASE_PATH") ||
|
||||
raise """
|
||||
environment variable DATABASE_PATH is missing.
|
||||
For example: /etc/arcology/arcology.db
|
||||
"""
|
||||
|
||||
config :arcology, Arcology.Repo,
|
||||
database: database_path,
|
||||
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "5")
|
||||
#+end_src
|
||||
|
||||
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 want to use a different value for prod and you most likely don't want to check this value into version control, so we use an environment variable instead.
|
||||
|
||||
#+begin_src elixir :tangle config/runtime.exs
|
||||
secret_key_base =
|
||||
System.get_env("SECRET_KEY_BASE") ||
|
||||
raise """
|
||||
environment variable SECRET_KEY_BASE is missing.
|
||||
You can generate one by calling: mix phx.gen.secret
|
||||
"""
|
||||
#+end_src
|
||||
|
||||
=PHX_HOST= and =PORT= are used to configure the route/URL generation. The app is configured to listen only to the loopback IPv4 interface since [[id:e4998eda-d14a-48ee-9661-3d7d1bead53c][Nginx]] will be handling the actual edge and SSL and whatnot. Otherwise it would be configured according to [[https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html][Plug.Cowboy]] documentation.
|
||||
|
||||
#+begin_src elixir :tangle config/runtime.exs
|
||||
host = System.get_env("PHX_HOST") || "example.com"
|
||||
port = String.to_integer(System.get_env("PORT") || "4000")
|
||||
|
||||
config :arcology, ArcologyWeb.Endpoint,
|
||||
url: [host: host, port: 443, scheme: "https"],
|
||||
http: [
|
||||
ip: {127, 0, 0, 1},
|
||||
port: port
|
||||
],
|
||||
secret_key_base: secret_key_base
|
||||
|
||||
#+end_src
|
||||
|
||||
These aren't used right now:
|
||||
|
||||
#+begin_src elixir
|
||||
# ## SSL Support
|
||||
#
|
||||
# To get SSL working, you will need to add the `https` key
|
||||
# to your endpoint configuration:
|
||||
#
|
||||
# config :arcology, ArcologyWeb.Endpoint,
|
||||
# https: [
|
||||
# ...,
|
||||
# port: 443,
|
||||
# cipher_suite: :strong,
|
||||
# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
|
||||
# certfile: System.get_env("SOME_APP_SSL_CERT_PATH")
|
||||
# ]
|
||||
#
|
||||
# The `cipher_suite` is set to `:strong` to support only the
|
||||
# latest and more secure SSL ciphers. This means old browsers
|
||||
# and clients may not be supported. You can set it to
|
||||
# `:compatible` for wider support.
|
||||
#
|
||||
# `:keyfile` and `:certfile` expect an absolute path to the key
|
||||
# and cert in disk or a relative path inside priv, for example
|
||||
# "priv/ssl/server.key". For all supported SSL configuration
|
||||
# options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1
|
||||
#
|
||||
# We also recommend setting `force_ssl` in your endpoint, ensuring
|
||||
# no data is ever sent via http, always redirecting to https:
|
||||
#
|
||||
# config :arcology, ArcologyWeb.Endpoint,
|
||||
# force_ssl: [hsts: true]
|
||||
#
|
||||
# Check `Plug.SSL` for all available options in `force_ssl`.
|
||||
|
||||
# ## Configuring the mailer
|
||||
#
|
||||
# In production you need to configure the mailer to use a different adapter.
|
||||
# Also, you may need to configure the Swoosh API client of your choice if you
|
||||
# are not using SMTP. Here is an example of the configuration:
|
||||
#
|
||||
# config :arcology, Arcology.Mailer,
|
||||
# adapter: Swoosh.Adapters.Mailgun,
|
||||
# api_key: System.get_env("MAILGUN_API_KEY"),
|
||||
# domain: System.get_env("MAILGUN_DOMAIN")
|
||||
#
|
||||
# For this example you need include a HTTP client required by Swoosh API client.
|
||||
# Swoosh supports Hackney and Finch out of the box:
|
||||
#
|
||||
# config :swoosh, :api_client, Swoosh.ApiClient.Hackney
|
||||
#
|
||||
# See https://hexdocs.pm/swoosh/Swoosh.html#module-installation for details.
|
||||
#+end_src
|
||||
|
||||
#+begin_src elixir :tangle config/runtime.exs
|
||||
end
|
||||
#+end_src
|
||||
|
|
Loading…
Reference in New Issue