Compare commits

...

4 Commits

Author SHA1 Message Date
f2ce0180d3 chore(release): bump version to 4.2.2
Some checks failed
CI / Type Check & Lint (push) Failing after 5s
CI / Build Test (Current Platform) (push) Successful in 6s
Release / build-and-release (push) Successful in 45s
CI / Build All Platforms (push) Successful in 48s
2025-10-20 12:14:16 +00:00
8c1be6555f fix(migrations): correct migration version from v4.0-to-v4.1 to v4.1-to-v4.2
The migration was incorrectly named as v4.0→v4.1 but was actually performing
the v4.1→v4.2 migration (moving thresholds from UPS-level to action-level).
This meant users upgrading from v4.1 would not get their configs migrated.

Changes:
- Renamed migration file from migration-v4.0-to-v4.1.ts to migration-v4.1-to-v4.2.ts
- Updated class name from MigrationV4_0ToV4_1 to MigrationV4_1ToV4_2
- Updated fromVersion from '4.0' to '4.1'
- Updated toVersion from '4.1' to '4.2'
- Updated shouldRun() to check for config.version === '4.1'
- Updated all imports and exports to reference the new class name
- Updated comments and log messages to reflect v4.1→v4.2 migration
2025-10-20 12:14:02 +00:00
1a5558e91f chore(release): bump version to 4.2.1
Some checks failed
CI / Type Check & Lint (push) Failing after 5s
CI / Build Test (Current Platform) (push) Successful in 4s
Release / build-and-release (push) Successful in 43s
CI / Build All Platforms (push) Successful in 51s
2025-10-20 12:08:44 +00:00
611a9ddd19 fix(cli): remove obsolete gatherThresholdSettings method
- Remove call to gatherThresholdSettings in runAddProcess
- Delete entire gatherThresholdSettings method
- Thresholds are now configured per-action in gatherActionSettings

Fixes: Cannot read properties of undefined (reading 'battery')
2025-10-20 12:08:29 +00:00
5 changed files with 22 additions and 57 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@serve.zone/nupst", "name": "@serve.zone/nupst",
"version": "4.2.0", "version": "4.2.2",
"exports": "./mod.ts", "exports": "./mod.ts",
"tasks": { "tasks": {
"dev": "deno run --allow-all mod.ts", "dev": "deno run --allow-all mod.ts",

View File

@@ -123,9 +123,6 @@ export class UpsHandler {
// Gather SNMP settings // Gather SNMP settings
await this.gatherSnmpSettings(newUps.snmp, prompt); await this.gatherSnmpSettings(newUps.snmp, prompt);
// Gather threshold settings
await this.gatherThresholdSettings(newUps.thresholds, prompt);
// Gather UPS model settings // Gather UPS model settings
await this.gatherUpsModelSettings(newUps.snmp, prompt); await this.gatherUpsModelSettings(newUps.snmp, prompt);
@@ -820,39 +817,6 @@ export class UpsHandler {
snmpConfig.privKey = privKey.trim() || defaultPrivKey; snmpConfig.privKey = privKey.trim() || defaultPrivKey;
} }
/**
* Gather threshold settings
* @param thresholds Thresholds configuration object to update
* @param prompt Function to prompt for user input
*/
private async gatherThresholdSettings(
thresholds: any,
prompt: (question: string) => Promise<string>,
): Promise<void> {
logger.log('');
logger.info('Shutdown Thresholds:');
// Battery threshold
const defaultBatteryThreshold = thresholds.battery || 60;
const batteryThresholdInput = await prompt(
`Battery percentage threshold [${defaultBatteryThreshold}%]: `,
);
const batteryThreshold = parseInt(batteryThresholdInput, 10);
thresholds.battery = batteryThresholdInput.trim() && !isNaN(batteryThreshold)
? batteryThreshold
: defaultBatteryThreshold;
// Runtime threshold
const defaultRuntimeThreshold = thresholds.runtime || 20;
const runtimeThresholdInput = await prompt(
`Runtime minutes threshold [${defaultRuntimeThreshold} minutes]: `,
);
const runtimeThreshold = parseInt(runtimeThresholdInput, 10);
thresholds.runtime = runtimeThresholdInput.trim() && !isNaN(runtimeThreshold)
? runtimeThreshold
: defaultRuntimeThreshold;
}
/** /**
* Gather UPS model settings * Gather UPS model settings
* @param snmpConfig SNMP configuration object to update * @param snmpConfig SNMP configuration object to update

View File

@@ -8,4 +8,4 @@ export { BaseMigration } from './base-migration.ts';
export { MigrationRunner } from './migration-runner.ts'; export { MigrationRunner } from './migration-runner.ts';
export { MigrationV1ToV2 } from './migration-v1-to-v2.ts'; export { MigrationV1ToV2 } from './migration-v1-to-v2.ts';
export { MigrationV3ToV4 } from './migration-v3-to-v4.ts'; export { MigrationV3ToV4 } from './migration-v3-to-v4.ts';
export { MigrationV4_0ToV4_1 } from './migration-v4.0-to-v4.1.ts'; export { MigrationV4_1ToV4_2 } from './migration-v4.1-to-v4.2.ts';

View File

@@ -1,7 +1,7 @@
import { BaseMigration } from './base-migration.ts'; import { BaseMigration } from './base-migration.ts';
import { MigrationV1ToV2 } from './migration-v1-to-v2.ts'; import { MigrationV1ToV2 } from './migration-v1-to-v2.ts';
import { MigrationV3ToV4 } from './migration-v3-to-v4.ts'; import { MigrationV3ToV4 } from './migration-v3-to-v4.ts';
import { MigrationV4_0ToV4_1 } from './migration-v4.0-to-v4.1.ts'; import { MigrationV4_1ToV4_2 } from './migration-v4.1-to-v4.2.ts';
import { logger } from '../logger.ts'; import { logger } from '../logger.ts';
/** /**
@@ -18,8 +18,8 @@ export class MigrationRunner {
this.migrations = [ this.migrations = [
new MigrationV1ToV2(), new MigrationV1ToV2(),
new MigrationV3ToV4(), new MigrationV3ToV4(),
new MigrationV4_0ToV4_1(), new MigrationV4_1ToV4_2(),
// Add future migrations here (v4.2, v4.3, etc.) // Add future migrations here (v4.3, v4.4, etc.)
]; ];
// Sort by version order to ensure they run in sequence // Sort by version order to ensure they run in sequence

View File

@@ -2,7 +2,7 @@ import { BaseMigration } from './base-migration.ts';
import { logger } from '../logger.ts'; import { logger } from '../logger.ts';
/** /**
* Migration from v4.0 to v4.1 * Migration from v4.1 to v4.2
* *
* Major changes: * Major changes:
* 1. Moves thresholds from UPS level to action level * 1. Moves thresholds from UPS level to action level
@@ -10,23 +10,24 @@ import { logger } from '../logger.ts';
* 3. Adds empty actions array to UPS devices without actions * 3. Adds empty actions array to UPS devices without actions
* 4. Adds empty actions array to groups * 4. Adds empty actions array to groups
* *
* Transforms v4.0 format: * Transforms v4.1 format (with UPS-level thresholds):
* { * {
* version: "4.0", * version: "4.1",
* upsDevices: [ * upsDevices: [
* { * {
* id: "ups-1", * id: "ups-1",
* name: "UPS 1", * name: "UPS 1",
* snmp: {...}, * snmp: {...},
* thresholds: { battery: 60, runtime: 20 }, // UPS-level * thresholds: { battery: 60, runtime: 20 }, // UPS-level
* groups: [] * groups: [],
* actions: []
* } * }
* ] * ]
* } * }
* *
* To v4.1 format: * To v4.2 format (with action-level thresholds):
* { * {
* version: "4.1", * version: "4.2",
* upsDevices: [ * upsDevices: [
* { * {
* id: "ups-1", * id: "ups-1",
@@ -37,7 +38,7 @@ import { logger } from '../logger.ts';
* { * {
* type: "shutdown", * type: "shutdown",
* thresholds: { battery: 60, runtime: 20 }, * thresholds: { battery: 60, runtime: 20 },
* onlyOnThresholdViolation: true, * triggerMode: "onlyThresholds",
* shutdownDelay: 5 * shutdownDelay: 5
* } * }
* ] * ]
@@ -45,28 +46,28 @@ import { logger } from '../logger.ts';
* ] * ]
* } * }
*/ */
export class MigrationV4_0ToV4_1 extends BaseMigration { export class MigrationV4_1ToV4_2 extends BaseMigration {
readonly fromVersion = '4.0'; readonly fromVersion = '4.1';
readonly toVersion = '4.1'; readonly toVersion = '4.2';
async shouldRun(config: any): Promise<boolean> { async shouldRun(config: any): Promise<boolean> {
// Run if config is version 4.0 or missing version with v4 structure // Run if config is version 4.1
if (config.version === '4.0') { if (config.version === '4.1') {
return true; return true;
} }
// Also run if config has upsDevices with thresholds at UPS level (v4.0 format) // Also run if config has upsDevices with thresholds at UPS level (v4.1 format)
if (config.upsDevices && config.upsDevices.length > 0) { if (config.upsDevices && config.upsDevices.length > 0) {
const firstDevice = config.upsDevices[0]; const firstDevice = config.upsDevices[0];
// v4.0 has thresholds at UPS level, v4.1 has them in actions // v4.1 has thresholds at UPS level, v4.2 has them in actions
return firstDevice.thresholds !== undefined && firstDevice.actions === undefined; return firstDevice.thresholds !== undefined;
} }
return false; return false;
} }
async migrate(config: any): Promise<any> { async migrate(config: any): Promise<any> {
logger.info(`${this.getName()}: Migrating v4.0 config to v4.1 format...`); logger.info(`${this.getName()}: Migrating v4.1 config to v4.2 format...`);
logger.dim(` - Moving thresholds from UPS level to action level`); logger.dim(` - Moving thresholds from UPS level to action level`);
logger.dim(` - Creating default shutdown actions from existing thresholds`); logger.dim(` - Creating default shutdown actions from existing thresholds`);