wme-cli 0.1.3

CLI tool for the Wikimedia Enterprise API
//! CLI command implementations for the Wikimedia Enterprise API.
//!
//! This module contains submodules for each major API category:
//!
//! - `article` - On-demand article fetching
//! - `auth` - Authentication and token management
//! - `meta` - Metadata APIs (projects, languages, namespaces)
//! - `realtime` - Realtime streaming and batch management
//! - `snapshot` - Snapshot listing, metadata, and downloads
//!
//! The `GlobalOpts` struct provides common options that are passed to all commands,
//! including authentication tokens, output format, and API parameters.

pub mod article;
pub mod auth;
pub mod meta;
pub mod realtime;
pub mod snapshot;

use anyhow::{Context, Result};
use wme_client::WmeClient;

use crate::client::build_client;
use crate::config::Config;
use crate::output::OutputFormat;

/// Global options passed to all CLI commands.
///
/// This struct holds configuration options that are shared across all commands,
/// including authentication tokens, output format preferences, and API parameters.
/// It is constructed in `main.rs` from command-line arguments and passed to
/// each command handler.
///
/// # Fields
///
/// * `token` - Optional bearer token override from `--token` flag
/// * `output` - Output format (JSON, NDJSON, Table, Quiet)
/// * `fields` - Comma-separated fields to include in API responses
/// * `filter` - Field filters as `field=value` pairs
/// * `limit` - Maximum number of results to return
/// * `config` - Loaded configuration from config file
#[derive(Debug, Clone)]
pub struct GlobalOpts {
    /// Bearer access token (overrides stored token)
    pub token: Option<String>,
    /// Output format
    pub output: OutputFormat,
    /// Comma-separated fields to include
    pub fields: Option<String>,
    /// Field filters as field=value
    pub filter: Vec<String>,
    /// Max results to return
    pub limit: Option<usize>,
    /// Config
    pub config: Config,
}

impl GlobalOpts {
    /// Build a WME client using the configured options.
    ///
    /// Creates a `WmeClient` using the stored configuration and optional
    /// token override. This method handles the authentication priority:
    /// CLI token > stored tokens > error if none available.
    ///
    /// # Errors
    ///
    /// Returns an error if no authentication is available or client creation fails.
    pub async fn build_client(&self) -> Result<WmeClient> {
        build_client(&self.config, self.token.clone())
            .await
            .context("Failed to create WME client")
    }

    /// Get the effective access token.
    ///
    /// Returns the CLI-provided token if available, otherwise falls back
    /// to the stored token from configuration (if not expired).
    ///
    /// # Returns
    ///
    /// Returns `Some(token)` if a valid token is available, otherwise `None`.
    pub fn get_token(&self) -> Option<String> {
        self.token
            .clone()
            .or_else(|| self.config.get_access_token())
    }
}