use crate::module::ModuleJson;
use crate::pkg_context::PkgContextInfo;
use crate::profile::Route;
const DEFAULT_SOURCE_ROOT: &str = "src/main/";
const SOURCE_EXTENSIONS: &[&str] = &[".ets", ".ts", ".js", ".mjs", ".cjs"];
pub(crate) fn strip_source_extension(path: &str) -> &str {
SOURCE_EXTENSIONS.iter().find_map(|ext| path.strip_suffix(ext)).unwrap_or(path)
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct RecordNames {
pub normalized: Option<String>,
pub bundled: Option<String>,
pub package_listed: bool,
}
impl RecordNames {
pub fn candidates(&self) -> Vec<&str> {
let (first, second) = if self.package_listed { (&self.normalized, &self.bundled) } else { (&self.bundled, &self.normalized) };
[first, second].into_iter().flatten().map(String::as_str).collect()
}
}
impl ModuleJson {
pub fn record_names(&self, src_entry: &str, packages: Option<&PkgContextInfo>) -> RecordNames {
let path = src_entry.strip_prefix("./").unwrap_or(src_entry).trim_start_matches('/');
let path = strip_source_extension(path);
let module = self.module.name.as_deref();
let package_name = self.module.package_name.as_deref().or(module);
let package = packages.zip(package_name).and_then(|(table, name)| table.get(name));
let normalized = package_name.map(|name| match package {
Some(p) if p.entry_path.ends_with('/') => format!("&{name}/{}{path}&{}", p.entry_path, p.version),
Some(p) => format!("&{name}/{DEFAULT_SOURCE_ROOT}{path}&{}", p.version),
None => format!("&{name}/{DEFAULT_SOURCE_ROOT}{path}&"),
});
let bundled = self.app.bundle_name.as_deref().zip(module).map(|(bundle, module)| format!("{bundle}/{module}/{path}"));
RecordNames { normalized, bundled, package_listed: package.is_some() }
}
pub fn route_record_names(&self, route: &Route, packages: Option<&PkgContextInfo>) -> RecordNames {
let module = self.module.name.as_deref();
let own_package = self.module.package_name.as_deref().or(module);
let path = route.record_path(own_package);
let listed = packages.zip(route.package_name.as_deref().or(own_package)).and_then(|(table, name)| table.get(name));
let from_source = path.as_ref().map(|path| format!("&{path}&{}", listed.map_or("", |package| package.version.as_str())));
let normalized = route.ohmurl_record().map(str::to_owned).or(from_source);
let is_own = route.package_name.as_deref().is_none_or(|package| Some(package) == own_package);
let source = route.page_source_file.as_deref().map(|source| source.trim_start_matches("./").trim_start_matches('/'));
let below_root = source.and_then(|source| source.strip_prefix(DEFAULT_SOURCE_ROOT)).filter(|_| is_own);
let bundled = self
.app
.bundle_name
.as_deref()
.zip(module)
.zip(below_root)
.map(|((bundle, module), path)| format!("{bundle}/{module}/{}", strip_source_extension(path)));
RecordNames { normalized, bundled, package_listed: listed.is_some() || route.ohmurl.is_some() }
}
}