node-os-utils
Version:
Advanced cross-platform operating system monitoring utilities with TypeScript support
244 lines • 7.52 kB
JavaScript
"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