use std::path::PathBuf;
use std::sync::Arc;
use serde::{Deserialize, Serialize};
pub const PKG_SUBDIR: &str = "pkg";
pub const LOCAL_FRONTEND_DISTRIBUTABLE: &str = "dist";
pub const CONTAINER_FRONTEND_DISTRIBUTABLE: &str = "/usr/local/frontend-dist";
pub const FRONTEND_DIST_ENV: &str = "IMPULSE_FRONTEND_DIST";
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct SeoDefaults {
#[serde(default)]
pub title_template: Option<String>,
#[serde(default)]
pub default_title: Option<String>,
#[serde(default)]
pub description: Option<String>,
#[serde(default)]
pub og_image: Option<String>,
#[serde(default)]
pub og_logo: Option<String>,
#[serde(default)]
pub canonical_base: Option<String>,
#[serde(default)]
pub twitter_handle: Option<String>,
#[serde(default)]
pub robots: Option<String>,
#[serde(default)]
pub locale: Option<String>,
#[serde(default)]
pub site_name: Option<String>,
}
#[derive(Clone, Default)]
pub enum FallbackStrategy {
#[default]
ErrorPage,
Custom(Arc<dyn Fn() -> String + Send + Sync>),
}
impl std::fmt::Debug for FallbackStrategy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FallbackStrategy::ErrorPage => f.write_str("ErrorPage"),
FallbackStrategy::Custom(_) => f.write_str("Custom(<fn>)"),
}
}
}
#[derive(Clone, Debug)]
pub struct LeptosOptions {
pub output_name: String,
pub site_root: PathBuf,
pub server_fn_prefix: String,
pub seo_defaults: SeoDefaults,
pub fallback: FallbackStrategy,
pub include_hydration_script: bool,
pub stream_mode: super::handler::SsrStreamMode,
}
impl Default for LeptosOptions {
fn default() -> Self {
Self {
output_name: String::new(),
site_root: PathBuf::from(LOCAL_FRONTEND_DISTRIBUTABLE),
server_fn_prefix: "/api".to_string(),
seo_defaults: SeoDefaults::default(),
fallback: FallbackStrategy::ErrorPage,
include_hydration_script: false,
stream_mode: super::handler::SsrStreamMode::InOrder,
}
}
}
impl LeptosOptions {
pub fn resolve_site_root(g: &crate::setup::GenericValues) -> PathBuf {
if let Ok(env_path) = std::env::var(FRONTEND_DIST_ENV)
&& !env_path.is_empty()
{
return PathBuf::from(env_path);
}
if let Some(p) = &g.frontend_dist_path {
return p.clone();
}
let local = PathBuf::from(LOCAL_FRONTEND_DISTRIBUTABLE);
if local.exists() {
return local;
}
PathBuf::from(CONTAINER_FRONTEND_DISTRIBUTABLE)
}
pub fn from_generic_values(g: &crate::setup::GenericValues) -> Self {
let mut opts = LeptosOptions {
site_root: LeptosOptions::resolve_site_root(g),
..Default::default()
};
if let Some(name) = &g.leptos_output_name {
opts.output_name = name.clone();
} else {
opts.output_name = g.app_name.clone();
}
if let Some(prefix) = &g.leptos_server_fn_prefix {
opts.server_fn_prefix = prefix.clone();
}
if let Some(seo) = &g.leptos_seo {
opts.seo_defaults = seo.clone();
}
opts
}
}