The migration was correct as v4.0→v4.1. Config version goes from 4.0 to 4.1
when thresholds are moved to actions. The original error was not the migration
but the ups-handler.ts bug (already fixed in v4.2.1).
User's config shows version "4.1" with actions already present, confirming
the migration ran successfully.
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
- Add process.stdin.destroy() after rl.close() in all interactive commands
to properly release stdin and allow process to exit cleanly
- Replace raw console.log with logger methods throughout CLI handlers
- Convert manual box drawing to logger.logBox() in daemon.ts
- Standardize menu formatting with logger.info() and logger.dim()
- Improve migration output to only show when migrations actually run
Fixes issue where process would not exit after "Setup complete!" message
due to stdin keeping the event loop alive.
The previous migration only checked for upsList field, but saveConfig()
strips upsList when saving, creating a race condition. If the daemon
restarted with a partially-migrated config (upsDevices with flat structure),
the migration wouldn't run because it only looked for upsList.
Now shouldRun() also detects:
- upsDevices with flat structure (host at top level, no snmp object)
And migrate() handles both:
- config.upsList (pure v3)
- config.upsDevices with flat structure (partially migrated)
This fixes the "Cannot read properties of undefined (reading 'host')"
error that occurred when configs had upsDevices but flat structure.
The v3→v4 migration was only renaming upsList to upsDevices without
transforming the device structure. V3 had a flat structure with SNMP
fields directly on the device object, while v4 expects a nested 'snmp'
object.
This commit fixes the migration to:
- Move host, port, community, version, etc. into nested snmp object
- Convert version from string to number
- Add default timeout (5000ms)
- Create thresholds object with defaults
- Preserve all SNMPv1, v2c, and v3 authentication fields
Also includes install.sh fix for better non-interactive handling.
- Create abstract BaseMigration class with order, shouldRun(), migrate()
- Add MigrationRunner to execute migrations in order
- Add Migration v1→v2 (snmp → upsDevices)
- Add Migration v3→v4 (upsList → upsDevices)
- Update INupstConfig with version field
- Update loadConfig() to run migrations automatically
- Update saveConfig() to ensure version field and remove legacy fields
- Update Docker test scripts to use real UPS data from .nogit/env.json
- Remove colors.bright (not available in @std/fmt/colors)
Config migrations allow users to jump versions (e.g., v1→v4) with all
intermediate migrations running automatically. Version field tracks
config format for future migrations.