From 4c94673ab5399d27e5a48e52f7a65b038a456265 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Fri, 4 Dec 2020 14:35:37 -0500 Subject: [PATCH] semver@7.3.4 --- node_modules/semver/classes/comparator.js | 8 +-- node_modules/semver/classes/range.js | 63 ++++++++++++++++--- node_modules/semver/classes/semver.js | 9 +-- node_modules/semver/functions/parse.js | 8 +-- node_modules/semver/internal/parse-options.js | 11 ++++ node_modules/semver/package.json | 7 ++- node_modules/semver/ranges/min-version.js | 7 ++- node_modules/semver/ranges/outside.js | 2 +- node_modules/semver/ranges/subset.js | 15 +++-- package-lock.json | 17 +++-- package.json | 2 +- 11 files changed, 109 insertions(+), 40 deletions(-) create mode 100644 node_modules/semver/internal/parse-options.js diff --git a/node_modules/semver/classes/comparator.js b/node_modules/semver/classes/comparator.js index 3595792d0ed0c..dbbef2d8fe20e 100644 --- a/node_modules/semver/classes/comparator.js +++ b/node_modules/semver/classes/comparator.js @@ -5,12 +5,7 @@ class Comparator { return ANY } constructor (comp, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + options = parseOptions(options) if (comp instanceof Comparator) { if (comp.loose === !!options.loose) { @@ -132,6 +127,7 @@ class Comparator { module.exports = Comparator +const parseOptions = require('../internal/parse-options') const {re, t} = require('../internal/re') const cmp = require('../functions/cmp') const debug = require('../internal/debug') diff --git a/node_modules/semver/classes/range.js b/node_modules/semver/classes/range.js index 83f8967717ebb..aa04f6bff9446 100644 --- a/node_modules/semver/classes/range.js +++ b/node_modules/semver/classes/range.js @@ -1,12 +1,7 @@ // hoisted class for cyclic dependency class Range { constructor (range, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + options = parseOptions(options) if (range instanceof Range) { if ( @@ -46,6 +41,24 @@ class Range { 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() } @@ -64,8 +77,17 @@ class Range { } parseRange (range) { - const loose = this.options.loose 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)) @@ -87,15 +109,33 @@ class Range { // ready to be split into comparators. const compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] - return range + const rangeList = range .split(' ') .map(comp => parseComparator(comp, this.options)) .join(' ') .split(/\s+/) + // >=0.0.0 is equivalent to * .map(comp => replaceGTE0(comp, this.options)) // in loose mode, throw out any that are not valid comparators .filter(this.options.loose ? comp => !!comp.match(compRe) : () => true) .map(comp => new Comparator(comp, this.options)) + + // 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 l = rangeList.length + const rangeMap = new Map() + for (const comp of rangeList) { + 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) { @@ -144,6 +184,10 @@ class Range { } module.exports = Range +const LRU = require('lru-cache') +const cache = new LRU({ max: 1000 }) + +const parseOptions = require('../internal/parse-options') const Comparator = require('./comparator') const debug = require('../internal/debug') const SemVer = require('./semver') @@ -155,6 +199,9 @@ const { caretTrimReplace } = require('../internal/re') +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) => { diff --git a/node_modules/semver/classes/semver.js b/node_modules/semver/classes/semver.js index 73247ad2b7eab..ed81a7ec6cbfe 100644 --- a/node_modules/semver/classes/semver.js +++ b/node_modules/semver/classes/semver.js @@ -2,15 +2,12 @@ const debug = require('../internal/debug') const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants') const { re, t } = require('../internal/re') +const parseOptions = require('../internal/parse-options') const { compareIdentifiers } = require('../internal/identifiers') class SemVer { constructor (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + options = parseOptions(options) + if (version instanceof SemVer) { if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) { diff --git a/node_modules/semver/functions/parse.js b/node_modules/semver/functions/parse.js index 457fee04a95c8..11f20f03745ab 100644 --- a/node_modules/semver/functions/parse.js +++ b/node_modules/semver/functions/parse.js @@ -2,13 +2,9 @@ const {MAX_LENGTH} = require('../internal/constants') const { re, t } = require('../internal/re') const SemVer = require('../classes/semver') +const parseOptions = require('../internal/parse-options') const parse = (version, options) => { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + options = parseOptions(options) if (version instanceof SemVer) { return version diff --git a/node_modules/semver/internal/parse-options.js b/node_modules/semver/internal/parse-options.js new file mode 100644 index 0000000000000..42d2ebd6fa32f --- /dev/null +++ b/node_modules/semver/internal/parse-options.js @@ -0,0 +1,11 @@ +// 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 = options => + !options ? {} + : typeof options !== 'object' ? { loose: true } + : opts.filter(k => options[k]).reduce((options, k) => { + options[k] = true + return options + }, {}) +module.exports = parseOptions diff --git a/node_modules/semver/package.json b/node_modules/semver/package.json index 07867975d152c..d4043d38a1352 100644 --- a/node_modules/semver/package.json +++ b/node_modules/semver/package.json @@ -1,6 +1,6 @@ { "name": "semver", - "version": "7.3.2", + "version": "7.3.4", "description": "The semantic version parser used by npm.", "main": "index.js", "scripts": { @@ -16,7 +16,7 @@ "license": "ISC", "repository": "https://github.com/npm/node-semver", "bin": { - "semver": "./bin/semver.js" + "semver": "bin/semver.js" }, "files": [ "bin/**/*.js", @@ -34,5 +34,8 @@ }, "engines": { "node": ">=10" + }, + "dependencies": { + "lru-cache": "^6.0.0" } } diff --git a/node_modules/semver/ranges/min-version.js b/node_modules/semver/ranges/min-version.js index 7118d237bf5c4..2fac412914fe2 100644 --- a/node_modules/semver/ranges/min-version.js +++ b/node_modules/semver/ranges/min-version.js @@ -19,6 +19,7 @@ const minVersion = (range, loose) => { for (let i = 0; i < range.set.length; ++i) { const comparators = range.set[i] + let setMin = null comparators.forEach((comparator) => { // Clone to avoid manipulating the comparator's semver object. const compver = new SemVer(comparator.semver.version) @@ -33,8 +34,8 @@ const minVersion = (range, loose) => { /* fallthrough */ case '': case '>=': - if (!minver || gt(minver, compver)) { - minver = compver + if (!setMin || gt(compver, setMin)) { + setMin = compver } break case '<': @@ -46,6 +47,8 @@ const minVersion = (range, loose) => { throw new Error(`Unexpected operation: ${comparator.operator}`) } }) + if (setMin && (!minver || gt(minver, setMin))) + minver = setMin } if (minver && range.test(minver)) { diff --git a/node_modules/semver/ranges/outside.js b/node_modules/semver/ranges/outside.js index e35ed1176c84e..2a4b0a13f9e29 100644 --- a/node_modules/semver/ranges/outside.js +++ b/node_modules/semver/ranges/outside.js @@ -32,7 +32,7 @@ const outside = (version, range, hilo, options) => { throw new TypeError('Must provide a hilo val of "<" or ">"') } - // If it satisifes the range it is not outside + // If it satisfies the range it is not outside if (satisfies(version, range, options)) { return false } diff --git a/node_modules/semver/ranges/subset.js b/node_modules/semver/ranges/subset.js index 6ae29a3c92b89..bb7d15fe2696b 100644 --- a/node_modules/semver/ranges/subset.js +++ b/node_modules/semver/ranges/subset.js @@ -21,15 +21,18 @@ const compare = require('../functions/compare.js') // - If EQ satisfies every C, return true // - Else return false // - If GT -// - If GT is lower than any > or >= comp in C, return false +// - If GT.semver is lower than any > or >= comp in C, return false // - If GT is >=, and GT.semver does not satisfy every C, return false // - If LT -// - If LT.semver is greater than that of any > comp in C, return false +// - If LT.semver is greater than any < or <= comp in C, return false // - If LT is <=, and LT.semver does not satisfy every C, return false // - If any C is a = range, and GT or LT are set, return false // - Else return true const subset = (sub, dom, options) => { + if (sub === dom) + return true + sub = new Range(sub, options) dom = new Range(dom, options) let sawNonNull = false @@ -52,6 +55,9 @@ const subset = (sub, dom, options) => { } const simpleSubset = (sub, dom, options) => { + if (sub === dom) + return true + if (sub.length === 1 && sub[0].semver === ANY) return dom.length === 1 && dom[0].semver === ANY @@ -90,6 +96,7 @@ const simpleSubset = (sub, dom, options) => { if (!satisfies(eq, String(c), options)) return false } + return true } @@ -101,7 +108,7 @@ const simpleSubset = (sub, dom, options) => { if (gt) { if (c.operator === '>' || c.operator === '>=') { higher = higherGT(gt, c, options) - if (higher === c) + if (higher === c && higher !== gt) return false } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) return false @@ -109,7 +116,7 @@ const simpleSubset = (sub, dom, options) => { if (lt) { if (c.operator === '<' || c.operator === '<=') { lower = lowerLT(lt, c, options) - if (lower === c) + if (lower === c && lower !== lt) return false } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) return false diff --git a/package-lock.json b/package-lock.json index e859b52224e42..debdb45e68516 100644 --- a/package-lock.json +++ b/package-lock.json @@ -135,7 +135,7 @@ "read-package-json": "^3.0.0", "read-package-json-fast": "^1.2.1", "rimraf": "^3.0.2", - "semver": "^7.3.2", + "semver": "^7.3.4", "sorted-object": "~2.0.1", "ssri": "^8.0.0", "tar": "^6.0.5", @@ -5476,9 +5476,13 @@ } }, "node_modules/semver": { - "version": "7.3.2", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "inBundle": true, - "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -12711,7 +12715,12 @@ } }, "semver": { - "version": "7.3.2" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } }, "set-blocking": { "version": "2.0.0" diff --git a/package.json b/package.json index 219e9a390a147..7a2bb79231cf9 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "read-package-json": "^3.0.0", "read-package-json-fast": "^1.2.1", "rimraf": "^3.0.2", - "semver": "^7.3.2", + "semver": "^7.3.4", "sorted-object": "~2.0.1", "ssri": "^8.0.0", "tar": "^6.0.5",