semver 7.5.1 → 7.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/classes/comparator.js +2 -1
- package/classes/range.js +40 -27
- package/classes/semver.js +5 -3
- package/functions/coerce.js +1 -1
- package/functions/diff.js +31 -20
- package/internal/constants.js +5 -0
- package/internal/re.js +30 -4
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -159,7 +159,9 @@ of primitive `operators` is:
|
|
|
159
159
|
|
|
160
160
|
For example, the comparator `>=1.2.7` would match the versions
|
|
161
161
|
`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6`
|
|
162
|
-
or `1.1.0`.
|
|
162
|
+
or `1.1.0`. The comparator `>1` is equivalent to `>=2.0.0` and
|
|
163
|
+
would match the versions `2.0.0` and `3.1.0`, but not the versions
|
|
164
|
+
`1.0.1` or `1.1.0`.
|
|
163
165
|
|
|
164
166
|
Comparators can be joined by whitespace to form a `comparator set`,
|
|
165
167
|
which is satisfied by the **intersection** of all of the comparators
|
package/classes/comparator.js
CHANGED
|
@@ -16,6 +16,7 @@ class Comparator {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
comp = comp.trim().split(/\s+/).join(' ')
|
|
19
20
|
debug('comparator', comp, options)
|
|
20
21
|
this.options = options
|
|
21
22
|
this.loose = !!options.loose
|
|
@@ -133,7 +134,7 @@ class Comparator {
|
|
|
133
134
|
module.exports = Comparator
|
|
134
135
|
|
|
135
136
|
const parseOptions = require('../internal/parse-options')
|
|
136
|
-
const { re, t } = require('../internal/re')
|
|
137
|
+
const { safeRe: re, t } = require('../internal/re')
|
|
137
138
|
const cmp = require('../functions/cmp')
|
|
138
139
|
const debug = require('../internal/debug')
|
|
139
140
|
const SemVer = require('./semver')
|
package/classes/range.js
CHANGED
|
@@ -26,19 +26,26 @@ class Range {
|
|
|
26
26
|
this.loose = !!options.loose
|
|
27
27
|
this.includePrerelease = !!options.includePrerelease
|
|
28
28
|
|
|
29
|
-
// First
|
|
29
|
+
// First reduce all whitespace as much as possible so we do not have to rely
|
|
30
|
+
// on potentially slow regexes like \s*. This is then stored and used for
|
|
31
|
+
// future error messages as well.
|
|
30
32
|
this.raw = range
|
|
31
|
-
|
|
33
|
+
.trim()
|
|
34
|
+
.split(/\s+/)
|
|
35
|
+
.join(' ')
|
|
36
|
+
|
|
37
|
+
// First, split on ||
|
|
38
|
+
this.set = this.raw
|
|
32
39
|
.split('||')
|
|
33
40
|
// map the range to a 2d array of comparators
|
|
34
|
-
.map(r => this.parseRange(r
|
|
41
|
+
.map(r => this.parseRange(r))
|
|
35
42
|
// throw out any comparator lists that are empty
|
|
36
43
|
// this generally means that it was not a valid range, which is allowed
|
|
37
44
|
// in loose mode, but will still throw if the WHOLE range is invalid.
|
|
38
45
|
.filter(c => c.length)
|
|
39
46
|
|
|
40
47
|
if (!this.set.length) {
|
|
41
|
-
throw new TypeError(`Invalid SemVer Range: ${
|
|
48
|
+
throw new TypeError(`Invalid SemVer Range: ${this.raw}`)
|
|
42
49
|
}
|
|
43
50
|
|
|
44
51
|
// if we have any that are not the null set, throw out null sets.
|
|
@@ -64,9 +71,7 @@ class Range {
|
|
|
64
71
|
|
|
65
72
|
format () {
|
|
66
73
|
this.range = this.set
|
|
67
|
-
.map((comps) =>
|
|
68
|
-
return comps.join(' ').trim()
|
|
69
|
-
})
|
|
74
|
+
.map((comps) => comps.join(' ').trim())
|
|
70
75
|
.join('||')
|
|
71
76
|
.trim()
|
|
72
77
|
return this.range
|
|
@@ -77,8 +82,6 @@ class Range {
|
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
parseRange (range) {
|
|
80
|
-
range = range.trim()
|
|
81
|
-
|
|
82
85
|
// memoize range parsing for performance.
|
|
83
86
|
// this is a very hot path, and fully deterministic.
|
|
84
87
|
const memoOpts =
|
|
@@ -95,18 +98,18 @@ class Range {
|
|
|
95
98
|
const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]
|
|
96
99
|
range = range.replace(hr, hyphenReplace(this.options.includePrerelease))
|
|
97
100
|
debug('hyphen replace', range)
|
|
101
|
+
|
|
98
102
|
// `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
|
|
99
103
|
range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace)
|
|
100
104
|
debug('comparator trim', range)
|
|
101
105
|
|
|
102
106
|
// `~ 1.2.3` => `~1.2.3`
|
|
103
107
|
range = range.replace(re[t.TILDETRIM], tildeTrimReplace)
|
|
108
|
+
debug('tilde trim', range)
|
|
104
109
|
|
|
105
110
|
// `^ 1.2.3` => `^1.2.3`
|
|
106
111
|
range = range.replace(re[t.CARETTRIM], caretTrimReplace)
|
|
107
|
-
|
|
108
|
-
// normalize spaces
|
|
109
|
-
range = range.split(/\s+/).join(' ')
|
|
112
|
+
debug('caret trim', range)
|
|
110
113
|
|
|
111
114
|
// At this point, the range is completely trimmed and
|
|
112
115
|
// ready to be split into comparators.
|
|
@@ -203,7 +206,7 @@ const Comparator = require('./comparator')
|
|
|
203
206
|
const debug = require('../internal/debug')
|
|
204
207
|
const SemVer = require('./semver')
|
|
205
208
|
const {
|
|
206
|
-
re,
|
|
209
|
+
safeRe: re,
|
|
207
210
|
t,
|
|
208
211
|
comparatorTrimReplace,
|
|
209
212
|
tildeTrimReplace,
|
|
@@ -257,10 +260,13 @@ const isX = id => !id || id.toLowerCase() === 'x' || id === '*'
|
|
|
257
260
|
// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0
|
|
258
261
|
// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0
|
|
259
262
|
// ~0.0.1 --> >=0.0.1 <0.1.0-0
|
|
260
|
-
const replaceTildes = (comp, options) =>
|
|
261
|
-
comp
|
|
262
|
-
|
|
263
|
-
|
|
263
|
+
const replaceTildes = (comp, options) => {
|
|
264
|
+
return comp
|
|
265
|
+
.trim()
|
|
266
|
+
.split(/\s+/)
|
|
267
|
+
.map((c) => replaceTilde(c, options))
|
|
268
|
+
.join(' ')
|
|
269
|
+
}
|
|
264
270
|
|
|
265
271
|
const replaceTilde = (comp, options) => {
|
|
266
272
|
const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]
|
|
@@ -298,10 +304,13 @@ const replaceTilde = (comp, options) => {
|
|
|
298
304
|
// ^1.2.0 --> >=1.2.0 <2.0.0-0
|
|
299
305
|
// ^0.0.1 --> >=0.0.1 <0.0.2-0
|
|
300
306
|
// ^0.1.0 --> >=0.1.0 <0.2.0-0
|
|
301
|
-
const replaceCarets = (comp, options) =>
|
|
302
|
-
comp
|
|
303
|
-
|
|
304
|
-
|
|
307
|
+
const replaceCarets = (comp, options) => {
|
|
308
|
+
return comp
|
|
309
|
+
.trim()
|
|
310
|
+
.split(/\s+/)
|
|
311
|
+
.map((c) => replaceCaret(c, options))
|
|
312
|
+
.join(' ')
|
|
313
|
+
}
|
|
305
314
|
|
|
306
315
|
const replaceCaret = (comp, options) => {
|
|
307
316
|
debug('caret', comp, options)
|
|
@@ -358,9 +367,10 @@ const replaceCaret = (comp, options) => {
|
|
|
358
367
|
|
|
359
368
|
const replaceXRanges = (comp, options) => {
|
|
360
369
|
debug('replaceXRanges', comp, options)
|
|
361
|
-
return comp
|
|
362
|
-
|
|
363
|
-
|
|
370
|
+
return comp
|
|
371
|
+
.split(/\s+/)
|
|
372
|
+
.map((c) => replaceXRange(c, options))
|
|
373
|
+
.join(' ')
|
|
364
374
|
}
|
|
365
375
|
|
|
366
376
|
const replaceXRange = (comp, options) => {
|
|
@@ -443,12 +453,15 @@ const replaceXRange = (comp, options) => {
|
|
|
443
453
|
const replaceStars = (comp, options) => {
|
|
444
454
|
debug('replaceStars', comp, options)
|
|
445
455
|
// Looseness is ignored here. star is always as loose as it gets!
|
|
446
|
-
return comp
|
|
456
|
+
return comp
|
|
457
|
+
.trim()
|
|
458
|
+
.replace(re[t.STAR], '')
|
|
447
459
|
}
|
|
448
460
|
|
|
449
461
|
const replaceGTE0 = (comp, options) => {
|
|
450
462
|
debug('replaceGTE0', comp, options)
|
|
451
|
-
return comp
|
|
463
|
+
return comp
|
|
464
|
+
.trim()
|
|
452
465
|
.replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '')
|
|
453
466
|
}
|
|
454
467
|
|
|
@@ -486,7 +499,7 @@ const hyphenReplace = incPr => ($0,
|
|
|
486
499
|
to = `<=${to}`
|
|
487
500
|
}
|
|
488
501
|
|
|
489
|
-
return
|
|
502
|
+
return `${from} ${to}`.trim()
|
|
490
503
|
}
|
|
491
504
|
|
|
492
505
|
const testSet = (set, version, options) => {
|
package/classes/semver.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const debug = require('../internal/debug')
|
|
2
2
|
const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants')
|
|
3
|
-
const { re, t } = require('../internal/re')
|
|
3
|
+
const { safeRe: re, t } = require('../internal/re')
|
|
4
4
|
|
|
5
5
|
const parseOptions = require('../internal/parse-options')
|
|
6
6
|
const { compareIdentifiers } = require('../internal/identifiers')
|
|
@@ -291,8 +291,10 @@ class SemVer {
|
|
|
291
291
|
default:
|
|
292
292
|
throw new Error(`invalid increment argument: ${release}`)
|
|
293
293
|
}
|
|
294
|
-
this.format()
|
|
295
|
-
this.
|
|
294
|
+
this.raw = this.format()
|
|
295
|
+
if (this.build.length) {
|
|
296
|
+
this.raw += `+${this.build.join('.')}`
|
|
297
|
+
}
|
|
296
298
|
return this
|
|
297
299
|
}
|
|
298
300
|
}
|
package/functions/coerce.js
CHANGED
package/functions/diff.js
CHANGED
|
@@ -13,6 +13,35 @@ const diff = (version1, version2) => {
|
|
|
13
13
|
const highVersion = v1Higher ? v1 : v2
|
|
14
14
|
const lowVersion = v1Higher ? v2 : v1
|
|
15
15
|
const highHasPre = !!highVersion.prerelease.length
|
|
16
|
+
const lowHasPre = !!lowVersion.prerelease.length
|
|
17
|
+
|
|
18
|
+
if (lowHasPre && !highHasPre) {
|
|
19
|
+
// Going from prerelease -> no prerelease requires some special casing
|
|
20
|
+
|
|
21
|
+
// If the low version has only a major, then it will always be a major
|
|
22
|
+
// Some examples:
|
|
23
|
+
// 1.0.0-1 -> 1.0.0
|
|
24
|
+
// 1.0.0-1 -> 1.1.1
|
|
25
|
+
// 1.0.0-1 -> 2.0.0
|
|
26
|
+
if (!lowVersion.patch && !lowVersion.minor) {
|
|
27
|
+
return 'major'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Otherwise it can be determined by checking the high version
|
|
31
|
+
|
|
32
|
+
if (highVersion.patch) {
|
|
33
|
+
// anything higher than a patch bump would result in the wrong version
|
|
34
|
+
return 'patch'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (highVersion.minor) {
|
|
38
|
+
// anything higher than a minor bump would result in the wrong version
|
|
39
|
+
return 'minor'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// bumping major/minor/patch all have same result
|
|
43
|
+
return 'major'
|
|
44
|
+
}
|
|
16
45
|
|
|
17
46
|
// add the `pre` prefix if we are going to a prerelease version
|
|
18
47
|
const prefix = highHasPre ? 'pre' : ''
|
|
@@ -29,26 +58,8 @@ const diff = (version1, version2) => {
|
|
|
29
58
|
return prefix + 'patch'
|
|
30
59
|
}
|
|
31
60
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (highHasPre) {
|
|
36
|
-
// high and low are preleases
|
|
37
|
-
return 'prerelease'
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (lowVersion.patch) {
|
|
41
|
-
// anything higher than a patch bump would result in the wrong version
|
|
42
|
-
return 'patch'
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (lowVersion.minor) {
|
|
46
|
-
// anything higher than a minor bump would result in the wrong version
|
|
47
|
-
return 'minor'
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// bumping major/minor/patch all have same result
|
|
51
|
-
return 'major'
|
|
61
|
+
// high and low are preleases
|
|
62
|
+
return 'prerelease'
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
module.exports = diff
|
package/internal/constants.js
CHANGED
|
@@ -9,6 +9,10 @@ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
|
|
|
9
9
|
// Max safe segment length for coercion.
|
|
10
10
|
const MAX_SAFE_COMPONENT_LENGTH = 16
|
|
11
11
|
|
|
12
|
+
// Max safe length for a build identifier. The max length minus 6 characters for
|
|
13
|
+
// the shortest version with a build 0.0.0+BUILD.
|
|
14
|
+
const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6
|
|
15
|
+
|
|
12
16
|
const RELEASE_TYPES = [
|
|
13
17
|
'major',
|
|
14
18
|
'premajor',
|
|
@@ -22,6 +26,7 @@ const RELEASE_TYPES = [
|
|
|
22
26
|
module.exports = {
|
|
23
27
|
MAX_LENGTH,
|
|
24
28
|
MAX_SAFE_COMPONENT_LENGTH,
|
|
29
|
+
MAX_SAFE_BUILD_LENGTH,
|
|
25
30
|
MAX_SAFE_INTEGER,
|
|
26
31
|
RELEASE_TYPES,
|
|
27
32
|
SEMVER_SPEC_VERSION,
|
package/internal/re.js
CHANGED
|
@@ -1,19 +1,45 @@
|
|
|
1
|
-
const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants')
|
|
1
|
+
const { MAX_SAFE_COMPONENT_LENGTH, MAX_SAFE_BUILD_LENGTH } = require('./constants')
|
|
2
2
|
const debug = require('./debug')
|
|
3
3
|
exports = module.exports = {}
|
|
4
4
|
|
|
5
5
|
// The actual regexps go on exports.re
|
|
6
6
|
const re = exports.re = []
|
|
7
|
+
const safeRe = exports.safeRe = []
|
|
7
8
|
const src = exports.src = []
|
|
8
9
|
const t = exports.t = {}
|
|
9
10
|
let R = 0
|
|
10
11
|
|
|
12
|
+
const LETTERDASHNUMBER = '[a-zA-Z0-9-]'
|
|
13
|
+
|
|
14
|
+
// Replace some greedy regex tokens to prevent regex dos issues. These regex are
|
|
15
|
+
// used internally via the safeRe object since all inputs in this library get
|
|
16
|
+
// normalized first to trim and collapse all extra whitespace. The original
|
|
17
|
+
// regexes are exported for userland consumption and lower level usage. A
|
|
18
|
+
// future breaking change could export the safer regex only with a note that
|
|
19
|
+
// all input should have extra whitespace removed.
|
|
20
|
+
const safeRegexReplacements = [
|
|
21
|
+
['\\s', 1],
|
|
22
|
+
['\\d', MAX_SAFE_COMPONENT_LENGTH],
|
|
23
|
+
[LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
const makeSafeRegex = (value) => {
|
|
27
|
+
for (const [token, max] of safeRegexReplacements) {
|
|
28
|
+
value = value
|
|
29
|
+
.split(`${token}*`).join(`${token}{0,${max}}`)
|
|
30
|
+
.split(`${token}+`).join(`${token}{1,${max}}`)
|
|
31
|
+
}
|
|
32
|
+
return value
|
|
33
|
+
}
|
|
34
|
+
|
|
11
35
|
const createToken = (name, value, isGlobal) => {
|
|
36
|
+
const safe = makeSafeRegex(value)
|
|
12
37
|
const index = R++
|
|
13
38
|
debug(name, index, value)
|
|
14
39
|
t[name] = index
|
|
15
40
|
src[index] = value
|
|
16
41
|
re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
|
|
42
|
+
safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined)
|
|
17
43
|
}
|
|
18
44
|
|
|
19
45
|
// The following Regular Expressions can be used for tokenizing,
|
|
@@ -23,13 +49,13 @@ const createToken = (name, value, isGlobal) => {
|
|
|
23
49
|
// A single `0`, or a non-zero digit followed by zero or more digits.
|
|
24
50
|
|
|
25
51
|
createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*')
|
|
26
|
-
createToken('NUMERICIDENTIFIERLOOSE', '
|
|
52
|
+
createToken('NUMERICIDENTIFIERLOOSE', '\\d+')
|
|
27
53
|
|
|
28
54
|
// ## Non-numeric Identifier
|
|
29
55
|
// Zero or more digits, followed by a letter or hyphen, and then zero or
|
|
30
56
|
// more letters, digits, or hyphens.
|
|
31
57
|
|
|
32
|
-
createToken('NONNUMERICIDENTIFIER',
|
|
58
|
+
createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`)
|
|
33
59
|
|
|
34
60
|
// ## Main Version
|
|
35
61
|
// Three dot-separated numeric identifiers.
|
|
@@ -64,7 +90,7 @@ createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
|
|
|
64
90
|
// ## Build Metadata Identifier
|
|
65
91
|
// Any combination of digits, letters, or hyphens.
|
|
66
92
|
|
|
67
|
-
createToken('BUILDIDENTIFIER',
|
|
93
|
+
createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`)
|
|
68
94
|
|
|
69
95
|
// ## Build Metadata
|
|
70
96
|
// Plus sign, followed by one or more period-separated build metadata
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "semver",
|
|
3
|
-
"version": "7.5.
|
|
3
|
+
"version": "7.5.3",
|
|
4
4
|
"description": "The semantic version parser used by npm.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@npmcli/eslint-config": "^4.0.0",
|
|
17
|
-
"@npmcli/template-oss": "4.
|
|
17
|
+
"@npmcli/template-oss": "4.15.1",
|
|
18
18
|
"tap": "^16.0.0"
|
|
19
19
|
},
|
|
20
20
|
"license": "ISC",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"range.bnf"
|
|
38
38
|
],
|
|
39
39
|
"tap": {
|
|
40
|
-
"
|
|
40
|
+
"timeout": 30,
|
|
41
41
|
"coverage-map": "map.js",
|
|
42
42
|
"nyc-arg": [
|
|
43
43
|
"--exclude",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"author": "GitHub Inc.",
|
|
54
54
|
"templateOSS": {
|
|
55
55
|
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
56
|
-
"version": "4.
|
|
56
|
+
"version": "4.15.1",
|
|
57
57
|
"engines": ">=10",
|
|
58
58
|
"ciVersions": [
|
|
59
59
|
"10.0.0",
|