1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! NPM registry client for package metadata queries.
//!
//! **What**: Provides HTTP client functionality for querying NPM registries to fetch
//! package metadata, versions, and upgrade information.
//!
//! **How**: This module uses reqwest with retry middleware to communicate with NPM
//! registries, handling authentication, timeouts, scoped packages, and private registries.
//! It parses registry responses and provides type-safe access to package metadata.
//!
//! **Why**: To enable reliable package upgrade detection by fetching the latest versions
//! and metadata from NPM registries, with proper error handling and enterprise support.
//!
//! # Features
//!
//! - **Public NPM Registry**: Query packages from the public NPM registry
//! - **Private Registries**: Support for private registries with authentication
//! - **Scoped Packages**: Handle scoped packages with custom registry mappings
//! - **Retry Logic**: Automatic retry on transient failures with exponential backoff
//! - **Authentication**: Bearer token authentication for private packages
//! - **Timeout Handling**: Configurable timeouts with proper error reporting
//! - **Version Comparison**: Semantic versioning comparison and upgrade type detection
//!
//! # Example
//!
//! ```rust,no_run
//! use sublime_pkg_tools::upgrade::{RegistryClient, UpgradeType};
//! use sublime_pkg_tools::config::RegistryConfig;
//! use std::path::PathBuf;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let workspace_root = PathBuf::from(".");
//! let config = RegistryConfig::default();
//!
//! // Create client
//! let client = RegistryClient::new(&workspace_root, config).await?;
//!
//! // Query package metadata
//! let metadata = client.get_package_info("express").await?;
//! println!("Package: {}", metadata.name);
//! println!("Latest version: {}", metadata.latest);
//! println!("Available versions: {}", metadata.versions.len());
//!
//! // Check if deprecated
//! if metadata.is_deprecated() {
//! println!("Warning: Package is deprecated!");
//! }
//!
//! // Get latest version directly
//! let latest = client.get_latest_version("lodash").await?;
//! println!("Latest lodash: {}", latest);
//!
//! // Compare versions
//! let upgrade = client.compare_versions("lodash", "1.2.3", "2.0.0")?;
//! println!("Upgrade type: {}", upgrade);
//! # Ok(())
//! # }
//! ```
//!
//! # Private Registry
//!
//! ```rust,no_run
//! use sublime_pkg_tools::upgrade::RegistryClient;
//! use sublime_pkg_tools::config::RegistryConfig;
//! use std::path::PathBuf;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let mut config = RegistryConfig::default();
//!
//! // Configure scoped registry
//! config.scoped_registries.insert(
//! "myorg".to_string(),
//! "https://npm.myorg.com".to_string()
//! );
//!
//! // Add authentication token
//! config.auth_tokens.insert(
//! "https://npm.myorg.com".to_string(),
//! "npm_AbCdEf123456".to_string()
//! );
//!
//! let client = RegistryClient::new(&PathBuf::from("."), config).await?;
//!
//! // Query private package
//! let metadata = client.get_package_info("@myorg/private-package").await?;
//! println!("Private package: {}", metadata.name);
//! # Ok(())
//! # }
//! ```
//!
//! # Configuration
//!
//! The registry client is configured via `RegistryConfig`:
//!
//! ```toml
//! [package_tools.upgrade.registry]
//! default_registry = "https://registry.npmjs.org"
//! timeout_secs = 30
//! retry_attempts = 3
//! retry_delay_ms = 1000
//! read_npmrc = true
//!
//! [package_tools.upgrade.registry.scoped]
//! "@myorg" = "https://npm.myorg.com"
//! "@internal" = "https://registry.internal.corp"
//! ```
//!
//! # Error Handling
//!
//! All registry operations return `Result<T, UpgradeError>` with specific error variants:
//!
//! - `PackageNotFound`: Package doesn't exist in registry (404)
//! - `AuthenticationFailed`: Authentication required or failed (401/403)
//! - `RegistryTimeout`: Request timed out
//! - `RegistryError`: General registry error (HTTP error)
//! - `InvalidResponse`: Registry returned malformed data
//! - `NetworkError`: Network connectivity issues
//!
//! # Module Structure
//!
//! This module is private with public types re-exported through the parent `upgrade` module:
//!
//! - `client`: Main `RegistryClient` implementation (pub(crate))
//! - `types`: Data structures for registry responses and upgrade types (pub(crate))
//! - `tests`: Integration tests with mock HTTP server
//!
//! Public API is accessed via `sublime_pkg_tools::upgrade::{RegistryClient, PackageMetadata, ...}`
pub
pub
// Re-export public API
pub use RegistryClient;
pub use ;