Files
cfw-autumn/shared/api/versionUtils/ApiVersionClass.ts
2025-10-19 10:23:49 +01:00

144 lines
3.2 KiB
TypeScript

import { API_VERSIONS, type ApiVersion } from "./ApiVersion.js";
import type { VersionMetadata } from "./versionRegistry.js";
import {
getVersionMetadata,
getVersionsSorted,
} from "./versionRegistryUtils.js";
/**
* ApiVersionClass - Encapsulates version comparison logic
*
* Provides semantic comparison methods (gt, lt, gte, lte, eq) for API versions.
* Only accepts valid versions from the ApiVersion enum.
*
* @example
* const v1 = new ApiVersionClass(ApiVersion.V1_1);
* const v2 = new ApiVersionClass(ApiVersion.V1_2);
* v2.gt(v1); // true
* v1.gte(ApiVersion.V1_1); // true
*/
export class ApiVersionClass {
private readonly version: ApiVersion;
private readonly metadata: VersionMetadata;
private readonly sortedVersions: ApiVersion[];
constructor(version: ApiVersion) {
if (!API_VERSIONS.includes(version)) {
throw new Error(`Invalid API version: ${version}`);
}
this.version = version;
this.metadata = getVersionMetadata({ version });
this.sortedVersions = getVersionsSorted();
}
/**
* Get the current version
*/
get value(): ApiVersion {
return this.version;
}
/**
* Get version metadata
*/
get meta(): VersionMetadata {
return this.metadata;
}
/**
* Get the CalVer representation (for headers)
*/
get calver(): string {
return this.metadata.calver;
}
/**
* Get the SemVer representation
*/
get semver(): ApiVersion {
return this.version;
}
/**
* Get the index of this version in the sorted list
*/
private getIndex(version: ApiVersion): number {
return this.sortedVersions.indexOf(version);
}
/**
* Greater than
*/
gt(other: ApiVersion | ApiVersionClass): boolean {
const otherVersion = other instanceof ApiVersionClass ? other.value : other;
return this.getIndex(this.version) > this.getIndex(otherVersion);
}
/**
* Greater than or equal
*/
gte(other: ApiVersion | ApiVersionClass): boolean {
const otherVersion = other instanceof ApiVersionClass ? other.value : other;
return this.getIndex(this.version) >= this.getIndex(otherVersion);
}
/**
* Less than
*/
lt(other: ApiVersion | ApiVersionClass): boolean {
const otherVersion = other instanceof ApiVersionClass ? other.value : other;
return this.getIndex(this.version) < this.getIndex(otherVersion);
}
/**
* Less than or equal
*/
lte(other: ApiVersion | ApiVersionClass): boolean {
const otherVersion = other instanceof ApiVersionClass ? other.value : other;
return this.getIndex(this.version) <= this.getIndex(otherVersion);
}
/**
* Equal
*/
eq(other: ApiVersion | ApiVersionClass): boolean {
const otherVersion = other instanceof ApiVersionClass ? other.value : other;
return this.version === otherVersion;
}
/**
* Not equal
*/
neq(other: ApiVersion | ApiVersionClass): boolean {
return !this.eq(other);
}
/**
* Check if this version is deprecated
*/
isDeprecated(): boolean {
return this.metadata.deprecated === true;
}
/**
* Get the version to migrate to (if deprecated)
*/
getMigrationVersion(): ApiVersion | null {
return this.metadata.migrateToVersion || null;
}
/**
* String representation
*/
toString(): string {
return this.version;
}
/**
* JSON representation
*/
toJSON(): string {
return this.version;
}
}