const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); /** * 版本服务 * 提供版本比较、文件哈希计算等功能 */ class VersionService { /** * 比较两个版本号 * @param {string} version1 - 版本号1(x.y.z 格式) * @param {string} version2 - 版本号2(x.y.z 格式) * @returns {number} 返回 1 表示 version1 > version2,-1 表示 version1 < version2,0 表示相等 */ compare_version(version1, version2) { if (!version1 || !version2) { throw new Error('版本号不能为空'); } // 验证版本号格式 const version_pattern = /^\d+\.\d+\.\d+$/; if (!version_pattern.test(version1) || !version_pattern.test(version2)) { throw new Error('版本号格式错误,应为 x.y.z 格式'); } // 将版本号按 "." 分割成数组 const v1_parts = version1.split('.').map(Number); const v2_parts = version2.split('.').map(Number); // 逐位比较 for (let i = 0; i < 3; i++) { if (v1_parts[i] > v2_parts[i]) { return 1; } else if (v1_parts[i] < v2_parts[i]) { return -1; } } return 0; } /** * 检查是否有新版本 * @param {string} current_version - 当前版本号 * @param {string} latest_version - 最新版本号 * @returns {boolean} 是否有新版本 */ has_new_version(current_version, latest_version) { try { const result = this.compare_version(latest_version, current_version); return result > 0; } catch (error) { return false; } } /** * 计算文件的 SHA256 哈希值 * @param {string} file_path - 文件路径 * @returns {Promise} SHA256 哈希值(小写十六进制字符串) */ async calculate_file_hash(file_path) { return new Promise((resolve, reject) => { // 检查文件是否存在 if (!fs.existsSync(file_path)) { return reject(new Error(`文件不存在: ${file_path}`)); } // 创建哈希对象 const hash = crypto.createHash('sha256'); const stream = fs.createReadStream(file_path); stream.on('data', (data) => { hash.update(data); }); stream.on('end', () => { const hash_value = hash.digest('hex'); resolve(hash_value); }); stream.on('error', (error) => { reject(error); }); }); } /** * 获取文件大小 * @param {string} file_path - 文件路径 * @returns {Promise} 文件大小(字节) */ async get_file_size(file_path) { return new Promise((resolve, reject) => { if (!fs.existsSync(file_path)) { return reject(new Error(`文件不存在: ${file_path}`)); } fs.stat(file_path, (error, stats) => { if (error) { return reject(error); } resolve(stats.size); }); }); } /** * 验证版本号格式 * @param {string} version - 版本号 * @returns {boolean} 是否有效 */ is_valid_version(version) { if (!version || typeof version !== 'string') { return false; } const version_pattern = /^\d+\.\d+\.\d+$/; return version_pattern.test(version); } /** * 验证平台类型 * @param {string} platform - 平台类型 * @returns {boolean} 是否有效 */ is_valid_platform(platform) { const valid_platforms = ['win32', 'darwin', 'linux']; return valid_platforms.includes(platform); } /** * 验证架构类型 * @param {string} arch - 架构类型 * @returns {boolean} 是否有效 */ is_valid_arch(arch) { const valid_archs = ['x64', 'ia32', 'arm64']; return valid_archs.includes(arch); } } // 导出单例 module.exports = new VersionService();