fix: resolve all TypeScript type errors across codebase for Deno strict mode

Comprehensive type safety improvements across all CLI handlers and daemon:

**Error handling type fixes:**
- Add 'error instanceof Error' checks before accessing error.message throughout
- Fix all error/retryError/stdError/upsError type assertions
- Replace direct error.message with proper type guards

**Switch case improvements:**
- Wrap case block declarations in braces to satisfy deno-lint
- Fix no-case-declarations warnings in CLI command handlers

**Null/undefined safety:**
- Add checks for config.snmp and config.thresholds before access
- Fix IUpsStatus lastStatusChange to handle undefined with default value
- Add proper null checks in legacy configuration paths

**Type annotations:**
- Add explicit type annotations to lambda parameters (groupId, updateAvailable, etc.)
- Add TUpsModel type cast for 'cyberpower' default
- Import and use INupstConfig type where needed

**Parameter type fixes:**
- Fix implicit 'any' type errors in array callbacks
- Add type annotations to filter/find/map parameters

Files modified:
- ts/cli.ts: config.snmp/thresholds null checks, unused error variable fixes
- ts/cli/group-handler.ts: 4 error.message fixes + 2 parameter type annotations
- ts/cli/service-handler.ts: 3 error.message fixes
- ts/cli/ups-handler.ts: 5 error.message fixes + config checks + TUpsModel import
- ts/daemon.ts: 8 error.message fixes + IUpsStatus lastStatusChange fix + updateAvailable type
- ts/nupst.ts: 1 error.message fix
- ts/systemd.ts: 5 error.message fixes + parameter type annotation

All tests passing (3/3 SNMP tests + 10/10 logger tests)
Type check: ✓ No errors
This commit is contained in:
2025-10-18 21:07:57 +00:00
parent 9ccbbbdc37
commit c2d39cc19a
7 changed files with 112 additions and 86 deletions

View File

@@ -115,13 +115,14 @@ export class NupstCli {
case 'add':
await upsHandler.add();
break;
case 'edit':
case 'edit': {
const upsId = subcommandArgs[0];
await upsHandler.edit(upsId);
break;
}
case 'remove':
case 'rm': // Alias
case 'delete': // Backward compatibility
case 'delete': { // Backward compatibility
const upsIdToRemove = subcommandArgs[0];
if (!upsIdToRemove) {
logger.error('UPS ID is required for remove command');
@@ -130,6 +131,7 @@ export class NupstCli {
}
await upsHandler.remove(upsIdToRemove);
break;
}
case 'list':
case 'ls': // Alias
await upsHandler.list();
@@ -153,7 +155,7 @@ export class NupstCli {
case 'add':
await groupHandler.add();
break;
case 'edit':
case 'edit': {
const groupId = subcommandArgs[0];
if (!groupId) {
logger.error('Group ID is required for edit command');
@@ -162,9 +164,10 @@ export class NupstCli {
}
await groupHandler.edit(groupId);
break;
}
case 'remove':
case 'rm': // Alias
case 'delete': // Backward compatibility
case 'delete': { // Backward compatibility
const groupIdToRemove = subcommandArgs[0];
if (!groupIdToRemove) {
logger.error('Group ID is required for remove command');
@@ -173,6 +176,7 @@ export class NupstCli {
}
await groupHandler.remove(groupIdToRemove);
break;
}
case 'list':
case 'ls': // Alias
await groupHandler.list();
@@ -291,7 +295,7 @@ export class NupstCli {
// Try to load configuration
try {
await this.nupst.getDaemon().loadConfig();
} catch (error) {
} catch (_error) {
const errorBoxWidth = 45;
logger.logBoxTitle('Configuration Error', errorBoxWidth);
logger.logBoxLine('No configuration found.');
@@ -351,49 +355,57 @@ export class NupstCli {
}
} else {
// Legacy single UPS configuration
// SNMP Settings
logger.logBoxLine('SNMP Settings:');
logger.logBoxLine(` Host: ${config.snmp.host}`);
logger.logBoxLine(` Port: ${config.snmp.port}`);
logger.logBoxLine(` Version: ${config.snmp.version}`);
logger.logBoxLine(` UPS Model: ${config.snmp.upsModel || 'cyberpower'}`);
if (!config.snmp) {
logger.logBoxLine('Error: Legacy configuration missing SNMP settings');
} else {
// SNMP Settings
logger.logBoxLine('SNMP Settings:');
logger.logBoxLine(` Host: ${config.snmp.host}`);
logger.logBoxLine(` Port: ${config.snmp.port}`);
logger.logBoxLine(` Version: ${config.snmp.version}`);
logger.logBoxLine(` UPS Model: ${config.snmp.upsModel || 'cyberpower'}`);
if (config.snmp.version === 1 || config.snmp.version === 2) {
logger.logBoxLine(` Community: ${config.snmp.community}`);
} else if (config.snmp.version === 3) {
logger.logBoxLine(` Security Level: ${config.snmp.securityLevel}`);
logger.logBoxLine(` Username: ${config.snmp.username}`);
if (config.snmp.version === 1 || config.snmp.version === 2) {
logger.logBoxLine(` Community: ${config.snmp.community}`);
} else if (config.snmp.version === 3) {
logger.logBoxLine(` Security Level: ${config.snmp.securityLevel}`);
logger.logBoxLine(` Username: ${config.snmp.username}`);
// Show auth and privacy details based on security level
if (
config.snmp.securityLevel === 'authNoPriv' ||
config.snmp.securityLevel === 'authPriv'
) {
logger.logBoxLine(` Auth Protocol: ${config.snmp.authProtocol || 'None'}`);
// Show auth and privacy details based on security level
if (
config.snmp.securityLevel === 'authNoPriv' ||
config.snmp.securityLevel === 'authPriv'
) {
logger.logBoxLine(` Auth Protocol: ${config.snmp.authProtocol || 'None'}`);
}
if (config.snmp.securityLevel === 'authPriv') {
logger.logBoxLine(` Privacy Protocol: ${config.snmp.privProtocol || 'None'}`);
}
// Show timeout value
logger.logBoxLine(` Timeout: ${config.snmp.timeout / 1000} seconds`);
}
if (config.snmp.securityLevel === 'authPriv') {
logger.logBoxLine(` Privacy Protocol: ${config.snmp.privProtocol || 'None'}`);
// Show OIDs if custom model is selected
if (config.snmp.upsModel === 'custom' && config.snmp.customOIDs) {
logger.logBoxLine('Custom OIDs:');
logger.logBoxLine(` Power Status: ${config.snmp.customOIDs.POWER_STATUS || 'Not set'}`);
logger.logBoxLine(
` Battery Capacity: ${config.snmp.customOIDs.BATTERY_CAPACITY || 'Not set'}`
);
logger.logBoxLine(` Battery Runtime: ${config.snmp.customOIDs.BATTERY_RUNTIME || 'Not set'}`);
}
// Show timeout value
logger.logBoxLine(` Timeout: ${config.snmp.timeout / 1000} seconds`);
}
// Show OIDs if custom model is selected
if (config.snmp.upsModel === 'custom' && config.snmp.customOIDs) {
logger.logBoxLine('Custom OIDs:');
logger.logBoxLine(` Power Status: ${config.snmp.customOIDs.POWER_STATUS || 'Not set'}`);
logger.logBoxLine(
` Battery Capacity: ${config.snmp.customOIDs.BATTERY_CAPACITY || 'Not set'}`
);
logger.logBoxLine(` Battery Runtime: ${config.snmp.customOIDs.BATTERY_RUNTIME || 'Not set'}`);
}
// Thresholds
logger.logBoxLine('Thresholds:');
logger.logBoxLine(` Battery: ${config.thresholds.battery}%`);
logger.logBoxLine(` Runtime: ${config.thresholds.runtime} minutes`);
if (!config.thresholds) {
logger.logBoxLine('Error: Legacy configuration missing threshold settings');
} else {
logger.logBoxLine('Thresholds:');
logger.logBoxLine(` Battery: ${config.thresholds.battery}%`);
logger.logBoxLine(` Runtime: ${config.thresholds.runtime} minutes`);
}
logger.logBoxLine(`Check Interval: ${config.checkInterval / 1000} seconds`);
// Configuration file location
@@ -419,11 +431,11 @@ export class NupstCli {
logger.logBoxLine(`Service Active: ${isActive ? 'Yes' : 'No'}`);
logger.logBoxLine(`Service Enabled: ${isEnabled ? 'Yes' : 'No'}`);
logger.logBoxEnd();
} catch (error) {
} catch (_error) {
// Ignore errors checking service status
}
} catch (error) {
logger.error(`Failed to display configuration: ${error.message}`);
logger.error(`Failed to display configuration: ${error instanceof Error ? error.message : String(error)}`);
}
}