mod discover;
mod error;
mod extract;
mod http;
mod index;
mod installer;
mod mise;
mod paths;
mod platform;
mod progress;
mod resolver;
mod self_install;
mod shasums;
mod sources;
mod spec;
pub use discover::{
InstallOrigin, InstalledNode, list_installed, mise_node_installs_dir, node_on_path,
probe_path_node,
};
pub use error::Error;
pub use mise::mise_on_path;
pub use paths::{install_dir, runtime_dir};
pub use platform::Platform;
pub use progress::{DownloadProgress, InstallPhase, NoopProgress};
pub use resolver::{NodeRuntime, Resolution, ResolvedFrom};
pub use self_install::{
InstalledAube, available_aube_versions, find_installed_aube, install_aube, list_installed_aube,
release_target_triple, self_dir,
};
pub use shasums::{sha256_from_sri, sri_sha256};
pub use sources::{effective_request, find_version_file};
pub use spec::{NodeRequest, NodeSpec, RequestSource};
use std::collections::BTreeMap;
pub const DEFAULT_MIRROR_BASE: &str = "https://nodejs.org/download/release";
pub const UNOFFICIAL_BASE: &str = "https://unofficial-builds.nodejs.org/download/release";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum InstallerMode {
#[default]
Auto,
Mise,
Aube,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum NetworkMode {
#[default]
Online,
Offline,
}
#[derive(Debug, Clone, Default)]
pub struct RuntimeConfig {
pub installer: InstallerMode,
pub mirror: Option<String>,
pub network: NetworkMode,
pub retries: u32,
}
impl RuntimeConfig {
pub fn new() -> Self {
RuntimeConfig {
retries: 2,
..Default::default()
}
}
pub(crate) fn mirror_base(&self) -> String {
match &self.mirror {
Some(m) => m.trim_end_matches('/').to_string(),
None => DEFAULT_MIRROR_BASE.to_string(),
}
}
pub(crate) fn artifact_base(&self, platform: &Platform) -> String {
if self.mirror.is_none() && platform.libc.as_deref() == Some("musl") {
UNOFFICIAL_BASE.to_string()
} else {
self.mirror_base()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PinnedNode {
pub version: node_semver::Version,
pub variants: Vec<PinnedVariant>,
}
impl PinnedNode {
pub fn variant_for(&self, os: &str, cpu: &str, libc: Option<&str>) -> Option<&PinnedVariant> {
self.variants
.iter()
.find(|v| v.os == os && v.cpu == cpu && v.libc.as_deref() == libc)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PinnedVariant {
pub os: String,
pub cpu: String,
pub libc: Option<String>,
pub archive: String,
pub url: String,
pub integrity_sri: String,
pub bin: BTreeMap<String, String>,
pub prefix: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mirror_bases() {
let mut cfg = RuntimeConfig::new();
assert_eq!(cfg.mirror_base(), DEFAULT_MIRROR_BASE);
cfg.mirror = Some("https://npmmirror.com/mirrors/node/".to_string());
assert_eq!(cfg.mirror_base(), "https://npmmirror.com/mirrors/node");
let musl = Platform {
os: "linux".into(),
cpu: "x64".into(),
libc: Some("musl".into()),
};
assert_eq!(
cfg.artifact_base(&musl),
"https://npmmirror.com/mirrors/node"
);
cfg.mirror = None;
assert_eq!(cfg.artifact_base(&musl), UNOFFICIAL_BASE);
let glibc = Platform {
os: "linux".into(),
cpu: "x64".into(),
libc: None,
};
assert_eq!(cfg.artifact_base(&glibc), DEFAULT_MIRROR_BASE);
}
}