UNPKG

node-os-utils

Version:

Advanced cross-platform operating system monitoring utilities with TypeScript support

244 lines 7.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BasePlatformAdapter = void 0; const errors_1 = require("../types/errors"); /** * 平台适配器抽象基类 * * 为不同操作系统提供统一的接口,子类需要实现具体的平台相关逻辑 */ class BasePlatformAdapter { constructor(platformName) { this.platformName = platformName; this.supportedFeatures = this.initializeSupportedFeatures(); } /** * 获取平台名称 */ getPlatform() { return this.platformName; } /** * 检查是否支持特定功能 */ isSupported(feature) { const parts = feature.split('.'); if (parts.length !== 2) { return false; } const [category, featureName] = parts; const categoryFeatures = this.supportedFeatures[category]; if (!categoryFeatures) { return false; } return categoryFeatures[featureName] === true; } /** * 获取支持的功能列表 */ getSupportedFeatures() { return { ...this.supportedFeatures }; } // 受保护的辅助方法 /** * 安全执行命令 */ async safeExecute(command, options) { try { return await this.executeCommand(command, options); } catch (error) { // 返回失败的结果而不是抛出异常 return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode: 1, platform: this.platformName, executionTime: 0, command }; } } /** * 创建不支持功能的错误 */ createUnsupportedError(feature) { return errors_1.MonitorError.createPlatformNotSupported(this.platformName, feature); } /** * 创建命令执行失败错误 */ createCommandError(command, details) { return errors_1.MonitorError.createCommandFailed(this.platformName, command, details); } /** * 创建解析错误 */ createParseError(data, reason) { return errors_1.MonitorError.createParseError(this.platformName, data, reason); } /** * 验证命令执行结果 */ validateCommandResult(result, command) { if (result.exitCode !== 0) { throw this.createCommandError(command, { exitCode: result.exitCode, stderr: result.stderr, stdout: result.stdout }); } if (!result.stdout || result.stdout.trim().length === 0) { throw this.createCommandError(command, { reason: 'Empty output', stderr: result.stderr }); } } /** * 安全解析 JSON */ safeParseJSON(data, fallback = null) { try { return JSON.parse(data); } catch (error) { return fallback; } } /** * 安全解析数字 */ safeParseNumber(value, fallback = 0) { if (typeof value === 'number') { return isNaN(value) ? fallback : value; } const parsed = parseFloat(value); return isNaN(parsed) ? fallback : parsed; } /** * 安全解析整数 */ safeParseInt(value, fallback = 0, radix = 10) { if (typeof value === 'number') { return isNaN(value) ? fallback : Math.floor(value); } const parsed = parseInt(value, radix); return isNaN(parsed) ? fallback : parsed; } /** * 解析键值对格式的输出 */ parseKeyValueOutput(output, separator = ':') { const result = {}; const lines = output.split('\n'); for (const line of lines) { const trimmed = line.trim(); if (!trimmed) continue; const separatorIndex = trimmed.indexOf(separator); if (separatorIndex === -1) continue; const key = trimmed.substring(0, separatorIndex).trim(); const value = trimmed.substring(separatorIndex + separator.length).trim(); if (key && value) { result[key] = value; } } return result; } /** * 解析表格格式的输出 */ parseTableOutput(output, hasHeader = true) { const lines = output.split('\n').map(line => line.trim()).filter(line => line); if (lines.length === 0) return []; let dataLines = lines; let headers = []; if (hasHeader && lines.length > 0) { headers = this.splitTableRow(lines[0]); dataLines = lines.slice(1); } const result = []; for (const line of dataLines) { const values = this.splitTableRow(line); if (values.length === 0) continue; const row = {}; if (headers.length > 0) { // 使用表头作为键 for (let i = 0; i < Math.min(headers.length, values.length); i++) { row[headers[i]] = values[i]; } } else { // 使用索引作为键 for (let i = 0; i < values.length; i++) { row[i.toString()] = values[i]; } } result.push(row); } return result; } /** * 分割表格行 */ splitTableRow(row) { // 支持多种分隔符:空格、制表符等 return row.split(/\s+/).filter(cell => cell.length > 0); } /** * 字节单位转换 */ /** * 将带单位的容量统一换算为字节,支持 SI 与二进制后缀 */ convertToBytes(value, unit) { const num = typeof value === 'string' ? this.safeParseNumber(value) : value; if (!unit) { // 尝试从值中提取单位 if (typeof value === 'string') { const match = value.match(/^([\d.]+)\s*([a-zA-Z]+)$/); if (match) { return this.convertToBytes(match[1], match[2]); } } return num; } const multipliers = { 'b': 1, 'byte': 1, 'bytes': 1, 'k': 1024, 'kb': 1024, 'kib': 1024, 'ki': 1024, 'kilobyte': 1024, 'kilobytes': 1024, 'm': 1024 * 1024, 'mb': 1024 * 1024, 'mib': 1024 * 1024, 'mi': 1024 * 1024, 'megabyte': 1024 * 1024, 'megabytes': 1024 * 1024, 'g': 1024 * 1024 * 1024, 'gb': 1024 * 1024 * 1024, 'gib': 1024 * 1024 * 1024, 'gi': 1024 * 1024 * 1024, 'gigabyte': 1024 * 1024 * 1024, 'gigabytes': 1024 * 1024 * 1024, 't': 1024 * 1024 * 1024 * 1024, 'tb': 1024 * 1024 * 1024 * 1024, 'tib': 1024 * 1024 * 1024 * 1024, 'ti': 1024 * 1024 * 1024 * 1024, 'terabyte': 1024 * 1024 * 1024 * 1024, 'terabytes': 1024 * 1024 * 1024 * 1024 }; const multiplier = multipliers[unit.toLowerCase()] || 1; return num * multiplier; } } exports.BasePlatformAdapter = BasePlatformAdapter; //# sourceMappingURL=platform-adapter.js.map