fix(core): tidy formatting and minor fixes across CLI, SNMP, HTTP server, migrations and packaging

This commit is contained in:
2026-01-29 17:10:17 +00:00
parent fda072d15e
commit ff2dc00f31
31 changed files with 693 additions and 362 deletions

View File

@@ -5,13 +5,13 @@ import { exec, execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { NupstSnmp } from './snmp/manager.ts';
import type { ISnmpConfig, IUpsStatus as ISnmpUpsStatus } from './snmp/types.ts';
import { logger, type ITableColumn } from './logger.ts';
import { type ITableColumn, logger } from './logger.ts';
import { MigrationRunner } from './migrations/index.ts';
import { theme, symbols, getBatteryColor, getRuntimeColor, formatPowerStatus } from './colors.ts';
import { formatPowerStatus, getBatteryColor, getRuntimeColor, symbols, theme } from './colors.ts';
import type { IActionConfig } from './actions/base-action.ts';
import { ActionManager, type IActionContext, type TPowerStatus } from './actions/index.ts';
import { NupstHttpServer } from './http-server.ts';
import { TIMING, THRESHOLDS, UI } from './constants.ts';
import { THRESHOLDS, TIMING, UI } from './constants.ts';
const execAsync = promisify(exec);
const execFileAsync = promisify(execFile);
@@ -100,10 +100,10 @@ export interface IUpsStatus {
powerStatus: 'online' | 'onBattery' | 'unknown';
batteryCapacity: number;
batteryRuntime: number;
outputLoad: number; // Load percentage (0-100%)
outputPower: number; // Power in watts
outputVoltage: number; // Voltage in volts
outputCurrent: number; // Current in amps
outputLoad: number; // Load percentage (0-100%)
outputPower: number; // Power in watts
outputVoltage: number; // Voltage in volts
outputCurrent: number; // Current in amps
lastStatusChange: number;
lastCheckTime: number;
}
@@ -155,7 +155,7 @@ export class NupstDaemon {
],
groups: [],
checkInterval: TIMING.CHECK_INTERVAL_MS, // Check every 30 seconds
}
};
private config: INupstConfig;
private snmp: NupstSnmp;
@@ -249,7 +249,12 @@ export class NupstDaemon {
* Helper method to log configuration errors consistently
*/
private logConfigError(message: string): void {
logger.logBox('Configuration Error', [message, "Please run 'nupst setup' first to create a configuration."], 45, 'error');
logger.logBox(
'Configuration Error',
[message, "Please run 'nupst setup' first to create a configuration."],
45,
'error',
);
}
/**
@@ -311,11 +316,15 @@ export class NupstDaemon {
this.config.httpServer.port,
this.config.httpServer.path,
this.config.httpServer.authToken,
() => this.upsStatus
() => this.upsStatus,
);
this.httpServer.start();
} catch (error) {
logger.error(`Failed to start HTTP server: ${error instanceof Error ? error.message : String(error)}`);
logger.error(
`Failed to start HTTP server: ${
error instanceof Error ? error.message : String(error)
}`,
);
}
}
@@ -364,7 +373,6 @@ export class NupstDaemon {
* Log the loaded configuration settings
*/
private logConfigLoaded(): void {
logger.log('');
logger.logBoxTitle('Configuration Loaded', 70, 'success');
logger.logBoxLine(`Check Interval: ${this.config.checkInterval / 1000} seconds`);
@@ -374,8 +382,10 @@ export class NupstDaemon {
// Display UPS devices in a table
if (this.config.upsDevices && this.config.upsDevices.length > 0) {
logger.info(`UPS Devices (${this.config.upsDevices.length}):`);
const upsColumns: Array<{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }> = [
const upsColumns: Array<
{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }
> = [
{ header: 'Name', key: 'name', align: 'left', color: theme.highlight },
{ header: 'ID', key: 'id', align: 'left', color: theme.dim },
{ header: 'Host:Port', key: 'host', align: 'left', color: theme.info },
@@ -399,8 +409,10 @@ export class NupstDaemon {
// Display groups in a table
if (this.config.groups && this.config.groups.length > 0) {
logger.info(`Groups (${this.config.groups.length}):`);
const groupColumns: Array<{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }> = [
const groupColumns: Array<
{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }
> = [
{ header: 'Name', key: 'name', align: 'left', color: theme.highlight },
{ header: 'ID', key: 'id', align: 'left', color: theme.dim },
{ header: 'Mode', key: 'mode', align: 'left', color: theme.info },
@@ -538,7 +550,7 @@ export class NupstDaemon {
// Only check when on battery power
if (status.powerStatus === 'onBattery' && ups.actions && ups.actions.length > 0) {
let anyThresholdExceeded = false;
for (const actionConfig of ups.actions) {
if (actionConfig.thresholds) {
if (
@@ -575,7 +587,7 @@ export class NupstDaemon {
*/
private logAllUpsStatus(): void {
const timestamp = new Date().toISOString();
logger.log('');
logger.logBoxTitle('Periodic Status Update', 70, 'info');
logger.logBoxLine(`Timestamp: ${timestamp}`);
@@ -583,7 +595,9 @@ export class NupstDaemon {
logger.log('');
// Build table data
const columns: Array<{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }> = [
const columns: Array<
{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }
> = [
{ header: 'UPS Name', key: 'name', align: 'left', color: theme.highlight },
{ header: 'ID', key: 'id', align: 'left', color: theme.dim },
{ header: 'Power Status', key: 'powerStatus', align: 'left' },
@@ -595,7 +609,7 @@ export class NupstDaemon {
for (const [id, status] of this.upsStatus.entries()) {
const batteryColor = getBatteryColor(status.batteryCapacity);
const runtimeColor = getRuntimeColor(status.batteryRuntime);
rows.push({
name: status.name,
id: id,
@@ -609,10 +623,6 @@ export class NupstDaemon {
logger.log('');
}
/**
* Build action context from UPS state
* @param ups UPS configuration
@@ -796,7 +806,9 @@ export class NupstDaemon {
logger.log('');
logger.logBoxTitle('Shutdown Monitoring Active', UI.WIDE_BOX_WIDTH, 'warning');
logger.logBoxLine(`Emergency threshold: ${THRESHOLDS.EMERGENCY_RUNTIME_MINUTES} minutes runtime`);
logger.logBoxLine(
`Emergency threshold: ${THRESHOLDS.EMERGENCY_RUNTIME_MINUTES} minutes runtime`,
);
logger.logBoxLine(`Check interval: ${TIMING.SHUTDOWN_CHECK_INTERVAL_MS / 1000} seconds`);
logger.logBoxLine(`Max monitoring time: ${TIMING.MAX_SHUTDOWN_MONITORING_MS / 1000} seconds`);
logger.logBoxEnd();
@@ -808,7 +820,9 @@ export class NupstDaemon {
logger.info('Checking UPS status during shutdown...');
// Build table for UPS status during shutdown
const columns: Array<{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }> = [
const columns: Array<
{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }
> = [
{ header: 'UPS Name', key: 'name', align: 'left', color: theme.highlight },
{ header: 'Battery', key: 'battery', align: 'right' },
{ header: 'Runtime', key: 'runtime', align: 'right' },
@@ -828,7 +842,7 @@ export class NupstDaemon {
const runtimeColor = getRuntimeColor(status.batteryRuntime);
const isCritical = status.batteryRuntime < THRESHOLDS.EMERGENCY_RUNTIME_MINUTES;
rows.push({
name: ups.name,
battery: batteryColor(status.batteryCapacity + '%'),
@@ -848,7 +862,7 @@ export class NupstDaemon {
runtime: theme.error('N/A'),
status: theme.error('ERROR'),
});
logger.error(
`Error checking UPS ${ups.name} during shutdown: ${
upsError instanceof Error ? upsError.message : String(upsError)
@@ -991,7 +1005,9 @@ export class NupstDaemon {
let lastConfigCheck = Date.now();
logger.log('Entering idle monitoring mode...');
logger.log(`Daemon will check for config changes every ${TIMING.IDLE_CHECK_INTERVAL_MS / 1000} seconds`);
logger.log(
`Daemon will check for config changes every ${TIMING.IDLE_CHECK_INTERVAL_MS / 1000} seconds`,
);
// Start file watcher for hot-reload
this.watchConfigFile();