use axum::{ http::{HeaderValue, header}, response::{Html, IntoResponse, Response}, }; const MODULES: &[&str] = &[ "api", "auth-ui", "clipboard", "editor-format", "emoji-data", "emoji-picker", "image-upload", "logger", "markdown", "modal", "session", "socket", "url-state", ]; pub fn render_html( template: &str, asset_version: &str, registration_enabled: bool, frontend_log_level: &str, upload_max_size_bytes: usize, entrypoint: &str, ) -> Response { let urls = AssetUrls::new(asset_version); let frontend_config = frontend_config(frontend_log_level, upload_max_size_bytes); let html = template .replace("__APP_STYLESHEET__", &urls.stylesheet("styles")) .replace("__APP_IMPORT_MAP__", &urls.import_map()) .replace("__APP_ENTRYPOINT__", &urls.entrypoint(entrypoint)) .replace( "__REGISTRATION_ENABLED__", if registration_enabled { "true" } else { "false" }, ) .replace("", &format!("{frontend_config}")); let mut response = Html(html).into_response(); response.headers_mut().insert( header::CACHE_CONTROL, HeaderValue::from_static("private, no-store"), ); response } pub fn stylesheet_tag(asset_version: &str, name: &str) -> String { AssetUrls::new(asset_version).stylesheet(name) } fn frontend_config(frontend_log_level: &str, upload_max_size_bytes: usize) -> String { format!( r#""#, escape_js_string(frontend_log_level), upload_max_size_bytes, ) } struct AssetUrls<'a> { version: &'a str, } impl<'a> AssetUrls<'a> { fn new(version: &'a str) -> Self { Self { version } } fn url(&self, path: &str) -> String { format!("/assets/{path}?v={}", self.version) } fn stylesheet(&self, name: &str) -> String { format!( r#""#, self.url(&format!("css/{name}.css")) ) } fn entrypoint(&self, name: &str) -> String { format!( r#""#, self.url(&format!("js/{name}.js")) ) } fn import_map(&self) -> String { let imports = MODULES .iter() .map(|module| { format!( r#""@rustpad/{module}":"{}""#, self.url(&format!("js/{module}.js")) ) }) .collect::>() .join(","); format!(r#""#) } } fn escape_js_string(value: &str) -> String { value .replace('\\', "\\\\") .replace('"', "\\\"") .replace('<', "\\u003c") }