use std::path::PathBuf;
pub fn runtime_dir() -> Option<PathBuf> {
if let Some(dir) = aube_util::env::embedder_env("RUNTIME_DIR")
&& !dir.is_empty()
{
return Some(PathBuf::from(dir));
}
let ns = aube_util::embedder().data_namespace;
#[cfg(windows)]
if let Ok(local) = std::env::var("LOCALAPPDATA") {
return Some(PathBuf::from(local).join(ns).join("nodejs"));
}
let data_home = match aube_util::env::xdg_data_home() {
Some(xdg) => xdg,
None => aube_util::env::home_dir()?.join(".local/share"),
};
Some(data_home.join(ns).join("nodejs"))
}
pub fn install_dir(version: &node_semver::Version) -> Option<PathBuf> {
runtime_dir().map(|d| d.join(version.to_string()))
}
pub(crate) fn downloads_dir() -> Option<PathBuf> {
runtime_dir().map(|d| d.join(".downloads"))
}
pub(crate) fn staging_dir() -> Option<PathBuf> {
runtime_dir().map(|d| d.join(".tmp"))
}
pub(crate) fn locks_dir() -> Option<PathBuf> {
runtime_dir().map(|d| d.join(".locks"))
}
pub(crate) fn cache_dir() -> Option<PathBuf> {
let ns = aube_util::embedder().cache_namespace;
if let Some(xdg) = aube_util::env::xdg_cache_home() {
return Some(xdg.join(ns));
}
#[cfg(windows)]
if let Ok(local) = std::env::var("LOCALAPPDATA") {
return Some(PathBuf::from(local).join(ns));
}
aube_util::env::home_dir().map(|h| h.join(".cache").join(ns))
}
pub(crate) fn index_cache_path(mirror_base: &str) -> Option<PathBuf> {
cache_dir().map(|d| {
d.join("node-index")
.join(origin_segment(mirror_base))
.join("index.json")
})
}
pub(crate) fn shasums_cache_path(
mirror_base: &str,
version: &node_semver::Version,
) -> Option<PathBuf> {
cache_dir().map(|d| {
d.join("node-shasums")
.join(origin_segment(mirror_base))
.join(format!("v{version}.txt"))
})
}
fn origin_segment(mirror_base: &str) -> String {
use sha2::Digest;
let digest = sha2::Sha256::digest(mirror_base.as_bytes());
format!("origin-{}", hex::encode(&digest[..8]))
}