2020-05-17 21:31:43 +00:00
|
|
|
const { Version } = require("./version");
|
2019-10-20 19:13:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents a set of version requirements.
|
|
|
|
*/
|
2020-05-17 21:31:43 +00:00
|
|
|
exports.VersionRange = class VersionRange {
|
2019-10-20 19:13:00 +00:00
|
|
|
constructor(requirements) {
|
|
|
|
this.requirements = requirements;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine if a given version satisfies this range.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-20 19:13:00 +00:00
|
|
|
* @param {Version} fver A version object to test against.
|
|
|
|
* @return {bool} Whether or not the given version matches this range.
|
|
|
|
*/
|
|
|
|
satisfied_by(fver) {
|
|
|
|
for (let i = 0; i < this.requirements.length; i += 1) {
|
|
|
|
let matches = true;
|
|
|
|
|
2020-05-22 09:43:18 +00:00
|
|
|
for (let j = 0; j < this.requirements[i].length; j += 1) {
|
2019-10-20 19:13:00 +00:00
|
|
|
let comparator = this.requirements[i][j][0];
|
|
|
|
let version = this.requirements[i][j][1];
|
|
|
|
|
2020-05-12 22:24:41 +00:00
|
|
|
matches =
|
|
|
|
matches && version.is_stable_or_compatible_prerelease(fver);
|
2019-10-20 19:13:00 +00:00
|
|
|
|
|
|
|
if (comparator === "" || comparator === "=") {
|
|
|
|
matches = matches && version.is_equal(fver);
|
|
|
|
} else if (comparator === ">") {
|
2020-05-22 09:43:18 +00:00
|
|
|
matches = matches && fver.has_precedence_over(version);
|
2019-10-20 19:13:00 +00:00
|
|
|
} else if (comparator === ">=") {
|
2020-05-12 22:24:41 +00:00
|
|
|
matches =
|
|
|
|
matches &&
|
2020-05-22 09:43:18 +00:00
|
|
|
(fver.has_precedence_over(version) ||
|
2020-05-12 22:24:41 +00:00
|
|
|
version.is_equal(fver));
|
2019-10-20 19:13:00 +00:00
|
|
|
} else if (comparator === "<") {
|
2020-05-22 09:43:18 +00:00
|
|
|
matches = matches && version.has_precedence_over(fver);
|
2019-10-20 19:13:00 +00:00
|
|
|
} else if (comparator === "<=") {
|
2020-05-12 22:24:41 +00:00
|
|
|
matches =
|
|
|
|
matches &&
|
2020-05-22 09:43:18 +00:00
|
|
|
(version.has_precedence_over(fver) ||
|
2020-05-12 22:24:41 +00:00
|
|
|
version.is_equal(fver));
|
2019-10-20 19:13:00 +00:00
|
|
|
} else if (comparator === "^") {
|
|
|
|
matches = matches && version.is_compatible_with(fver);
|
|
|
|
}
|
|
|
|
}
|
2020-05-22 09:43:18 +00:00
|
|
|
|
|
|
|
if (matches) {
|
|
|
|
return true;
|
|
|
|
}
|
2019-10-20 19:13:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse a requirement string into a version range.
|
2020-05-12 22:24:41 +00:00
|
|
|
*
|
2019-10-20 19:13:00 +00:00
|
|
|
* @param {string} requirement The version requirements, consisting of a
|
|
|
|
* series of space-separated strings, each one being a semver version
|
|
|
|
* optionally prefixed by a comparator (e.g. <, <=, >, >=, =, or ^), or the
|
|
|
|
* string ||.
|
|
|
|
* @return {VersionRange} A version range object.
|
|
|
|
*/
|
|
|
|
static from_requirement_string(requirement) {
|
|
|
|
let components = requirement.split(" ");
|
|
|
|
let requirement_set = [];
|
|
|
|
let requirements = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < components.length; i += 1) {
|
|
|
|
if (components[i] === "||") {
|
|
|
|
if (requirement_set.length > 0) {
|
|
|
|
requirements.push(requirement_set);
|
|
|
|
requirement_set = [];
|
|
|
|
}
|
2020-05-22 09:43:18 +00:00
|
|
|
} else if (components[i].length > 0) {
|
2019-10-20 19:13:00 +00:00
|
|
|
let match = /[0-9]/.exec(components[i]);
|
|
|
|
let comparator = components[i].slice(0, match.index).trim();
|
2020-05-12 22:24:41 +00:00
|
|
|
let version = Version.from_semver(
|
|
|
|
components[i].slice(match.index).trim()
|
|
|
|
);
|
2019-10-20 19:13:00 +00:00
|
|
|
|
|
|
|
requirement_set.push([comparator, version]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (requirement_set.length > 0) {
|
|
|
|
requirements.push(requirement_set);
|
|
|
|
}
|
2019-11-17 20:14:24 +00:00
|
|
|
|
2020-05-22 09:43:18 +00:00
|
|
|
return new VersionRange(requirements);
|
2019-10-20 19:13:00 +00:00
|
|
|
}
|
2020-05-17 21:31:43 +00:00
|
|
|
};
|