-module(refrakt@cli@templates). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/refrakt/cli/templates.gleam"). -export([gleam_toml/2, gitignore/0, readme/1, main_module/2, config_module/1, context_module/2, router_module/2, home_handler/1, error_handler/1, root_layout/0, flash_component/0, repo_module/2, app_css/0, app_js/0, main_test/1, home_handler_test/1, resource_handler/6, resource_domain_type/2]). -file("src/refrakt/cli/templates.gleam", 13). -spec gleam_toml(binary(), refrakt@cli@types:db_choice()) -> binary(). gleam_toml(Name, Db) -> Db_dep = case Db of postgres -> <<"\npog = \">= 4.1.0 and < 5.0.0\""/utf8>>; sqlite -> <<"\nsqlight = \">= 1.0.0 and < 2.0.0\""/utf8>>; no_db -> <<""/utf8>> end, <<<<<<<<"name = \""/utf8, Name/binary>>/binary, "\" version = \"0.1.0\" target = \"erlang\" gleam = \">= 1.14.0\" [dependencies] gleam_stdlib = \">= 0.44.0 and < 2.0.0\" gleam_erlang = \">= 0.34.0 and < 2.0.0\" gleam_http = \">= 4.3.0 and < 5.0.0\" envoy = \">= 1.1.0 and < 2.0.0\" mist = \">= 5.0.0 and < 6.0.0\" wisp = \">= 2.2.0 and < 3.0.0\" lustre = \">= 5.6.0 and < 6.0.0\" gleam_json = \">= 3.1.0 and < 4.0.0\" refrakt = \">= 0.1.0 and < 1.0.0\""/utf8>>/binary, Db_dep/binary>>/binary, " [dev-dependencies] gleeunit = \">= 1.0.0 and < 2.0.0\" "/utf8>>. -file("src/refrakt/cli/templates.gleam", 41). -spec gitignore() -> binary(). gitignore() -> <<"/build/ .DS_Store "/utf8>>. -file("src/refrakt/cli/templates.gleam", 47). -spec readme(binary()) -> binary(). readme(Name) -> <<<<"# "/utf8, Name/binary>>/binary, " A web application built with [Refrakt](https://github.com/raskell-io/refrakt). ## Development ```bash gleam run # Start the server at http://localhost:4000 gleam test # Run tests ``` "/utf8>>. -file("src/refrakt/cli/templates.gleam", 65). -spec main_module(binary(), refrakt@cli@types:db_choice()) -> binary(). main_module(Name, Db) -> Db_import = case Db of postgres -> <<<<"\nimport "/utf8, Name/binary>>/binary, "/data/repo"/utf8>>; sqlite -> <<<<"\nimport "/utf8, Name/binary>>/binary, "/data/repo"/utf8>>; no_db -> <<""/utf8>> end, Db_ctx = case Db of postgres -> <<"\n let assert Ok(db) = repo.connect(cfg)\n let ctx = context.Context(config: cfg, db: db)"/utf8>>; sqlite -> <<"\n let db_path = repo.database_path(cfg)\n let ctx = context.Context(config: cfg, db_path: db_path)"/utf8>>; no_db -> <<"\n let ctx = context.Context(config: cfg)"/utf8>> end, <<<<<<<<<<<<<<<<<<<<"import gleam/erlang/process import gleam/io import mist import "/utf8, Name/binary>>/binary, "/config import "/utf8>>/binary, Name/binary>>/binary, "/context import "/utf8>>/binary, Name/binary>>/binary, "/router import wisp import wisp/wisp_mist"/utf8>>/binary, Db_import/binary>>/binary, " pub fn main() { wisp.configure_logger() let cfg = config.load()"/utf8>>/binary, Db_ctx/binary>>/binary, " let assert Ok(_) = wisp_mist.handler(router.handle_request(_, ctx), cfg.secret_key_base) |> mist.new |> mist.port(cfg.port) |> mist.start io.println(\"Listening on http://localhost:\" <> cfg.port_string) process.sleep_forever() } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 106). -spec config_module(binary()) -> binary(). config_module(_) -> <<"import envoy import gleam/int import gleam/result pub type Config { Config( port: Int, port_string: String, secret_key_base: String, env: Env, ) } pub type Env { Dev Test Prod } pub fn load() -> Config { let port = envoy.get(\"PORT\") |> result.try(int.parse) |> result.unwrap(4000) let secret_key_base = envoy.get(\"SECRET_KEY_BASE\") |> result.unwrap( \"dev-secret-key-base-that-is-at-least-64-bytes-long-for-security!!\", ) let env = case envoy.get(\"APP_ENV\") { Ok(\"prod\") -> Prod Ok(\"test\") -> Test _ -> Dev } Config( port: port, port_string: int.to_string(port), secret_key_base: secret_key_base, env: env, ) } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 154). -spec context_module(binary(), refrakt@cli@types:db_choice()) -> binary(). context_module(Name, Db) -> Db_field = case Db of postgres -> <<", db: pog.Connection"/utf8>>; sqlite -> <<", db_path: String"/utf8>>; no_db -> <<""/utf8>> end, Db_import = case Db of postgres -> <<"\nimport pog"/utf8>>; _ -> <<""/utf8>> end, <<<<<<<<<<<<"import "/utf8, Name/binary>>/binary, "/config"/utf8>>/binary, Db_import/binary>>/binary, " pub type Context { Context(config: config.Config"/utf8>>/binary, Db_field/binary>>/binary, ") } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 174). -spec router_module(binary(), refrakt@cli@types:db_choice()) -> binary(). router_module(Name, _) -> <<<<<<<<<<<<<<<<"import gleam/http import "/utf8, Name/binary>>/binary, "/context.{type Context} import "/utf8>>/binary, Name/binary>>/binary, "/web/error_handler import "/utf8>>/binary, Name/binary>>/binary, "/web/home_handler import wisp.{type Request, type Response} pub fn handle_request(req: Request, ctx: Context) -> Response { use req <- middleware(req) case wisp.path_segments(req), req.method { [], http.Get -> home_handler.index(req, ctx) _, _ -> error_handler.not_found(req) } } fn middleware( req: Request, next: fn(Request) -> Response, ) -> Response { let req = wisp.method_override(req) use <- wisp.log_request(req) use <- wisp.rescue_crashes use <- wisp.serve_static(req, under: \"/static\", from: priv_static()) next(req) } fn priv_static() -> String { let assert Ok(priv) = wisp.priv_directory(\""/utf8>>/binary, Name/binary>>/binary, "\") priv <> \"/static\" } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 208). -spec home_handler(binary()) -> binary(). home_handler(Name) -> <<<<<<<<<<<<"import lustre/attribute.{class} import lustre/element.{text} import lustre/element/html.{h1, p, section} import "/utf8, Name/binary>>/binary, "/context.{type Context} import "/utf8>>/binary, Name/binary>>/binary, "/web/layouts/root_layout import wisp.{type Request, type Response} pub fn index(_req: Request, _ctx: Context) -> Response { section([class(\"hero\")], [ h1([], [text(\"Welcome to "/utf8>>/binary, Name/binary>>/binary, "\")]), p([], [text(\"Built with Refrakt — a convention-first web framework for Gleam.\")]), ]) |> root_layout.wrap(\"Home\") |> wisp.html_response(200) } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 227). -spec error_handler(binary()) -> binary(). error_handler(_) -> <<"import lustre/attribute.{class} import lustre/element.{text} import lustre/element/html.{h1, p, section} import wisp.{type Request, type Response} pub fn not_found(_req: Request) -> Response { section([class(\"error-page\")], [ h1([], [text(\"404\")]), p([], [text(\"Page not found.\")]), ]) |> element.to_string |> wisp.html_response(404) } pub fn internal_error(_req: Request) -> Response { section([class(\"error-page\")], [ h1([], [text(\"500\")]), p([], [text(\"Something went wrong.\")]), ]) |> element.to_string |> wisp.html_response(500) } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 253). -spec root_layout() -> binary(). root_layout() -> <<"import lustre/attribute.{charset, class, content, href, name, rel} import lustre/element.{type Element} import lustre/element/html.{body, head, html, link, main, meta, title} pub fn wrap(inner: Element(Nil), page_title: String) -> String { html([], [ head([], [ meta([charset(\"utf-8\")]), meta([name(\"viewport\"), content(\"width=device-width, initial-scale=1\")]), title([], page_title), link([rel(\"stylesheet\"), href(\"/static/css/app.css\")]), ]), body([], [main([class(\"container\")], [inner])]), ]) |> element.to_document_string } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 273). -spec flash_component() -> binary(). flash_component() -> <<"import lustre/attribute.{class} import lustre/element.{type Element, text} import lustre/element/html.{div, p} import gleam/option.{type Option, None, Some} pub fn render(message: Option(String)) -> Element(Nil) { case message { Some(msg) -> div([class(\"flash\")], [ p([], [text(msg)]), ]) None -> text(\"\") } } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 291). -spec repo_module(binary(), refrakt@cli@types:db_choice()) -> binary(). repo_module(Name, Db) -> case Db of postgres -> <<<<<<<<<<<<<<<<"import "/utf8, Name/binary>>/binary, "/config.{type Config} import gleam/erlang/process import gleam/result import pog pub fn connect(cfg: Config) -> Result(pog.Connection, Nil) { let db_url = case cfg.env { config.Test -> \"postgres://localhost:5432/"/utf8>>/binary, Name/binary>>/binary, "_test\" _ -> \"postgres://localhost:5432/"/utf8>>/binary, Name/binary>>/binary, "_dev\" } let pool_name = process.new_name(prefix: \""/utf8>>/binary, Name/binary>>/binary, "_db\") use db_config <- result.try(pog.url_config(pool_name, db_url)) case pog.start(db_config) { Ok(_started) -> Ok(pog.named_connection(pool_name)) Error(_) -> Error(Nil) } } "/utf8>>; sqlite -> <<<<<<<<"import "/utf8, Name/binary>>/binary, "/config.{type Config} /// Get the SQLite database path for the current environment. pub fn database_path(cfg: Config) -> String { case cfg.env { config.Test -> \":memory:\" _ -> \""/utf8>>/binary, Name/binary>>/binary, ".db\" } } "/utf8>>; no_db -> <<""/utf8>> end. -file("src/refrakt/cli/templates.gleam", 330). -spec app_css() -> binary(). app_css() -> <<"/* Refrakt default styles */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --font-sans: system-ui, -apple-system, sans-serif; --font-mono: ui-monospace, \"Cascadia Code\", \"Fira Code\", monospace; --color-bg: #fafafa; --color-text: #1a1a1a; --color-muted: #666; --color-border: #e5e5e5; --color-accent: #5b21b6; --color-accent-light: #7c3aed; --color-error: #dc2626; --max-width: 48rem; } body { font-family: var(--font-sans); color: var(--color-text); background: var(--color-bg); line-height: 1.6; } .container { max-width: var(--max-width); margin: 0 auto; padding: 2rem 1rem; } /* Hero */ .hero { text-align: center; padding: 4rem 0; } .hero h1 { font-size: 2.5rem; margin-bottom: 0.5rem; } .hero p { color: var(--color-muted); font-size: 1.125rem; } /* Links */ a { color: var(--color-accent); text-decoration: none; } a:hover { text-decoration: underline; } /* Buttons */ .btn { display: inline-block; padding: 0.5rem 1rem; background: var(--color-accent); color: white; border: none; border-radius: 0.25rem; font-size: 0.875rem; cursor: pointer; text-decoration: none; } .btn:hover { background: var(--color-accent-light); text-decoration: none; } /* Forms */ .field { margin-bottom: 1rem; } .field label { display: block; font-weight: 500; margin-bottom: 0.25rem; } .field input[type=\"text\"], .field input[type=\"email\"], .field input[type=\"password\"], .field textarea, .field select { width: 100%; padding: 0.5rem; border: 1px solid var(--color-border); border-radius: 0.25rem; font-size: 1rem; font-family: inherit; } .field textarea { min-height: 8rem; resize: vertical; } .field .error { color: var(--color-error); font-size: 0.875rem; margin-top: 0.25rem; } /* Flash */ .flash { padding: 0.75rem 1rem; border-radius: 0.25rem; background: #dbeafe; border: 1px solid #93c5fd; margin-bottom: 1rem; } /* Error pages */ .error-page { text-align: center; padding: 4rem 0; } .error-page h1 { font-size: 4rem; color: var(--color-muted); } /* Lists */ .post-list { list-style: none; } .post-list li { padding: 0.75rem 0; border-bottom: 1px solid var(--color-border); } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; } .actions { margin-top: 1.5rem; display: flex; gap: 0.5rem; } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 491). -spec app_js() -> binary(). app_js() -> <<"// Refrakt client-side JavaScript // Add your client-side code here. "/utf8>>. -file("src/refrakt/cli/templates.gleam", 501). -spec main_test(binary()) -> binary(). main_test(_) -> <<"import gleeunit pub fn main() { gleeunit.main() } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 510). -spec home_handler_test(binary()) -> binary(). home_handler_test(_) -> <<"import gleeunit/should pub fn placeholder_test() { 1 + 1 |> should.equal(2) } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 524). -spec resource_handler( binary(), binary(), binary(), binary(), binary(), refrakt@cli@types:db_choice() ) -> binary(). resource_handler(App_name, Resource_plural, Resource_singular, Type_name, _, Db) -> Db_arg = case Db of sqlite -> <<"ctx.db_path"/utf8>>; _ -> <<"ctx.db"/utf8>> end, <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"import gleam/int import "/utf8, App_name/binary>>/binary, "/context.{type Context} import "/utf8>>/binary, App_name/binary>>/binary, "/data/"/utf8>>/binary, Resource_singular/binary>>/binary, "_repo import "/utf8>>/binary, App_name/binary>>/binary, "/web/error_handler import "/utf8>>/binary, App_name/binary>>/binary, "/web/forms/"/utf8>>/binary, Resource_singular/binary>>/binary, "_form import "/utf8>>/binary, App_name/binary>>/binary, "/web/layouts/root_layout import "/utf8>>/binary, App_name/binary>>/binary, "/web/"/utf8>>/binary, Resource_singular/binary>>/binary, "_views import refrakt/flash import wisp.{type Request, type Response} pub fn index(_req: Request, ctx: Context) -> Response { let items = "/utf8>>/binary, Resource_singular/binary>>/binary, "_repo.list("/utf8>>/binary, Db_arg/binary>>/binary, ") "/utf8>>/binary, Resource_singular/binary>>/binary, "_views.index_view(items) |> root_layout.wrap(\""/utf8>>/binary, Type_name/binary>>/binary, "s\") |> wisp.html_response(200) } pub fn show(req: Request, ctx: Context, id: String) -> Response { case int.parse(id) { Error(_) -> error_handler.not_found(req) Ok(id) -> case "/utf8>>/binary, Resource_singular/binary>>/binary, "_repo.get("/utf8>>/binary, Db_arg/binary>>/binary, ", id) { Error(_) -> error_handler.not_found(req) Ok(item) -> "/utf8>>/binary, Resource_singular/binary>>/binary, "_views.show_view(item) |> root_layout.wrap(\""/utf8>>/binary, Type_name/binary>>/binary, "\") |> wisp.html_response(200) } } } pub fn new(_req: Request, _ctx: Context) -> Response { "/utf8>>/binary, Resource_singular/binary>>/binary, "_views.form_view("/utf8>>/binary, Resource_singular/binary>>/binary, "_form.empty(), []) |> root_layout.wrap(\"New "/utf8>>/binary, Type_name/binary>>/binary, "\") |> wisp.html_response(200) } pub fn create(req: Request, ctx: Context) -> Response { use form_data <- wisp.require_form(req) case "/utf8>>/binary, Resource_singular/binary>>/binary, "_form.decode(form_data) { Error(errors) -> "/utf8>>/binary, Resource_singular/binary>>/binary, "_views.form_view( "/utf8>>/binary, Resource_singular/binary>>/binary, "_form.from_form_data(form_data), errors, ) |> root_layout.wrap(\"New "/utf8>>/binary, Type_name/binary>>/binary, "\") |> wisp.html_response(422) Ok(params) -> case "/utf8>>/binary, Resource_singular/binary>>/binary, "_repo.create("/utf8>>/binary, Db_arg/binary>>/binary, ", params) { Ok(item) -> wisp.redirect(\"/"/utf8>>/binary, Resource_plural/binary>>/binary, "/\" <> int.to_string(item.id)) |> flash.set_flash(req, \"info\", \""/utf8>>/binary, Type_name/binary>>/binary, " created\") Error(_) -> error_handler.internal_error(req) } } } pub fn edit(req: Request, ctx: Context, id: String) -> Response { case int.parse(id) { Error(_) -> error_handler.not_found(req) Ok(id) -> case "/utf8>>/binary, Resource_singular/binary>>/binary, "_repo.get("/utf8>>/binary, Db_arg/binary>>/binary, ", id) { Error(_) -> error_handler.not_found(req) Ok(item) -> "/utf8>>/binary, Resource_singular/binary>>/binary, "_views.form_view("/utf8>>/binary, Resource_singular/binary>>/binary, "_form.from_"/utf8>>/binary, Resource_singular/binary>>/binary, "(item), []) |> root_layout.wrap(\"Edit "/utf8>>/binary, Type_name/binary>>/binary, "\") |> wisp.html_response(200) } } } pub fn update(req: Request, ctx: Context, id: String) -> Response { use form_data <- wisp.require_form(req) case int.parse(id) { Error(_) -> error_handler.not_found(req) Ok(id) -> case "/utf8>>/binary, Resource_singular/binary>>/binary, "_form.decode(form_data) { Error(errors) -> "/utf8>>/binary, Resource_singular/binary>>/binary, "_views.form_view( "/utf8>>/binary, Resource_singular/binary>>/binary, "_form.from_form_data(form_data), errors, ) |> root_layout.wrap(\"Edit "/utf8>>/binary, Type_name/binary>>/binary, "\") |> wisp.html_response(422) Ok(params) -> case "/utf8>>/binary, Resource_singular/binary>>/binary, "_repo.update("/utf8>>/binary, Db_arg/binary>>/binary, ", id, params) { Ok(_) -> wisp.redirect(\"/"/utf8>>/binary, Resource_plural/binary>>/binary, "/\" <> int.to_string(id)) |> flash.set_flash(req, \"info\", \""/utf8>>/binary, Type_name/binary>>/binary, " updated\") Error(_) -> error_handler.internal_error(req) } } } } pub fn delete(req: Request, ctx: Context, id: String) -> Response { case int.parse(id) { Error(_) -> error_handler.not_found(req) Ok(id) -> { let _ = "/utf8>>/binary, Resource_singular/binary>>/binary, "_repo.delete("/utf8>>/binary, Db_arg/binary>>/binary, ", id) wisp.redirect(\"/"/utf8>>/binary, Resource_plural/binary>>/binary, "\") |> flash.set_flash(req, \"info\", \""/utf8>>/binary, Type_name/binary>>/binary, " deleted\") } } } "/utf8>>. -file("src/refrakt/cli/templates.gleam", 702). -spec do_list_reverse(list(AGIN), list(AGIN)) -> list(AGIN). do_list_reverse(Items, Acc) -> case Items of [] -> Acc; [First | Rest] -> do_list_reverse(Rest, [First | Acc]) end. -file("src/refrakt/cli/templates.gleam", 698). -spec list_reverse(list(AGIK)) -> list(AGIK). list_reverse(Items) -> do_list_reverse(Items, []). -file("src/refrakt/cli/templates.gleam", 687). -spec do_list_map_join(list(AGIG), fun((AGIG) -> binary()), list(binary())) -> list(binary()). do_list_map_join(Items, F, Acc) -> case Items of [] -> list_reverse(Acc); [First | Rest] -> do_list_map_join(Rest, F, [F(First) | Acc]) end. -file("src/refrakt/cli/templates.gleam", 677). -spec list_map_join(list(AGIE), fun((AGIE) -> binary()), binary()) -> binary(). list_map_join(Items, F, Separator) -> _pipe = Items, _pipe@1 = do_list_map_join(_pipe, F, []), gleam@string:join(_pipe@1, Separator). -file("src/refrakt/cli/templates.gleam", 650). -spec resource_domain_type(binary(), list({binary(), binary()})) -> binary(). resource_domain_type(Type_name, Fields) -> Field_defs = begin _pipe = Fields, list_map_join( _pipe, fun(Field) -> {Name, Gleam_type} = Field, <<<<<<<<" "/utf8, Name/binary>>/binary, ": "/utf8>>/binary, Gleam_type/binary>>/binary, ","/utf8>> end, <<"\n"/utf8>> ) end, <<<<<<<<<<<<"pub type "/utf8, Type_name/binary>>/binary, " { "/utf8>>/binary, Type_name/binary>>/binary, "( id: Int, "/utf8>>/binary, Field_defs/binary>>/binary, " ) } "/utf8>>.