vx_tool_node/
config.rs

1//! Node.js installation configuration
2//!
3//! This module provides Node.js-specific installation configuration,
4//! including URL building, platform detection, and installation methods.
5
6use std::path::PathBuf;
7use vx_installer::{ArchiveFormat, InstallConfig, InstallMethod};
8use vx_tool_standard::{StandardToolConfig, StandardUrlBuilder, ToolDependency};
9
10/// Standard configuration for Node.js tool
11pub struct Config;
12
13/// Node.js URL builder for consistent download URL generation
14pub struct NodeUrlBuilder;
15
16impl StandardUrlBuilder for NodeUrlBuilder {
17    /// Generate download URL for Node.js version
18    fn download_url(version: &str) -> Option<String> {
19        let _platform = Self::get_platform_string();
20        let filename = Self::get_filename(version);
21
22        Some(format!("https://nodejs.org/dist/v{}/{}", version, filename))
23    }
24
25    /// Get platform-specific filename
26    fn get_filename(version: &str) -> String {
27        let platform = Self::get_platform_string();
28        if cfg!(windows) {
29            format!("node-v{}-{}.zip", version, platform)
30        } else {
31            format!("node-v{}-{}.tar.gz", version, platform)
32        }
33    }
34
35    /// Get platform string for Node.js downloads
36    fn get_platform_string() -> String {
37        match (std::env::consts::OS, std::env::consts::ARCH) {
38            ("windows", "x86_64") => "win-x64".to_string(),
39            ("windows", "x86") => "win-x86".to_string(),
40            ("windows", "aarch64") => "win-arm64".to_string(),
41            ("macos", "x86_64") => "darwin-x64".to_string(),
42            ("macos", "aarch64") => "darwin-arm64".to_string(),
43            ("linux", "x86_64") => "linux-x64".to_string(),
44            ("linux", "x86") => "linux-x86".to_string(),
45            ("linux", "aarch64") => "linux-arm64".to_string(),
46            ("linux", "arm") => "linux-armv7l".to_string(),
47            _ => "linux-x64".to_string(), // Default fallback
48        }
49    }
50}
51
52/// Implementation of standard tool configuration for Node.js
53impl StandardToolConfig for Config {
54    fn tool_name() -> &'static str {
55        "node"
56    }
57
58    fn create_install_config(version: &str, install_dir: PathBuf) -> InstallConfig {
59        create_install_config(version, install_dir)
60    }
61
62    fn get_install_methods() -> Vec<String> {
63        get_install_methods()
64    }
65
66    fn supports_auto_install() -> bool {
67        true
68    }
69
70    fn get_manual_instructions() -> String {
71        get_manual_instructions()
72    }
73
74    fn get_dependencies() -> Vec<ToolDependency> {
75        // Node.js has no dependencies - it's a base runtime
76        vec![]
77    }
78
79    fn get_default_version() -> &'static str {
80        "20.11.0" // LTS version
81    }
82}
83
84/// Create Node.js installation configuration
85pub fn create_install_config(version: &str, install_dir: PathBuf) -> InstallConfig {
86    let actual_version = if version == "latest" {
87        "20.11.0" // Default to LTS version
88    } else {
89        version
90    };
91
92    let download_url = NodeUrlBuilder::download_url(actual_version);
93    let install_method = InstallMethod::Archive {
94        format: if cfg!(windows) {
95            ArchiveFormat::Zip
96        } else {
97            ArchiveFormat::TarGz
98        },
99    };
100
101    InstallConfig::builder()
102        .tool_name("node")
103        .version(version.to_string())
104        .install_method(install_method)
105        .download_url(download_url.unwrap_or_default())
106        .install_dir(install_dir)
107        .build()
108}
109
110/// Get available Node.js installation methods
111pub fn get_install_methods() -> Vec<String> {
112    vec![
113        "Official releases".to_string(),
114        if cfg!(target_os = "macos") {
115            "Homebrew".to_string()
116        } else {
117            "Package manager".to_string()
118        },
119        "Node Version Manager (nvm)".to_string(),
120    ]
121}
122
123/// Check if Node.js supports automatic installation
124pub fn supports_auto_install() -> bool {
125    true
126}
127
128/// Get manual installation instructions for Node.js
129pub fn get_manual_instructions() -> String {
130    "To install Node.js manually:\n\
131     • Visit: https://nodejs.org/\n\
132     • Or use a version manager like nvm"
133        .to_string()
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139
140    #[test]
141    fn test_node_url_builder() {
142        let url = NodeUrlBuilder::download_url("18.17.0");
143        assert!(url.is_some());
144        assert!(url.unwrap().contains("nodejs.org"));
145    }
146
147    #[test]
148    fn test_platform_string() {
149        let platform = NodeUrlBuilder::get_platform_string();
150        assert!(!platform.is_empty());
151    }
152
153    #[test]
154    fn test_create_install_config() {
155        let config = create_install_config("18.17.0", PathBuf::from("/tmp/node"));
156        assert_eq!(config.tool_name, "node");
157        assert_eq!(config.version, "18.17.0");
158        assert!(config.download_url.is_some());
159    }
160
161    #[test]
162    fn test_latest_version_handling() {
163        let config = create_install_config("latest", PathBuf::from("/tmp/node"));
164        assert_eq!(config.version, "latest");
165        // Should use actual version in URL
166        assert!(config.download_url.unwrap().contains("20.11.0"));
167    }
168}