use std::path::PathBuf;
use std::sync::LazyLock as Lazy;
use aube_registry::NetworkMode;
use aube_registry::client::RegistryClient;
use aube_registry::config::NpmConfig;
use eyre::Result;
use crate::backend::VersionInfo;
use crate::backend::npm::is_semver_prerelease;
use crate::config::Settings;
static CLIENT: Lazy<RegistryClient> = Lazy::new(|| {
let config = NpmConfig::load(&meta_dir());
let settings = Settings::get();
let mode = if settings.offline() {
NetworkMode::Offline
} else if settings.prefer_offline() {
NetworkMode::PreferOffline
} else {
NetworkMode::Online
};
let _ = crate::file::create_dir_all(meta_dir());
RegistryClient::from_config(config).with_network_mode(mode)
});
fn meta_dir() -> PathBuf {
crate::dirs::CACHE.join("npm-meta")
}
async fn fetch_packument(name: &str) -> Result<aube_registry::Packument> {
Ok(CLIENT
.fetch_packument_with_time_cached(name, &meta_dir())
.await?)
}
pub async fn list_versions(name: &str) -> Result<Vec<VersionInfo>> {
let packument = fetch_packument(name).await?;
let mut versions: Vec<&String> = packument.versions.keys().collect();
versions.sort_by_cached_key(|v| {
let parsed = versions::SemVer::new(v);
(parsed.is_none(), parsed)
});
Ok(versions
.into_iter()
.map(|version| VersionInfo {
version: version.clone(),
created_at: packument.time.get(version).cloned(),
prerelease: is_semver_prerelease(version),
..Default::default()
})
.collect())
}
pub async fn latest_dist_tag(name: &str) -> Result<Option<String>> {
let packument = fetch_packument(name).await?;
Ok(packument.dist_tags.get("latest").cloned())
}