pub mod checker;
pub mod discovery;
mod pm_bun;
mod pm_npm;
mod pm_pnpm;
mod pm_yarn;
use std::collections::{HashMap, HashSet};
use std::path::Path;
use anyhow::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PackageManager {
Npm,
Pnpm,
Yarn,
Bun,
}
impl PackageManager {
pub fn command(self) -> &'static str {
match self {
Self::Npm => "npm",
Self::Pnpm => "pnpm",
Self::Yarn => "yarn",
Self::Bun => "bun",
}
}
}
impl std::fmt::Display for PackageManager {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.command())
}
}
#[derive(Debug, Clone)]
pub struct OutdatedEntry {
pub current: String,
pub latest: String,
}
pub trait PackageManagerChecker {
async fn list_packages(&self, dir: &Path) -> Result<Vec<(String, String, bool)>>;
async fn outdated_packages(&self, dir: &Path) -> Result<HashMap<String, OutdatedEntry>>;
}
pub(super) fn read_dev_dependency_names(dir: &Path) -> HashSet<String> {
let Ok(content) = std::fs::read_to_string(dir.join("package.json")) else {
return HashSet::new();
};
let Ok(pkg) = serde_json::from_str::<serde_json::Value>(&content) else {
return HashSet::new();
};
pkg.get("devDependencies")
.and_then(|v| v.as_object())
.map(|obj| obj.keys().cloned().collect())
.unwrap_or_default()
}