feat(server): embed SPA via memory-serve behind embed-web feature
Adds `memory-serve` 2.1 as an optional workspace dependency, a `build.rs` that runs `load_directory` only when `CARGO_FEATURE_EMBED_WEB` is set, a `web_assets` module serving `web/dist` at `/` with SPA fallback (200 OK) for unknown client-side routes, and a feature-gated integration test. The default build (no feature) compiles and tests cleanly without `web/dist`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
|
||||
mod config;
|
||||
|
||||
#[cfg(feature = "embed-web")]
|
||||
mod web_assets;
|
||||
|
||||
pub use config::Config;
|
||||
|
||||
use anyhow::Context;
|
||||
@@ -65,6 +68,9 @@ pub async fn run(config: Config) -> anyhow::Result<()> {
|
||||
pub async fn serve(listener: TcpListener, state: AppState) -> anyhow::Result<()> {
|
||||
let app = build_app(state);
|
||||
|
||||
#[cfg(feature = "embed-web")]
|
||||
let app = app.merge(web_assets::routes());
|
||||
|
||||
axum::serve(listener, app)
|
||||
.await
|
||||
.context("running the HTTP server")?;
|
||||
@@ -72,6 +78,14 @@ pub async fn serve(listener: TcpListener, state: AppState) -> anyhow::Result<()>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "embed-web")]
|
||||
pub mod test_support {
|
||||
/// The SPA-asset router, for tests.
|
||||
pub fn web_router() -> axum::Router {
|
||||
super::web_assets::routes()
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a user from the CLI (admin bootstrap). Opens its own connection (CLI
|
||||
/// one-shot); reads the password from the `BOOTSTRAP_PASSWORD` env var if set,
|
||||
/// otherwise prompts (hidden input). The plaintext is not zeroized, but it is
|
||||
|
||||
Reference in New Issue
Block a user