Major type safety improvements throughout the codebase:
- Updated DEFAULT_CONFIG version to 4.2
- Replaced 'any' with proper types in systemd.ts:
* displaySingleUpsStatus now uses IUpsConfig and NupstSnmp types
* Fixed legacy config handling to use proper IUpsConfig format
* Removed inline 'any' type annotations
- Replaced 'any' with proper types in daemon.ts:
* emergencyUps now properly typed as { ups: IUpsConfig, status: ISnmpUpsStatus }
* Exported IUpsStatus interface for reuse
* Added ISnmpUpsStatus import to disambiguate from daemon's IUpsStatus
- Replaced 'any' with Record<string, unknown> in migration system:
* Updated BaseMigration abstract class signatures
* Updated MigrationRunner.run() signature
* Updated migration-v4.0-to-v4.1.ts to use proper types
* Migrations use Record<string, unknown> because they deal with
unknown config schemas that are being upgraded
Benefits:
- TypeScript now catches type errors at compile time
- Would have caught the ups.thresholds bug earlier
- Better IDE autocomplete and type checking
- More maintainable and self-documenting code
68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
/**
|
|
* Abstract base class for configuration migrations
|
|
*
|
|
* Each migration represents an upgrade from one config version to another.
|
|
* Migrations run in order based on the `order` field, allowing users to jump
|
|
* multiple versions (e.g., v1 → v4 runs migrations 2, 3, and 4).
|
|
*/
|
|
/**
|
|
* Abstract base class for configuration migrations
|
|
*
|
|
* Each migration represents an upgrade from one config version to another.
|
|
* Migrations run in order based on the `toVersion` field, allowing users to jump
|
|
* multiple versions (e.g., v1 → v4 runs migrations 2, 3, and 4).
|
|
*/
|
|
export abstract class BaseMigration {
|
|
/**
|
|
* Source version this migration upgrades from
|
|
* e.g., "1.x", "3.x"
|
|
*/
|
|
abstract readonly fromVersion: string;
|
|
|
|
/**
|
|
* Target version this migration upgrades to
|
|
* e.g., "2.0", "4.0", "4.1"
|
|
*/
|
|
abstract readonly toVersion: string;
|
|
|
|
/**
|
|
* Check if this migration should run on the given config
|
|
*
|
|
* @param config - Raw configuration object to check (unknown schema for migrations)
|
|
* @returns True if migration should run, false otherwise
|
|
*/
|
|
abstract shouldRun(config: Record<string, unknown>): Promise<boolean>;
|
|
|
|
/**
|
|
* Perform the migration on the given config
|
|
*
|
|
* @param config - Raw configuration object to migrate (unknown schema for migrations)
|
|
* @returns Migrated configuration object
|
|
*/
|
|
abstract migrate(config: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
|
|
/**
|
|
* Get human-readable name for this migration
|
|
*
|
|
* @returns Migration name
|
|
*/
|
|
getName(): string {
|
|
return `Migration ${this.fromVersion} → ${this.toVersion}`;
|
|
}
|
|
|
|
/**
|
|
* Parse version string into a comparable number
|
|
* Supports formats like "2.0", "4.1", etc.
|
|
* Returns a number like 2.0, 4.1 for sorting
|
|
*
|
|
* @returns Parsed version number for ordering
|
|
*/
|
|
getVersionOrder(): number {
|
|
const parsed = parseFloat(this.toVersion);
|
|
if (isNaN(parsed)) {
|
|
throw new Error(`Invalid version format: ${this.toVersion}`);
|
|
}
|
|
return parsed;
|
|
}
|
|
}
|