pub(super) fn npm_config_env_entries_from(env: &[(String, String)]) -> Vec<(String, String)> {
env.iter()
.filter_map(|(n, v)| translate_npm_config_env(n, v))
.collect()
}
pub(super) fn translate_npm_config_env(name: &str, value: &str) -> Option<(String, String)> {
let suffix = name
.strip_prefix("npm_config_")
.or_else(|| name.strip_prefix("NPM_CONFIG_"))?;
if suffix.starts_with("//") {
return Some((suffix.to_string(), value.to_string()));
}
if let Some(rest) = suffix.strip_prefix('@')
&& let Some((scope, tail)) = rest.split_once(':')
&& tail.eq_ignore_ascii_case("registry")
{
return Some((
format!("@{}:registry", scope.to_ascii_lowercase()),
value.to_string(),
));
}
let npmrc_key = match suffix.to_ascii_lowercase().as_str() {
"registry" => "registry",
"https_proxy" => "https-proxy",
"http_proxy" => "http-proxy",
"proxy" => "proxy",
"noproxy" => "noproxy",
"strict_ssl" => "strict-ssl",
"local_address" => "local-address",
"maxsockets" => "maxsockets",
_ => return None,
};
Some((npmrc_key.to_string(), value.to_string()))
}
pub(super) fn env_any(names: &[&str]) -> Option<String> {
for n in names {
if let Ok(v) = std::env::var(n) {
let trimmed = v.trim();
if !trimmed.is_empty() {
return Some(trimmed.to_string());
}
}
}
None
}