# Changelog ## 1.0.1 - 2026-07-31 A documentation and CLI-ergonomics patch. No behavior changes to the framework runtime. ### Fixed - **`generate scaffold`/`controller` no longer error on the old `--api` flag.** The 1.0 adaptive-generator rebuild removed the `--api`/`--html`/`--htmx` (and `-k/--kind`) flags — scaffold now auto-detects headless vs. clientside from `frontend/`, and controllers are always JSON API controllers — but the docs (including the *Your first app* tutorial) still showed `--api`, so copy-pasting them failed with `error: unexpected argument '--api' found`. The generators now accept the old flags for compatibility: `--api` is a no-op (it's the headless default) and `--html`/`--htmx` return a clear message pointing at the React SPA frontend that replaced server-rendered views. ([#1790](https://github.com/loco-rs/loco/issues/1790)) - **Docs resync.** Removed every reference to the removed scaffold/controller kind flags and the deleted `ScaffoldKind` enum / `mappings.json` across the tutorials, how-to guides, and CLI/generators reference; corrected the field-type reference to describe `loco-gen/src/column.rs` (including that `array:int` is now a 64-bit `BigInt` array, consistent with the scalar `int` → `i64` change). ## 1.0.0 - 2026-07-25 1.0.0 is the first stable Loco release — a single, intentionally-breaking milestone. Its headline is the move to **Sea-ORM 2.0**, alongside first-class LLM/agent support, priority queues, a broad dependency modernization, and a deep hardening pass across the queue, storage, config, error, remote-IP, and middleware subsystems. Follow the step-by-step [0.16 → 1.0 upgrade guide](https://loco.rs/docs/extras/upgrades/). ### Breaking Changes - **Sea-ORM 2.0 + sqlx 0.9.** Bump `sea-orm`/`sea-orm-migration` to **`2.0`** (app + `migration` crate), direct `sqlx` to `0.9`, update the Sea-ORM CLI, and regenerate entities. Raw-`Statement` calls gain a `_raw` suffix; runtime SQL strings need `AssertSqlSafe`. MSRV is **1.94** (sea-orm 2.0.0 declares it). (Adopted from the SeaQL fork and [#1698](https://github.com/loco-rs/loco/pull/1698).) - **Generated primary/foreign keys are now 64-bit (BIGINT / `i64`).** Also the `int`/`unsigned` field types generate 64-bit columns. Only affects newly generated code; existing tables are untouched. - **Priority queues — Redis backend change.** The Redis worker moved from Lists to Sorted Sets (ZSET) to support priority; **drain existing Redis queues before upgrading**. Postgres/SQLite auto-migrate a `priority` column (no action). ([#1693](https://github.com/loco-rs/loco/pull/1693)) - **`Worker::perform_later()` returns the job ID** (`Result`), and `Queue::enqueue()` returns `Result>`. Existing `perform_later(...).await?;` keeps working. ([#1624](https://github.com/loco-rs/loco/pull/1624), fixes [#1623](https://github.com/loco-rs/loco/issues/1623)) - **`PageResponse` exposes `meta: PagerMeta`** instead of flat `total_pages`/`total_items` (also carries `page`/`page_size`). ([#1685](https://github.com/loco-rs/loco/pull/1685), fixes [#1683](https://github.com/loco-rs/loco/issues/1683)) - **View engine:** use `engines::TeraView::build_with_post_process(...)` instead of `TeraView::build()?.post_process(...)` in `after_routes`. - **Dependency majors:** `thiserror` 1→2, `tower` 0.4→0.5, `heck`→0.5, `byte-unit` 4→5, `ipnetwork` 0.20→0.21, `strum`→0.27, `redis` 0.31→1, `bb8-redis`→0.26, `opendal` 0.54→0.57; `serde_yaml`→`serde_yaml_ng`. Transitive for most apps. - Removed the dead `loco-cli` crate (superseded by `loco-new`, the published `loco` binary). - **`ExtraDbInitializer` removed; use `MultiDbInitializer`.** The single-extra-connection initializer (`initializers.extra_db`, which layered a bare `Extension`) is gone. Use `MultiDbInitializer` with a one-entry `initializers.multi_db` map instead, and extract the connection with `Extension` + `multi_db.get("")`. This collapses two near-identical initializers into one named-connections abstraction. - **`AppContext` is now `#[non_exhaustive]`.** Construct it with `AppContext::builder(environment, db, config)` (or `builder(environment, config)` without the `with-db` feature) followed by optional `.queue_provider(..)`/`.mailer(..)`/`.storage(..)`/`.cache(..)`/`.shared_store(..)` and `.build()`. Direct struct-literal construction and exhaustive pattern matches on `AppContext` from outside the crate no longer compile; field access (`ctx.db`, `ctx.config`, `State`/`FromRef` extraction) is unchanged. This makes future context fields non-breaking to add. - **Storage `MirrorStrategy` and `BackupStrategy` merged into `ReplicatedStrategy`.** The two strategies were the same primary-plus-secondaries replication engine; they are now one `storage::strategies::replicated::ReplicatedStrategy` with a single `FailurePolicy` enum. Migrate: `MirrorStrategy::new(p, s, MirrorAll)` → `ReplicatedStrategy::mirror(p, s, FailurePolicy::FailIfAny)`; `BackupStrategy::new(p, s, BackupAll)` → `ReplicatedStrategy::backup(p, s, FailurePolicy::FailIfAny)`. Old `FailureMode` maps: `AllowMirrorFailure`/ `AllowBackupFailure` → `AllowAll`, `AtLeastOneFailure` → `AllowSingleFailure`, `CountFailure(n)` → `FailAtFailures(n)`. Secondary writes for the former backup strategy now run concurrently (previously sequential); the collected errors and failure decision are unchanged. - **Local storage driver no longer defaults its root to `/`.** `storage::drivers::local::new()` previously rooted the filesystem store at `/`, so any key — including one derived from user input — resolved against the whole disk (e.g. downloading key `etc/passwd` read `/etc/passwd`). It now roots at the current working directory. Apps that relied on absolute-path keys should switch to `local::new_with_prefix("/your/root")` to opt back into an explicit absolute root. - **Background queue reworked into a `QueueProvider` adapter interface.** The `bgworker::Queue` enum (`Postgres`/`Sqlite`/`Redis`/`None`) is now a newtype over `Arc`, so backends are pluggable (implement `QueueProvider` and wrap with `Queue::from_provider`). All existing methods (`enqueue`, `register`, `run`, `ping`, `cancel_jobs`, `clear_by_status`, `requeue`, …) keep the same signatures and behavior. Only two source-level changes affect callers: construct a no-op queue with `Queue::empty()` instead of `Queue::None`, and code that pattern-matched the enum variants (e.g. `Queue::Postgres(pool, ..)` to reach the raw pool) no longer compiles — use the provider methods instead. - **Fallback middleware defaults to `404`.** When the built-in fallback is enabled without an explicit `code`, it now returns `404 Not Found` (matching its docs and the bundled not-found page) instead of `200 OK`. Apps that relied on the enabled fallback returning `200` must set `code: 200` explicitly. The file-based fallback is unaffected (`ServeFile` reports its own status). - **`{env}.local.yaml` now deep-merges over `{env}.yaml`.** Previously the first existing file won and the other was ignored, so a `.local.yaml` had to restate the whole config. Both files are now layered with local precedence: mappings merge recursively; scalars and sequences in local replace the base value (sequences are not concatenated). Base keys now persist unless explicitly overridden. - **More accurate HTTP status codes for errors.** `IntoResponse for Error` previously collapsed ~28 of 35 variants to `500`. `Model(EntityNotFound)` now returns `404`, `Model(EntityAlreadyExists)` returns `409`, model validation and form-body rejections return `4xx` (matching JSON rejections) instead of `500`. Genuinely-internal errors still return a generic `500`. Handlers that asserted on the old `500`s will observe the corrected codes. - **`JWT::algorithm()` restricted to the HMAC family.** It now takes a new `loco_rs::auth::jwt::JWTAlgorithm` enum (`HS256`/`HS384`/`HS512`) instead of `jsonwebtoken::Algorithm`. Asymmetric algorithms — which could never work with Loco's shared base64 secret and silently produced broken tokens — are no longer representable. - **`remote_ip` middleware rebuilt on `axum-client-ip`; `trusted_proxies` removed.** Previously this middleware walked `X-Forwarded-For` right-to-left, skipping any address in a configurable `trusted_proxies` CIDR list (or a built-in RFC-1918 + loopback list), so it could see through a chain of one or more trusted proxies. It now trusts exactly **one** configured source (`source: ClientIpSource`, default `RightmostXForwardedFor`) and does **no** CIDR filtering — for the default it takes the last comma-separated value of the last `X-Forwarded-For` header verbatim, private or not. Single reverse-proxy deployments are unaffected. **Multi-hop topologies (CDN → LB → ingress) must now configure their innermost hop to set the client IP (e.g. nginx `set_real_ip_from`/`real_ip_recursive`), or point `source` at a provider header (`CfConnectingIp`, `CloudFrontViewerAddress`, `XRealIp`, `ConnectInfo`, …).** Note: an old config's `trusted_proxies:` key is silently ignored (unknown field), so review `remote_ip` before upgrading — this is a silent security-relevant behavior change, not a load error. The `RemoteIP` extractor and its `Display` output are unchanged. - **`auth_jwt` feature renamed to `auth`.** Update `features = ["auth_jwt"]` → `["auth"]` (it gates JWT auth and the `ApiToken` extractor, as before). - **Background-queue features collapsed.** `bg_pg`/`bg_sqlt` → `worker` (Postgres+SQLite; free once `sqlx` is compiled), `bg_redis` → `worker_redis` (adds `dep:redis`). `default` now has `worker` (not Redis). A Redis queue needs `worker_redis`; the queue backend is selected at runtime by `queue.kind`. - **Mailer `Template::new(dir)` now returns `Result`** (call `Template::new(dir)?`). Email templates render through a full Tera instance so they support inheritance and shared templates. Standard usage via `Mailer::mail_template` is unchanged. ([#1694](https://github.com/loco-rs/loco/pull/1694)) - **`Vars::cli_arg` returns `Result<&str>`** (was `Result<&String>`). Callers that relied on `&String` (e.g. `.clone()` into a `String`) should use `.to_owned()`. ([#1732](https://github.com/loco-rs/loco/pull/1732)) ### Added - **First-class LLM / agent support.** Root `AGENTS.md` teaches agents to build Loco apps; `llms.txt` / `llms-full.txt` are served from the site (llmstxt.org). Every `loco new` app ships an app-level `AGENTS.md`. - **Priority queues** with `Worker::perform_later_with_priority(...)`; mailer jobs default to priority `100`. ([#1693](https://github.com/loco-rs/loco/pull/1693)) - **Mailer implicit TLS (SMTPS / port 465)** via `mailer.smtp.tls`. ([#1774](https://github.com/loco-rs/loco/pull/1774), fixes [#1773](https://github.com/loco-rs/loco/issues/1773)) - **Run the scheduler without a worker** — `--scheduler` flag + `StartMode::ServerAndScheduler`/`WorkerAndScheduler`. ([#1742](https://github.com/loco-rs/loco/pull/1742), fixes [#1737](https://github.com/loco-rs/loco/issues/1737)) - Email headers support in the mailer ([#1700](https://github.com/loco-rs/loco/pull/1700)). - **Multi-recipient emails.** `Mailer::mail_multi` / `mail_template_multi` and the `MultiEmail` / `MultiArgs` types send one email to multiple To/CC/BCC recipients (processed by a dedicated `MultiMailerWorker`). ([#1764](https://github.com/loco-rs/loco/pull/1764)) - **Email template inheritance & shared templates.** Mailer templates support Tera `{% extends %}` / `{% block %}` and can share a common layout via `Mailer::mail_template_with_shared` / `Template::new_with_shared`. `loco generate mailer` now scaffolds a `src/mailers/shared/` base layout that the welcome template extends. ([#1694](https://github.com/loco-rs/loco/pull/1694)) - "Create user" task ([#1670](https://github.com/loco-rs/loco/pull/1670)). - `UuidUniqWithDefault` and `UuidWithDefault` types ([#1642](https://github.com/loco-rs/loco/pull/1642)). - Allow overriding a secure header ([#1659](https://github.com/loco-rs/loco/pull/1659)). - **`Mailer::deliver_now` / `mail_template_now` for synchronous sends.** Complements `Mailer::mail`/`mail_template` (which enqueue via the background worker, like Rails `deliver_later`) with an inline send that bypasses the queue (Rails `deliver_now`). - **`MiddlewareStackExt` for surgical middleware-stack edits.** Inside `Hooks::middlewares`, tweak the default stack instead of rebuilding it: `stack.insert_before("cors", ..)`, `.insert_after(..)`, `.replace(..)`, and `.delete("logger")` — matched by middleware name (Rails' `config.middleware.insert_before`/`delete`). Available via the prelude. - **Optional JWT extraction.** `JWT` now implements `OptionalFromRequestParts`, so a handler can take `Option` to serve authenticated and anonymous callers from one endpoint (`Some` when a valid token is present, `None` otherwise). - **Ergonomic verb-explicit route methods.** `Routes` now has `get`/`post`/ `put`/`delete`/`patch`/`head`/`options`/`trace` builder methods — `Routes::new().get("/ping", ping)` alongside the existing `.add("/ping", get(ping))`. They record the HTTP verb directly (exact `cargo loco routes` output without relying on the debug-format regex). Purely additive; `add` is unchanged. - **Opt-in background-job reaper (visibility timeout).** Each queue backend's config accepts a `reaper: { age_minutes, interval_seconds }` block. When set, the worker periodically requeues jobs stranded in `Processing` (e.g. by a crashed worker) back to `Queued`, instead of requiring a manual `cargo loco jobs requeue`. Disabled by default — existing behavior is unchanged. - **TLS to managed Postgres and Redis.** Postgres TLS works via the connection URL (`sslmode=require`, `sslrootcert=...`) with no feature flag, and a new `redis_tls` feature enables `rediss://` for both the queue and cache Redis backends (webpki roots, pure-Rust `ring` provider — no C toolchain). New how-to: "Connect to Postgres and Redis over TLS". ([#1191](https://github.com/loco-rs/loco/issues/1191), [#1341](https://github.com/loco-rs/loco/issues/1341)) - **Typed, streaming `db::dump::()`** — counterpart to `db::seed::()` that streams rows through their entity `Model` straight to disk (memory bounded to a single row) with full type fidelity. New `Hooks::dump` (default dumps every table; override it to call `db::dump` per entity) backs `cargo loco db seed --dump`. ([#1691](https://github.com/loco-rs/loco/issues/1691)) - **`logger::init_layer` / `logger::init_env_filter` are now public** building blocks, so an app overriding `Hooks::init_logger` can reuse Loco's formatting and filter policy while adding its own layers (e.g. `tracing-flame`, OTLP). ([#1753](https://github.com/loco-rs/loco/issues/1753)) ### Changed - Wrap `TeraView` in `Arc` to reduce runtime memory usage ([#1703](https://github.com/loco-rs/loco/pull/1703)). - Refactor users model to reuse `find_by_api_key` in `Authenticable` ([#1706](https://github.com/loco-rs/loco/pull/1706)). - Split error detail generic parameters ([#1709](https://github.com/loco-rs/loco/pull/1709)). - Update `loco-new` for the new Rhai version ([#1704](https://github.com/loco-rs/loco/pull/1704)). - Replaced hand-rolled `Cargo.lock` parsing with the `cargo-lock` crate; retired `duct_sh`. - **`Error` → HTTP-status mapping is now exhaustive.** The `IntoResponse for Error` match dropped its trailing `_ => 500` wildcard: every variant (and every nested `ModelError` variant) is now classified explicitly, so adding a new error variant is a compile error until its status is chosen — it can no longer silently default to `500`. The `Error` enum is also reorganized into client-facing vs internal/infra regions. Behavior is unchanged (all infra errors still map to `500`); no variant was renamed, so existing code is unaffected. - **Rust edition 2024.** `loco-rs`, `loco-gen`, `xtask`, and the `loco` new-app generator now compile on edition 2024 (MSRV floor unchanged at 1.94; edition 2024 needs ≥ 1.85). Editions are per-crate, so apps depending on Loco need not change. Newly generated apps stay on edition 2021 for now. - Deduplicated the Postgres and SQLite background-queue providers: the shared `Job`/`JobRegistry`/`RunOpts` now live in one module behind a `Driver` trait (internal refactor, no behavior or API-path change). - In-memory cache now uses `moka::future::Cache` instead of wrapping the synchronous cache behind `#[async_trait]` (removes a sync-behind-async smell; no API change). - Cookie token extraction now uses `axum_extra`'s `Cookie::value()` instead of hand-parsing the cookie string (byte-identical behavior). - Internal de-duplication pass (no public-API-path or behavior change unless noted): the response helpers in `format` are now single-sourced through `RenderBuilder`; the `JWT`/`JWTWithUser` extractors share one validate/decode helper; the six validate extractors are generated from shared decoder fns + two error-tier macros; the byte-identical `Job` struct is shared across the SQL and Redis queue backends; the twin `cli::main` functions share one `dispatch_common`; and duplicate env-var name constants were removed. - `format`'s two response paths were converged onto axum's canonical behavior: `RenderBuilder::json` and `RenderBuilder::redirect_with_header_key` are now infallible with respect to bad input (they return a `500` response, matching `axum::Json` / `axum::response::Redirect`) instead of returning `Err`. ### Fixed - **`db seed --dump` datetime round-trip on SQLite.** Loco's timestamptz columns default to `CURRENT_TIMESTAMP`, which SQLite stores as space-separated text (`"YYYY-MM-DD HH:MM:SS"`); dumps captured that verbatim and then failed chrono's RFC3339 parse on re-seed (`Json("premature end of input")`). Dumps now normalize such datetimes to RFC3339 (already-RFC3339 text is untouched). ([#1736](https://github.com/loco-rs/loco/issues/1736), [#1691](https://github.com/loco-rs/loco/issues/1691)) - `cargo fmt` error in `loco-new` ([#1669](https://github.com/loco-rs/loco/pull/1669)). - UUID pattern in form field generation ([#1665](https://github.com/loco-rs/loco/pull/1665)). - Clippy warnings for recent Rust ([#1705](https://github.com/loco-rs/loco/pull/1705)). - Add tests for the auth extractor ([#1671](https://github.com/loco-rs/loco/pull/1671)). - **Postgres/SQLite queue backends now behave consistently.** Two divergences between the Postgres and SQLite job backends are fixed: (1) `enqueue` on Postgres previously *swallowed* a tag-serialization error (storing `tags = null`); it now propagates the error like SQLite. (2) `complete_job` without a repeat interval on Postgres stamped `run_at = NOW()` on the completed row while SQLite left it untouched; Postgres now leaves `run_at` as-is, matching SQLite (the interval path still reschedules `run_at` on both). The shared `to_job` row mapper is now single-sourced across both backends. - **Storage mirror fan-out no longer stops at the first failing secondary.** `rename`, `copy`, and `upload_stream` checked the failure mode *inside* the secondary loop and returned early on the first failure, silently leaving later mirrors stale (`upload`/`delete` were already correct). All five mutating methods now share one helper that attempts every secondary (concurrently) and applies the failure mode once. - **Postgres `BOOLEAN` columns are no longer dropped from `dump_tables`.** The decode probe chain had no `bool` arm, so PG booleans (which don't fall back to the numeric arms like SQLite's integer-backed booleans) were silently omitted. - **`Hooks::on_shutdown` now runs in worker-only start modes.** `WorkerOnly` and `WorkerAndScheduler` bypassed `H::serve` (the hook's only caller); the shutdown hook is now invoked on their shutdown path too. - **Postgres admin/maintenance URI is derived with the `url` crate.** Building it via `db_uri.replace(db_name, "/postgres")` corrupted the URI when the database name also appeared in the host or credentials. - **Foreign-key names are normalized consistently.** `reference_id` received a normalized table name in `create_table` but raw names in `add_reference`/`remove_reference`, so irregular plurals produced mismatched FK column/constraint names between creation and later add/remove. - `ViewEngine` extractor now rejects gracefully (HTTP `500`) when the opt-in Tera layer is absent, instead of declaring `Infallible` and then panicking. - `cargo loco routes` lists every HTTP verb of a multi-method route (route introspection previously reported only the first). - Removed a fossilized 3-second `sleep` on every Redis queue boot (a leaked test-isolation artifact; Postgres/SQLite had no equivalent). - Password redaction in test snapshots (`cleanup_user_model`) now targets the quoted value precisely; the previous pattern had a degenerate quantifier that swallowed the field following `password`. - Postgres test-database cleanup now completes synchronously (a joined worker thread) instead of a fire-and-forget task, so parallel test runs no longer leak databases; `PostgresTest` also builds its connection strings with the `url` crate rather than a corruption-prone substring replace. - `RenderBuilder::template` now threads the builder's chained `status`/`header`/ `etag`/`cookies` through to the response; it previously delegated to the free `html()` and silently dropped them. - `llms.txt`: two `Core concepts` links pointed at doc pages that don't exist (`the-app/configuration/`, `the-app/testing/`); repointed to the sections that actually document them. A new `cargo xtask llms-check` CI step now verifies the curated LLM docs against the docs tree so these links can't drift silently. ### Removed - **`Error` enum narrowing.** Removed four low-value/dependency-leaking variants that all mapped to HTTP 500 and were never matched: `Error::EnvVar`, `Error::SemVer`, `Error::TaskJoinError`, and `Error::Hash` (hashing errors now surface as `Error::Message`). `Error` remains `#[non_exhaustive]`, so exhaustive matches already require a wildcard arm and are unaffected. - Deleted shipped-but-dead code: the never-compiled `controller/middleware/_archive/content_etag.rs` module and a commented-out block of backtrace-blocklist regexes. ## v0.16.4 - Feat: decouple JWT authentication from database dependency. [https://github.com/loco-rs/loco/pull/1546](https://github.com/loco-rs/loco/pull/1546) - Fix: add sqlx dependency to with-db feature. [https://github.com/loco-rs/loco/pull/1557](https://github.com/loco-rs/loco/pull/1557) - Remove the deprecated `--link` generate command and fix the table name creation. [https://github.com/loco-rs/loco/pull/1556](https://github.com/loco-rs/loco/pull/1556) - Support underscore for migration join table. [https://github.com/loco-rs/loco/pull/1562](https://github.com/loco-rs/loco/pull/1562) - Fix: resolve deployment CLI argument parsing issue. [https://github.com/loco-rs/loco/pull/1566](https://github.com/loco-rs/loco/pull/1566) - Add database enum support (Postgres only). [https://github.com/loco-rs/loco/pull/1593](https://github.com/loco-rs/loco/pull/1568) - Remove duplicated #[async_trait::async_trait]. [https://github.com/loco-rs/loco/pull/1593](https://github.com/loco-rs/loco/pull/1572) - Clippy fixes for Rust 1.89. [https://github.com/loco-rs/loco/pull/1593](https://github.com/loco-rs/loco/pull/1593) - Improvement: do not hot-reload unless files have changed. [https://github.com/loco-rs/loco/pull/1552](https://github.com/loco-rs/loco/pull/1552) - Feat: add --without-tz flag for controlling timestamp generation. [https://github.com/loco-rs/loco/pull/1592](https://github.com/loco-rs/loco/pull/1592) - Support extra fields when generating the join table migration. [https://github.com/loco-rs/loco/pull/1595](https://github.com/loco-rs/loco/pull/1595) - Convert validator to trait-based API (add ValidatorTrait, keep derive adapter, update docs). [https://github.com/loco-rs/loco/pull/1597](https://github.com/loco-rs/loco/pull/1597) - Rename dockerfile to Dockerfile. [https://github.com/loco-rs/loco/pull/1574](https://github.com/loco-rs/loco/pull/1574) - Enable edit CORS expose headers. [https://github.com/loco-rs/loco/pull/1599](https://github.com/loco-rs/loco/pull/1599) - Adding new imports about multipart. [https://github.com/loco-rs/loco/pull/1600](https://github.com/loco-rs/loco/pull/1600) - Adding readiness default endpoint. [https://github.com/loco-rs/loco/pull/1563](https://github.com/loco-rs/loco/pull/1563) - Add Route methods to make collecting and nesting easier. [https://github.com/loco-rs/loco/pull/1608](https://github.com/loco-rs/loco/pull/1608) - Add streaming support for both download and upload. [https://github.com/loco-rs/loco/pull/1610](https://github.com/loco-rs/loco/pull/1610) - Fix Clippy for Rust 1.90. [https://github.com/loco-rs/loco/pull/1630](https://github.com/loco-rs/loco/pull/1630) - Loco CLI: Update rhai version. [https://github.com/loco-rs/loco/pull/1631](https://github.com/loco-rs/loco/pull/1631) ## v0.16.3 - Support nullable foreign keys with `references?` syntax. [https://github.com/loco-rs/loco/pull/1544](https://github.com/loco-rs/loco/pull/1544) - **HOTFIX**: **Breaking changes** Fixed a critical issue introduced in version `v0.16.2` that caused `cargo build --release` to fail after merging #1540. [https://github.com/loco-rs/loco/pull/1551](https://github.com/loco-rs/loco/pull/1551) - Add an API to re-send verification mail. [https://github.com/loco-rs/loco/pull/1456](https://github.com/loco-rs/loco/pull/1456) - Adding to ci cargo build --release. [https://github.com/loco-rs/loco/pull/1553](https://github.com/loco-rs/loco/pull/1553) ### Breaking Changes In file `src/initializers/view_engine.rs`, modify the method `after_routes`: Before ```rust async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result { #[allow(unused_mut)] let mut tera_engine = engines::TeraView::build()?; if std::path::Path::new(I18N_DIR).exists() { let arc = ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US")) .shared_resources(Some(&[I18N_SHARED.into()])) .customize(|bundle| bundle.set_use_isolating(false)) .build() .map_err(|e| Error::string(&e.to_string()))?; #[cfg(debug_assertions)] tera_engine .tera .lock() .expect("lock") .register_function("t", FluentLoader::new(arc)); #[cfg(not(debug_assertions))] tera_engine .tera .register_function("t", FluentLoader::new(arc)); info!("locales loaded"); } Ok(router.layer(Extension(ViewEngine::from(tera_engine)))) } ``` After (use `post_process` to add i18n initialization code) ```rust async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result { let tera_engine = if std::path::Path::new(I18N_DIR).exists() { let arc = std::sync::Arc::new( ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US")) .shared_resources(Some(&[I18N_SHARED.into()])) .customize(|bundle| bundle.set_use_isolating(false)) .build() .map_err(|e| Error::string(&e.to_string()))?, ); info!("locales loaded"); engines::TeraView::build()?.post_process(move |tera| { tera.register_function("t", FluentLoader::new(arc.clone())); Ok(()) })? } else { engines::TeraView::build()? }; Ok(router.layer(Extension(ViewEngine::from(tera_engine)))) } ``` ## v0.16.2 - Update auth import in the Authentication document. [https://github.com/loco-rs/loco/pull/1531](https://github.com/loco-rs/loco/pull/1531) - Adding cache control header to the static asset middleware. [https://github.com/loco-rs/loco/pull/1535](https://github.com/loco-rs/loco/pull/1535) - Fix borrow checker when sending config to handle_job_command when feature with-db is off. [https://github.com/loco-rs/loco/pull/1536](https://github.com/loco-rs/loco/pull/1536) - feat: add initializer health checks to doctor command. [https://github.com/loco-rs/loco/pull/1537](https://github.com/loco-rs/loco/pull/1537) - Update shuttle template to 0.56. [https://github.com/loco-rs/loco/pull/1518](https://github.com/loco-rs/loco/pull/1518) - Encapsulate post-processing into Tera engine creation. [https://github.com/loco-rs/loco/pull/1540](https://github.com/loco-rs/loco/pull/1540) - Adding QueryValidateWithMessage. [https://github.com/loco-rs/loco/pull/1521](https://github.com/loco-rs/loco/pull/1521) - Add S3 driver with credentials and endpoint support. [https://github.com/loco-rs/loco/pull/1539](https://github.com/loco-rs/loco/pull/1539) ## v0.16.1 - fix clippy result_large_err. [https://github.com/loco-rs/loco/pull/1496](https://github.com/loco-rs/loco/pull/1496) - chore: remove async-std. [https://github.com/loco-rs/loco/pull/1492](https://github.com/loco-rs/loco/pull/1492) - fix: Bump shuttle version to 0.55.0. [https://github.com/loco-rs/loco/pull/1488](https://github.com/loco-rs/loco/pull/1488) - Change the Docker building image to 1.87. [https://github.com/loco-rs/loco/pull/1475](https://github.com/loco-rs/loco/pull/1475) - Fix Clippy warnings for Rust 1.88 stable. [https://github.com/loco-rs/loco/pull/1519](https://github.com/loco-rs/loco/pull/1519) - Remove Migrator from boot_test_* doc comments. [https://github.com/loco-rs/loco/pull/1512](https://github.com/loco-rs/loco/pull/1512) - fix: use rust-lld linker on Windows. [https://github.com/loco-rs/loco/pull/1508](https://github.com/loco-rs/loco/pull/1508) - Fix precompressed in static assets. [https://github.com/loco-rs/loco/pull/1524](https://github.com/loco-rs/loco/pull/1524) - Support multiple JWT locations. [https://github.com/loco-rs/loco/pull/1497](https://github.com/loco-rs/loco/pull/1497) ## v0.16.0 **Note:** For detailed upgrade steps for breaking changes, see the [upgrade guide](https://loco.rs/docs/extras/upgrades/#upgrade-from-0-15-x-to-0-16-x). - chore: improve readability and performance by using map_err in Model. [https://github.com/loco-rs/loco/pull/1311](https://github.com/loco-rs/loco/pull/1311) - Allow testing the controller by passing a cookie. [https://github.com/loco-rs/loco/pull/1326](https://github.com/loco-rs/loco/pull/1326) - Support BigInt in the scaffold Array. [https://github.com/loco-rs/loco/pull/1304](https://github.com/loco-rs/loco/pull/1304) - Add `escape` Tera function to the scaffold list template. [https://github.com/loco-rs/loco/pull/1337](https://github.com/loco-rs/loco/pull/1337) - Return a specific error when logging in with a non-existent email. [https://github.com/loco-rs/loco/pull/1336](https://github.com/loco-rs/loco/pull/1336) - Return a specific error when trying to verify with an invalid token. [https://github.com/loco-rs/loco/pull/1340](https://github.com/loco-rs/loco/pull/1340) - Clippy 1.86. [https://github.com/loco-rs/loco/pull/1353](https://github.com/loco-rs/loco/pull/1353) - Fix the DB creation. [https://github.com/loco-rs/loco/pull/1352](https://github.com/loco-rs/loco/pull/1352) - YAML responses. [https://github.com/loco-rs/loco/pull/1360](https://github.com/loco-rs/loco/pull/1360) - Swap to the validators' built-in email validation. [https://github.com/loco-rs/loco/pull/1359](https://github.com/loco-rs/loco/pull/1359) - Cancellation tokens for the Postgres and SQLite background workers. [https://github.com/loco-rs/loco/pull/1365](https://github.com/loco-rs/loco/pull/1365) - docs: testing auth routes. [https://github.com/loco-rs/loco/pull/1303](https://github.com/loco-rs/loco/pull/1303) - Add comprehensive tests for the task module. [https://github.com/loco-rs/loco/pull/1386](https://github.com/loco-rs/loco/pull/1386) - Add comprehensive test coverage for the data module. [https://github.com/loco-rs/loco/pull/1387](https://github.com/loco-rs/loco/pull/1387) - Add validator extractors test suite. [https://github.com/loco-rs/loco/pull/1388](https://github.com/loco-rs/loco/pull/1388) - **Breaking changes** Replace sidekiq job management: existing Redis jobs incompatible. [https://github.com/loco-rs/loco/pull/1384](https://github.com/loco-rs/loco/pull/1384) - **Breaking changes** Add generic type support to the Cache API: cache method calls need type parameters. [https://github.com/loco-rs/loco/pull/1385](https://github.com/loco-rs/loco/pull/1385) - Adding cache redis driver + configuration instead of enabling from code. [https://github.com/loco-rs/loco/pull/1389](https://github.com/loco-rs/loco/pull/1389) - Ability to configure pragma for SQLite. [https://github.com/loco-rs/loco/pull/1346](https://github.com/loco-rs/loco/pull/1346) - **Breaking changes** swap to validators builtin email validation: custom email validator syntax changed. [https://github.com/loco-rs/loco/pull/1359](https://github.com/loco-rs/loco/pull/1359) - Optimize worker tag filtering string handling. [https://github.com/loco-rs/loco/pull/1396](https://github.com/loco-rs/loco/pull/1396) - Add test coverage for db.rs. [https://github.com/loco-rs/loco/pull/1400](https://github.com/loco-rs/loco/pull/1400) - Allow storage of arbitrary custom objects in AppContext. [https://github.com/loco-rs/loco/pull/1404](https://github.com/loco-rs/loco/pull/1404) - Improve deployment generator CLI. [https://github.com/loco-rs/loco/pull/1413](https://github.com/loco-rs/loco/pull/1413) - Move auth and validate to the extractor folder. [https://github.com/loco-rs/loco/pull/1414](https://github.com/loco-rs/loco/pull/1414) - Hot reload on extended Tera templates. [https://github.com/loco-rs/loco/pull/1416](https://github.com/loco-rs/loco/pull/1416) - **Breaking changes** Update the `init_logger` to use `AppContext` instead of config: function signature changed. [https://github.com/loco-rs/loco/pull/1418](https://github.com/loco-rs/loco/pull/1418) - Support embedded assets. [https://github.com/loco-rs/loco/pull/1427](https://github.com/loco-rs/loco/pull/1427) - **Removed dependencies:** - [`hyper`](https://github.com/loco-rs/loco/pull/1430) - [`thousands`](https://github.com/loco-rs/loco/pull/1431) - [`cfg-if`](https://github.com/loco-rs/loco/pull/1432) - [`reqwest`](https://github.com/loco-rs/loco/pull/1434) - [`serde_variant`](https://github.com/loco-rs/loco/pull/1493) * **Dependency updates:** - Bumped [`tokio`] to `1.45` and [`tokio-util`] to `0.7` ([#1435](https://github.com/loco-rs/loco/pull/1435)) - Bumped [`colored`] to `3.0` ([#1437](https://github.com/loco-rs/loco/pull/1437)) - Bumped [`rand`] to `0.9` ([#1439](https://github.com/loco-rs/loco/pull/1439)) - Bumped [`duct`] to `1.0` ([#1438](https://github.com/loco-rs/loco/pull/1438)) - Bumped [`redis`] to `0.31`, [`bb8`] to `0.9`, and [`bb8-redis`] to `0.23` ([commit `7e7be`](https://github.com/loco-rs/loco/commit/7e7bebe15f74c377c93d979aab41c52eb871d667)) - Updated Loco template crates ([#1440](https://github.com/loco-rs/loco/pull/1440)) - Support custom flags from `sea-orm entity`. [https://github.com/loco-rs/loco/pull/1442](https://github.com/loco-rs/loco/pull/1442) - Better `loco new` cleanup folders. [https://github.com/loco-rs/loco/pull/1429](https://github.com/loco-rs/loco/pull/1429) - Remove legacy mailer derive macro code. [https://github.com/loco-rs/loco/pull/1472](https://github.com/loco-rs/loco/pull/1472) - Make extract_token and get_jwt_from_config fn public. [https://github.com/loco-rs/loco/pull/1495](https://github.com/loco-rs/loco/pull/1495) ## v0.15.0 - Added total_items to pagination view & response. [https://github.com/loco-rs/loco/pull/1197](https://github.com/loco-rs/loco/pull/1197) - Flatten (de)serialization of custom user claims. [https://github.com/loco-rs/loco/pull/1159](https://github.com/loco-rs/loco/pull/1159) - Updated validator to 0.20. [https://github.com/loco-rs/loco/pull/1199](https://github.com/loco-rs/loco/pull/1199) - Scaffold v2. [https://github.com/loco-rs/loco/pull/1209](https://github.com/loco-rs/loco/pull/1209) - Fix generator Docker deployment to support both server-side and client-side rendering. [https://github.com/loco-rs/loco/pull/1227](https://github.com/loco-rs/loco/pull/1227) - Docs: num_workers worker configuration. [https://github.com/loco-rs/loco/pull/1242](https://github.com/loco-rs/loco/pull/1242) - Smoother model validations. [https://github.com/loco-rs/loco/pull/1233](https://github.com/loco-rs/loco/pull/1233) - Docs: num_workers worker configuration. [https://github.com/loco-rs/loco/pull/1242](https://github.com/loco-rs/loco/pull/1242) - Ignore SQLite WAL and SHM files and update Cargo watch crate docs. [https://github.com/loco-rs/loco/pull/1254](https://github.com/loco-rs/loco/pull/1254) - Remove fs-err crate. [https://github.com/loco-rs/loco/pull/1253](https://github.com/loco-rs/loco/pull/1253) - Allows to run scheduler as part of cargo loco start. [https://github.com/loco-rs/loco/pull/1247](https://github.com/loco-rs/loco/pull/1247) - Added prefix and route nesting to AppRoutes. [https://github.com/loco-rs/loco/pull/1241](https://github.com/loco-rs/loco/pull/1241) - Replace hyper crate with axum. [https://github.com/loco-rs/loco/pull/1258](https://github.com/loco-rs/loco/pull/1258) - Remove mime crate. [https://github.com/loco-rs/loco/pull/1256](https://github.com/loco-rs/loco/pull/1256) - Support async tests. [https://github.com/loco-rs/loco/pull/1237](https://github.com/loco-rs/loco/pull/1237) - Change job queue status from cli. [https://github.com/loco-rs/loco/pull/1228](https://github.com/loco-rs/loco/pull/1228) - Handle panics in queue worker. [https://github.com/loco-rs/loco/pull/1274](https://github.com/loco-rs/loco/pull/1274) - Schema with defaults. [https://github.com/loco-rs/loco/pull/1273](https://github.com/loco-rs/loco/pull/1273) - Add data subsystem. [https://github.com/loco-rs/loco/pull/1267](https://github.com/loco-rs/loco/pull/1267) - Add "endpoint" arg to azure storage builder.[https://github.com/loco-rs/loco/pull/1317](https://github.com/loco-rs/loco/pull/1317) - Improve readability and performance by using map_err in Model. [https://github.com/loco-rs/loco/pull/1311](https://github.com/loco-rs/loco/pull/1311) ### Breaking Changes In module `loco_rs::auth::jwt` in struct `JWT`, the impl method `generate_token` signature has changed. Migration: Before ```rust jwt.generate_token(&expiration, pid.clone(), None); ``` After ```rust jwt.generate_token(expiration, pid.clone(), Map::new()); // ^ no "&" ^ serde_json::map (doesn't allocate in constructor) ``` ## v0.14.1 - Fix: bump shuttle to 0.51.0. [https://github.com/loco-rs/loco/pull/1169](https://github.com/loco-rs/loco/pull/1169) - Return 422 status code for JSON rejection errors. [https://github.com/loco-rs/loco/pull/1173](https://github.com/loco-rs/loco/pull/1173) - Address clippy warnings for Rust stable 1.84. [https://github.com/loco-rs/loco/pull/1168](https://github.com/loco-rs/loco/pull/1168) - Bump shuttle to 0.51.0. [https://github.com/loco-rs/loco/pull/1169](https://github.com/loco-rs/loco/pull/1169) - Return 422 status code for JSON rejection errors. [https://github.com/loco-rs/loco/pull/1173](https://github.com/loco-rs/loco/pull/1173) - Return json validation details response. [https://github.com/loco-rs/loco/pull/1174](https://github.com/loco-rs/loco/pull/1174) - Fix example command after generating schedule. [https://github.com/loco-rs/loco/pull/1176](https://github.com/loco-rs/loco/pull/1176) - Fixed independent features. [https://github.com/loco-rs/loco/pull/1177](https://github.com/loco-rs/loco/pull/1177) - Custom response header for redirect. [https://github.com/loco-rs/loco/pull/1186](https://github.com/loco-rs/loco/pull/1186) - Added run_on_start feature to scheduler. [https://github.com/loco-rs/loco/pull/1184](https://github.com/loco-rs/loco/pull/1184) - feat: public jwt extractor from non-mutable reference to parts. [https://github.com/loco-rs/loco/pull/1190](https://github.com/loco-rs/loco/pull/1190) ## v0.14 - feat: smart migration generator. you can now generate migration based on naming them for creating a table, adding columns, references, join tables and more. [https://github.com/loco-rs/loco/pull/1086](https://github.com/loco-rs/loco/pull/1086) - feat: `cargo loco routes` will now pretty-print routes - fix: guard jwt error behind feature flag. [https://github.com/loco-rs/loco/pull/1032](https://github.com/loco-rs/loco/pull/1032) - fix: logger file_appender not using the seperated format setting. [https://github.com/loco-rs/loco/pull/1036](https://github.com/loco-rs/loco/pull/1036) - seed cli command. [https://github.com/loco-rs/loco/pull/1046](https://github.com/loco-rs/loco/pull/1046) - Updated validator to 0.19. [https://github.com/loco-rs/loco/pull/993](https://github.com/loco-rs/loco/pull/993) ### Breaking Changes Bump validator to 0.19 in your local `Cargo.toml` - Testing helpers: simplified function calls + adding html selector. [https://github.com/loco-rs/loco/pull/1047](https://github.com/loco-rs/loco/pull/1047) ### Breaking Changes #### Updated Import Paths The testing module import path has been updated. To adapt your code, update imports from: ```rust use loco_rs::testing; ``` to: ```rust use testing::prelude::*; ``` #### Simplified Function Calls Function calls within the testing module no longer require the testing:: prefix. Update your code accordingly. For example: Before: ```rust let boot = testing::boot_test::().await.unwrap(); ``` After: ```rust let boot = boot_test::().await.unwrap(); ``` - implement commands to manage background jobs. [https://github.com/loco-rs/loco/pull/1071](https://github.com/loco-rs/loco/pull/1071) - magic link. [https://github.com/loco-rs/loco/pull/1085](https://github.com/loco-rs/loco/pull/1085) - infer migration. [https://github.com/loco-rs/loco/pull/1086](https://github.com/loco-rs/loco/pull/1086) - Remove unnecessary calls to 'register_tasks' functions in scheduler. [https://github.com/loco-rs/loco/pull/1100](https://github.com/loco-rs/loco/pull/1100) - implement commands to manage background jobs. [https://github.com/loco-rs/loco/pull/1071](https://github.com/loco-rs/loco/pull/1071) - expose hello_name for SMTP client config. [https://github.com/loco-rs/loco/pull/1057](https://github.com/loco-rs/loco/pull/1057) - use reqwest with rustls rather than openssl. [https://github.com/loco-rs/loco/pull/1058](https://github.com/loco-rs/loco/pull/1058) - more flexible config, take more values from ENV. [https://github.com/loco-rs/loco/pull/1058](https://github.com/loco-rs/loco/pull/1058) - refactor: Use opendal to replace object_store. [https://github.com/loco-rs/loco/pull/897](https://github.com/loco-rs/loco/pull/897) - allow override loco template. [https://github.com/loco-rs/loco/pull/1102](https://github.com/loco-rs/loco/pull/1102) - support custom config folder. [https://github.com/loco-rs/loco/pull/1081](https://github.com/loco-rs/loco/pull/1081) - feat: upgrade to Axum 8. [https://github.com/loco-rs/loco/pull/1130](https://github.com/loco-rs/loco/pull/1130) - create load config hook. [https://github.com/loco-rs/loco/pull/1143](https://github.com/loco-rs/loco/pull/1143) - initial impl new migration dsl. [https://github.com/loco-rs/loco/pull/1125](https://github.com/loco-rs/loco/pull/1125) - allow disable limit_payload middleware. [https://github.com/loco-rs/loco/pull/1113](https://github.com/loco-rs/loco/pull/1113) ## v0.13.2 - static fallback now returns 200 and not 404 [https://github.com/loco-rs/loco/pull/991](https://github.com/loco-rs/loco/pull/991) - cache system now has expiry [https://github.com/loco-rs/loco/pull/1006](https://github.com/loco-rs/loco/pull/1006) - fixed: http interface binding [https://github.com/loco-rs/loco/pull/1007](https://github.com/loco-rs/loco/pull/1007) - JWT claims now editable and public [https://github.com/loco-rs/loco/issues/988](https://github.com/loco-rs/loco/issues/988) - CORS now not enabled in dev mode to avoid friction [https://github.com/loco-rs/loco/pull/1009](https://github.com/loco-rs/loco/pull/1009) - fixed: task code generation now injects in all cases [https://github.com/loco-rs/loco/pull/1012](https://github.com/loco-rs/loco/pull/1012) **BREAKING** In your `app.rs` add the following injection comment at the bottom: ```rust fn register_tasks(tasks: &mut Tasks) { tasks.register(tasks::user_report::UserReport); tasks.register(tasks::seed::SeedData); tasks.register(tasks::foo::Foo); // tasks-inject (do not remove) } ``` - fix: seeding now sets autoincrement fields in the relevant DBs [https://github.com/loco-rs/loco/pull/1014](https://github.com/loco-rs/loco/pull/1014) - fix: avoid generating entities from queue tables when the queue backend is database based [https://github.com/loco-rs/loco/issues/1013](https://github.com/loco-rs/loco/issues/1013) - removed: channels moved to an initializer [https://github.com/loco-rs/loco/issues/892](https://github.com/loco-rs/loco/issues/892) **BREAKING** See how this looks like in [https://github.com/loco-rs/chat-rooms](https://github.com/loco-rs/chat-rooms) ## v0.13.0 - Added SQLite background job support [https://github.com/loco-rs/loco/pull/969](https://github.com/loco-rs/loco/pull/969) - Added automatic updating of `updated_at` on change [https://github.com/loco-rs/loco/pull/962](https://github.com/loco-rs/loco/pull/962) - fixed codegen injection point in migrations [https://github.com/loco-rs/loco/pull/952](https://github.com/loco-rs/loco/pull/952) **NOTE: update your migration listing module like so:** ```rust // migrations/src/lib.rs vec![ Box::new(m20220101_000001_users::Migration), Box::new(m20231103_114510_notes::Migration), Box::new(m20240416_071825_roles::Migration), Box::new(m20240416_082115_users_roles::Migration), // inject-above (do not remove this comment) ] ``` Add the comment just before the closing array (`inject-above`) - Added ability to name references in [https://github.com/loco-rs/loco/pull/955](https://github.com/loco-rs/loco/pull/955): ```sh $ generate scaffold posts title:string! content:string! written_by:references:users approved_by:references:users ``` - Added hot-reload like experience to Tera templates [https://github.com/loco-rs/loco/issues/977](https://github.com/loco-rs/loco/issues/977), in debug builds only. **NOTE: update your initializers `after_routes` like so:** ```rust // src/initializers/view_engine.rs async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result { #[allow(unused_mut)] let mut tera_engine = engines::TeraView::build()?; if std::path::Path::new(I18N_DIR).exists() { let arc = ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US")) .shared_resources(Some(&[I18N_SHARED.into()])) .customize(|bundle| bundle.set_use_isolating(false)) .build() .map_err(|e| Error::string(&e.to_string()))?; #[cfg(debug_assertions)] tera_engine .tera .lock() .expect("lock") .register_function("t", FluentLoader::new(arc)); #[cfg(not(debug_assertions))] tera_engine .tera .register_function("t", FluentLoader::new(arc)); info!("locales loaded"); } Ok(router.layer(Extension(ViewEngine::from(tera_engine)))) } ``` - `loco doctor` now checks for app-specific minimum dependency versions. This should help in upgrades. `doctor` also supports "production only" checks which you can run in production with `loco doctor --production`. This, for example, will check your connections but will not check dependencies. [https://github.com/loco-rs/loco/pull/931](https://github.com/loco-rs/loco/pull/931) - Use a single loco-rs dep for a whole project. [https://github.com/loco-rs/loco/pull/927](https://github.com/loco-rs/loco/pull/927) - chore: fix generated testcase. [https://github.com/loco-rs/loco/pull/939](https://github.com/loco-rs/loco/pull/939) - chore: Correct cargo test message. [https://github.com/loco-rs/loco/pull/938](https://github.com/loco-rs/loco/pull/938) - Add relevant meta tags for better defaults. [https://github.com/loco-rs/loco/pull/943](https://github.com/loco-rs/loco/pull/943) - Update cli message with correct command. [https://github.com/loco-rs/loco/pull/942](https://github.com/loco-rs/loco/pull/942) - remove lazy_static. [https://github.com/loco-rs/loco/pull/941](https://github.com/loco-rs/loco/pull/941) - change update HTTP verb semantics to put+patch. [https://github.com/loco-rs/loco/pull/919](https://github.com/loco-rs/loco/pull/919) - Fixed HTML scaffold error. [https://github.com/loco-rs/loco/pull/960](https://github.com/loco-rs/loco/pull/960) - Scaffolded HTML update method should be POST. [https://github.com/loco-rs/loco/pull/963](https://github.com/loco-rs/loco/pull/963) ## v0.12.0 This release have been primarily about cleanups and simplification. Please update: - `loco-rs` - `loco-cli` Changes: - **generators (BREAKING)**: all prefixes in starters (e.g. `/api`) are now _local to each controller_, and generators will be prefix-aware (`--api` generator will add an `/api` prefix to controllers) [https://github.com/loco-rs/loco/pull/818](https://github.com/loco-rs/loco/pull/818) To migrate, please move prefixes from `app.rs` to each controller you use in `controllers/`, for example in `notes` controller: ```rust Routes::new() .prefix("api/notes") .add("/", get(list)) ``` - **starters**: removed `.devcontainer` which can now be found in [loco-devcontainer](https://github.com/loco-rs/loco-devcontainer) - **starters**: removed example `notes` scaffold (model, controllers, etc), and unified `user` and `auth` into a single file: `auth.rs` - **generators**: `scaffold` generator will now generate a CRUD with `PUT` and `PATCH` semantics for updating an entity [https://github.com/loco-rs/loco/issues/896](https://github.com/loco-rs/loco/issues/896) - **cleanup**: `loco-extras` was moved out of the repo, but we've incorporated `MultiDB` and `ExtraDB` from `extras` into `loco-rs` [https://github.com/loco-rs/loco/pull/917](https://github.com/loco-rs/loco/pull/917) - `cargo loco doctor` now checks for minimal required SeaORM CLI version - **BREAKING** Improved migration generator. If you have an existing migration project, add the following comment indicator to the top of the `vec` statement and right below the opening bracked like so in `migration/src/lib.rs`: ```rust fn migrations() -> Vec> { vec![ // inject-below (do not remove this comment) ``` ## v0.11.0 - Upgrade **SeaORM to v1.1.0** - Added OpenAPI example - Improve health route [https://github.com/loco-rs/loco/pull/851](https://github.com/loco-rs/loco/pull/851) - Add good pragmas to Sqlite [https://github.com/loco-rs/loco/pull/848](https://github.com/loco-rs/loco/pull/848) - Upgrade to rsbuild 1.0. [https://github.com/loco-rs/loco/pull/792](https://github.com/loco-rs/loco/pull/792) - Implements fmt::Debug to pub structs. [https://github.com/loco-rs/loco/pull/812](https://github.com/loco-rs/loco/pull/812) - Add num_workers config for sidekiq queue. [https://github.com/loco-rs/loco/pull/823](https://github.com/loco-rs/loco/pull/823) - Fix some comments in the starters and example code. [https://github.com/loco-rs/loco/pull/824](https://github.com/loco-rs/loco/pull/824) - Fix Y2038 bug for JWT on 32 bit platforms. [https://github.com/loco-rs/loco/pull/825](https://github.com/loco-rs/loco/pull/825) - Make App URL in Boot Banner Clickable. [https://github.com/loco-rs/loco/pull/826](https://github.com/loco-rs/loco/pull/826) - Add `--no-banner` flag to allow disabling the banner display. [https://github.com/loco-rs/loco/pull/839](https://github.com/loco-rs/loco/pull/839) - add on_shutdown hook. [https://github.com/loco-rs/loco/pull/842](https://github.com/loco-rs/loco/pull/842) ## v0.10.1 - `Format(respond_to): Format` extractor in controller can now be replaced with `respond_to: RespondTo` extractor for less typing. - When supplying data to views, you can now use `data!` instead of `serde_json::json!` for shorthand. - Refactor middlewares. [https://github.com/loco-rs/loco/pull/785](https://github.com/loco-rs/loco/pull/785). Middleware selection, configuration, and tweaking is MUCH more powerful and convenient now. You can keep the `middleware:` section empty or remove it now, see more in [the middleware docs](https://loco.rs/docs/the-app/controller/#middleware) - **NEW (BREAKING)** background worker subsystem is now queue agnostic. Providing for both Redis and Postgres with a change of configuration. This means you can now use a full-Postgres stack to remove Redis as a dependency if you wish. Here are steps to migrate your codebase: ```rust // in your app.rs, change the worker registration code: // BEFORE fn connect_workers<'a>(p: &'a mut Processor, ctx: &'a AppContext) { p.register(DownloadWorker::build(ctx)); } // AFTER async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()>{ queue.register(DownloadWorker::build(ctx)).await?; Ok(()) } // in your app.rs, replace the `worker` module references. // REMOVE worker::{AppWorker, Processor}, // REPLACE WITH bgworker::{BackgroundWorker, Queue}, // in your workers change the signature, and add the `build` function // BEFORE impl worker::Worker for DownloadWorker { async fn perform(&self, args: DownloadWorkerArgs) -> worker::Result<()> { // AFTER #[async_trait] impl BackgroundWorker for DownloadWorker { fn build(ctx: &AppContext) -> Self { Self { ctx: ctx.clone() } } async fn perform(&self, args: DownloadWorkerArgs) -> Result<()> { // Finally, remove the `AppWorker` trait implementation completely. // REMOVE impl worker::AppWorker for DownloadWorker { fn build(ctx: &AppContext) -> Self { Self { ctx: ctx.clone() } } } ``` Finally, update your `development.yaml` and `test.yaml` with a `kind`: ```yaml queue: kind: Redis # add this to the existing `queue` section ``` - **UPGRADED (BREAKING)**: `validator` crate was upgraded which require some small tweaks to work with the new API: ```rust // BEFORE: #[validate(custom = "validation::is_valid_email")] pub email: String, // AFTER: #[validate(custom (function = "validation::is_valid_email"))] pub email: String, ``` Then update your `Cargo.toml` to take version `0.18`: ```toml # update validator = { version = "0.18" } ``` - **UPGRADED (BREAKING)**: `axum-test` crate was upgraded Update your `Cargo.toml` to version `16`: ```toml # update axum-test = { version = "16" } ``` ## v0.9.0 - Add fallback behavior. [https://github.com/loco-rs/loco/pull/732](https://github.com/loco-rs/loco/pull/732) - Add Scheduler Feature for Running Cron Jobs. [https://github.com/loco-rs/loco/pull/735](https://github.com/loco-rs/loco/pull/735) - Add `--html`, `--htmx` and `--api` flags to scaffold CLI command. [https://github.com/loco-rs/loco/pull/749](https://github.com/loco-rs/loco/pull/749) - Add base template for scaffold generation. [https://github.com/loco-rs/loco/pull/752](https://github.com/loco-rs/loco/pull/752) - Connect Redis only when the worker is BackgroundQueue. [https://github.com/loco-rs/loco/pull/755](https://github.com/loco-rs/loco/pull/755) - Add loco doctor --config. [https://github.com/loco-rs/loco/pull/736](https://github.com/loco-rs/loco/pull/736) - Rename demo: blo -> demo_app. [https://github.com/loco-rs/loco/pull/741](https://github.com/loco-rs/loco/pull/741) ## v0.8.1 - fix: introduce secondary binary for compile-and-run on Windows. [https://github.com/loco-rs/loco/pull/727](https://github.com/loco-rs/loco/pull/727) ## v0.8.0 - Added: loco-cli (`loco new`) now receives options from CLI and/or interactively asks for configuration options such as which asset pipeline, background worker type, or database provider to use. - Fix: custom queue names now merge with default queues. - Added `remote_ip` middleware for resolving client remote IP when under a proxy or loadbalancer, similar to the Rails `remote_ip` middleware. - Added `secure_headers` middleware for setting secure headers by default, similar to how [https://github.com/github/secure_headers](https://github.com/github/secure_headers) works. This is now ON by default to promote security-by-default. - Added: `money`, `blob` types to entitie generator. ## 0.7.0 - Moving to _timezone aware timestamps_. From now on migrations will generate **timestamps with time zone** by default. Moving to TZ aware timestamps in combination with newly revamped timestamp code generation in SeaORM v1.0.0 finally allows for _seamlessly_ moving between using `sqlite` and `postgres` with minimal or no entities code changes (resolved [this long standing issue](https://github.com/loco-rs/loco/issues/518#issuecomment-2051708319)). TZ aware timestamps also aligns us with how Rails works today (initially Rails had a no-tz timestamps, and today the default is to use timestamps). If not specified the TZ is the server TZ, which is usually UTC, therefore semantically this is almost like a no-tz timestamp. **A few highlights:** Generated entities will now always use `DateTimeWithTimeZone` for the default timestamp fields: ``` ... Generating users.rs > Column `created_at`: DateTimeWithTimeZone, not_null > Column `updated_at`: DateTimeWithTimeZone, not_null ... ``` For better cross database provider compatibility, from now on prefer the `tstz` type instead of just `ts` when using generators (i.e. `cargo loco generate model movie released:tstz`) - remove eyer lib. [https://github.com/loco-rs/loco/pull/650](https://github.com/loco-rs/loco/pull/650) ### Breaking Changes: 1. Update the Main Function in src/bin/main Replace the return type of the main function: **Before:** ```rust async fn main() -> eyre::Result<()> ``` **After:** ```rust async fn main() -> loco_rs::Result<()> ``` 2. Modify examples/playground.rs You need to apply two changes here: a. Update the Function Signature **Before:** ```rust async fn main() -> eyre::Result<()> ``` **After:** ```rust async fn main() -> loco_rs::Result<()> ``` b. Adjust the Context Handling **Before:** ```rust let _ctx = playground::().await.context("playground")?; ``` **After:** ```rust let _ctx = playground::().await?; ``` Note, If you are using eyre in your project, you can continue to do so. We have only removed this crate from our base code dependencies. - Bump rstest crate to 0.21.0. [https://github.com/loco-rs/loco/pull/650](https://github.com/loco-rs/loco/pull/650) - Bump serial_test crate to 3.1.1. [https://github.com/loco-rs/loco/pull/651](https://github.com/loco-rs/loco/pull/651) - Bumo object store to create to 0.10.2. [https://github.com/loco-rs/loco/pull/654](https://github.com/loco-rs/loco/pull/654) - Bump axum crate to 0.7.5. [https://github.com/loco-rs/loco/pull/652](https://github.com/loco-rs/loco/pull/652) - Add Hooks::before_routes to give user control over initial axum::Router construction. [https://github.com/loco-rs/loco/pull/646](https://github.com/loco-rs/loco/pull/646) - Support logger file appender. [https://github.com/loco-rs/loco/pull/636](https://github.com/loco-rs/loco/pull/636) - Response from the template. [https://github.com/loco-rs/loco/pull/682](https://github.com/loco-rs/loco/pull/682) - Add get_or_insert function to cache layer. [https://github.com/loco-rs/loco/pull/637](https://github.com/loco-rs/loco/pull/637) - Bump ORM create to 1.0.0. [https://github.com/loco-rs/loco/pull/684](https://github.com/loco-rs/loco/pull/684) ## 0.6.2 - Use Rust-based tooling for SaaS starter frontend. [https://github.com/loco-rs/loco/pull/625](https://github.com/loco-rs/loco/pull/625) - Default binding to localhost to avoid firewall dialogues during development on macOS. [https://github.com/loco-rs/loco/pull/627](https://github.com/loco-rs/loco/pull/627) - upgrade sea-orm to 1.0.0 RC 7. [https://github.com/loco-rs/loco/pull/627](https://github.com/loco-rs/loco/pull/639) - Add a down migration command. [https://github.com/loco-rs/loco/pull/414](https://github.com/loco-rs/loco/pull/414) - replace create_postgres_database function table_name to db_name. [https://github.com/loco-rs/loco/pull/647](https://github.com/loco-rs/loco/pull/647) ## 0.6.1 - Upgrade htmx generator to htmx2. [https://github.com/loco-rs/loco/pull/629](https://github.com/loco-rs/loco/pull/629) ## 0.6.0 https://github.com/loco-rs/loco/pull/610 - Bump socketioxide to v0.13.1. [https://github.com/loco-rs/loco/pull/594](https://github.com/loco-rs/loco/pull/594) - Add CC and BCC fields to the mailers. [https://github.com/loco-rs/loco/pull/599](https://github.com/loco-rs/loco/pull/599) - Delete reset tokens after use. [https://github.com/loco-rs/loco/pull/602](https://github.com/loco-rs/loco/pull/602) - Generator html support delete entity. [https://github.com/loco-rs/loco/pull/604](https://github.com/loco-rs/loco/pull/604) - **Breaking changes** move task args from BTreeMap to struct. [https://github.com/loco-rs/loco/pull/609](https://github.com/loco-rs/loco/pull/609) - Change task signature from `async fn run(&self, app_context: &AppContext, vars: &BTreeMap)` to `async fn run(&self, _app_context: &AppContext, _vars: &task::Vars) -> Result<()>` - **Breaking changes** change default port to 5150. [https://github.com/loco-rs/loco/pull/611](https://github.com/loco-rs/loco/pull/611) - Update shuttle version in deployment generation. [https://github.com/loco-rs/loco/pull/616](https://github.com/loco-rs/loco/pull/616) ## v0.5.0 https://github.com/loco-rs/loco/pull/593 - refactor auth middleware for supporting bearer, cookie and query. [https://github.com/loco-rs/loco/pull/560](https://github.com/loco-rs/loco/pull/560) - SeaORM upgraded: `rc1` -> `rc4`. [https://github.com/loco-rs/loco/pull/585](https://github.com/loco-rs/loco/pull/585) - Adding Cache to app content. [https://github.com/loco-rs/loco/pull/570](https://github.com/loco-rs/loco/pull/570) - Apply a layer to a specific handler using `layer` method. [https://github.com/loco-rs/loco/pull/554](https://github.com/loco-rs/loco/pull/554) - Add the debug macro to the templates to improve the errors. [https://github.com/loco-rs/loco/pull/547](https://github.com/loco-rs/loco/pull/547) - Opentelemetry initializer. [https://github.com/loco-rs/loco/pull/531](https://github.com/loco-rs/loco/pull/531) - Refactor auth middleware for supporting bearer, cookie and query [https://github.com/loco-rs/loco/pull/560](https://github.com/loco-rs/loco/pull/560) - Add redirect response [https://github.com/loco-rs/loco/pull/563](https://github.com/loco-rs/loco/pull/563) - **Breaking changes** Adding a custom claims `Option` to the `UserClaims` struct (type changed). [https://github.com/loco-rs/loco/pull/578](https://github.com/loco-rs/loco/pull/578) - **Breaking changes** Refactored DSL and Pagination: namespace changes. [https://github.com/loco-rs/loco/pull/566](https://github.com/loco-rs/loco/pull/566) - Replaced `model::query::dsl::` with `model::query`. - Replaced `model::query::exec::paginate` with `model::query::paginate`. - Updated the `PaginatedResponse` struct. Refer to its usage example [here](https://github.com/loco-rs/loco/blob/master/examples/demo/src/views/notes.rs#L29). - **Breaking changes** When introducing the Cache system which is much more flexible than having just Redis, we now call the 'redis' member simply a 'queue' which indicates it should be used only for the internal queue and not as a general purpose cache. In the application configuration setting `redis`, change to `queue`. [https://github.com/loco-rs/loco/pull/590](https://github.com/loco-rs/loco/pull/590) ```yaml # before: redis: # after: queue: ``` - **Breaking changes** We have made a few parts of the context pluggable, such as the `storage` and new `cache` subsystems, this is why we decided to let you configure the context entirely before starting up your app. As a result, if you have a storage building hook code it should move to `after_context`, see example [here](https://github.com/loco-rs/loco/pull/570/files#diff-5534e8826fb82e5c7f2587d270a51b48009341e79889d1504e6b63b2f0b652bdR83). [https://github.com/loco-rs/loco/pull/570](https://github.com/loco-rs/loco/pull/570) ## v0.4.0 - Refactored model validation for better developer experience. Added a few traits and structs to `loco::prelude` for a smoother import story. Introducing `Validatable`: ```rust impl Validatable for super::_entities::users::ActiveModel { fn validator(&self) -> Box { Box::new(Validator { name: self.name.as_ref().to_owned(), email: self.email.as_ref().to_owned(), }) } } // now you can call `user.validate()` freely ``` - Refactored type field mapping to be centralized. Now model, scaffold share the same field mapping, so no more gaps like [https://github.com/loco-rs/loco/issues/513](https://github.com/loco-rs/loco/issues/513) (e.g. when calling `loco generate model title:string` the ability to map `string` into something useful in the code generation side) **NOTE** the `_integer` class of types are now just `_int`, e.g. `big_int`, so that it correlate with the `int` field name in a better way - Adding to to quiery dsl `is_in` and `is_not_in`. [https://github.com/loco-rs/loco/pull/507](https://github.com/loco-rs/loco/pull/507) - Added: in your configuration you can now use an `initializers:` section for initializer specific settings ```yaml # Initializers Configuration initializers: # oauth2: # authorization_code: # Authorization code grant type # - client_identifier: google # Identifier for the OAuth2 provider. Replace 'google' with your provider's name if different, must be unique within the oauth2 config. # ... other fields ``` - Docs: fix schema data types mapping. [https://github.com/loco-rs/loco/pull/506](https://github.com/loco-rs/loco/pull/506) - Let Result accept other errors. [https://github.com/loco-rs/loco/pull/505](https://github.com/loco-rs/loco/pull/505) - Allow trailing slashes in URIs by adding the NormalizePathLayer. [https://github.com/loco-rs/loco/pull/481](https://github.com/loco-rs/loco/pull/481) - **BREAKING** Move from `Result` to `Result`. This enables much greater flexibility building APIs, where with `Result` you mix and match response types based on custom logic (returning JSON and HTML/String in the same route). - **Added**: mime responders similar to `respond_to` in Rails: 1. Use the `Format` extractor 2. Match on `respond_to` 3. Create different content for different response formats The following route will always return JSON, unless explicitly asked for HTML with a `Content-Type: text/html` (or `Accept: `) header: ```rust pub async fn get_one( Format(respond_to): Format, Path(id): Path, State(ctx): State, ) -> Result { let item = load_item(&ctx, id).await?; match respond_to { RespondTo::Html => format::html(&format!("{:?}", item.title)), _ => format::json(item), } } ``` ## 0.3.2 - Redisgin pagination. [https://github.com/loco-rs/loco/pull/463](https://github.com/loco-rs/loco/pull/463) - Wrap seaorm query and condition for common use cases. [https://github.com/loco-rs/loco/pull/463](https://github.com/loco-rs/loco/pull/463) - Adding to loco-extras initializer for extra or multiple db. [https://github.com/loco-rs/loco/pull/471](https://github.com/loco-rs/loco/pull/471) - Scaffold now supporting different templates such as API,HTML or htmx, this future is in beta.[https://github.com/loco-rs/loco/pull/474](https://github.com/loco-rs/loco/pull/474) - Fix generatore fields types + adding tests. [https://github.com/loco-rs/loco/pull/459](https://github.com/loco-rs/loco/pull/459) - Fix channel cors. [https://github.com/loco-rs/loco/pull/430](https://github.com/loco-rs/loco/pull/430) - Improve auth controller compatibility with frontend [https://github.com/loco-rs/loco/pull/472](https://github.com/loco-rs/loco/pull/472) ## 0.3.1 - **Breaking changes** Upgrade sea-orm to v1.0.0-rc.1. [https://github.com/loco-rs/loco/pull/420](https://github.com/loco-rs/loco/pull/420) Needs to update `sea-orm` crate to use `v1.0.0-rc.1` version. - Implemented file upload support with versatile strategies. [https://github.com/loco-rs/loco/pull/423](https://github.com/loco-rs/loco/pull/423) - Create a `loco_extra` crate to share common basic implementations. [https://github.com/loco-rs/loco/pull/425](https://github.com/loco-rs/loco/pull/425) - Update shuttle deployment template to 0.38. [https://github.com/loco-rs/loco/pull/422](https://github.com/loco-rs/loco/pull/422) - Enhancement: Move the Serve to Hook flow with the ability to override default serve settings. [https://github.com/loco-rs/loco/pull/418](https://github.com/loco-rs/loco/pull/418) - Avoid cloning sea_query::ColumnDef. [https://github.com/loco-rs/loco/pull/415](https://github.com/loco-rs/loco/pull/415) - Allow required UUID type in a scaffold. [https://github.com/loco-rs/loco/pull/408](https://github.com/loco-rs/loco/pull/408) - Cover `SqlxMySqlPoolConnection` in db.rs. [https://github.com/loco-rs/loco/pull/411](https://github.com/loco-rs/loco/pull/411) - Update worker docs and change default worker mode. [https://github.com/loco-rs/loco/pull/412](https://github.com/loco-rs/loco/pull/412) - Added server-side view generation through a new `ViewEngine` infrastructure and `Tera` server-side templates: [https://github.com/loco-rs/loco/pull/389](https://github.com/loco-rs/loco/pull/389) - Added `generate model --migration-only` [https://github.com/loco-rs/loco/issues/400](https://github.com/loco-rs/loco/issues/400) - Add JSON to scaffold gen. [https://github.com/loco-rs/loco/pull/396](https://github.com/loco-rs/loco/pull/396) - Add --binding(-b) and --port(-b) to `cargo loco start`.[https://github.com/loco-rs/loco/pull/402](https://github.com/loco-rs/loco/pull/402) ## 0.2.3 - Add: support for [pre-compressed assets](https://github.com/loco-rs/loco/pull/370/files). - Added: Support socket channels, see working example [here](https://github.com/loco-rs/chat-rooms). [https://github.com/loco-rs/loco/pull/380](https://github.com/loco-rs/loco/pull/380) - refactor: optimize checking permissions on Postgres. [9416c](https://github.com/loco-rs/loco/commit/9416c5db85a27e3d30471374effec3fe88bf80a2) - Added: E2E db. [https://github.com/loco-rs/loco/pull/371](https://github.com/loco-rs/loco/pull/371) ## v0.2.2 - fix: public fields in mailer-op. [e51b7e](https://github.com/loco-rs/loco/commit/e51b7e64e7667c519451ac8a8bea574b2c5d4403) - fix: handle missing db permissions. [e51b7e](https://github.com/loco-rs/loco/commit/e51b7e64e7667c519451ac8a8bea574b2c5d4403) ## v0.2.1 - enable compression for CompressionLayer, not etag. [https://github.com/loco-rs/loco/pull/356](https://github.com/loco-rs/loco/pull/356) - Fix nullable JSONB column schema definition. [https://github.com/loco-rs/loco/pull/357](https://github.com/loco-rs/loco/pull/357) ## v0.2.0 - Add: Loco now has Initializers ([see the docs](https://loco.rs/docs/the-app/initializers/)). Initializers help you integrate infra into your app in a seamless way, as well as share pieces of setup code between your projects - Add: an `init_logger` hook in `src/app.rs` for those who want to take ownership of their logging and tracing stack. - Add: Return a JSON schema when payload json could not serialize to a struct. [https://github.com/loco-rs/loco/pull/343](https://github.com/loco-rs/loco/pull/343) - Init logger in cli.rs. [https://github.com/loco-rs/loco/pull/338](https://github.com/loco-rs/loco/pull/338) - Add: return JSON schema in panic HTTP layer. [https://github.com/loco-rs/loco/pull/336](https://github.com/loco-rs/loco/pull/336) - Add: JSON field support in model generation. [https://github.com/loco-rs/loco/pull/327](https://github.com/loco-rs/loco/pull/327) [https://github.com/loco-rs/loco/pull/332](https://github.com/loco-rs/loco/pull/332) - Add: float support in model generation. [https://github.com/loco-rs/loco/pull/317](https://github.com/loco-rs/loco/pull/317) - Fix: conflicting idx definition on M:M migration. [https://github.com/loco-rs/loco/issues/311](https://github.com/loco-rs/loco/issues/311) - Add: **Breaking changes** Supply `AppContext` to `routes` Hook. Migration steps in `src/app.rs`: ```rust // src/app.rs: add app context to routes function impl Hooks for App { ... fn routes(_ctx: &AppContext) -> AppRoutes; ... } ``` - Add: **Breaking changes** change parameter type from `&str` to `&Environment` in `src/app.rs` ```rust // src/app.rs: change parameter type for `environment` from `&str` to `&Environment` impl Hooks for App { ... async fn boot(mode: StartMode, environment: &Environment) -> Result { create_app::(mode, environment).await } ... ``` - Added: setting cookies: ```rust format::render() .cookies(&[ cookie::Cookie::new("foo", "bar"), cookie::Cookie::new("baz", "qux"), ])? .etag("foobar")? .json(notes) ``` ## v0.1.9 - Adding [pagination](https://loco.rs/docs/the-app/pagination/) on Models. [https://github.com/loco-rs/loco/pull/238](https://github.com/loco-rs/loco/pull/238) - Adding compression middleware. [https://github.com/loco-rs/loco/pull/205](https://github.com/loco-rs/loco/pull/205) Added support for [compression middleware](https://docs.rs/tower-http/0.5.0/tower_http/compression/index.html). usage: ```yaml middlewares: compression: enable: true ``` - Create a new Database from the CLI. [https://github.com/loco-rs/loco/pull/223](https://github.com/loco-rs/loco/pull/223) - Validate if seaorm CLI is installed before running `cargo loco db entities` and show a better error to the user. [https://github.com/loco-rs/loco/pull/212](https://github.com/loco-rs/loco/pull/212) - Adding to `saas and `rest-api` starters a redis and DB in GitHub action workflow to allow users work with github action out of the box. [https://github.com/loco-rs/loco/pull/215](https://github.com/loco-rs/loco/pull/215) - Adding the app name and the environment to the DB name when creating a new starter. [https://github.com/loco-rs/loco/pull/216](https://github.com/loco-rs/loco/pull/216) - Fix generator when users adding a `created_at` or `update_at` fields. [https://github.com/loco-rs/loco/pull/214](https://github.com/loco-rs/loco/pull/214) - Add: `format::render` which allows a builder-like formatting, including setting etag and ad-hoc headers - Add: Etag middleware, enabled by default in starter projects. Once you set an Etag it will check for cache headers and return `304` if needed. To enable etag in your existing project: ```yaml #... middlewares: etag: enable: true ``` usage: ```rust format::render() .etag("foobar")? .json(Entity::find().all(&ctx.db).await?) ``` #### Authentication: Added API Token Authentication! - See [https://github.com/loco-rs/loco/pull/217](https://github.com/loco-rs/loco/pull/217) Now when you generate a `saas starter` or `rest api` starter you will get additional authentication methods for free: - Added: authentication added -- **api authentication** where each user has an API token in the schema, and you can authenticate with `Bearer` against that user. - Added: authentication added -- `JWTWithUser` extractor, which is a convenience for resolving the authenticated JWT claims into a current user from database **migrating an existing codebase** Add the following to your generated `src/models/user.rs`: ```rust #[async_trait] impl Authenticable for super::_entities::users::Model { async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult { let user = users::Entity::find() .filter(users::Column::ApiKey.eq(api_key)) .one(db) .await?; user.ok_or_else(|| ModelError::EntityNotFound) } async fn find_by_claims_key(db: &DatabaseConnection, claims_key: &str) -> ModelResult { super::_entities::users::Model::find_by_pid(db, claims_key).await } } ``` Update imports in this file to include `model::Authenticable`: ```rust use loco_rs::{ auth, hash, model::{Authenticable, ModelError, ModelResult}, validation, validator::Validate, }; ``` ## v0.1.8 - Added: `loco version` for getting an operable version string containing logical crate version and git SHA if available: `0.3.0 ()` To migrate to this behavior from earlier versions, it requires adding the following to your `app.rs` app hooks: ```rust fn app_version() -> String { format!( "{} ({})", env!("CARGO_PKG_VERSION"), option_env!("BUILD_SHA") .or(option_env!("GITHUB_SHA")) .unwrap_or("dev") ) } ``` Reminder: `loco --version` will give you the current Loco framework which your app was built against and `loco version` gives you your app version. - Added: `loco generate migration` for adding ad-hoc migrations - Added: added support in model generator for many-to-many link table generation via `loco generate model --link` - Docs: added Migration section, added relations documentation 1:M, M:M - Adding .devcontainer to starter projects [https://github.com/loco-rs/loco/issues/170](https://github.com/loco-rs/loco/issues/170) - **Braking changes**: Adding `Hooks::boot` application. Migration steps: ```rust // Load boot::{create_app, BootResult, StartMode} from loco_rs lib // Load migration: use migration::Migrator; Only when using DB // Adding boot hook with the following code impl Hooks for App { ... async fn boot(mode: StartMode, environment: &str) -> Result { // With DB: create_app::(mode, environment).await // Without DB: create_app::(mode, environment).await } ... } ``` ## v0.1.7 - Added pretty backtraces [https://github.com/loco-rs/loco/issues/41](https://github.com/loco-rs/loco/issues/41) - adding tests for note requests [https://github.com/loco-rs/loco/pull/156](https://github.com/loco-rs/loco/pull/156) - Define the min rust version the loco can run [https://github.com/loco-rs/loco/pull/164](https://github.com/loco-rs/loco/pull/164) - Added `cargo loco doctor` cli command for validate and diagnose configurations. [https://github.com/loco-rs/loco/pull/145](https://github.com/loco-rs/loco/pull/145) - Added ability to specify `settings:` in config files, which are available in context - Adding compilation mode in the banner. [https://github.com/loco-rs/loco/pull/127](https://github.com/loco-rs/loco/pull/127) - Support shuttle deployment generator. [https://github.com/loco-rs/loco/pull/124](https://github.com/loco-rs/loco/pull/124) - Adding a static asset middleware which allows to serve static folder/data. Enable this section in config. [https://github.com/loco-rs/loco/pull/134](https://github.com/loco-rs/loco/pull/134) ```yaml static: enable: true # ensure that both the folder.path and fallback file path are existence. must_exist: true folder: uri: "/assets" path: "frontend/dist" fallback: "frontend/dist/index.html" ``` - fix: `loco generate request` test template. [https://github.com/loco-rs/loco/pull/133](https://github.com/loco-rs/loco/pull/133) - Improve docker deployment generator. [https://github.com/loco-rs/loco/pull/131](https://github.com/loco-rs/loco/pull/131) ## v0.1.6 - refactor: local settings are now `.local.yaml` and available for all environments, for example you can add a local `test.local.yaml` and `development.local.yaml` - refactor: removed `config-rs` and now doing config loading by ourselves. - fix: email template rendering will not escape URLs - Config with variables: It is now possible to use [tera](https://keats.github.io/tera) templates in config YAML files Example of pulling a port from environment: ```yaml server: port: { { get_env(name="NODE_PORT", default=5150) } } ``` It is possible to use any `tera` templating constructs such as loops, conditionals, etc. inside YAML configuration files. - Mailer: expose `stub` in non-test - `Hooks::before_run` with a default blank implementation. You can now code some custom loading of resources or other things before the app runs - an LLM inference example, text generation in Rust, using an API (`examples/inference`) - Loco starters version & create release script [https://github.com/loco-rs/loco/pull/110](https://github.com/loco-rs/loco/pull/110) - Configure Cors middleware [https://github.com/loco-rs/loco/pull/114](https://github.com/loco-rs/loco/pull/114) - `Hooks::after_routes` Invoke this function after the Loco routers have been constructed. This function enables you to configure custom Axum logics, such as layers, that are compatible with Axum. [https://github.com/loco-rs/loco/pull/114](https://github.com/loco-rs/loco/pull/114) - Adding docker deployment generator [https://github.com/loco-rs/loco/pull/119](https://github.com/loco-rs/loco/pull/119) DOCS: - Remove duplicated docs in auth section - FAQ docs: [https://github.com/loco-rs/loco/pull/116](https://github.com/loco-rs/loco/pull/116) ENHANCEMENTS: - Remove unused libs: [https://github.com/loco-rs/loco/pull/106](https://github.com/loco-rs/loco/pull/106) - turn off default features in tokio [https://github.com/loco-rs/loco/pull/118](https://github.com/loco-rs/loco/pull/118) ## 0.1.5 NEW FEATURES - `format:html` [https://github.com/loco-rs/loco/issues/74](https://github.com/loco-rs/loco/issues/74) - Create a stateless HTML starter [https://github.com/loco-rs/loco/pull/100](https://github.com/loco-rs/loco/pull/100) - Added worker generator + adding a way to test workers [https://github.com/loco-rs/loco/pull/92](https://github.com/loco-rs/loco/pull/92) ENHANCEMENTS: - CI: allows cargo cli run on fork prs [https://github.com/loco-rs/loco/pull/96](https://github.com/loco-rs/loco/pull/96)