adnv 1.5.0

CLI that tracks, checks and auto-updates infrastructure dependency versions across Terraform, Helm, Docker, Git and npm
Documentation
use serde::Deserialize;
use std::collections::HashMap;

use super::Tag;
use crate::sources::data::NpmSource;
use crate::{Error, Result};

#[derive(Debug, Clone, Deserialize)]
struct Response {
    versions: HashMap<String, serde_json::Value>,
    time: HashMap<String, chrono::DateTime<chrono::Utc>>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct Entry {
    pub version: String,
    pub created: chrono::DateTime<chrono::Utc>,
}

pub async fn fetch_entries(index: &str) -> Result<Vec<Entry>> {
    let res = crate::util::http::client()?.get(index).send().await?;
    let data: Response = serde_json::from_str(&crate::util::http::body(res).await?)?;

    let entries = data
        .versions
        .keys()
        .filter_map(|version| Some((version, data.time.get(version)?)))
        .map(|(version, date)| Entry {
            version: version.clone(),
            created: *date,
        })
        .collect();

    Ok(entries)
}

pub async fn list_tags(source: &NpmSource) -> Result<Vec<Tag>> {
    let repo_url = if let Some(url) = source.url().as_str().strip_prefix("npm+") {
        url.to_string()
    } else if let Some(package_name) = source.url().host_str() {
        format!("https://registry.npmjs.org/{package_name}")
    } else {
        return Err(Error::NpmRegistryURL(source.url().to_string()));
    };

    let entries = fetch_entries(&repo_url).await?;

    Ok(entries
        .into_iter()
        .map(|entry| Tag::new(entry.version, entry.created))
        .collect())
}