use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use sublime_standard_tools::config::{ConfigResult, Configurable};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(default)]
pub struct UpgradeConfig {
pub registry: RegistryConfig,
pub auto_changeset: bool,
pub changeset_bump: String,
pub backup: BackupConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(default)]
pub struct RegistryConfig {
pub default_registry: String,
pub scoped_registries: HashMap<String, String>,
pub auth_tokens: HashMap<String, String>,
pub timeout_secs: u64,
pub retry_attempts: usize,
pub retry_delay_ms: u64,
pub read_npmrc: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(default)]
pub struct BackupConfig {
pub enabled: bool,
pub backup_dir: String,
pub keep_after_success: bool,
pub max_backups: usize,
}
impl Default for UpgradeConfig {
fn default() -> Self {
Self {
registry: RegistryConfig::default(),
auto_changeset: true,
changeset_bump: "patch".to_string(),
backup: BackupConfig::default(),
}
}
}
impl Default for RegistryConfig {
fn default() -> Self {
Self {
default_registry: "https://registry.npmjs.org".to_string(),
scoped_registries: HashMap::new(),
auth_tokens: HashMap::new(),
timeout_secs: 30,
retry_attempts: 3,
retry_delay_ms: 1000,
read_npmrc: true,
}
}
}
impl Default for BackupConfig {
fn default() -> Self {
Self {
enabled: true,
backup_dir: ".workspace-backups".to_string(),
keep_after_success: false,
max_backups: 5,
}
}
}
impl Configurable for UpgradeConfig {
fn validate(&self) -> ConfigResult<()> {
match self.changeset_bump.as_str() {
"major" | "minor" | "patch" | "none" => {}
_ => {
return Err(sublime_standard_tools::config::ConfigError::ValidationError {
message: format!(
"upgrade.changeset_bump: Invalid bump type '{}'. Must be one of: major, minor, patch, none",
self.changeset_bump
),
});
}
}
self.registry.validate()?;
self.backup.validate()?;
Ok(())
}
fn merge_with(&mut self, other: Self) -> ConfigResult<()> {
self.registry.merge_with(other.registry)?;
self.auto_changeset = other.auto_changeset;
self.changeset_bump = other.changeset_bump;
self.backup.merge_with(other.backup)?;
Ok(())
}
}
impl Configurable for RegistryConfig {
fn validate(&self) -> ConfigResult<()> {
if self.default_registry.is_empty() {
return Err(sublime_standard_tools::config::ConfigError::ValidationError {
message: "upgrade.registry.default_registry: Default registry URL cannot be empty"
.to_string(),
});
}
if self.timeout_secs == 0 {
return Err(sublime_standard_tools::config::ConfigError::ValidationError {
message: "upgrade.registry.timeout_secs: Timeout must be greater than 0"
.to_string(),
});
}
Ok(())
}
fn merge_with(&mut self, other: Self) -> ConfigResult<()> {
self.default_registry = other.default_registry;
self.scoped_registries = other.scoped_registries;
self.auth_tokens = other.auth_tokens;
self.timeout_secs = other.timeout_secs;
self.retry_attempts = other.retry_attempts;
self.retry_delay_ms = other.retry_delay_ms;
self.read_npmrc = other.read_npmrc;
Ok(())
}
}
impl Configurable for BackupConfig {
fn validate(&self) -> ConfigResult<()> {
if self.backup_dir.is_empty() {
return Err(sublime_standard_tools::config::ConfigError::ValidationError {
message: "upgrade.backup.backup_dir: Backup directory cannot be empty".to_string(),
});
}
Ok(())
}
fn merge_with(&mut self, other: Self) -> ConfigResult<()> {
self.enabled = other.enabled;
self.backup_dir = other.backup_dir;
self.keep_after_success = other.keep_after_success;
self.max_backups = other.max_backups;
Ok(())
}
}