defmodule Firebird.Phoenix.Scaffold do @moduledoc """ Generates a complete Phoenix WASM application scaffold. Creates a ready-to-run project that uses Firebird's WASM-accelerated Phoenix components for HTTP request handling. ## Generated Structure my_app/ ├── lib/ │ ├── my_app/ │ │ ├── application.ex # OTP Application with Phoenix WASM supervisor │ │ ├── router.ex # Route definitions using RouterDSL │ │ ├── controllers/ │ │ │ ├── page_controller.ex │ │ │ └── user_controller.ex │ │ └── templates/ │ │ ├── layout.html.eex │ │ └── page/ │ │ └── index.html.eex │ └── my_app.ex # Main module ├── test/ │ ├── test_helper.exs │ └── my_app/ │ └── router_test.exs ├── config/ │ └── config.exs └── mix.exs """ @doc """ Generate a Phoenix WASM application scaffold. ## Parameters - `app_name` - Application name (e.g., "my_app") - `opts` - Options: - `:path` - Output directory (default: current dir + app_name) - `:module` - Module name (default: camelized app_name) ## Returns - `{:ok, path}` - Scaffold generated at path - `{:error, reason}` - Generation failed """ @spec generate(String.t(), keyword()) :: {:ok, String.t()} | {:error, term()} def generate(app_name, opts \\ []) do module_name = Keyword.get(opts, :module, Macro.camelize(app_name)) base_path = Keyword.get(opts, :path, Path.join(File.cwd!(), app_name)) files = [ {"mix.exs", mix_exs(app_name, module_name)}, {"lib/#{app_name}.ex", main_module(module_name)}, {"lib/#{app_name}/application.ex", application(module_name)}, {"lib/#{app_name}/router.ex", router(module_name)}, {"lib/#{app_name}/controllers/page_controller.ex", page_controller(module_name)}, {"lib/#{app_name}/controllers/user_controller.ex", user_controller(module_name)}, {"lib/#{app_name}/templates/layout.html.eex", layout_template()}, {"lib/#{app_name}/templates/page/index.html.eex", page_index_template()}, {"test/test_helper.exs", test_helper()}, {"test/#{app_name}/router_test.exs", router_test(module_name)}, {"config/config.exs", config(app_name)}, {"README.md", readme(app_name, module_name)} ] Enum.each(files, fn {rel_path, content} -> full_path = Path.join(base_path, rel_path) File.mkdir_p!(Path.dirname(full_path)) File.write!(full_path, content) end) {:ok, base_path} end defp mix_exs(app_name, module_name) do """ defmodule #{module_name}.MixProject do use Mix.Project def project do [ app: :#{app_name}, version: "0.1.0", elixir: "~> 1.14", start_permanent: Mix.env() == :prod, deps: deps() ] end def application do [ extra_applications: [:logger], mod: {#{module_name}.Application, []} ] end defp deps do [ {:firebird, "~> 0.1.0"}, {:jason, "~> 1.4"} ] end end """ end defp main_module(module_name) do """ defmodule #{module_name} do @moduledoc \"\"\" #{module_name} - A Phoenix WASM application powered by Firebird. \"\"\" end """ end defp application(module_name) do """ defmodule #{module_name}.Application do use Application @impl true def start(_type, _args) do children = [ {Firebird.Phoenix.Application, name: :phoenix_wasm} ] opts = [strategy: :one_for_one, name: #{module_name}.Supervisor] Supervisor.start_link(children, opts) end end """ end defp router(module_name) do """ defmodule #{module_name}.Router do use Firebird.Phoenix.RouterDSL pipeline :browser do plug "put_secure_headers" plug "accept:text/html" end pipeline :api do plug "accept:application/json" plug "cors:*" end scope "/" do get "/", "PageController.index" get "/about", "PageController.about" end scope "/api", :api do resources "/users", "UserController" end @doc \"\"\" Define action handlers for route dispatch. \"\"\" def actions do %{ "PageController.index" => {200, "text/html", "
Powered by Firebird WASM
"} end end """ end defp user_controller(module_name) do """ defmodule #{module_name}.UserController do @moduledoc "Handles user API requests." def index(_params) do {200, "application/json", ~s([{"id":"1","name":"Alice"},{"id":"2","name":"Bob"}])} end def show(%{"id" => id}) do {200, "application/json", ~s({"id":"#{"\#{id}"}","name":"User #{"\#{id}}"}"})} end def create(_params) do {201, "application/json", ~s({"status":"created"})} end def update(%{"id" => id}) do {200, "application/json", ~s({"id":"#{"\#{id}"}","status":"updated"})} end def delete(_params) do {204, "text/plain", ""} end end """ end defp layout_template do """This application is powered by Firebird Phoenix WASM.
All request processing uses WebAssembly modules for: