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")
}