@bscotch/yy
Version:
Stringify, parse, read, and write GameMaker yy and yyp files.
101 lines • 3.55 kB
JavaScript
import { ok } from 'node:assert';
/** Utility class for GameMaker version strings, allowing easy comparison etc */
export class GameMakerVersionString {
version;
#parsed;
constructor(version) {
this.version = version;
this.#parsed = GameMakerVersionString.parse(version);
}
/** Get an array of integer values making up the version (returns a cloned array) */
get parsed() {
return [...this.#parsed];
}
compare(other) {
return GameMakerVersionString.compare(this.version, typeof other === 'string' ? other : other.version);
}
gt(other) {
return GameMakerVersionString.gt(this.version, other);
}
gte(other) {
return GameMakerVersionString.gte(this.version, other);
}
eq(other) {
return GameMakerVersionString.eq(this.version, other);
}
lt(other) {
return GameMakerVersionString.lt(this.version, other);
}
lte(other) {
return GameMakerVersionString.lte(this.version, other);
}
toString() {
return this.version;
}
toJSON() {
return this.version;
}
static from(versions) {
if (Array.isArray(versions)) {
return versions.map((v) => new GameMakerVersionString(v));
}
return new GameMakerVersionString(versions);
}
/**
* A function that can be used for sorting GameMaker IDE/Runtime version
* strings, which are in the format "W.X.Y.Z" where W, X, Y, and Z
* are all integers.
* Note that comparisons across branches (lts, public, dev, beta)
* are messy, so mileage will vary for those.
* @returns -1 if a < b, 0 if a === b, 1 if a > b
*/
static compare(a, b) {
const aVersion = typeof a === 'string' ? GameMakerVersionString.parse(a) : a.parsed;
const bVersion = typeof b === 'string' ? GameMakerVersionString.parse(b) : b.parsed;
for (let i = 0; i < 4; i++) {
let [aPart, bPart] = [aVersion[i], bVersion[i]];
if (i === 1) {
// GameMaker adds two zeros to the end of beta-channel versions, so if this entry is >= 100 we want to divide by 100
if (aPart >= 100) {
aPart = Math.floor(aPart / 100);
}
if (bPart >= 100) {
bPart = Math.floor(bPart / 100);
}
}
if (aPart < bPart)
return -1;
if (aPart > bPart)
return 1;
}
return 0;
}
static gt(a, b) {
return GameMakerVersionString.compare(a, b) > 0;
}
static gte(a, b) {
return GameMakerVersionString.compare(a, b) >= 0;
}
static eq(a, b) {
return GameMakerVersionString.compare(a, b) === 0;
}
static lt(a, b) {
return GameMakerVersionString.compare(a, b) < 0;
}
static lte(a, b) {
return GameMakerVersionString.compare(a, b) <= 0;
}
static parse(version) {
const parts = version.split('.');
ok(parts.length === 4, `Invalid GameMaker version string: ${version}`);
return parts.map((n) => {
const num = parseInt(n);
ok(!isNaN(num), `Invalid GameMaker version string: ${version}`);
return num;
});
}
static sort(versions) {
return versions.sort((a, b) => GameMakerVersionString.compare(typeof a === 'string' ? a : a.version, typeof b === 'string' ? b : b.version));
}
}
//# sourceMappingURL=GameMakerVersionString.js.map