2020-05-17 21:31:43 +00:00
|
|
|
exports.Version = class Version {
|
2019-10-13 19:33:44 +00:00
|
|
|
/**
|
|
|
|
* Construct a Version from components.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-13 19:33:44 +00:00
|
|
|
* @param {number} major The major version
|
|
|
|
* @param {number} minor The minor version
|
|
|
|
* @param {number} patch The patch version
|
|
|
|
* @param {array|undefined} pr_ident A list of pre-release identifiers, if
|
|
|
|
* any.
|
|
|
|
* @param {array|undefined} build_ident A list of build identifiers, if
|
|
|
|
* any.
|
|
|
|
*/
|
|
|
|
constructor(major, minor, patch, pr_ident, build_ident) {
|
|
|
|
this.major = major;
|
|
|
|
this.minor = minor;
|
|
|
|
this.patch = patch;
|
|
|
|
this.pr_ident = pr_ident;
|
|
|
|
this.build_ident = build_ident;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Construct a version from a semver 2 compliant string.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-13 19:33:44 +00:00
|
|
|
* This function is intended for use with semver 2 compliant strings.
|
|
|
|
* Malformatted strins may still parse correctly, however.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-13 19:33:44 +00:00
|
|
|
* @param {string} version_string A semver 2.0.0 compliant version string.
|
|
|
|
* @return {Version} A version object.
|
|
|
|
*/
|
|
|
|
static from_semver(version_string) {
|
|
|
|
let build_split = version_string.split("+"),
|
|
|
|
pr_split = build_split[0].split("-"),
|
|
|
|
version_split = pr_split[0].split("."),
|
|
|
|
version = [];
|
2020-05-12 22:24:41 +00:00
|
|
|
|
2019-10-13 19:33:44 +00:00
|
|
|
version.push(parseInt(version_split[0]));
|
|
|
|
|
|
|
|
if (version_split[1] != undefined) {
|
|
|
|
version.push(parseInt(version_split[1]));
|
|
|
|
} else {
|
|
|
|
version.push(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (version_split[2] != undefined) {
|
|
|
|
version.push(parseInt(version_split[2]));
|
|
|
|
} else {
|
|
|
|
version.push(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pr_split[1] != undefined) {
|
|
|
|
version.push(pr_split[1].split("."));
|
|
|
|
} else {
|
|
|
|
version.push(undefined);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (build_split[1] != undefined) {
|
|
|
|
version.push(build_split[1].split("."));
|
|
|
|
} else {
|
|
|
|
version.push(undefined);
|
|
|
|
}
|
|
|
|
|
2020-05-12 22:24:41 +00:00
|
|
|
return new Version(
|
|
|
|
version[0],
|
|
|
|
version[1],
|
|
|
|
version[2],
|
|
|
|
version[3],
|
|
|
|
version[4]
|
|
|
|
);
|
2019-10-13 19:33:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if a given version is compatible with this one.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-13 19:33:44 +00:00
|
|
|
* Compatibility is defined as having the same nonzero major version
|
|
|
|
* number, or if both major versions are zero, the same nonzero minor
|
|
|
|
* version number, or if both minor versions are zero, the same nonzero
|
|
|
|
* patch version number.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-20 19:13:00 +00:00
|
|
|
* This implements the ^ operator in npm's semver package, with the
|
|
|
|
* exception of the prerelease exclusion rule.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-13 19:33:44 +00:00
|
|
|
* @param {Version} fver The other version to test against
|
|
|
|
* @return {bool}
|
|
|
|
*/
|
|
|
|
is_compatible_with(fver) {
|
2020-05-12 22:24:41 +00:00
|
|
|
return (
|
|
|
|
(this.major !== 0 && this.major === fver.major) ||
|
|
|
|
(this.major === 0 &&
|
|
|
|
fver.major === 0 &&
|
2020-05-17 22:40:41 +00:00
|
|
|
this.minor !== 0 &&
|
2020-05-12 22:24:41 +00:00
|
|
|
this.minor === fver.minor) ||
|
|
|
|
(this.major === 0 &&
|
|
|
|
fver.major === 0 &&
|
|
|
|
this.minor === 0 &&
|
|
|
|
fver.minor === 0 &&
|
2020-05-17 22:40:41 +00:00
|
|
|
this.patch !== 0 &&
|
2020-05-12 22:24:41 +00:00
|
|
|
this.patch === fver.patch)
|
|
|
|
);
|
2019-10-13 19:33:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if this version has precedence over (is newer than) another
|
|
|
|
* version.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-20 19:13:00 +00:00
|
|
|
* Precedence is defined as in the Semver 2 spec. This implements the >
|
|
|
|
* operator in npm's semver package, with the exception of the prerelease
|
|
|
|
* exclusion rule.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-13 19:33:44 +00:00
|
|
|
* @param {Version} fver The other version to test against
|
|
|
|
* @return {bool} True if this version has precedence over the other one.
|
|
|
|
*/
|
|
|
|
has_precedence_over(fver) {
|
|
|
|
if (this.major > fver.major) {
|
|
|
|
return true;
|
|
|
|
} else if (this.major < fver.major) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.minor > fver.minor) {
|
|
|
|
return true;
|
|
|
|
} else if (this.minor < fver.minor) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.patch > fver.patch) {
|
|
|
|
return true;
|
|
|
|
} else if (this.patch < fver.patch) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.pr_ident === undefined && fver.pr_ident !== undefined) {
|
|
|
|
return true;
|
|
|
|
} else if (this.pr_ident !== undefined && fver.pr_ident !== undefined) {
|
|
|
|
let is_numeric = /^[0-9]*$/;
|
2020-05-12 22:24:41 +00:00
|
|
|
for (
|
|
|
|
let i = 0;
|
|
|
|
i < this.pr_ident.length && i < fver.pr_ident.length;
|
|
|
|
i += 1
|
|
|
|
) {
|
|
|
|
if (
|
|
|
|
!is_numeric.test(this.pr_ident[i]) &&
|
|
|
|
is_numeric.test(fver.pr_ident[i])
|
|
|
|
) {
|
2019-10-13 19:33:44 +00:00
|
|
|
return true;
|
2020-05-12 22:24:41 +00:00
|
|
|
} else if (
|
|
|
|
is_numeric.test(this.pr_ident[i]) &&
|
|
|
|
is_numeric.test(fver.pr_ident[i])
|
|
|
|
) {
|
|
|
|
if (
|
|
|
|
parseInt(this.pr_ident[i]) > parseInt(fver.pr_ident[i])
|
|
|
|
) {
|
2019-10-13 19:33:44 +00:00
|
|
|
return true;
|
2020-05-12 22:24:41 +00:00
|
|
|
} else if (
|
|
|
|
parseInt(this.pr_ident[i]) < parseInt(fver.pr_ident[i])
|
|
|
|
) {
|
2019-10-13 19:33:44 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-05-12 22:24:41 +00:00
|
|
|
} else if (
|
|
|
|
is_numeric.test(this.pr_ident[i]) &&
|
|
|
|
!is_numeric.test(fver.pr_ident[i])
|
|
|
|
) {
|
2020-05-12 22:07:21 +00:00
|
|
|
return false;
|
2020-05-12 22:24:41 +00:00
|
|
|
} else if (
|
|
|
|
!is_numeric.test(this.pr_ident[i]) &&
|
|
|
|
!is_numeric.test(fver.pr_ident[i])
|
|
|
|
) {
|
2019-10-13 19:33:44 +00:00
|
|
|
if (this.pr_ident[i] > fver.pr_ident[i]) {
|
|
|
|
return true;
|
2020-05-12 22:07:21 +00:00
|
|
|
} else if (this.pr_ident[i] < fver.pr_ident[i]) {
|
2019-10-13 19:33:44 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-05-12 22:24:41 +00:00
|
|
|
|
2019-10-13 19:33:44 +00:00
|
|
|
return this.pr_ident.length > fver.pr_ident.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2019-10-20 19:13:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests if a given version is equivalent to this one.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-20 19:13:00 +00:00
|
|
|
* Build and prerelease tags are ignored.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-20 19:13:00 +00:00
|
|
|
* @param {Version} fver The other version to test against
|
|
|
|
* @return {bool} True if the given version is equivalent.
|
|
|
|
*/
|
|
|
|
is_equal(fver) {
|
2020-05-12 22:24:41 +00:00
|
|
|
return (
|
|
|
|
this.major === fver.major &&
|
2019-10-20 19:13:00 +00:00
|
|
|
this.minor === fver.minor &&
|
2020-05-12 22:24:41 +00:00
|
|
|
this.patch === fver.patch
|
|
|
|
);
|
2019-10-20 19:13:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests if a given version is stable or a compatible prerelease for this
|
|
|
|
* version.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-20 19:13:00 +00:00
|
|
|
* This implements the prerelease exclusion rule of NPM semver: a
|
|
|
|
* prerelease version can only pass this check if the major/minor/patch
|
|
|
|
* components of both versions are the same. Otherwise, the prerelease
|
|
|
|
* version always fails.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-20 19:13:00 +00:00
|
|
|
* @param {Version} fver The other version to test against
|
|
|
|
* @return {bool} True if the given version is either stable, or a
|
|
|
|
* prerelease in the same series as this one.
|
|
|
|
*/
|
|
|
|
is_stable_or_compatible_prerelease(fver) {
|
|
|
|
if (fver.pr_ident === undefined) {
|
|
|
|
return true;
|
|
|
|
} else {
|
2020-05-12 22:24:41 +00:00
|
|
|
return (
|
|
|
|
this.major === fver.major &&
|
2019-10-20 19:13:00 +00:00
|
|
|
this.minor === fver.minor &&
|
2020-05-12 22:24:41 +00:00
|
|
|
this.patch === fver.patch
|
|
|
|
);
|
2019-10-20 19:13:00 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-17 21:31:43 +00:00
|
|
|
};
|