From 80b7fc3ea7defc823e4097693e4edbd0216a42e7 Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Wed, 12 Feb 2025 17:38:48 -0500 Subject: [PATCH] chore(tasks): make it work on umbrella child apps (#757) --- lib/beacon/igniter.ex | 9 ++ lib/mix/tasks/beacon.gen.proxy_endpoint.ex | 112 ++++++++++++-------- lib/mix/tasks/beacon.gen.site.ex | 17 ++- lib/mix/tasks/beacon.gen.tailwind_config.ex | 13 +++ lib/mix/tasks/beacon.install.ex | 15 ++- mix.exs | 2 +- mix.lock | 8 +- 7 files changed, 125 insertions(+), 51 deletions(-) diff --git a/lib/beacon/igniter.ex b/lib/beacon/igniter.ex index a8ae4a5c..1cae236c 100644 --- a/lib/beacon/igniter.ex +++ b/lib/beacon/igniter.ex @@ -88,5 +88,14 @@ if Code.ensure_loaded?(Igniter) do |> Rewrite.Source.diff() |> IO.iodata_to_binary() end + + def config_file_path(igniter, file_name) do + case igniter |> Igniter.Project.Application.config_path() |> Path.split() do + [path] -> [path] + path -> Enum.drop(path, -1) + end + |> Path.join() + |> Path.join(file_name) + end end end diff --git a/lib/mix/tasks/beacon.gen.proxy_endpoint.ex b/lib/mix/tasks/beacon.gen.proxy_endpoint.ex index 1318a5b8..0e6a68ab 100644 --- a/lib/mix/tasks/beacon.gen.proxy_endpoint.ex +++ b/lib/mix/tasks/beacon.gen.proxy_endpoint.ex @@ -43,6 +43,9 @@ if Code.ensure_loaded?(Igniter) do @moduledoc __MODULE__.Docs.long_doc() + @impl Igniter.Mix.Task + def supports_umbrella?, do: true + @impl Igniter.Mix.Task def info(_argv, _composing_task) do %Igniter.Mix.Task.Info{ @@ -60,6 +63,16 @@ if Code.ensure_loaded?(Igniter) do @impl Igniter.Mix.Task def igniter(igniter) do + if Mix.Project.umbrella?() do + Mix.shell().error(""" + Running 'mix beacon.gen.proxy_endpoint' in the root of Umbrella apps is not supported yet. + + Please execute that task inside a child app. + """) + + exit({:shutdown, 1}) + end + options = igniter.args.options proxy_endpoint_module_name = Igniter.Libs.Phoenix.web_module_name(igniter, "ProxyEndpoint") @@ -85,11 +98,6 @@ if Code.ensure_loaded?(Igniter) do |> add_secret_key_base_to_dev_exs(secret_key_base) |> update_existing_endpoints(otp_app, existing_endpoints) |> configure_proxy_endpoint(otp_app, proxy_endpoint_module_name) - |> Igniter.add_notice(""" - ProxyEndpoint generated successfully. - - This enables your application to serve sites at multiple hosts, each with their own Endpoint. - """) end end @@ -107,7 +115,14 @@ if Code.ensure_loaded?(Igniter) do end defp add_signing_salt_to_config_exs(igniter, signing_salt) do - Igniter.update_elixir_file(igniter, "config/config.exs", fn zipper -> + default = + """ + import Config + + signing_salt = \"#{signing_salt}\" + """ + + Igniter.create_or_update_elixir_file(igniter, Beacon.Igniter.config_file_path(igniter, "config.exs"), default, fn zipper -> case Beacon.Igniter.move_to_variable(zipper, :signing_salt) do {:ok, _already_exists} -> zipper @@ -120,7 +135,14 @@ if Code.ensure_loaded?(Igniter) do end defp add_secret_key_base_to_dev_exs(igniter, secret_key_base) do - Igniter.update_elixir_file(igniter, "config/dev.exs", fn zipper -> + default = + """ + import Config + + secret_key_base = \"#{secret_key_base}\" + """ + + Igniter.create_or_update_elixir_file(igniter, Beacon.Igniter.config_file_path(igniter, "dev.exs"), default, fn zipper -> case Beacon.Igniter.move_to_variable(zipper, :secret_key_base) do {:ok, _already_exists} -> zipper @@ -149,7 +171,8 @@ if Code.ensure_loaded?(Igniter) do signing_salt: signing_salt, same_site: "#{session_same_site}" ] - """)} + """)}, + after: &match?({:=, _, [{:signing_salt, _, _}, _]}, &1.node) ) end @@ -157,39 +180,35 @@ if Code.ensure_loaded?(Igniter) do pubsub = Igniter.Project.Module.module_name(igniter, "PubSub") igniter - |> Igniter.update_elixir_file("config/config.exs", fn zipper -> - {:ok, - zipper - |> Beacon.Igniter.move_to_variable!(:signing_salt) - |> Igniter.Project.Config.modify_configuration_code( - [proxy_endpoint_module_name], - otp_app, - Sourceror.parse_string!(""" - [ - adapter: Bandit.PhoenixAdapter, - pubsub_server: #{inspect(pubsub)}, - live_view: [signing_salt: signing_salt] - ] - """) - )} - end) - |> Igniter.update_elixir_file("config/dev.exs", fn zipper -> - {:ok, - zipper - |> Beacon.Igniter.move_to_variable!(:secret_key_base) - |> Igniter.Project.Config.modify_configuration_code( - [proxy_endpoint_module_name], - otp_app, - Sourceror.parse_string!(""" - [ - http: [ip: {127, 0, 0, 1}, port: 4000], - check_origin: false, - debug_errors: true, - secret_key_base: secret_key_base - ] - """) - )} - end) + |> Igniter.Project.Config.configure( + "config.exs", + otp_app, + [proxy_endpoint_module_name], + {:code, + Sourceror.parse_string!(""" + [ + adapter: Bandit.PhoenixAdapter, + pubsub_server: #{inspect(pubsub)}, + live_view: [signing_salt: signing_salt] + ] + """)}, + after: &match?({:=, _, [{:signing_salt, _, _}, _]}, &1.node) + ) + |> Igniter.Project.Config.configure( + "dev.exs", + otp_app, + [proxy_endpoint_module_name], + {:code, + Sourceror.parse_string!(""" + [ + http: [ip: {127, 0, 0, 1}, port: 4000], + check_origin: false, + debug_errors: true, + secret_key_base: secret_key_base + ] + """)}, + after: &match?({:=, _, [{:secret_key_base, _, _}, _]}, &1.node) + ) |> Igniter.Project.Config.configure_runtime_env( :prod, otp_app, @@ -229,9 +248,16 @@ if Code.ensure_loaded?(Igniter) do "config.exs", otp_app, [endpoint, :live_view, :signing_salt], - {:code, Sourceror.parse_string!("signing_salt")} + {:code, Sourceror.parse_string!("signing_salt")}, + after: &match?({:=, _, [{:signing_salt, _, _}, _]}, &1.node) + ) + |> Igniter.Project.Config.configure( + "dev.exs", + otp_app, + [endpoint, :secret_key_base], + {:code, Sourceror.parse_string!("secret_key_base")}, + after: &match?({:=, _, [{:secret_key_base, _, _}, _]}, &1.node) ) - |> Igniter.Project.Config.configure("dev.exs", otp_app, [endpoint, :secret_key_base], {:code, Sourceror.parse_string!("secret_key_base")}) |> Igniter.Project.Config.configure("dev.exs", otp_app, [endpoint, :http], [], updater: fn zipper -> if port_matches_value?(zipper, 4000) do diff --git a/lib/mix/tasks/beacon.gen.site.ex b/lib/mix/tasks/beacon.gen.site.ex index 93fbaaf5..5a8126a4 100644 --- a/lib/mix/tasks/beacon.gen.site.ex +++ b/lib/mix/tasks/beacon.gen.site.ex @@ -56,6 +56,9 @@ if Code.ensure_loaded?(Igniter) do @test? Beacon.Config.env_test?() + @impl Igniter.Mix.Task + def supports_umbrella?, do: true + @impl Igniter.Mix.Task def info(_argv, _composing_task) do %Igniter.Mix.Task.Info{ @@ -79,6 +82,16 @@ if Code.ensure_loaded?(Igniter) do @impl Igniter.Mix.Task def igniter(igniter) do + if Mix.Project.umbrella?() do + Mix.shell().error(""" + Running 'mix beacon.gen.site' in the root of Umbrella apps is not supported yet. + + Please execute that task inside a child app. + """) + + exit({:shutdown, 1}) + end + options = igniter.args.options argv = igniter.args.argv @@ -390,7 +403,7 @@ if Code.ensure_loaded?(Igniter) do &if(Igniter.Project.Config.configures_key?(&1, "config.exs", otp_app, new_endpoint), do: &1, else: - Igniter.update_elixir_file(&1, "config/config.exs", fn zipper -> + Igniter.update_elixir_file(&1, Beacon.Igniter.config_file_path(igniter, "config.exs"), fn zipper -> {:ok, zipper |> Beacon.Igniter.move_to_variable!(:signing_salt) @@ -417,7 +430,7 @@ if Code.ensure_loaded?(Igniter) do &if(Igniter.Project.Config.configures_key?(&1, "dev.exs", otp_app, new_endpoint), do: &1, else: - Igniter.update_elixir_file(&1, "config/dev.exs", fn zipper -> + Igniter.update_elixir_file(&1, Beacon.Igniter.config_file_path(igniter, "dev.exs"), fn zipper -> {:ok, zipper |> Beacon.Igniter.move_to_variable!(:secret_key_base) diff --git a/lib/mix/tasks/beacon.gen.tailwind_config.ex b/lib/mix/tasks/beacon.gen.tailwind_config.ex index f2494c9f..d3cbcfbe 100644 --- a/lib/mix/tasks/beacon.gen.tailwind_config.ex +++ b/lib/mix/tasks/beacon.gen.tailwind_config.ex @@ -35,6 +35,9 @@ if Code.ensure_loaded?(Igniter) do @moduledoc __MODULE__.Docs.long_doc() + @impl Igniter.Mix.Task + def supports_umbrella?, do: true + @impl Igniter.Mix.Task def info(_argv, _composing_task) do %Igniter.Mix.Task.Info{ @@ -46,6 +49,16 @@ if Code.ensure_loaded?(Igniter) do @impl Igniter.Mix.Task def igniter(igniter) do + if Mix.Project.umbrella?() do + Mix.shell().error(""" + Running 'mix beacon.gen.tailwind_config' in the root of Umbrella apps is not supported yet. + + Please execute that task inside a child app. + """) + + exit({:shutdown, 1}) + end + options = igniter.args.options site = Keyword.fetch!(options, :site) |> String.to_atom() diff --git a/lib/mix/tasks/beacon.install.ex b/lib/mix/tasks/beacon.install.ex index 34fceb1b..170f5ea9 100644 --- a/lib/mix/tasks/beacon.install.ex +++ b/lib/mix/tasks/beacon.install.ex @@ -28,7 +28,7 @@ defmodule Mix.Tasks.Beacon.Install.Docs do ``` ```bash - "mix beacon.install --site my_site --path / + mix beacon.install --site my_site --path / ``` ## Options @@ -48,6 +48,9 @@ if Code.ensure_loaded?(Igniter) do @moduledoc __MODULE__.Docs.long_doc() + @impl Igniter.Mix.Task + def supports_umbrella?, do: true + @impl Igniter.Mix.Task def info(_argv, _composing_task) do %Igniter.Mix.Task.Info{ @@ -61,6 +64,16 @@ if Code.ensure_loaded?(Igniter) do @impl Igniter.Mix.Task def igniter(igniter) do + if Mix.Project.umbrella?() do + Mix.shell().error(""" + Running 'mix beacon.install' in the root of Umbrella apps is not supported yet. + + Please execute that task inside a child app. + """) + + exit({:shutdown, 1}) + end + argv = igniter.args.argv options = igniter.args.options diff --git a/mix.exs b/mix.exs index 38b533c8..1f93c25c 100644 --- a/mix.exs +++ b/mix.exs @@ -80,7 +80,7 @@ defmodule Beacon.MixProject do {:solid, "~> 0.14"}, {:tailwind, "~> 0.2"}, {:esbuild, "~> 0.5"}, - {:igniter, "~> 0.5", optional: true}, + {:igniter, ">= 0.5.24", optional: true}, # Dev, Test, Docs {:credo, "~> 1.6", only: [:dev, :test], runtime: false}, diff --git a/mix.lock b/mix.lock index 58577034..a6981447 100644 --- a/mix.lock +++ b/mix.lock @@ -32,7 +32,7 @@ "hpax": {:hex, :hpax, "1.0.2", "762df951b0c399ff67cc57c3995ec3cf46d696e41f0bba17da0518d94acd4aac", [:mix], [], "hexpm", "2f09b4c1074e0abd846747329eaa26d535be0eb3d189fa69d812bfb8bfefd32f"}, "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, - "igniter": {:hex, :igniter, "0.5.21", "b80e16a47cb1fe724a2113c1f2661507d9e458978c2d610aeb87b15d9c2d43e5", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:inflex, "~> 2.0", [hex: :inflex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "19e516b5e06d90447c74fc4fdfc14b71318c41ef966999ac6b34d038e1aa2b9c"}, + "igniter": {:hex, :igniter, "0.5.24", "d5d275f085485350cb9b57bb54d7bf5510fd453ed294e64683879c0549fcead1", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:inflex, "~> 2.0", [hex: :inflex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "49f4bbc97590164c51745529142c715b7ced772ced3ead2a4153843b9596e903"}, "image": {:hex, :image, "0.56.0", "3c248d23cc0af384182ff722f5d55e531771559dbea25bcd038268c4c474df56", [:mix], [{:bumblebee, "~> 0.6", [hex: :bumblebee, repo: "hexpm", optional: true]}, {:evision, "~> 0.1.33 or ~> 0.2", [hex: :evision, repo: "hexpm", optional: true]}, {:exla, "~> 0.9", [hex: :exla, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:kino, "~> 0.13", [hex: :kino, repo: "hexpm", optional: true]}, {:nx, "~> 0.9", [hex: :nx, repo: "hexpm", optional: true]}, {:nx_image, "~> 0.1", [hex: :nx_image, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.1 or ~> 3.2 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: true]}, {:req, "~> 0.4", [hex: :req, repo: "hexpm", optional: true]}, {:rustler, "> 0.0.0", [hex: :rustler, repo: "hexpm", optional: true]}, {:scholar, "~> 0.3", [hex: :scholar, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: false]}, {:vix, "~> 0.23", [hex: :vix, repo: "hexpm", optional: false]}], "hexpm", "f32bb924c4fd6404108533f7a4de9a3d4c5471038c65e961c1671286eb14ef73"}, "inflex": {:hex, :inflex, "2.1.0", "a365cf0821a9dacb65067abd95008ca1b0bb7dcdd85ae59965deef2aa062924c", [:mix], [], "hexpm", "14c17d05db4ee9b6d319b0bff1bdf22aa389a25398d1952c7a0b5f3d93162dd8"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, @@ -43,12 +43,12 @@ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, - "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, + "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "oembed": {:hex, :oembed, "0.5.0", "6fa2b54966771f1b9f8007d0b96c425de05db761161e794ed36d7a5f6e47713b", [:mix], [{:exconstructor, ">= 1.0.0", [hex: :exconstructor, repo: "hexpm", optional: false]}, {:floki, ">= 0.24.0", [hex: :floki, repo: "hexpm", optional: false]}, {:httpoison, ">= 0.9.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "c4006bc27d957ca39fa1378817bb8af28f992526300d35d444416d13151cef32"}, - "owl": {:hex, :owl, "0.12.1", "d3146087315c4528ee32411495ba10ec88102597b638d4d1455cf9d245dfb57a", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "d7eb9746aa89c40c46b479d6c2a70b82b94993520e40f21d0b09654f23eebf35"}, + "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "phoenix": {:hex, :phoenix, "1.7.19", "36617efe5afbd821099a8b994ff4618a340a5bfb25531a1802c4d4c634017a57", [: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.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "ba4dc14458278773f905f8ae6c2ec743d52c3a35b6b353733f64f02dfe096cd6"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.3", "f686701b0499a07f2e3b122d84d52ff8a31f5def386e03706c916f6feddf69ef", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "909502956916a657a197f94cc1206d9a65247538de8a5e186f7537c895d95764"}, @@ -73,7 +73,7 @@ "safe_code": {:hex, :safe_code, "0.2.3", "c37329a03d4ac847ccd437344abdbb6d8a8ff6a46f1b6e5ad976bf9a86a5227f", [:mix], [{:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix_live_view, ">= 0.18.17", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "de5f3ad37d0f7804281f42be8dac32ee52f7b5f7c5c4c851eba34e42bffd4aef"}, "solid": {:hex, :solid, "0.17.2", "5c09bde715f7a0f17f608f1bbfe6970c7ddc64aa3718c4a5a90eac36c3b59ba0", [:mix], [{:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db24f927bf073b345d5d65e6767b7a0937650aeeec02ed22a1d93d40cec5ff6b"}, "sourceror": {:hex, :sourceror, "1.7.1", "599d78f4cc2be7d55c9c4fd0a8d772fd0478e3a50e726697c20d13d02aa056d4", [:mix], [], "hexpm", "cd6f268fe29fa00afbc535e215158680a0662b357dc784646d7dff28ac65a0fc"}, - "spitfire": {:hex, :spitfire, "0.1.4", "8fe0df66e735323e4f2a56e719603391b160dd68efd922cadfbb85a2cf6c68af", [:mix], [], "hexpm", "d40d850f4ede5235084876246756b90c7bcd12994111d57c55e2e1e23ac3fe61"}, + "spitfire": {:hex, :spitfire, "0.1.5", "10b041e781bff9544d2fdf00893e1a325758408c5366a9bfa4333072568659b1", [:mix], [], "hexpm", "866a55d21fe827934ff38200111335c9dd311df13cbf2580ed71d84b0a783150"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "sweet_xml": {:hex, :sweet_xml, "0.7.5", "803a563113981aaac202a1dbd39771562d0ad31004ddbfc9b5090bdcd5605277", [:mix], [], "hexpm", "193b28a9b12891cae351d81a0cead165ffe67df1b73fe5866d10629f4faefb12"}, "tailwind": {:hex, :tailwind, "0.2.4", "5706ec47182d4e7045901302bf3a333e80f3d1af65c442ba9a9eed152fb26c2e", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "c6e4a82b8727bab593700c998a4d98cf3d8025678bfde059aed71d0000c3e463"},