use jsonc_parser::ast::ObjectProp;
use serde::{Deserialize, Serialize};
use validator::ValidateUrl;
use crate::ext::{Validator, validation_error, value_range};
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct PublishConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub access: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub registry: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tag: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub provenance: Option<bool>,
}
impl Validator for PublishConfig {
fn validate(&self, publish_config: Option<&ObjectProp>) -> miette::Result<()> {
if let Some(access) = self.access.as_ref() {
let access_regex = lazy_regex::regex_is_match!(r"^(public|restricted|private)$", access);
if !access_regex {
return Err(validation_error(
"Invalid access",
None,
"Please provide a valid access",
value_range(publish_config, &["access"]),
"Invalid access",
));
}
}
if let Some(registry) = self.registry.as_ref() {
if !registry.validate_url() {
return Err(validation_error(
"Invalid registry",
None,
"Please provide a valid registry",
value_range(publish_config, &["registry"]),
"Invalid registry",
));
}
}
if let Some(tag) = self.tag.as_ref() {
let tag_regex = lazy_regex::regex_is_match!(r"^[a-zA-Z0-9-_.]+$", tag);
if !tag_regex {
return Err(validation_error(
"Invalid tag",
None,
"Please provide a valid tag",
value_range(publish_config, &["tag"]),
"Invalid tag",
));
}
}
if let Some(provenance) = self.provenance.as_ref() {
if !provenance {
return Err(validation_error(
"Invalid provenance",
None,
"Please provide a valid provenance",
value_range(publish_config, &["provenance"]),
"Invalid provenance",
));
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use crate::PackageJsonParser;
#[test]
fn should_pass_validate_publish_config() {
let jsones = [
r#"{"publishConfig": {"access": "public", "registry": "https://registry.npmjs.org/"}}"#,
r#"{"publishConfig": {"access": "restricted", "registry": "https://registry.npmjs.org/"}}"#,
r#"{"publishConfig": {"access": "private", "registry": "https://registry.npmjs.org/"}}"#,
r#"{"publishConfig": {"access": "public", "registry": "https://registry.npmjs.org/", "tag": "invalid"}}"#,
];
for json in jsones {
let res = PackageJsonParser::parse_str(json).unwrap();
let res = res.validate();
assert!(res.is_ok());
}
}
#[test]
fn should_fail_validate_publish_config() {
let jsones = [
r#"{"publishConfig": {"access": "invalid", "registry": "https://registry.npmjs.org/"}}"#,
r#"{"publishConfig": {"access": "public", "registry": "invalid"}}"#,
r#"{"publishConfig": {"access": "invalid", "registry": "invalid"}}"#,
];
for json in jsones {
let res = PackageJsonParser::parse_str(json).unwrap();
let res = res.validate();
assert!(res.is_err());
}
}
}