1#![forbid(unsafe_code)]
13
14pub mod wasm;
15pub use wasm::Sandbox;
16
17use serde::{Deserialize, Serialize};
18use std::collections::BTreeMap;
19use vanta_core::{Artifact, Checksum, Platform};
20
21#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
23pub struct ProviderDef {
24 pub id: String,
26 pub tool: String,
28 pub url_template: String,
30 pub archive: String,
32 #[serde(default)]
34 pub strip: u32,
35 #[serde(default)]
37 pub bin: Vec<String>,
38 #[serde(default)]
40 pub os_map: BTreeMap<String, String>,
41 #[serde(default)]
43 pub arch_map: BTreeMap<String, String>,
44}
45
46impl ProviderDef {
47 pub fn render_artifact(
50 &self,
51 version: &str,
52 platform: &Platform,
53 checksum: Checksum,
54 size: Option<u64>,
55 ) -> Artifact {
56 let os = self.map_os(platform);
57 let arch = self.map_arch(platform);
58 let url = self
59 .url_template
60 .replace("{version}", version)
61 .replace("{os}", &os)
62 .replace("{arch}", &arch)
63 .replace("{ext}", ext_for(&self.archive));
64 Artifact {
65 url,
66 mirrors: Vec::new(),
67 archive: self.archive.clone(),
68 size,
69 checksum,
70 signature: None,
71 signature_key: None,
72 bin: self.bin.clone(),
73 strip: self.strip,
74 store_key: None,
75 }
76 }
77
78 fn map_os(&self, platform: &Platform) -> String {
79 let key = platform.os.as_str();
80 self.os_map
81 .get(key)
82 .cloned()
83 .unwrap_or_else(|| key.to_string())
84 }
85
86 fn map_arch(&self, platform: &Platform) -> String {
87 let key = platform.arch.as_str();
88 self.arch_map
89 .get(key)
90 .cloned()
91 .unwrap_or_else(|| key.to_string())
92 }
93}
94
95pub fn ext_for(archive: &str) -> &'static str {
97 match archive {
98 "tar.gz" | "tgz" => "tar.gz",
99 "tar.xz" => "tar.xz",
100 "zip" => "zip",
101 _ => "",
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108 use vanta_core::{Arch, Libc, Os};
109
110 fn node_provider() -> ProviderDef {
111 let mut os_map = BTreeMap::new();
112 os_map.insert("macos".into(), "darwin".into());
113 let mut arch_map = BTreeMap::new();
114 arch_map.insert("aarch64".into(), "arm64".into());
115 ProviderDef {
116 id: "official/node".into(),
117 tool: "node".into(),
118 url_template: "https://nodejs.org/dist/v{version}/node-v{version}-{os}-{arch}.{ext}"
119 .into(),
120 archive: "tar.gz".into(),
121 strip: 1,
122 bin: vec!["bin/node".into()],
123 os_map,
124 arch_map,
125 }
126 }
127
128 #[test]
129 fn renders_url_with_token_maps() {
130 let p = node_provider();
131 let plat = Platform {
132 os: Os::Macos,
133 arch: Arch::Aarch64,
134 libc: Libc::None,
135 };
136 let art = p.render_artifact(
137 "24.6.0",
138 &plat,
139 Checksum {
140 algo: "sha256".into(),
141 value: "abc".into(),
142 },
143 Some(100),
144 );
145 assert_eq!(
146 art.url,
147 "https://nodejs.org/dist/v24.6.0/node-v24.6.0-darwin-arm64.tar.gz"
148 );
149 assert_eq!(art.archive, "tar.gz");
150 assert_eq!(art.bin, vec!["bin/node".to_string()]);
151 assert_eq!(art.checksum.value, "abc");
152 }
153}