feat(core): Centralize timeouts/constants, add CLI prompt helpers, and introduce webhook/script actions with safety and SNMP refactors

This commit is contained in:
2026-01-29 17:04:12 +00:00
parent d0e3a4ae74
commit 07648b4880
24 changed files with 1019 additions and 590 deletions

View File

@@ -3,7 +3,7 @@ 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 IGroupConfig } from '../daemon.ts';
import type { IGroupConfig, IUpsConfig, INupstConfig } from '../daemon.ts';
/**
* Class for handling group-related CLI commands
@@ -100,24 +100,7 @@ export class GroupHandler {
*/
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) => {
// Try to load configuration
try {
await this.nupst.getDaemon().loadConfig();
@@ -200,10 +183,7 @@ export class GroupHandler {
this.nupst.getUpsHandler().restartServiceIfRunning();
logger.log('\nGroup setup complete!');
} finally {
rl.close();
process.stdin.destroy();
}
});
} catch (error) {
logger.error(`Add group error: ${error instanceof Error ? error.message : String(error)}`);
}
@@ -215,24 +195,7 @@ export class GroupHandler {
*/
public async edit(groupId: 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) => {
// Try to load configuration
try {
await this.nupst.getDaemon().loadConfig();
@@ -318,10 +281,7 @@ export class GroupHandler {
this.nupst.getUpsHandler().restartServiceIfRunning();
logger.log('\nGroup edit complete!');
} finally {
rl.close();
process.stdin.destroy();
}
});
} catch (error) {
logger.error(`Edit group error: ${error instanceof Error ? error.message : String(error)}`);
}
@@ -362,23 +322,11 @@ export class GroupHandler {
const groupToDelete = config.groups[groupIndex];
// 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 group "${groupToDelete.name}" (${groupId})? [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 group "${groupToDelete.name}" (${groupId})? [y/N]: `,
)).toLowerCase();
close();
if (confirm !== 'y' && confirm !== 'yes') {
logger.log('Deletion cancelled.');
@@ -419,8 +367,8 @@ export class GroupHandler {
* @param prompt Function to prompt for user input
*/
public async assignUpsToGroups(
ups: any,
groups: any[],
ups: IUpsConfig,
groups: IGroupConfig[],
prompt: (question: string) => Promise<string>,
): Promise<void> {
// Initialize groups array if it doesn't exist
@@ -514,7 +462,7 @@ export class GroupHandler {
*/
public async assignUpsToGroup(
groupId: string,
config: any,
config: INupstConfig,
prompt: (question: string) => Promise<string>,
): Promise<void> {
if (!config.upsDevices || config.upsDevices.length === 0) {
@@ -522,7 +470,7 @@ export class GroupHandler {
return;
}
const group = config.groups.find((g: { id: string }) => g.id === groupId);
const group = config.groups.find((g) => g.id === groupId);
if (!group) {
logger.error(`Group with ID "${groupId}" not found.`);
return;
@@ -530,7 +478,7 @@ export class GroupHandler {
// Show current assignments
logger.log(`\nUPS devices in group "${group.name}" (${group.id}):`);
const upsInGroup = config.upsDevices.filter((ups: { groups?: string[] }) =>
const upsInGroup = config.upsDevices.filter((ups) =>
ups.groups && ups.groups.includes(groupId)
);
if (upsInGroup.length === 0) {