semver 7.3.0 → 7.3.4

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 CHANGED
@@ -256,8 +256,8 @@ inclusive range, then all versions that start with the supplied parts
256
256
  of the tuple are accepted, but nothing that would be greater than the
257
257
  provided tuple parts.
258
258
 
259
- * `1.2.3 - 2.3` := `>=1.2.3 <2.4.0`
260
- * `1.2.3 - 2` := `>=1.2.3 <3.0.0`
259
+ * `1.2.3 - 2.3` := `>=1.2.3 <2.4.0-0`
260
+ * `1.2.3 - 2` := `>=1.2.3 <3.0.0-0`
261
261
 
262
262
  #### X-Ranges `1.2.x` `1.X` `1.2.*` `*`
263
263
 
@@ -265,28 +265,28 @@ Any of `X`, `x`, or `*` may be used to "stand in" for one of the
265
265
  numeric values in the `[major, minor, patch]` tuple.
266
266
 
267
267
  * `*` := `>=0.0.0` (Any version satisfies)
268
- * `1.x` := `>=1.0.0 <2.0.0` (Matching major version)
269
- * `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions)
268
+ * `1.x` := `>=1.0.0 <2.0.0-0` (Matching major version)
269
+ * `1.2.x` := `>=1.2.0 <1.3.0-0` (Matching major and minor versions)
270
270
 
271
271
  A partial version range is treated as an X-Range, so the special
272
272
  character is in fact optional.
273
273
 
274
274
  * `""` (empty string) := `*` := `>=0.0.0`
275
- * `1` := `1.x.x` := `>=1.0.0 <2.0.0`
276
- * `1.2` := `1.2.x` := `>=1.2.0 <1.3.0`
275
+ * `1` := `1.x.x` := `>=1.0.0 <2.0.0-0`
276
+ * `1.2` := `1.2.x` := `>=1.2.0 <1.3.0-0`
277
277
 
278
278
  #### Tilde Ranges `~1.2.3` `~1.2` `~1`
279
279
 
280
280
  Allows patch-level changes if a minor version is specified on the
281
281
  comparator. Allows minor-level changes if not.
282
282
 
283
- * `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0`
284
- * `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`)
285
- * `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`)
286
- * `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0`
287
- * `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`)
288
- * `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`)
289
- * `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in
283
+ * `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0-0`
284
+ * `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0-0` (Same as `1.2.x`)
285
+ * `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0-0` (Same as `1.x`)
286
+ * `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0-0`
287
+ * `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0-0` (Same as `0.2.x`)
288
+ * `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0-0` (Same as `0.x`)
289
+ * `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0-0` Note that prereleases in
290
290
  the `1.2.3` version will be allowed, if they are greater than or
291
291
  equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but
292
292
  `1.2.4-beta.2` would not, because it is a prerelease of a
@@ -308,15 +308,15 @@ However, it presumes that there will *not* be breaking changes between
308
308
  `0.2.4` and `0.2.5`. It allows for changes that are presumed to be
309
309
  additive (but non-breaking), according to commonly observed practices.
310
310
 
311
- * `^1.2.3` := `>=1.2.3 <2.0.0`
312
- * `^0.2.3` := `>=0.2.3 <0.3.0`
313
- * `^0.0.3` := `>=0.0.3 <0.0.4`
314
- * `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in
311
+ * `^1.2.3` := `>=1.2.3 <2.0.0-0`
312
+ * `^0.2.3` := `>=0.2.3 <0.3.0-0`
313
+ * `^0.0.3` := `>=0.0.3 <0.0.4-0`
314
+ * `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0-0` Note that prereleases in
315
315
  the `1.2.3` version will be allowed, if they are greater than or
316
316
  equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but
317
317
  `1.2.4-beta.2` would not, because it is a prerelease of a
318
318
  different `[major, minor, patch]` tuple.
319
- * `^0.0.3-beta` := `>=0.0.3-beta <0.0.4` Note that prereleases in the
319
+ * `^0.0.3-beta` := `>=0.0.3-beta <0.0.4-0` Note that prereleases in the
320
320
  `0.0.3` version *only* will be allowed, if they are greater than or
321
321
  equal to `beta`. So, `0.0.3-pr.2` would be allowed.
322
322
 
@@ -324,16 +324,16 @@ When parsing caret ranges, a missing `patch` value desugars to the
324
324
  number `0`, but will allow flexibility within that value, even if the
325
325
  major and minor versions are both `0`.
326
326
 
327
- * `^1.2.x` := `>=1.2.0 <2.0.0`
328
- * `^0.0.x` := `>=0.0.0 <0.1.0`
329
- * `^0.0` := `>=0.0.0 <0.1.0`
327
+ * `^1.2.x` := `>=1.2.0 <2.0.0-0`
328
+ * `^0.0.x` := `>=0.0.0 <0.1.0-0`
329
+ * `^0.0` := `>=0.0.0 <0.1.0-0`
330
330
 
331
331
  A missing `minor` and `patch` values will desugar to zero, but also
332
332
  allow flexibility within those values, even if the major version is
333
333
  zero.
334
334
 
335
- * `^1.x` := `>=1.0.0 <2.0.0`
336
- * `^0.x` := `>=0.0.0 <1.0.0`
335
+ * `^1.x` := `>=1.0.0 <2.0.0-0`
336
+ * `^0.x` := `>=0.0.0 <1.0.0-0`
337
337
 
338
338
  ### Range Grammar
339
339
 
@@ -5,12 +5,7 @@ class Comparator {
5
5
  return ANY
6
6
  }
7
7
  constructor (comp, options) {
8
- if (!options || typeof options !== 'object') {
9
- options = {
10
- loose: !!options,
11
- includePrerelease: false
12
- }
13
- }
8
+ options = parseOptions(options)
14
9
 
15
10
  if (comp instanceof Comparator) {
16
11
  if (comp.loose === !!options.loose) {
@@ -132,6 +127,7 @@ class Comparator {
132
127
 
133
128
  module.exports = Comparator
134
129
 
130
+ const parseOptions = require('../internal/parse-options')
135
131
  const {re, t} = require('../internal/re')
136
132
  const cmp = require('../functions/cmp')
137
133
  const debug = require('../internal/debug')
package/classes/range.js CHANGED
@@ -1,12 +1,7 @@
1
1
  // hoisted class for cyclic dependency
2
2
  class Range {
3
3
  constructor (range, options) {
4
- if (!options || typeof options !== 'object') {
5
- options = {
6
- loose: !!options,
7
- includePrerelease: false
8
- }
9
- }
4
+ options = parseOptions(options)
10
5
 
11
6
  if (range instanceof Range) {
12
7
  if (
@@ -46,6 +41,24 @@ class Range {
46
41
  throw new TypeError(`Invalid SemVer Range: ${range}`)
47
42
  }
48
43
 
44
+ // if we have any that are not the null set, throw out null sets.
45
+ if (this.set.length > 1) {
46
+ // keep the first one, in case they're all null sets
47
+ const first = this.set[0]
48
+ this.set = this.set.filter(c => !isNullSet(c[0]))
49
+ if (this.set.length === 0)
50
+ this.set = [first]
51
+ else if (this.set.length > 1) {
52
+ // if we have any that are *, then the range is just *
53
+ for (const c of this.set) {
54
+ if (c.length === 1 && isAny(c[0])) {
55
+ this.set = [c]
56
+ break
57
+ }
58
+ }
59
+ }
60
+ }
61
+
49
62
  this.format()
50
63
  }
51
64
 
@@ -64,8 +77,17 @@ class Range {
64
77
  }
65
78
 
66
79
  parseRange (range) {
67
- const loose = this.options.loose
68
80
  range = range.trim()
81
+
82
+ // memoize range parsing for performance.
83
+ // this is a very hot path, and fully deterministic.
84
+ const memoOpts = Object.keys(this.options).join(',')
85
+ const memoKey = `parseRange:${memoOpts}:${range}`
86
+ const cached = cache.get(memoKey)
87
+ if (cached)
88
+ return cached
89
+
90
+ const loose = this.options.loose
69
91
  // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
70
92
  const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]
71
93
  range = range.replace(hr, hyphenReplace(this.options.includePrerelease))
@@ -87,15 +109,33 @@ class Range {
87
109
  // ready to be split into comparators.
88
110
 
89
111
  const compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
90
- return range
112
+ const rangeList = range
91
113
  .split(' ')
92
114
  .map(comp => parseComparator(comp, this.options))
93
115
  .join(' ')
94
116
  .split(/\s+/)
117
+ // >=0.0.0 is equivalent to *
95
118
  .map(comp => replaceGTE0(comp, this.options))
96
119
  // in loose mode, throw out any that are not valid comparators
97
120
  .filter(this.options.loose ? comp => !!comp.match(compRe) : () => true)
98
121
  .map(comp => new Comparator(comp, this.options))
122
+
123
+ // if any comparators are the null set, then replace with JUST null set
124
+ // if more than one comparator, remove any * comparators
125
+ // also, don't include the same comparator more than once
126
+ const l = rangeList.length
127
+ const rangeMap = new Map()
128
+ for (const comp of rangeList) {
129
+ if (isNullSet(comp))
130
+ return [comp]
131
+ rangeMap.set(comp.value, comp)
132
+ }
133
+ if (rangeMap.size > 1 && rangeMap.has(''))
134
+ rangeMap.delete('')
135
+
136
+ const result = [...rangeMap.values()]
137
+ cache.set(memoKey, result)
138
+ return result
99
139
  }
100
140
 
101
141
  intersects (range, options) {
@@ -144,6 +184,10 @@ class Range {
144
184
  }
145
185
  module.exports = Range
146
186
 
187
+ const LRU = require('lru-cache')
188
+ const cache = new LRU({ max: 1000 })
189
+
190
+ const parseOptions = require('../internal/parse-options')
147
191
  const Comparator = require('./comparator')
148
192
  const debug = require('../internal/debug')
149
193
  const SemVer = require('./semver')
@@ -155,6 +199,9 @@ const {
155
199
  caretTrimReplace
156
200
  } = require('../internal/re')
157
201
 
202
+ const isNullSet = c => c.value === '<0.0.0-0'
203
+ const isAny = c => c.value === ''
204
+
158
205
  // take a set of comparators and determine whether there
159
206
  // exists a version which can satisfy it
160
207
  const isSatisfiable = (comparators, options) => {
@@ -192,11 +239,11 @@ const parseComparator = (comp, options) => {
192
239
  const isX = id => !id || id.toLowerCase() === 'x' || id === '*'
193
240
 
194
241
  // ~, ~> --> * (any, kinda silly)
195
- // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
196
- // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
197
- // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
198
- // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
199
- // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
242
+ // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0
243
+ // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0
244
+ // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0
245
+ // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0
246
+ // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0
200
247
  const replaceTildes = (comp, options) =>
201
248
  comp.trim().split(/\s+/).map((comp) => {
202
249
  return replaceTilde(comp, options)
@@ -211,18 +258,18 @@ const replaceTilde = (comp, options) => {
211
258
  if (isX(M)) {
212
259
  ret = ''
213
260
  } else if (isX(m)) {
214
- ret = `>=${M}.0.0 <${+M + 1}.0.0`
261
+ ret = `>=${M}.0.0 <${+M + 1}.0.0-0`
215
262
  } else if (isX(p)) {
216
- // ~1.2 == >=1.2.0 <1.3.0
217
- ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0`
263
+ // ~1.2 == >=1.2.0 <1.3.0-0
264
+ ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`
218
265
  } else if (pr) {
219
266
  debug('replaceTilde pr', pr)
220
267
  ret = `>=${M}.${m}.${p}-${pr
221
- } <${M}.${+m + 1}.0`
268
+ } <${M}.${+m + 1}.0-0`
222
269
  } else {
223
- // ~1.2.3 == >=1.2.3 <1.3.0
270
+ // ~1.2.3 == >=1.2.3 <1.3.0-0
224
271
  ret = `>=${M}.${m}.${p
225
- } <${M}.${+m + 1}.0`
272
+ } <${M}.${+m + 1}.0-0`
226
273
  }
227
274
 
228
275
  debug('tilde return', ret)
@@ -231,11 +278,11 @@ const replaceTilde = (comp, options) => {
231
278
  }
232
279
 
233
280
  // ^ --> * (any, kinda silly)
234
- // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
235
- // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
236
- // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
237
- // ^1.2.3 --> >=1.2.3 <2.0.0
238
- // ^1.2.0 --> >=1.2.0 <2.0.0
281
+ // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0
282
+ // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0
283
+ // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0
284
+ // ^1.2.3 --> >=1.2.3 <2.0.0-0
285
+ // ^1.2.0 --> >=1.2.0 <2.0.0-0
239
286
  const replaceCarets = (comp, options) =>
240
287
  comp.trim().split(/\s+/).map((comp) => {
241
288
  return replaceCaret(comp, options)
@@ -252,40 +299,40 @@ const replaceCaret = (comp, options) => {
252
299
  if (isX(M)) {
253
300
  ret = ''
254
301
  } else if (isX(m)) {
255
- ret = `>=${M}.0.0${z} <${+M + 1}.0.0${z}`
302
+ ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`
256
303
  } else if (isX(p)) {
257
304
  if (M === '0') {
258
- ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0${z}`
305
+ ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`
259
306
  } else {
260
- ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0${z}`
307
+ ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`
261
308
  }
262
309
  } else if (pr) {
263
310
  debug('replaceCaret pr', pr)
264
311
  if (M === '0') {
265
312
  if (m === '0') {
266
313
  ret = `>=${M}.${m}.${p}-${pr
267
- } <${M}.${m}.${+p + 1}${z}`
314
+ } <${M}.${m}.${+p + 1}-0`
268
315
  } else {
269
316
  ret = `>=${M}.${m}.${p}-${pr
270
- } <${M}.${+m + 1}.0${z}`
317
+ } <${M}.${+m + 1}.0-0`
271
318
  }
272
319
  } else {
273
320
  ret = `>=${M}.${m}.${p}-${pr
274
- } <${+M + 1}.0.0${z}`
321
+ } <${+M + 1}.0.0-0`
275
322
  }
276
323
  } else {
277
324
  debug('no pr')
278
325
  if (M === '0') {
279
326
  if (m === '0') {
280
327
  ret = `>=${M}.${m}.${p
281
- }${z} <${M}.${m}.${+p + 1}${z}`
328
+ }${z} <${M}.${m}.${+p + 1}-0`
282
329
  } else {
283
330
  ret = `>=${M}.${m}.${p
284
- }${z} <${M}.${+m + 1}.0${z}`
331
+ }${z} <${M}.${+m + 1}.0-0`
285
332
  }
286
333
  } else {
287
334
  ret = `>=${M}.${m}.${p
288
- } <${+M + 1}.0.0${z}`
335
+ } <${+M + 1}.0.0-0`
289
336
  }
290
337
  }
291
338
 
@@ -358,12 +405,15 @@ const replaceXRange = (comp, options) => {
358
405
  }
359
406
  }
360
407
 
408
+ if (gtlt === '<')
409
+ pr = '-0'
410
+
361
411
  ret = `${gtlt + M}.${m}.${p}${pr}`
362
412
  } else if (xm) {
363
- ret = `>=${M}.0.0${pr} <${+M + 1}.0.0${pr}`
413
+ ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`
364
414
  } else if (xp) {
365
415
  ret = `>=${M}.${m}.0${pr
366
- } <${M}.${+m + 1}.0${pr}`
416
+ } <${M}.${+m + 1}.0-0`
367
417
  }
368
418
 
369
419
  debug('xRange return', ret)
@@ -389,8 +439,8 @@ const replaceGTE0 = (comp, options) => {
389
439
  // This function is passed to string.replace(re[t.HYPHENRANGE])
390
440
  // M, m, patch, prerelease, build
391
441
  // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
392
- // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
393
- // 1.2 - 3.4 => >=1.2.0 <3.5.0
442
+ // 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do
443
+ // 1.2 - 3.4 => >=1.2.0 <3.5.0-0
394
444
  const hyphenReplace = incPr => ($0,
395
445
  from, fM, fm, fp, fpr, fb,
396
446
  to, tM, tm, tp, tpr, tb) => {
@@ -409,9 +459,9 @@ const hyphenReplace = incPr => ($0,
409
459
  if (isX(tM)) {
410
460
  to = ''
411
461
  } else if (isX(tm)) {
412
- to = `<${+tM + 1}.0.0${incPr ? '-0' : ''}`
462
+ to = `<${+tM + 1}.0.0-0`
413
463
  } else if (isX(tp)) {
414
- to = `<${tM}.${+tm + 1}.0${incPr ? '-0' : ''}`
464
+ to = `<${tM}.${+tm + 1}.0-0`
415
465
  } else if (tpr) {
416
466
  to = `<=${tM}.${tm}.${tp}-${tpr}`
417
467
  } else if (incPr) {
package/classes/semver.js CHANGED
@@ -2,15 +2,12 @@ const debug = require('../internal/debug')
2
2
  const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants')
3
3
  const { re, t } = require('../internal/re')
4
4
 
5
+ const parseOptions = require('../internal/parse-options')
5
6
  const { compareIdentifiers } = require('../internal/identifiers')
6
7
  class SemVer {
7
8
  constructor (version, options) {
8
- if (!options || typeof options !== 'object') {
9
- options = {
10
- loose: !!options,
11
- includePrerelease: false
12
- }
13
- }
9
+ options = parseOptions(options)
10
+
14
11
  if (version instanceof SemVer) {
15
12
  if (version.loose === !!options.loose &&
16
13
  version.includePrerelease === !!options.includePrerelease) {
@@ -2,13 +2,9 @@ const {MAX_LENGTH} = require('../internal/constants')
2
2
  const { re, t } = require('../internal/re')
3
3
  const SemVer = require('../classes/semver')
4
4
 
5
+ const parseOptions = require('../internal/parse-options')
5
6
  const parse = (version, options) => {
6
- if (!options || typeof options !== 'object') {
7
- options = {
8
- loose: !!options,
9
- includePrerelease: false
10
- }
11
- }
7
+ options = parseOptions(options)
12
8
 
13
9
  if (version instanceof SemVer) {
14
10
  return version
@@ -0,0 +1,11 @@
1
+ // parse out just the options we care about so we always get a consistent
2
+ // obj with keys in a consistent order.
3
+ const opts = ['includePrerelease', 'loose', 'rtl']
4
+ const parseOptions = options =>
5
+ !options ? {}
6
+ : typeof options !== 'object' ? { loose: true }
7
+ : opts.filter(k => options[k]).reduce((options, k) => {
8
+ options[k] = true
9
+ return options
10
+ }, {})
11
+ module.exports = parseOptions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "semver",
3
- "version": "7.3.0",
3
+ "version": "7.3.4",
4
4
  "description": "The semantic version parser used by npm.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,7 +16,7 @@
16
16
  "license": "ISC",
17
17
  "repository": "https://github.com/npm/node-semver",
18
18
  "bin": {
19
- "semver": "./bin/semver.js"
19
+ "semver": "bin/semver.js"
20
20
  },
21
21
  "files": [
22
22
  "bin/**/*.js",
@@ -34,5 +34,8 @@
34
34
  },
35
35
  "engines": {
36
36
  "node": ">=10"
37
+ },
38
+ "dependencies": {
39
+ "lru-cache": "^6.0.0"
37
40
  }
38
41
  }
@@ -19,6 +19,7 @@ const minVersion = (range, loose) => {
19
19
  for (let i = 0; i < range.set.length; ++i) {
20
20
  const comparators = range.set[i]
21
21
 
22
+ let setMin = null
22
23
  comparators.forEach((comparator) => {
23
24
  // Clone to avoid manipulating the comparator's semver object.
24
25
  const compver = new SemVer(comparator.semver.version)
@@ -33,8 +34,8 @@ const minVersion = (range, loose) => {
33
34
  /* fallthrough */
34
35
  case '':
35
36
  case '>=':
36
- if (!minver || gt(minver, compver)) {
37
- minver = compver
37
+ if (!setMin || gt(compver, setMin)) {
38
+ setMin = compver
38
39
  }
39
40
  break
40
41
  case '<':
@@ -46,6 +47,8 @@ const minVersion = (range, loose) => {
46
47
  throw new Error(`Unexpected operation: ${comparator.operator}`)
47
48
  }
48
49
  })
50
+ if (setMin && (!minver || gt(minver, setMin)))
51
+ minver = setMin
49
52
  }
50
53
 
51
54
  if (minver && range.test(minver)) {
package/ranges/outside.js CHANGED
@@ -32,7 +32,7 @@ const outside = (version, range, hilo, options) => {
32
32
  throw new TypeError('Must provide a hilo val of "<" or ">"')
33
33
  }
34
34
 
35
- // If it satisifes the range it is not outside
35
+ // If it satisfies the range it is not outside
36
36
  if (satisfies(version, range, options)) {
37
37
  return false
38
38
  }
package/ranges/subset.js CHANGED
@@ -21,15 +21,18 @@ const compare = require('../functions/compare.js')
21
21
  // - If EQ satisfies every C, return true
22
22
  // - Else return false
23
23
  // - If GT
24
- // - If GT is lower than any > or >= comp in C, return false
24
+ // - If GT.semver is lower than any > or >= comp in C, return false
25
25
  // - If GT is >=, and GT.semver does not satisfy every C, return false
26
26
  // - If LT
27
- // - If LT.semver is greater than that of any > comp in C, return false
27
+ // - If LT.semver is greater than any < or <= comp in C, return false
28
28
  // - If LT is <=, and LT.semver does not satisfy every C, return false
29
29
  // - If any C is a = range, and GT or LT are set, return false
30
30
  // - Else return true
31
31
 
32
32
  const subset = (sub, dom, options) => {
33
+ if (sub === dom)
34
+ return true
35
+
33
36
  sub = new Range(sub, options)
34
37
  dom = new Range(dom, options)
35
38
  let sawNonNull = false
@@ -52,6 +55,9 @@ const subset = (sub, dom, options) => {
52
55
  }
53
56
 
54
57
  const simpleSubset = (sub, dom, options) => {
58
+ if (sub === dom)
59
+ return true
60
+
55
61
  if (sub.length === 1 && sub[0].semver === ANY)
56
62
  return dom.length === 1 && dom[0].semver === ANY
57
63
 
@@ -90,6 +96,7 @@ const simpleSubset = (sub, dom, options) => {
90
96
  if (!satisfies(eq, String(c), options))
91
97
  return false
92
98
  }
99
+
93
100
  return true
94
101
  }
95
102
 
@@ -101,7 +108,7 @@ const simpleSubset = (sub, dom, options) => {
101
108
  if (gt) {
102
109
  if (c.operator === '>' || c.operator === '>=') {
103
110
  higher = higherGT(gt, c, options)
104
- if (higher === c)
111
+ if (higher === c && higher !== gt)
105
112
  return false
106
113
  } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options))
107
114
  return false
@@ -109,7 +116,7 @@ const simpleSubset = (sub, dom, options) => {
109
116
  if (lt) {
110
117
  if (c.operator === '<' || c.operator === '<=') {
111
118
  lower = lowerLT(lt, c, options)
112
- if (lower === c)
119
+ if (lower === c && lower !== lt)
113
120
  return false
114
121
  } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options))
115
122
  return false