1663 lines
45 KiB
JavaScript
1663 lines
45 KiB
JavaScript
import { y as yallist } from '../shared/nuxi.cc8dd4a9.mjs';
|
|
|
|
function _mergeNamespaces(n, m) {
|
|
for (var i = 0; i < m.length; i++) {
|
|
const e = m[i];
|
|
if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) {
|
|
if (k !== 'default' && !(k in n)) {
|
|
n[k] = e[k];
|
|
}
|
|
} }
|
|
}
|
|
return n;
|
|
}
|
|
|
|
// A linked list to keep track of recently-used-ness
|
|
const Yallist = yallist;
|
|
|
|
const MAX = Symbol('max');
|
|
const LENGTH = Symbol('length');
|
|
const LENGTH_CALCULATOR = Symbol('lengthCalculator');
|
|
const ALLOW_STALE = Symbol('allowStale');
|
|
const MAX_AGE = Symbol('maxAge');
|
|
const DISPOSE = Symbol('dispose');
|
|
const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet');
|
|
const LRU_LIST = Symbol('lruList');
|
|
const CACHE = Symbol('cache');
|
|
const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet');
|
|
|
|
const naiveLength = () => 1;
|
|
|
|
// lruList is a yallist where the head is the youngest
|
|
// item, and the tail is the oldest. the list contains the Hit
|
|
// objects as the entries.
|
|
// Each Hit object has a reference to its Yallist.Node. This
|
|
// never changes.
|
|
//
|
|
// cache is a Map (or PseudoMap) that matches the keys to
|
|
// the Yallist.Node object.
|
|
class LRUCache {
|
|
constructor (options) {
|
|
if (typeof options === 'number')
|
|
options = { max: options };
|
|
|
|
if (!options)
|
|
options = {};
|
|
|
|
if (options.max && (typeof options.max !== 'number' || options.max < 0))
|
|
throw new TypeError('max must be a non-negative number')
|
|
// Kind of weird to have a default max of Infinity, but oh well.
|
|
this[MAX] = options.max || Infinity;
|
|
|
|
const lc = options.length || naiveLength;
|
|
this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc;
|
|
this[ALLOW_STALE] = options.stale || false;
|
|
if (options.maxAge && typeof options.maxAge !== 'number')
|
|
throw new TypeError('maxAge must be a number')
|
|
this[MAX_AGE] = options.maxAge || 0;
|
|
this[DISPOSE] = options.dispose;
|
|
this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false;
|
|
this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false;
|
|
this.reset();
|
|
}
|
|
|
|
// resize the cache when the max changes.
|
|
set max (mL) {
|
|
if (typeof mL !== 'number' || mL < 0)
|
|
throw new TypeError('max must be a non-negative number')
|
|
|
|
this[MAX] = mL || Infinity;
|
|
trim(this);
|
|
}
|
|
get max () {
|
|
return this[MAX]
|
|
}
|
|
|
|
set allowStale (allowStale) {
|
|
this[ALLOW_STALE] = !!allowStale;
|
|
}
|
|
get allowStale () {
|
|
return this[ALLOW_STALE]
|
|
}
|
|
|
|
set maxAge (mA) {
|
|
if (typeof mA !== 'number')
|
|
throw new TypeError('maxAge must be a non-negative number')
|
|
|
|
this[MAX_AGE] = mA;
|
|
trim(this);
|
|
}
|
|
get maxAge () {
|
|
return this[MAX_AGE]
|
|
}
|
|
|
|
// resize the cache when the lengthCalculator changes.
|
|
set lengthCalculator (lC) {
|
|
if (typeof lC !== 'function')
|
|
lC = naiveLength;
|
|
|
|
if (lC !== this[LENGTH_CALCULATOR]) {
|
|
this[LENGTH_CALCULATOR] = lC;
|
|
this[LENGTH] = 0;
|
|
this[LRU_LIST].forEach(hit => {
|
|
hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key);
|
|
this[LENGTH] += hit.length;
|
|
});
|
|
}
|
|
trim(this);
|
|
}
|
|
get lengthCalculator () { return this[LENGTH_CALCULATOR] }
|
|
|
|
get length () { return this[LENGTH] }
|
|
get itemCount () { return this[LRU_LIST].length }
|
|
|
|
rforEach (fn, thisp) {
|
|
thisp = thisp || this;
|
|
for (let walker = this[LRU_LIST].tail; walker !== null;) {
|
|
const prev = walker.prev;
|
|
forEachStep(this, fn, walker, thisp);
|
|
walker = prev;
|
|
}
|
|
}
|
|
|
|
forEach (fn, thisp) {
|
|
thisp = thisp || this;
|
|
for (let walker = this[LRU_LIST].head; walker !== null;) {
|
|
const next = walker.next;
|
|
forEachStep(this, fn, walker, thisp);
|
|
walker = next;
|
|
}
|
|
}
|
|
|
|
keys () {
|
|
return this[LRU_LIST].toArray().map(k => k.key)
|
|
}
|
|
|
|
values () {
|
|
return this[LRU_LIST].toArray().map(k => k.value)
|
|
}
|
|
|
|
reset () {
|
|
if (this[DISPOSE] &&
|
|
this[LRU_LIST] &&
|
|
this[LRU_LIST].length) {
|
|
this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value));
|
|
}
|
|
|
|
this[CACHE] = new Map(); // hash of items by key
|
|
this[LRU_LIST] = new Yallist(); // list of items in order of use recency
|
|
this[LENGTH] = 0; // length of items in the list
|
|
}
|
|
|
|
dump () {
|
|
return this[LRU_LIST].map(hit =>
|
|
isStale(this, hit) ? false : {
|
|
k: hit.key,
|
|
v: hit.value,
|
|
e: hit.now + (hit.maxAge || 0)
|
|
}).toArray().filter(h => h)
|
|
}
|
|
|
|
dumpLru () {
|
|
return this[LRU_LIST]
|
|
}
|
|
|
|
set (key, value, maxAge) {
|
|
maxAge = maxAge || this[MAX_AGE];
|
|
|
|
if (maxAge && typeof maxAge !== 'number')
|
|
throw new TypeError('maxAge must be a number')
|
|
|
|
const now = maxAge ? Date.now() : 0;
|
|
const len = this[LENGTH_CALCULATOR](value, key);
|
|
|
|
if (this[CACHE].has(key)) {
|
|
if (len > this[MAX]) {
|
|
del(this, this[CACHE].get(key));
|
|
return false
|
|
}
|
|
|
|
const node = this[CACHE].get(key);
|
|
const item = node.value;
|
|
|
|
// dispose of the old one before overwriting
|
|
// split out into 2 ifs for better coverage tracking
|
|
if (this[DISPOSE]) {
|
|
if (!this[NO_DISPOSE_ON_SET])
|
|
this[DISPOSE](key, item.value);
|
|
}
|
|
|
|
item.now = now;
|
|
item.maxAge = maxAge;
|
|
item.value = value;
|
|
this[LENGTH] += len - item.length;
|
|
item.length = len;
|
|
this.get(key);
|
|
trim(this);
|
|
return true
|
|
}
|
|
|
|
const hit = new Entry(key, value, len, now, maxAge);
|
|
|
|
// oversized objects fall out of cache automatically.
|
|
if (hit.length > this[MAX]) {
|
|
if (this[DISPOSE])
|
|
this[DISPOSE](key, value);
|
|
|
|
return false
|
|
}
|
|
|
|
this[LENGTH] += hit.length;
|
|
this[LRU_LIST].unshift(hit);
|
|
this[CACHE].set(key, this[LRU_LIST].head);
|
|
trim(this);
|
|
return true
|
|
}
|
|
|
|
has (key) {
|
|
if (!this[CACHE].has(key)) return false
|
|
const hit = this[CACHE].get(key).value;
|
|
return !isStale(this, hit)
|
|
}
|
|
|
|
get (key) {
|
|
return get(this, key, true)
|
|
}
|
|
|
|
peek (key) {
|
|
return get(this, key, false)
|
|
}
|
|
|
|
pop () {
|
|
const node = this[LRU_LIST].tail;
|
|
if (!node)
|
|
return null
|
|
|
|
del(this, node);
|
|
return node.value
|
|
}
|
|
|
|
del (key) {
|
|
del(this, this[CACHE].get(key));
|
|
}
|
|
|
|
load (arr) {
|
|
// reset the cache
|
|
this.reset();
|
|
|
|
const now = Date.now();
|
|
// A previous serialized cache has the most recent items first
|
|
for (let l = arr.length - 1; l >= 0; l--) {
|
|
const hit = arr[l];
|
|
const expiresAt = hit.e || 0;
|
|
if (expiresAt === 0)
|
|
// the item was created without expiration in a non aged cache
|
|
this.set(hit.k, hit.v);
|
|
else {
|
|
const maxAge = expiresAt - now;
|
|
// dont add already expired items
|
|
if (maxAge > 0) {
|
|
this.set(hit.k, hit.v, maxAge);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
prune () {
|
|
this[CACHE].forEach((value, key) => get(this, key, false));
|
|
}
|
|
}
|
|
|
|
const get = (self, key, doUse) => {
|
|
const node = self[CACHE].get(key);
|
|
if (node) {
|
|
const hit = node.value;
|
|
if (isStale(self, hit)) {
|
|
del(self, node);
|
|
if (!self[ALLOW_STALE])
|
|
return undefined
|
|
} else {
|
|
if (doUse) {
|
|
if (self[UPDATE_AGE_ON_GET])
|
|
node.value.now = Date.now();
|
|
self[LRU_LIST].unshiftNode(node);
|
|
}
|
|
}
|
|
return hit.value
|
|
}
|
|
};
|
|
|
|
const isStale = (self, hit) => {
|
|
if (!hit || (!hit.maxAge && !self[MAX_AGE]))
|
|
return false
|
|
|
|
const diff = Date.now() - hit.now;
|
|
return hit.maxAge ? diff > hit.maxAge
|
|
: self[MAX_AGE] && (diff > self[MAX_AGE])
|
|
};
|
|
|
|
const trim = self => {
|
|
if (self[LENGTH] > self[MAX]) {
|
|
for (let walker = self[LRU_LIST].tail;
|
|
self[LENGTH] > self[MAX] && walker !== null;) {
|
|
// We know that we're about to delete this one, and also
|
|
// what the next least recently used key will be, so just
|
|
// go ahead and set it now.
|
|
const prev = walker.prev;
|
|
del(self, walker);
|
|
walker = prev;
|
|
}
|
|
}
|
|
};
|
|
|
|
const del = (self, node) => {
|
|
if (node) {
|
|
const hit = node.value;
|
|
if (self[DISPOSE])
|
|
self[DISPOSE](hit.key, hit.value);
|
|
|
|
self[LENGTH] -= hit.length;
|
|
self[CACHE].delete(hit.key);
|
|
self[LRU_LIST].removeNode(node);
|
|
}
|
|
};
|
|
|
|
class Entry {
|
|
constructor (key, value, length, now, maxAge) {
|
|
this.key = key;
|
|
this.value = value;
|
|
this.length = length;
|
|
this.now = now;
|
|
this.maxAge = maxAge || 0;
|
|
}
|
|
}
|
|
|
|
const forEachStep = (self, fn, node, thisp) => {
|
|
let hit = node.value;
|
|
if (isStale(self, hit)) {
|
|
del(self, node);
|
|
if (!self[ALLOW_STALE])
|
|
hit = undefined;
|
|
}
|
|
if (hit)
|
|
fn.call(thisp, hit.value, hit.key, self);
|
|
};
|
|
|
|
var lruCache = LRUCache;
|
|
|
|
// parse out just the options we care about so we always get a consistent
|
|
// obj with keys in a consistent order.
|
|
const opts = ['includePrerelease', 'loose', 'rtl'];
|
|
const parseOptions$1 = options =>
|
|
!options ? {}
|
|
: typeof options !== 'object' ? { loose: true }
|
|
: opts.filter(k => options[k]).reduce((o, k) => {
|
|
o[k] = true;
|
|
return o
|
|
}, {});
|
|
var parseOptions_1 = parseOptions$1;
|
|
|
|
var re$1 = {exports: {}};
|
|
|
|
// Note: this is the semver.org version of the spec that it implements
|
|
// Not necessarily the package version of this code.
|
|
const SEMVER_SPEC_VERSION = '2.0.0';
|
|
|
|
const MAX_LENGTH$1 = 256;
|
|
const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER ||
|
|
/* istanbul ignore next */ 9007199254740991;
|
|
|
|
// Max safe segment length for coercion.
|
|
const MAX_SAFE_COMPONENT_LENGTH = 16;
|
|
|
|
var constants = {
|
|
SEMVER_SPEC_VERSION,
|
|
MAX_LENGTH: MAX_LENGTH$1,
|
|
MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1,
|
|
MAX_SAFE_COMPONENT_LENGTH,
|
|
};
|
|
|
|
const debug$1 = (
|
|
typeof process === 'object' &&
|
|
process.env &&
|
|
process.env.NODE_DEBUG &&
|
|
/\bsemver\b/i.test(process.env.NODE_DEBUG)
|
|
) ? (...args) => console.error('SEMVER', ...args)
|
|
: () => {};
|
|
|
|
var debug_1 = debug$1;
|
|
|
|
(function (module, exports) {
|
|
const { MAX_SAFE_COMPONENT_LENGTH } = constants;
|
|
const debug = debug_1;
|
|
exports = module.exports = {};
|
|
|
|
// The actual regexps go on exports.re
|
|
const re = exports.re = [];
|
|
const src = exports.src = [];
|
|
const t = exports.t = {};
|
|
let R = 0;
|
|
|
|
const createToken = (name, value, isGlobal) => {
|
|
const index = R++;
|
|
debug(name, index, value);
|
|
t[name] = index;
|
|
src[index] = value;
|
|
re[index] = new RegExp(value, isGlobal ? 'g' : undefined);
|
|
};
|
|
|
|
// The following Regular Expressions can be used for tokenizing,
|
|
// validating, and parsing SemVer version strings.
|
|
|
|
// ## Numeric Identifier
|
|
// A single `0`, or a non-zero digit followed by zero or more digits.
|
|
|
|
createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*');
|
|
createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+');
|
|
|
|
// ## Non-numeric Identifier
|
|
// Zero or more digits, followed by a letter or hyphen, and then zero or
|
|
// more letters, digits, or hyphens.
|
|
|
|
createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*');
|
|
|
|
// ## Main Version
|
|
// Three dot-separated numeric identifiers.
|
|
|
|
createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
|
|
`(${src[t.NUMERICIDENTIFIER]})\\.` +
|
|
`(${src[t.NUMERICIDENTIFIER]})`);
|
|
|
|
createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
|
|
`(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
|
|
`(${src[t.NUMERICIDENTIFIERLOOSE]})`);
|
|
|
|
// ## Pre-release Version Identifier
|
|
// A numeric identifier, or a non-numeric identifier.
|
|
|
|
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
|
|
}|${src[t.NONNUMERICIDENTIFIER]})`);
|
|
|
|
createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
|
|
}|${src[t.NONNUMERICIDENTIFIER]})`);
|
|
|
|
// ## Pre-release Version
|
|
// Hyphen, followed by one or more dot-separated pre-release version
|
|
// identifiers.
|
|
|
|
createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
|
|
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);
|
|
|
|
createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
|
|
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);
|
|
|
|
// ## Build Metadata Identifier
|
|
// Any combination of digits, letters, or hyphens.
|
|
|
|
createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+');
|
|
|
|
// ## Build Metadata
|
|
// Plus sign, followed by one or more period-separated build metadata
|
|
// identifiers.
|
|
|
|
createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
|
|
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`);
|
|
|
|
// ## Full Version String
|
|
// A main version, followed optionally by a pre-release version and
|
|
// build metadata.
|
|
|
|
// Note that the only major, minor, patch, and pre-release sections of
|
|
// the version string are capturing groups. The build metadata is not a
|
|
// capturing group, because it should not ever be used in version
|
|
// comparison.
|
|
|
|
createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
|
|
}${src[t.PRERELEASE]}?${
|
|
src[t.BUILD]}?`);
|
|
|
|
createToken('FULL', `^${src[t.FULLPLAIN]}$`);
|
|
|
|
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
|
|
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
|
|
// common in the npm registry.
|
|
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
|
|
}${src[t.PRERELEASELOOSE]}?${
|
|
src[t.BUILD]}?`);
|
|
|
|
createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`);
|
|
|
|
createToken('GTLT', '((?:<|>)?=?)');
|
|
|
|
// Something like "2.*" or "1.2.x".
|
|
// Note that "x.x" is a valid xRange identifer, meaning "any version"
|
|
// Only the first item is strictly required.
|
|
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
|
|
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
|
|
|
|
createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
|
|
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
|
|
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
|
|
`(?:${src[t.PRERELEASE]})?${
|
|
src[t.BUILD]}?` +
|
|
`)?)?`);
|
|
|
|
createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
|
|
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
|
|
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
|
|
`(?:${src[t.PRERELEASELOOSE]})?${
|
|
src[t.BUILD]}?` +
|
|
`)?)?`);
|
|
|
|
createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
|
|
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);
|
|
|
|
// Coercion.
|
|
// Extract anything that could conceivably be a part of a valid semver
|
|
createToken('COERCE', `${'(^|[^\\d])' +
|
|
'(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
|
|
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
|
|
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
|
|
`(?:$|[^\\d])`);
|
|
createToken('COERCERTL', src[t.COERCE], true);
|
|
|
|
// Tilde ranges.
|
|
// Meaning is "reasonably at or greater than"
|
|
createToken('LONETILDE', '(?:~>?)');
|
|
|
|
createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true);
|
|
exports.tildeTrimReplace = '$1~';
|
|
|
|
createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
|
|
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
|
|
|
|
// Caret ranges.
|
|
// Meaning is "at least and backwards compatible with"
|
|
createToken('LONECARET', '(?:\\^)');
|
|
|
|
createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true);
|
|
exports.caretTrimReplace = '$1^';
|
|
|
|
createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
|
|
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
|
|
|
|
// A simple gt/lt/eq thing, or just "" to indicate "any version"
|
|
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
|
|
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
|
|
|
|
// An expression to strip any whitespace between the gtlt and the thing
|
|
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
|
|
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
|
|
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
|
|
exports.comparatorTrimReplace = '$1$2$3';
|
|
|
|
// Something like `1.2.3 - 1.2.4`
|
|
// Note that these all use the loose form, because they'll be
|
|
// checked against either the strict or loose comparator form
|
|
// later.
|
|
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
|
|
`\\s+-\\s+` +
|
|
`(${src[t.XRANGEPLAIN]})` +
|
|
`\\s*$`);
|
|
|
|
createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
|
|
`\\s+-\\s+` +
|
|
`(${src[t.XRANGEPLAINLOOSE]})` +
|
|
`\\s*$`);
|
|
|
|
// Star ranges basically just allow anything at all.
|
|
createToken('STAR', '(<|>)?=?\\s*\\*');
|
|
// >=0.0.0 is like a star
|
|
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$');
|
|
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$');
|
|
} (re$1, re$1.exports));
|
|
|
|
const numeric = /^[0-9]+$/;
|
|
const compareIdentifiers$1 = (a, b) => {
|
|
const anum = numeric.test(a);
|
|
const bnum = numeric.test(b);
|
|
|
|
if (anum && bnum) {
|
|
a = +a;
|
|
b = +b;
|
|
}
|
|
|
|
return a === b ? 0
|
|
: (anum && !bnum) ? -1
|
|
: (bnum && !anum) ? 1
|
|
: a < b ? -1
|
|
: 1
|
|
};
|
|
|
|
const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a);
|
|
|
|
var identifiers = {
|
|
compareIdentifiers: compareIdentifiers$1,
|
|
rcompareIdentifiers,
|
|
};
|
|
|
|
const debug = debug_1;
|
|
const { MAX_LENGTH, MAX_SAFE_INTEGER } = constants;
|
|
const { re, t } = re$1.exports;
|
|
|
|
const parseOptions = parseOptions_1;
|
|
const { compareIdentifiers } = identifiers;
|
|
let SemVer$1 = class SemVer {
|
|
constructor (version, options) {
|
|
options = parseOptions(options);
|
|
|
|
if (version instanceof SemVer$1) {
|
|
if (version.loose === !!options.loose &&
|
|
version.includePrerelease === !!options.includePrerelease) {
|
|
return version
|
|
} else {
|
|
version = version.version;
|
|
}
|
|
} else if (typeof version !== 'string') {
|
|
throw new TypeError(`Invalid Version: ${version}`)
|
|
}
|
|
|
|
if (version.length > MAX_LENGTH) {
|
|
throw new TypeError(
|
|
`version is longer than ${MAX_LENGTH} characters`
|
|
)
|
|
}
|
|
|
|
debug('SemVer', version, options);
|
|
this.options = options;
|
|
this.loose = !!options.loose;
|
|
// this isn't actually relevant for versions, but keep it so that we
|
|
// don't run into trouble passing this.options around.
|
|
this.includePrerelease = !!options.includePrerelease;
|
|
|
|
const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);
|
|
|
|
if (!m) {
|
|
throw new TypeError(`Invalid Version: ${version}`)
|
|
}
|
|
|
|
this.raw = version;
|
|
|
|
// these are actually numbers
|
|
this.major = +m[1];
|
|
this.minor = +m[2];
|
|
this.patch = +m[3];
|
|
|
|
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
|
|
throw new TypeError('Invalid major version')
|
|
}
|
|
|
|
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
|
|
throw new TypeError('Invalid minor version')
|
|
}
|
|
|
|
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
|
|
throw new TypeError('Invalid patch version')
|
|
}
|
|
|
|
// numberify any prerelease numeric ids
|
|
if (!m[4]) {
|
|
this.prerelease = [];
|
|
} else {
|
|
this.prerelease = m[4].split('.').map((id) => {
|
|
if (/^[0-9]+$/.test(id)) {
|
|
const num = +id;
|
|
if (num >= 0 && num < MAX_SAFE_INTEGER) {
|
|
return num
|
|
}
|
|
}
|
|
return id
|
|
});
|
|
}
|
|
|
|
this.build = m[5] ? m[5].split('.') : [];
|
|
this.format();
|
|
}
|
|
|
|
format () {
|
|
this.version = `${this.major}.${this.minor}.${this.patch}`;
|
|
if (this.prerelease.length) {
|
|
this.version += `-${this.prerelease.join('.')}`;
|
|
}
|
|
return this.version
|
|
}
|
|
|
|
toString () {
|
|
return this.version
|
|
}
|
|
|
|
compare (other) {
|
|
debug('SemVer.compare', this.version, this.options, other);
|
|
if (!(other instanceof SemVer$1)) {
|
|
if (typeof other === 'string' && other === this.version) {
|
|
return 0
|
|
}
|
|
other = new SemVer$1(other, this.options);
|
|
}
|
|
|
|
if (other.version === this.version) {
|
|
return 0
|
|
}
|
|
|
|
return this.compareMain(other) || this.comparePre(other)
|
|
}
|
|
|
|
compareMain (other) {
|
|
if (!(other instanceof SemVer$1)) {
|
|
other = new SemVer$1(other, this.options);
|
|
}
|
|
|
|
return (
|
|
compareIdentifiers(this.major, other.major) ||
|
|
compareIdentifiers(this.minor, other.minor) ||
|
|
compareIdentifiers(this.patch, other.patch)
|
|
)
|
|
}
|
|
|
|
comparePre (other) {
|
|
if (!(other instanceof SemVer$1)) {
|
|
other = new SemVer$1(other, this.options);
|
|
}
|
|
|
|
// NOT having a prerelease is > having one
|
|
if (this.prerelease.length && !other.prerelease.length) {
|
|
return -1
|
|
} else if (!this.prerelease.length && other.prerelease.length) {
|
|
return 1
|
|
} else if (!this.prerelease.length && !other.prerelease.length) {
|
|
return 0
|
|
}
|
|
|
|
let i = 0;
|
|
do {
|
|
const a = this.prerelease[i];
|
|
const b = other.prerelease[i];
|
|
debug('prerelease compare', i, a, b);
|
|
if (a === undefined && b === undefined) {
|
|
return 0
|
|
} else if (b === undefined) {
|
|
return 1
|
|
} else if (a === undefined) {
|
|
return -1
|
|
} else if (a === b) {
|
|
continue
|
|
} else {
|
|
return compareIdentifiers(a, b)
|
|
}
|
|
} while (++i)
|
|
}
|
|
|
|
compareBuild (other) {
|
|
if (!(other instanceof SemVer$1)) {
|
|
other = new SemVer$1(other, this.options);
|
|
}
|
|
|
|
let i = 0;
|
|
do {
|
|
const a = this.build[i];
|
|
const b = other.build[i];
|
|
debug('prerelease compare', i, a, b);
|
|
if (a === undefined && b === undefined) {
|
|
return 0
|
|
} else if (b === undefined) {
|
|
return 1
|
|
} else if (a === undefined) {
|
|
return -1
|
|
} else if (a === b) {
|
|
continue
|
|
} else {
|
|
return compareIdentifiers(a, b)
|
|
}
|
|
} while (++i)
|
|
}
|
|
|
|
// preminor will bump the version up to the next minor release, and immediately
|
|
// down to pre-release. premajor and prepatch work the same way.
|
|
inc (release, identifier) {
|
|
switch (release) {
|
|
case 'premajor':
|
|
this.prerelease.length = 0;
|
|
this.patch = 0;
|
|
this.minor = 0;
|
|
this.major++;
|
|
this.inc('pre', identifier);
|
|
break
|
|
case 'preminor':
|
|
this.prerelease.length = 0;
|
|
this.patch = 0;
|
|
this.minor++;
|
|
this.inc('pre', identifier);
|
|
break
|
|
case 'prepatch':
|
|
// If this is already a prerelease, it will bump to the next version
|
|
// drop any prereleases that might already exist, since they are not
|
|
// relevant at this point.
|
|
this.prerelease.length = 0;
|
|
this.inc('patch', identifier);
|
|
this.inc('pre', identifier);
|
|
break
|
|
// If the input is a non-prerelease version, this acts the same as
|
|
// prepatch.
|
|
case 'prerelease':
|
|
if (this.prerelease.length === 0) {
|
|
this.inc('patch', identifier);
|
|
}
|
|
this.inc('pre', identifier);
|
|
break
|
|
|
|
case 'major':
|
|
// If this is a pre-major version, bump up to the same major version.
|
|
// Otherwise increment major.
|
|
// 1.0.0-5 bumps to 1.0.0
|
|
// 1.1.0 bumps to 2.0.0
|
|
if (
|
|
this.minor !== 0 ||
|
|
this.patch !== 0 ||
|
|
this.prerelease.length === 0
|
|
) {
|
|
this.major++;
|
|
}
|
|
this.minor = 0;
|
|
this.patch = 0;
|
|
this.prerelease = [];
|
|
break
|
|
case 'minor':
|
|
// If this is a pre-minor version, bump up to the same minor version.
|
|
// Otherwise increment minor.
|
|
// 1.2.0-5 bumps to 1.2.0
|
|
// 1.2.1 bumps to 1.3.0
|
|
if (this.patch !== 0 || this.prerelease.length === 0) {
|
|
this.minor++;
|
|
}
|
|
this.patch = 0;
|
|
this.prerelease = [];
|
|
break
|
|
case 'patch':
|
|
// If this is not a pre-release version, it will increment the patch.
|
|
// If it is a pre-release it will bump up to the same patch version.
|
|
// 1.2.0-5 patches to 1.2.0
|
|
// 1.2.0 patches to 1.2.1
|
|
if (this.prerelease.length === 0) {
|
|
this.patch++;
|
|
}
|
|
this.prerelease = [];
|
|
break
|
|
// This probably shouldn't be used publicly.
|
|
// 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
|
|
case 'pre':
|
|
if (this.prerelease.length === 0) {
|
|
this.prerelease = [0];
|
|
} else {
|
|
let i = this.prerelease.length;
|
|
while (--i >= 0) {
|
|
if (typeof this.prerelease[i] === 'number') {
|
|
this.prerelease[i]++;
|
|
i = -2;
|
|
}
|
|
}
|
|
if (i === -1) {
|
|
// didn't increment anything
|
|
this.prerelease.push(0);
|
|
}
|
|
}
|
|
if (identifier) {
|
|
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
|
|
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
|
|
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
|
|
if (isNaN(this.prerelease[1])) {
|
|
this.prerelease = [identifier, 0];
|
|
}
|
|
} else {
|
|
this.prerelease = [identifier, 0];
|
|
}
|
|
}
|
|
break
|
|
|
|
default:
|
|
throw new Error(`invalid increment argument: ${release}`)
|
|
}
|
|
this.format();
|
|
this.raw = this.version;
|
|
return this
|
|
}
|
|
};
|
|
|
|
var semver = SemVer$1;
|
|
|
|
const SemVer = semver;
|
|
const compare$6 = (a, b, loose) =>
|
|
new SemVer(a, loose).compare(new SemVer(b, loose));
|
|
|
|
var compare_1 = compare$6;
|
|
|
|
const compare$5 = compare_1;
|
|
const eq$1 = (a, b, loose) => compare$5(a, b, loose) === 0;
|
|
var eq_1 = eq$1;
|
|
|
|
const compare$4 = compare_1;
|
|
const neq$1 = (a, b, loose) => compare$4(a, b, loose) !== 0;
|
|
var neq_1 = neq$1;
|
|
|
|
const compare$3 = compare_1;
|
|
const gt$1 = (a, b, loose) => compare$3(a, b, loose) > 0;
|
|
var gt_1 = gt$1;
|
|
|
|
const compare$2 = compare_1;
|
|
const gte$1 = (a, b, loose) => compare$2(a, b, loose) >= 0;
|
|
var gte_1 = gte$1;
|
|
|
|
const compare$1 = compare_1;
|
|
const lt$1 = (a, b, loose) => compare$1(a, b, loose) < 0;
|
|
var lt_1 = lt$1;
|
|
|
|
const compare = compare_1;
|
|
const lte$1 = (a, b, loose) => compare(a, b, loose) <= 0;
|
|
var lte_1 = lte$1;
|
|
|
|
const eq = eq_1;
|
|
const neq = neq_1;
|
|
const gt = gt_1;
|
|
const gte = gte_1;
|
|
const lt = lt_1;
|
|
const lte = lte_1;
|
|
|
|
const cmp = (a, op, b, loose) => {
|
|
switch (op) {
|
|
case '===':
|
|
if (typeof a === 'object') {
|
|
a = a.version;
|
|
}
|
|
if (typeof b === 'object') {
|
|
b = b.version;
|
|
}
|
|
return a === b
|
|
|
|
case '!==':
|
|
if (typeof a === 'object') {
|
|
a = a.version;
|
|
}
|
|
if (typeof b === 'object') {
|
|
b = b.version;
|
|
}
|
|
return a !== b
|
|
|
|
case '':
|
|
case '=':
|
|
case '==':
|
|
return eq(a, b, loose)
|
|
|
|
case '!=':
|
|
return neq(a, b, loose)
|
|
|
|
case '>':
|
|
return gt(a, b, loose)
|
|
|
|
case '>=':
|
|
return gte(a, b, loose)
|
|
|
|
case '<':
|
|
return lt(a, b, loose)
|
|
|
|
case '<=':
|
|
return lte(a, b, loose)
|
|
|
|
default:
|
|
throw new TypeError(`Invalid operator: ${op}`)
|
|
}
|
|
};
|
|
var cmp_1 = cmp;
|
|
|
|
var comparator;
|
|
var hasRequiredComparator;
|
|
|
|
function requireComparator () {
|
|
if (hasRequiredComparator) return comparator;
|
|
hasRequiredComparator = 1;
|
|
const ANY = Symbol('SemVer ANY');
|
|
// hoisted class for cyclic dependency
|
|
class Comparator {
|
|
static get ANY () {
|
|
return ANY
|
|
}
|
|
|
|
constructor (comp, options) {
|
|
options = parseOptions(options);
|
|
|
|
if (comp instanceof Comparator) {
|
|
if (comp.loose === !!options.loose) {
|
|
return comp
|
|
} else {
|
|
comp = comp.value;
|
|
}
|
|
}
|
|
|
|
debug('comparator', comp, options);
|
|
this.options = options;
|
|
this.loose = !!options.loose;
|
|
this.parse(comp);
|
|
|
|
if (this.semver === ANY) {
|
|
this.value = '';
|
|
} else {
|
|
this.value = this.operator + this.semver.version;
|
|
}
|
|
|
|
debug('comp', this);
|
|
}
|
|
|
|
parse (comp) {
|
|
const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR];
|
|
const m = comp.match(r);
|
|
|
|
if (!m) {
|
|
throw new TypeError(`Invalid comparator: ${comp}`)
|
|
}
|
|
|
|
this.operator = m[1] !== undefined ? m[1] : '';
|
|
if (this.operator === '=') {
|
|
this.operator = '';
|
|
}
|
|
|
|
// if it literally is just '>' or '' then allow anything.
|
|
if (!m[2]) {
|
|
this.semver = ANY;
|
|
} else {
|
|
this.semver = new SemVer(m[2], this.options.loose);
|
|
}
|
|
}
|
|
|
|
toString () {
|
|
return this.value
|
|
}
|
|
|
|
test (version) {
|
|
debug('Comparator.test', version, this.options.loose);
|
|
|
|
if (this.semver === ANY || version === ANY) {
|
|
return true
|
|
}
|
|
|
|
if (typeof version === 'string') {
|
|
try {
|
|
version = new SemVer(version, this.options);
|
|
} catch (er) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return cmp(version, this.operator, this.semver, this.options)
|
|
}
|
|
|
|
intersects (comp, options) {
|
|
if (!(comp instanceof Comparator)) {
|
|
throw new TypeError('a Comparator is required')
|
|
}
|
|
|
|
if (!options || typeof options !== 'object') {
|
|
options = {
|
|
loose: !!options,
|
|
includePrerelease: false,
|
|
};
|
|
}
|
|
|
|
if (this.operator === '') {
|
|
if (this.value === '') {
|
|
return true
|
|
}
|
|
return new Range(comp.value, options).test(this.value)
|
|
} else if (comp.operator === '') {
|
|
if (comp.value === '') {
|
|
return true
|
|
}
|
|
return new Range(this.value, options).test(comp.semver)
|
|
}
|
|
|
|
const sameDirectionIncreasing =
|
|
(this.operator === '>=' || this.operator === '>') &&
|
|
(comp.operator === '>=' || comp.operator === '>');
|
|
const sameDirectionDecreasing =
|
|
(this.operator === '<=' || this.operator === '<') &&
|
|
(comp.operator === '<=' || comp.operator === '<');
|
|
const sameSemVer = this.semver.version === comp.semver.version;
|
|
const differentDirectionsInclusive =
|
|
(this.operator === '>=' || this.operator === '<=') &&
|
|
(comp.operator === '>=' || comp.operator === '<=');
|
|
const oppositeDirectionsLessThan =
|
|
cmp(this.semver, '<', comp.semver, options) &&
|
|
(this.operator === '>=' || this.operator === '>') &&
|
|
(comp.operator === '<=' || comp.operator === '<');
|
|
const oppositeDirectionsGreaterThan =
|
|
cmp(this.semver, '>', comp.semver, options) &&
|
|
(this.operator === '<=' || this.operator === '<') &&
|
|
(comp.operator === '>=' || comp.operator === '>');
|
|
|
|
return (
|
|
sameDirectionIncreasing ||
|
|
sameDirectionDecreasing ||
|
|
(sameSemVer && differentDirectionsInclusive) ||
|
|
oppositeDirectionsLessThan ||
|
|
oppositeDirectionsGreaterThan
|
|
)
|
|
}
|
|
}
|
|
|
|
comparator = Comparator;
|
|
|
|
const parseOptions = parseOptions_1;
|
|
const { re, t } = re$1.exports;
|
|
const cmp = cmp_1;
|
|
const debug = debug_1;
|
|
const SemVer = semver;
|
|
const Range = requireRange();
|
|
return comparator;
|
|
}
|
|
|
|
var range;
|
|
var hasRequiredRange;
|
|
|
|
function requireRange () {
|
|
if (hasRequiredRange) return range;
|
|
hasRequiredRange = 1;
|
|
// hoisted class for cyclic dependency
|
|
class Range {
|
|
constructor (range, options) {
|
|
options = parseOptions(options);
|
|
|
|
if (range instanceof Range) {
|
|
if (
|
|
range.loose === !!options.loose &&
|
|
range.includePrerelease === !!options.includePrerelease
|
|
) {
|
|
return range
|
|
} else {
|
|
return new Range(range.raw, options)
|
|
}
|
|
}
|
|
|
|
if (range instanceof Comparator) {
|
|
// just put it in the set and return
|
|
this.raw = range.value;
|
|
this.set = [[range]];
|
|
this.format();
|
|
return this
|
|
}
|
|
|
|
this.options = options;
|
|
this.loose = !!options.loose;
|
|
this.includePrerelease = !!options.includePrerelease;
|
|
|
|
// First, split based on boolean or ||
|
|
this.raw = range;
|
|
this.set = range
|
|
.split('||')
|
|
// map the range to a 2d array of comparators
|
|
.map(r => this.parseRange(r.trim()))
|
|
// throw out any comparator lists that are empty
|
|
// this generally means that it was not a valid range, which is allowed
|
|
// in loose mode, but will still throw if the WHOLE range is invalid.
|
|
.filter(c => c.length);
|
|
|
|
if (!this.set.length) {
|
|
throw new TypeError(`Invalid SemVer Range: ${range}`)
|
|
}
|
|
|
|
// if we have any that are not the null set, throw out null sets.
|
|
if (this.set.length > 1) {
|
|
// keep the first one, in case they're all null sets
|
|
const first = this.set[0];
|
|
this.set = this.set.filter(c => !isNullSet(c[0]));
|
|
if (this.set.length === 0) {
|
|
this.set = [first];
|
|
} else if (this.set.length > 1) {
|
|
// if we have any that are *, then the range is just *
|
|
for (const c of this.set) {
|
|
if (c.length === 1 && isAny(c[0])) {
|
|
this.set = [c];
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.format();
|
|
}
|
|
|
|
format () {
|
|
this.range = this.set
|
|
.map((comps) => {
|
|
return comps.join(' ').trim()
|
|
})
|
|
.join('||')
|
|
.trim();
|
|
return this.range
|
|
}
|
|
|
|
toString () {
|
|
return this.range
|
|
}
|
|
|
|
parseRange (range) {
|
|
range = range.trim();
|
|
|
|
// memoize range parsing for performance.
|
|
// this is a very hot path, and fully deterministic.
|
|
const memoOpts = Object.keys(this.options).join(',');
|
|
const memoKey = `parseRange:${memoOpts}:${range}`;
|
|
const cached = cache.get(memoKey);
|
|
if (cached) {
|
|
return cached
|
|
}
|
|
|
|
const loose = this.options.loose;
|
|
// `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
|
|
const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE];
|
|
range = range.replace(hr, hyphenReplace(this.options.includePrerelease));
|
|
debug('hyphen replace', range);
|
|
// `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
|
|
range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace);
|
|
debug('comparator trim', range);
|
|
|
|
// `~ 1.2.3` => `~1.2.3`
|
|
range = range.replace(re[t.TILDETRIM], tildeTrimReplace);
|
|
|
|
// `^ 1.2.3` => `^1.2.3`
|
|
range = range.replace(re[t.CARETTRIM], caretTrimReplace);
|
|
|
|
// normalize spaces
|
|
range = range.split(/\s+/).join(' ');
|
|
|
|
// At this point, the range is completely trimmed and
|
|
// ready to be split into comparators.
|
|
|
|
let rangeList = range
|
|
.split(' ')
|
|
.map(comp => parseComparator(comp, this.options))
|
|
.join(' ')
|
|
.split(/\s+/)
|
|
// >=0.0.0 is equivalent to *
|
|
.map(comp => replaceGTE0(comp, this.options));
|
|
|
|
if (loose) {
|
|
// in loose mode, throw out any that are not valid comparators
|
|
rangeList = rangeList.filter(comp => {
|
|
debug('loose invalid filter', comp, this.options);
|
|
return !!comp.match(re[t.COMPARATORLOOSE])
|
|
});
|
|
}
|
|
debug('range list', rangeList);
|
|
|
|
// if any comparators are the null set, then replace with JUST null set
|
|
// if more than one comparator, remove any * comparators
|
|
// also, don't include the same comparator more than once
|
|
const rangeMap = new Map();
|
|
const comparators = rangeList.map(comp => new Comparator(comp, this.options));
|
|
for (const comp of comparators) {
|
|
if (isNullSet(comp)) {
|
|
return [comp]
|
|
}
|
|
rangeMap.set(comp.value, comp);
|
|
}
|
|
if (rangeMap.size > 1 && rangeMap.has('')) {
|
|
rangeMap.delete('');
|
|
}
|
|
|
|
const result = [...rangeMap.values()];
|
|
cache.set(memoKey, result);
|
|
return result
|
|
}
|
|
|
|
intersects (range, options) {
|
|
if (!(range instanceof Range)) {
|
|
throw new TypeError('a Range is required')
|
|
}
|
|
|
|
return this.set.some((thisComparators) => {
|
|
return (
|
|
isSatisfiable(thisComparators, options) &&
|
|
range.set.some((rangeComparators) => {
|
|
return (
|
|
isSatisfiable(rangeComparators, options) &&
|
|
thisComparators.every((thisComparator) => {
|
|
return rangeComparators.every((rangeComparator) => {
|
|
return thisComparator.intersects(rangeComparator, options)
|
|
})
|
|
})
|
|
)
|
|
})
|
|
)
|
|
})
|
|
}
|
|
|
|
// if ANY of the sets match ALL of its comparators, then pass
|
|
test (version) {
|
|
if (!version) {
|
|
return false
|
|
}
|
|
|
|
if (typeof version === 'string') {
|
|
try {
|
|
version = new SemVer(version, this.options);
|
|
} catch (er) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < this.set.length; i++) {
|
|
if (testSet(this.set[i], version, this.options)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
range = Range;
|
|
|
|
const LRU = lruCache;
|
|
const cache = new LRU({ max: 1000 });
|
|
|
|
const parseOptions = parseOptions_1;
|
|
const Comparator = requireComparator();
|
|
const debug = debug_1;
|
|
const SemVer = semver;
|
|
const {
|
|
re,
|
|
t,
|
|
comparatorTrimReplace,
|
|
tildeTrimReplace,
|
|
caretTrimReplace,
|
|
} = re$1.exports;
|
|
|
|
const isNullSet = c => c.value === '<0.0.0-0';
|
|
const isAny = c => c.value === '';
|
|
|
|
// take a set of comparators and determine whether there
|
|
// exists a version which can satisfy it
|
|
const isSatisfiable = (comparators, options) => {
|
|
let result = true;
|
|
const remainingComparators = comparators.slice();
|
|
let testComparator = remainingComparators.pop();
|
|
|
|
while (result && remainingComparators.length) {
|
|
result = remainingComparators.every((otherComparator) => {
|
|
return testComparator.intersects(otherComparator, options)
|
|
});
|
|
|
|
testComparator = remainingComparators.pop();
|
|
}
|
|
|
|
return result
|
|
};
|
|
|
|
// comprised of xranges, tildes, stars, and gtlt's at this point.
|
|
// already replaced the hyphen ranges
|
|
// turn into a set of JUST comparators.
|
|
const parseComparator = (comp, options) => {
|
|
debug('comp', comp, options);
|
|
comp = replaceCarets(comp, options);
|
|
debug('caret', comp);
|
|
comp = replaceTildes(comp, options);
|
|
debug('tildes', comp);
|
|
comp = replaceXRanges(comp, options);
|
|
debug('xrange', comp);
|
|
comp = replaceStars(comp, options);
|
|
debug('stars', comp);
|
|
return comp
|
|
};
|
|
|
|
const isX = id => !id || id.toLowerCase() === 'x' || id === '*';
|
|
|
|
// ~, ~> --> * (any, kinda silly)
|
|
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0
|
|
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0
|
|
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0
|
|
// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0
|
|
// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0
|
|
// ~0.0.1 --> >=0.0.1 <0.1.0-0
|
|
const replaceTildes = (comp, options) =>
|
|
comp.trim().split(/\s+/).map((c) => {
|
|
return replaceTilde(c, options)
|
|
}).join(' ');
|
|
|
|
const replaceTilde = (comp, options) => {
|
|
const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE];
|
|
return comp.replace(r, (_, M, m, p, pr) => {
|
|
debug('tilde', comp, _, M, m, p, pr);
|
|
let ret;
|
|
|
|
if (isX(M)) {
|
|
ret = '';
|
|
} else if (isX(m)) {
|
|
ret = `>=${M}.0.0 <${+M + 1}.0.0-0`;
|
|
} else if (isX(p)) {
|
|
// ~1.2 == >=1.2.0 <1.3.0-0
|
|
ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`;
|
|
} else if (pr) {
|
|
debug('replaceTilde pr', pr);
|
|
ret = `>=${M}.${m}.${p}-${pr
|
|
} <${M}.${+m + 1}.0-0`;
|
|
} else {
|
|
// ~1.2.3 == >=1.2.3 <1.3.0-0
|
|
ret = `>=${M}.${m}.${p
|
|
} <${M}.${+m + 1}.0-0`;
|
|
}
|
|
|
|
debug('tilde return', ret);
|
|
return ret
|
|
})
|
|
};
|
|
|
|
// ^ --> * (any, kinda silly)
|
|
// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0
|
|
// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0
|
|
// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0
|
|
// ^1.2.3 --> >=1.2.3 <2.0.0-0
|
|
// ^1.2.0 --> >=1.2.0 <2.0.0-0
|
|
// ^0.0.1 --> >=0.0.1 <0.0.2-0
|
|
// ^0.1.0 --> >=0.1.0 <0.2.0-0
|
|
const replaceCarets = (comp, options) =>
|
|
comp.trim().split(/\s+/).map((c) => {
|
|
return replaceCaret(c, options)
|
|
}).join(' ');
|
|
|
|
const replaceCaret = (comp, options) => {
|
|
debug('caret', comp, options);
|
|
const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET];
|
|
const z = options.includePrerelease ? '-0' : '';
|
|
return comp.replace(r, (_, M, m, p, pr) => {
|
|
debug('caret', comp, _, M, m, p, pr);
|
|
let ret;
|
|
|
|
if (isX(M)) {
|
|
ret = '';
|
|
} else if (isX(m)) {
|
|
ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`;
|
|
} else if (isX(p)) {
|
|
if (M === '0') {
|
|
ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`;
|
|
} else {
|
|
ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`;
|
|
}
|
|
} else if (pr) {
|
|
debug('replaceCaret pr', pr);
|
|
if (M === '0') {
|
|
if (m === '0') {
|
|
ret = `>=${M}.${m}.${p}-${pr
|
|
} <${M}.${m}.${+p + 1}-0`;
|
|
} else {
|
|
ret = `>=${M}.${m}.${p}-${pr
|
|
} <${M}.${+m + 1}.0-0`;
|
|
}
|
|
} else {
|
|
ret = `>=${M}.${m}.${p}-${pr
|
|
} <${+M + 1}.0.0-0`;
|
|
}
|
|
} else {
|
|
debug('no pr');
|
|
if (M === '0') {
|
|
if (m === '0') {
|
|
ret = `>=${M}.${m}.${p
|
|
}${z} <${M}.${m}.${+p + 1}-0`;
|
|
} else {
|
|
ret = `>=${M}.${m}.${p
|
|
}${z} <${M}.${+m + 1}.0-0`;
|
|
}
|
|
} else {
|
|
ret = `>=${M}.${m}.${p
|
|
} <${+M + 1}.0.0-0`;
|
|
}
|
|
}
|
|
|
|
debug('caret return', ret);
|
|
return ret
|
|
})
|
|
};
|
|
|
|
const replaceXRanges = (comp, options) => {
|
|
debug('replaceXRanges', comp, options);
|
|
return comp.split(/\s+/).map((c) => {
|
|
return replaceXRange(c, options)
|
|
}).join(' ')
|
|
};
|
|
|
|
const replaceXRange = (comp, options) => {
|
|
comp = comp.trim();
|
|
const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE];
|
|
return comp.replace(r, (ret, gtlt, M, m, p, pr) => {
|
|
debug('xRange', comp, ret, gtlt, M, m, p, pr);
|
|
const xM = isX(M);
|
|
const xm = xM || isX(m);
|
|
const xp = xm || isX(p);
|
|
const anyX = xp;
|
|
|
|
if (gtlt === '=' && anyX) {
|
|
gtlt = '';
|
|
}
|
|
|
|
// if we're including prereleases in the match, then we need
|
|
// to fix this to -0, the lowest possible prerelease value
|
|
pr = options.includePrerelease ? '-0' : '';
|
|
|
|
if (xM) {
|
|
if (gtlt === '>' || gtlt === '<') {
|
|
// nothing is allowed
|
|
ret = '<0.0.0-0';
|
|
} else {
|
|
// nothing is forbidden
|
|
ret = '*';
|
|
}
|
|
} else if (gtlt && anyX) {
|
|
// we know patch is an x, because we have any x at all.
|
|
// replace X with 0
|
|
if (xm) {
|
|
m = 0;
|
|
}
|
|
p = 0;
|
|
|
|
if (gtlt === '>') {
|
|
// >1 => >=2.0.0
|
|
// >1.2 => >=1.3.0
|
|
gtlt = '>=';
|
|
if (xm) {
|
|
M = +M + 1;
|
|
m = 0;
|
|
p = 0;
|
|
} else {
|
|
m = +m + 1;
|
|
p = 0;
|
|
}
|
|
} else if (gtlt === '<=') {
|
|
// <=0.7.x is actually <0.8.0, since any 0.7.x should
|
|
// pass. Similarly, <=7.x is actually <8.0.0, etc.
|
|
gtlt = '<';
|
|
if (xm) {
|
|
M = +M + 1;
|
|
} else {
|
|
m = +m + 1;
|
|
}
|
|
}
|
|
|
|
if (gtlt === '<') {
|
|
pr = '-0';
|
|
}
|
|
|
|
ret = `${gtlt + M}.${m}.${p}${pr}`;
|
|
} else if (xm) {
|
|
ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`;
|
|
} else if (xp) {
|
|
ret = `>=${M}.${m}.0${pr
|
|
} <${M}.${+m + 1}.0-0`;
|
|
}
|
|
|
|
debug('xRange return', ret);
|
|
|
|
return ret
|
|
})
|
|
};
|
|
|
|
// Because * is AND-ed with everything else in the comparator,
|
|
// and '' means "any version", just remove the *s entirely.
|
|
const replaceStars = (comp, options) => {
|
|
debug('replaceStars', comp, options);
|
|
// Looseness is ignored here. star is always as loose as it gets!
|
|
return comp.trim().replace(re[t.STAR], '')
|
|
};
|
|
|
|
const replaceGTE0 = (comp, options) => {
|
|
debug('replaceGTE0', comp, options);
|
|
return comp.trim()
|
|
.replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '')
|
|
};
|
|
|
|
// This function is passed to string.replace(re[t.HYPHENRANGE])
|
|
// M, m, patch, prerelease, build
|
|
// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
|
|
// 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do
|
|
// 1.2 - 3.4 => >=1.2.0 <3.5.0-0
|
|
const hyphenReplace = incPr => ($0,
|
|
from, fM, fm, fp, fpr, fb,
|
|
to, tM, tm, tp, tpr, tb) => {
|
|
if (isX(fM)) {
|
|
from = '';
|
|
} else if (isX(fm)) {
|
|
from = `>=${fM}.0.0${incPr ? '-0' : ''}`;
|
|
} else if (isX(fp)) {
|
|
from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}`;
|
|
} else if (fpr) {
|
|
from = `>=${from}`;
|
|
} else {
|
|
from = `>=${from}${incPr ? '-0' : ''}`;
|
|
}
|
|
|
|
if (isX(tM)) {
|
|
to = '';
|
|
} else if (isX(tm)) {
|
|
to = `<${+tM + 1}.0.0-0`;
|
|
} else if (isX(tp)) {
|
|
to = `<${tM}.${+tm + 1}.0-0`;
|
|
} else if (tpr) {
|
|
to = `<=${tM}.${tm}.${tp}-${tpr}`;
|
|
} else if (incPr) {
|
|
to = `<${tM}.${tm}.${+tp + 1}-0`;
|
|
} else {
|
|
to = `<=${to}`;
|
|
}
|
|
|
|
return (`${from} ${to}`).trim()
|
|
};
|
|
|
|
const testSet = (set, version, options) => {
|
|
for (let i = 0; i < set.length; i++) {
|
|
if (!set[i].test(version)) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
if (version.prerelease.length && !options.includePrerelease) {
|
|
// Find the set of versions that are allowed to have prereleases
|
|
// For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
|
|
// That should allow `1.2.3-pr.2` to pass.
|
|
// However, `1.2.4-alpha.notready` should NOT be allowed,
|
|
// even though it's within the range set by the comparators.
|
|
for (let i = 0; i < set.length; i++) {
|
|
debug(set[i].semver);
|
|
if (set[i].semver === Comparator.ANY) {
|
|
continue
|
|
}
|
|
|
|
if (set[i].semver.prerelease.length > 0) {
|
|
const allowed = set[i].semver;
|
|
if (allowed.major === version.major &&
|
|
allowed.minor === version.minor &&
|
|
allowed.patch === version.patch) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
// Version has a -pre, but it's not one of the ones we like.
|
|
return false
|
|
}
|
|
|
|
return true
|
|
};
|
|
return range;
|
|
}
|
|
|
|
const Range = requireRange();
|
|
const satisfies = (version, range, options) => {
|
|
try {
|
|
range = new Range(range, options);
|
|
} catch (er) {
|
|
return false
|
|
}
|
|
return range.test(version)
|
|
};
|
|
var satisfies_1 = satisfies;
|
|
|
|
const satisfies$1 = /*#__PURE__*/_mergeNamespaces({
|
|
__proto__: null,
|
|
default: satisfies_1
|
|
}, [satisfies_1]);
|
|
|
|
export { satisfies$1 as s };
|