browsr-types 0.4.0

Shared data models and schemas for Browsr browser automation flows.
Documentation
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// Supported proxy options for the embedded Chromium browser
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum BrowserProxy {
    /// Route traffic through an HTTPS proxy at the provided host:port
    Https { address: String },
    /// Route traffic through a SOCKS5 proxy at the provided host:port
    Socks5 { address: String },
    /// Route traffic through an HTTP proxy with username/password authentication
    HttpAuth {
        address: String,
        username: String,
        password: String,
    },
}

/// Chromium driver configuration shared across orchestrator + CLI
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(default, deny_unknown_fields)]
pub struct BrowsrClientConfig {
    /// Preferred viewport size (defaults to 1920x1080)
    #[serde(skip_serializing_if = "Option::is_none")]
    pub window_size: Option<(u32, u32)>,
    /// Whether to run Chromium in headless mode
    #[serde(skip_serializing_if = "Option::is_none")]
    pub headless: Option<bool>,
    /// Enable stealth adjustments to reduce detection heuristics
    pub enable_stealth_mode: bool,
    /// Enable Spider's "real" emulation for fonts, media, etc.
    pub enable_real_emulation: bool,
    /// Optional proxy information passed to Chromium
    #[serde(skip_serializing_if = "Option::is_none")]
    pub proxy: Option<BrowserProxy>,
    /// Model settings for structured extraction (loaded from browsr.toml) - stored as JSON to avoid circular dependencies
    #[serde(skip_serializing_if = "Option::is_none")]
    pub analysis_model_settings: Option<serde_json::Value>,
    /// Custom user agent string (defaults to modern Chrome on macOS)
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user_agent: Option<String>,
    /// Generate a random modern Chrome user agent on session start (overrides user_agent if set)
    #[serde(default)]
    pub use_random_user_agent: bool,
    /// Disable automation detection features (webdriver flag, etc.)
    #[serde(default = "default_true")]
    pub disable_automation_detection: bool,
}

fn default_true() -> bool {
    true
}

impl Default for BrowsrClientConfig {
    fn default() -> Self {
        Self {
            window_size: None,
            headless: Some(true),
            enable_stealth_mode: true,
            enable_real_emulation: true,
            proxy: None,
            analysis_model_settings: None,
            user_agent: None,
            use_random_user_agent: false,
            disable_automation_detection: true,
        }
    }
}

/// Serializable cookie representation used for session persistence
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct BrowserCookie {
    pub name: String,
    pub value: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub domain: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub path: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub expires: Option<f64>,
    #[serde(default)]
    pub http_only: bool,
    #[serde(default)]
    pub secure: bool,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub same_site: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub priority: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub source_scheme: Option<String>,
}

/// Captured browser state (cookies + last URL)
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct BrowserSessionState {
    pub cookies: Vec<BrowserCookie>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub last_url: Option<String>,
    #[schemars(with = "String")]
    pub captured_at: chrono::DateTime<chrono::Utc>,
}

/// Persisted browser session entry keyed by user id
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct BrowserSessionRecord {
    pub user_id: String,
    pub state: BrowserSessionState,
    #[schemars(with = "String")]
    pub updated_at: chrono::DateTime<chrono::Utc>,
}