feat(core): Centralize timeouts/constants, add CLI prompt helpers, and introduce webhook/script actions with safety and SNMP refactors
This commit is contained in:
@@ -4,8 +4,17 @@ import { Nupst } from '../nupst.ts';
|
||||
import { logger, type ITableColumn } from '../logger.ts';
|
||||
import { theme } from '../colors.ts';
|
||||
import * as helpers from '../helpers/index.ts';
|
||||
import type { TUpsModel } from '../snmp/types.ts';
|
||||
import type { INupstConfig } from '../daemon.ts';
|
||||
import type { ISnmpConfig, TUpsModel, IUpsStatus as ISnmpUpsStatus } from '../snmp/types.ts';
|
||||
import type { INupstConfig, IUpsConfig, IUpsStatus } from '../daemon.ts';
|
||||
import type { IActionConfig } from '../actions/base-action.ts';
|
||||
|
||||
/**
|
||||
* Thresholds configuration for CLI display
|
||||
*/
|
||||
interface IThresholds {
|
||||
battery: number;
|
||||
runtime: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for handling UPS-related CLI commands
|
||||
@@ -27,29 +36,9 @@ export class UpsHandler {
|
||||
*/
|
||||
public async add(): Promise<void> {
|
||||
try {
|
||||
// Import readline module for user input
|
||||
const readline = await import('node:readline');
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
// Helper function to prompt for input
|
||||
const prompt = (question: string): Promise<string> => {
|
||||
return new Promise((resolve) => {
|
||||
rl.question(question, (answer: string) => {
|
||||
resolve(answer);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
await helpers.withPrompt(async (prompt) => {
|
||||
await this.runAddProcess(prompt);
|
||||
} finally {
|
||||
rl.close();
|
||||
process.stdin.destroy();
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(`Add UPS error: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
@@ -160,29 +149,9 @@ export class UpsHandler {
|
||||
*/
|
||||
public async edit(upsId?: string): Promise<void> {
|
||||
try {
|
||||
// Import readline module for user input
|
||||
const readline = await import('node:readline');
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
// Helper function to prompt for input
|
||||
const prompt = (question: string): Promise<string> => {
|
||||
return new Promise((resolve) => {
|
||||
rl.question(question, (answer: string) => {
|
||||
resolve(answer);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
await helpers.withPrompt(async (prompt) => {
|
||||
await this.runEditProcess(upsId, prompt);
|
||||
} finally {
|
||||
rl.close();
|
||||
process.stdin.destroy();
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(`Edit UPS error: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
@@ -337,23 +306,11 @@ export class UpsHandler {
|
||||
const upsToDelete = config.upsDevices[upsIndex];
|
||||
|
||||
// Get confirmation before deleting
|
||||
const readline = await import('node:readline');
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
const confirm = await new Promise<string>((resolve) => {
|
||||
rl.question(
|
||||
`Are you sure you want to delete UPS "${upsToDelete.name}" (${upsId})? [y/N]: `,
|
||||
(answer) => {
|
||||
resolve(answer.toLowerCase());
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
rl.close();
|
||||
process.stdin.destroy();
|
||||
const { prompt, close } = await helpers.createPrompt();
|
||||
const confirm = (await prompt(
|
||||
`Are you sure you want to delete UPS "${upsToDelete.name}" (${upsId})? [y/N]: `,
|
||||
)).toLowerCase();
|
||||
close();
|
||||
|
||||
if (confirm !== 'y' && confirm !== 'yes') {
|
||||
logger.log('Deletion cancelled.');
|
||||
@@ -509,7 +466,7 @@ export class UpsHandler {
|
||||
* Display the configuration for testing
|
||||
* @param config Current configuration or individual UPS configuration
|
||||
*/
|
||||
private displayTestConfig(config: any): void {
|
||||
private displayTestConfig(config: IUpsConfig | INupstConfig): void {
|
||||
// Check if this is a UPS device or full configuration
|
||||
const isUpsConfig = config.snmp;
|
||||
const snmpConfig = isUpsConfig ? config.snmp : config.snmp || {};
|
||||
@@ -571,7 +528,7 @@ export class UpsHandler {
|
||||
* Test connection to the UPS
|
||||
* @param config Current UPS configuration or legacy config
|
||||
*/
|
||||
private async testConnection(config: any): Promise<void> {
|
||||
private async testConnection(config: IUpsConfig | INupstConfig): Promise<void> {
|
||||
const upsId = config.id || 'default';
|
||||
const upsName = config.name || 'Default UPS';
|
||||
logger.log(`\nTesting connection to UPS: ${upsName} (${upsId})...`);
|
||||
@@ -610,7 +567,7 @@ export class UpsHandler {
|
||||
* @param status UPS status
|
||||
* @param thresholds Threshold configuration
|
||||
*/
|
||||
private analyzeThresholds(status: any, thresholds: any): void {
|
||||
private analyzeThresholds(status: ISnmpUpsStatus, thresholds: IThresholds): void {
|
||||
const boxWidth = 45;
|
||||
logger.logBoxTitle('Threshold Analysis', boxWidth);
|
||||
|
||||
@@ -649,7 +606,7 @@ export class UpsHandler {
|
||||
* @param prompt Function to prompt for user input
|
||||
*/
|
||||
private async gatherSnmpSettings(
|
||||
snmpConfig: any,
|
||||
snmpConfig: Partial<ISnmpConfig>,
|
||||
prompt: (question: string) => Promise<string>,
|
||||
): Promise<void> {
|
||||
// SNMP IP Address
|
||||
@@ -693,7 +650,7 @@ export class UpsHandler {
|
||||
* @param prompt Function to prompt for user input
|
||||
*/
|
||||
private async gatherSnmpV3Settings(
|
||||
snmpConfig: any,
|
||||
snmpConfig: Partial<ISnmpConfig>,
|
||||
prompt: (question: string) => Promise<string>,
|
||||
): Promise<void> {
|
||||
logger.log('');
|
||||
@@ -771,7 +728,7 @@ export class UpsHandler {
|
||||
* @param prompt Function to prompt for user input
|
||||
*/
|
||||
private async gatherAuthenticationSettings(
|
||||
snmpConfig: any,
|
||||
snmpConfig: Partial<ISnmpConfig>,
|
||||
prompt: (question: string) => Promise<string>,
|
||||
): Promise<void> {
|
||||
// Authentication protocol
|
||||
@@ -798,7 +755,7 @@ export class UpsHandler {
|
||||
* @param prompt Function to prompt for user input
|
||||
*/
|
||||
private async gatherPrivacySettings(
|
||||
snmpConfig: any,
|
||||
snmpConfig: Partial<ISnmpConfig>,
|
||||
prompt: (question: string) => Promise<string>,
|
||||
): Promise<void> {
|
||||
// Privacy protocol
|
||||
@@ -823,7 +780,7 @@ export class UpsHandler {
|
||||
* @param prompt Function to prompt for user input
|
||||
*/
|
||||
private async gatherUpsModelSettings(
|
||||
snmpConfig: any,
|
||||
snmpConfig: Partial<ISnmpConfig>,
|
||||
prompt: (question: string) => Promise<string>,
|
||||
): Promise<void> {
|
||||
logger.log('');
|
||||
@@ -888,7 +845,7 @@ export class UpsHandler {
|
||||
* @param prompt Function to prompt for user input
|
||||
*/
|
||||
private async gatherActionSettings(
|
||||
actions: any[],
|
||||
actions: IActionConfig[],
|
||||
prompt: (question: string) => Promise<string>,
|
||||
): Promise<void> {
|
||||
logger.log('');
|
||||
@@ -915,7 +872,7 @@ export class UpsHandler {
|
||||
const typeInput = await prompt('Select action type [1]: ');
|
||||
const typeValue = parseInt(typeInput, 10) || 1;
|
||||
|
||||
const action: any = {};
|
||||
const action: Partial<IActionConfig> = {};
|
||||
|
||||
if (typeValue === 1) {
|
||||
// Shutdown action
|
||||
@@ -1014,8 +971,8 @@ export class UpsHandler {
|
||||
};
|
||||
}
|
||||
|
||||
actions.push(action);
|
||||
logger.success(`${action.type.charAt(0).toUpperCase() + action.type.slice(1)} action added (mode: ${action.triggerMode || 'powerChangesAndThresholds'})`);
|
||||
actions.push(action as IActionConfig);
|
||||
logger.success(`${action.type!.charAt(0).toUpperCase() + action.type!.slice(1)} action added (mode: ${action.triggerMode || 'powerChangesAndThresholds'})`);
|
||||
|
||||
const more = await prompt('Add another action? (y/N): ');
|
||||
addMore = more.toLowerCase() === 'y';
|
||||
@@ -1031,7 +988,7 @@ export class UpsHandler {
|
||||
* Display UPS configuration summary
|
||||
* @param ups UPS configuration
|
||||
*/
|
||||
private displayUpsConfigSummary(ups: any): void {
|
||||
private displayUpsConfigSummary(ups: IUpsConfig): void {
|
||||
const boxWidth = 45;
|
||||
logger.log('');
|
||||
logger.logBoxTitle(`UPS Configuration: ${ups.name}`, boxWidth);
|
||||
@@ -1055,7 +1012,7 @@ export class UpsHandler {
|
||||
* @param prompt Function to prompt for user input
|
||||
*/
|
||||
private async optionallyTestConnection(
|
||||
snmpConfig: any,
|
||||
snmpConfig: ISnmpConfig,
|
||||
prompt: (question: string) => Promise<string>,
|
||||
): Promise<void> {
|
||||
const testConnection = await prompt(
|
||||
|
||||
Reference in New Issue
Block a user