semver 5.4.0 → 5.6.0

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
@@ -20,6 +20,8 @@ semver.clean(' =v1.2.3 ') // '1.2.3'
20
20
  semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
21
21
  semver.gt('1.2.3', '9.8.7') // false
22
22
  semver.lt('1.2.3', '9.8.7') // true
23
+ semver.valid(semver.coerce('v2')) // '2.0.0'
24
+ semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
23
25
  ```
24
26
 
25
27
  As a command-line utility:
@@ -27,8 +29,6 @@ As a command-line utility:
27
29
  ```
28
30
  $ semver -h
29
31
 
30
- SemVer 5.3.0
31
-
32
32
  A JavaScript implementation of the http://semver.org/ specification
33
33
  Copyright Isaac Z. Schlueter
34
34
 
@@ -52,6 +52,13 @@ Options:
52
52
  -l --loose
53
53
  Interpret versions and ranges loosely
54
54
 
55
+ -p --include-prerelease
56
+ Always include prerelease versions in range matching
57
+
58
+ -c --coerce
59
+ Coerce a string into SemVer if possible
60
+ (does not imply --loose)
61
+
55
62
  Program exits successfully if any valid version satisfies
56
63
  all supplied ranges, and prints all satisfying versions.
57
64
 
@@ -268,7 +275,7 @@ logical-or ::= ( ' ' ) * '||' ( ' ' ) *
268
275
  range ::= hyphen | simple ( ' ' simple ) * | ''
269
276
  hyphen ::= partial ' - ' partial
270
277
  simple ::= primitive | partial | tilde | caret
271
- primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | ) partial
278
+ primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
272
279
  partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
273
280
  xr ::= 'x' | 'X' | '*' | nr
274
281
  nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
@@ -283,9 +290,19 @@ part ::= nr | [-0-9A-Za-z]+
283
290
 
284
291
  ## Functions
285
292
 
286
- All methods and classes take a final `loose` boolean argument that, if
287
- true, will be more forgiving about not-quite-valid semver strings.
288
- The resulting output will always be 100% strict, of course.
293
+ All methods and classes take a final `options` object argument. All
294
+ options in this object are `false` by default. The options supported
295
+ are:
296
+
297
+ - `loose` Be more forgiving about not-quite-valid semver strings.
298
+ (Any resulting output will always be 100% strict compliant, of
299
+ course.) For backwards compatibility reasons, if the `options`
300
+ argument is a boolean value instead of an object, it is interpreted
301
+ to be the `loose` param.
302
+ - `includePrerelease` Set to suppress the [default
303
+ behavior](https://github.com/npm/node-semver#prerelease-tags) of
304
+ excluding prerelease tagged versions from ranges unless they are
305
+ explicitly opted into.
289
306
 
290
307
  Strict-mode Comparators and Ranges will be strict about the SemVer
291
308
  strings that they parse.
@@ -364,3 +381,19 @@ satisfy the range.
364
381
 
365
382
  If you want to know if a version satisfies or does not satisfy a
366
383
  range, use the `satisfies(version, range)` function.
384
+
385
+ ### Coercion
386
+
387
+ * `coerce(version)`: Coerces a string to semver if possible
388
+
389
+ This aims to provide a very forgiving translation of a non-semver
390
+ string to semver. It looks for the first digit in a string, and
391
+ consumes all remaining characters which satisfy at least a partial semver
392
+ (e.g., `1`, `1.2`, `1.2.3`) up to the max permitted length (256 characters).
393
+ Longer versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`).
394
+ All surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes `3.4.0`).
395
+ Only text which lacks digits will fail coercion (`version one` is not valid).
396
+ The maximum length for any semver component considered for coercion is 16 characters;
397
+ longer components will be ignored (`10000000000000000.4.7.4` becomes `4.7.4`).
398
+ The maximum value for any semver component is `Integer.MAX_SAFE_INTEGER || (2**53 - 1)`;
399
+ higher value components are invalid (`9999999999999999.4.7.4` is likely invalid).
package/bin/semver CHANGED
@@ -12,9 +12,12 @@ var argv = process.argv.slice(2)
12
12
  , inc = null
13
13
  , version = require("../package.json").version
14
14
  , loose = false
15
+ , includePrerelease = false
16
+ , coerce = false
15
17
  , identifier = undefined
16
18
  , semver = require("../semver")
17
19
  , reverse = false
20
+ , options = {}
18
21
 
19
22
  main()
20
23
 
@@ -34,6 +37,9 @@ function main () {
34
37
  case "-l": case "--loose":
35
38
  loose = true
36
39
  break
40
+ case "-p": case "--include-prerelease":
41
+ includePrerelease = true
42
+ break
37
43
  case "-v": case "--version":
38
44
  versions.push(argv.shift())
39
45
  break
@@ -54,6 +60,9 @@ function main () {
54
60
  case "-r": case "--range":
55
61
  range.push(argv.shift())
56
62
  break
63
+ case "-c": case "--coerce":
64
+ coerce = true
65
+ break
57
66
  case "-h": case "--help": case "-?":
58
67
  return help()
59
68
  default:
@@ -62,8 +71,12 @@ function main () {
62
71
  }
63
72
  }
64
73
 
65
- versions = versions.filter(function (v) {
66
- return semver.valid(v, loose)
74
+ var options = { loose: loose, includePrerelease: includePrerelease }
75
+
76
+ versions = versions.map(function (v) {
77
+ return coerce ? (semver.coerce(v) || {version: v}).version : v
78
+ }).filter(function (v) {
79
+ return semver.valid(v)
67
80
  })
68
81
  if (!versions.length) return fail()
69
82
  if (inc && (versions.length !== 1 || range.length))
@@ -71,7 +84,7 @@ function main () {
71
84
 
72
85
  for (var i = 0, l = range.length; i < l ; i ++) {
73
86
  versions = versions.filter(function (v) {
74
- return semver.satisfies(v, range[i], loose)
87
+ return semver.satisfies(v, range[i], options)
75
88
  })
76
89
  if (!versions.length) return fail()
77
90
  }
@@ -88,11 +101,11 @@ function fail () { process.exit(1) }
88
101
  function success () {
89
102
  var compare = reverse ? "rcompare" : "compare"
90
103
  versions.sort(function (a, b) {
91
- return semver[compare](a, b, loose)
104
+ return semver[compare](a, b, options)
92
105
  }).map(function (v) {
93
- return semver.clean(v, loose)
106
+ return semver.clean(v, options)
94
107
  }).map(function (v) {
95
- return inc ? semver.inc(v, inc, loose, identifier) : v
108
+ return inc ? semver.inc(v, inc, options, identifier) : v
96
109
  }).forEach(function (v,i,_) { console.log(v) })
97
110
  }
98
111
 
@@ -122,6 +135,13 @@ function help () {
122
135
  ,"-l --loose"
123
136
  ," Interpret versions and ranges loosely"
124
137
  ,""
138
+ ,"-p --include-prerelease"
139
+ ," Always include prerelease versions in range matching"
140
+ ,""
141
+ ,"-c --coerce"
142
+ ," Coerce a string into SemVer if possible"
143
+ ," (does not imply --loose)"
144
+ ,""
125
145
  ,"Program exits successfully if any valid version satisfies"
126
146
  ,"all supplied ranges, and prints all satisfying versions."
127
147
  ,""
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "semver",
3
- "version": "5.4.0",
3
+ "version": "5.6.0",
4
4
  "description": "The semantic version parser used by npm.",
5
5
  "main": "semver.js",
6
6
  "scripts": {
7
7
  "test": "tap test/*.js --cov -J"
8
8
  },
9
9
  "devDependencies": {
10
- "tap": "^10.7.0"
10
+ "tap": "^12.0.1"
11
11
  },
12
12
  "license": "ISC",
13
13
  "repository": "https://github.com/npm/node-semver",
package/range.bnf CHANGED
@@ -3,10 +3,10 @@ logical-or ::= ( ' ' ) * '||' ( ' ' ) *
3
3
  range ::= hyphen | simple ( ' ' simple ) * | ''
4
4
  hyphen ::= partial ' - ' partial
5
5
  simple ::= primitive | partial | tilde | caret
6
- primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | ) partial
6
+ primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
7
7
  partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
8
8
  xr ::= 'x' | 'X' | '*' | nr
9
- nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
9
+ nr ::= '0' | [1-9] ( [0-9] ) *
10
10
  tilde ::= '~' partial
11
11
  caret ::= '^' partial
12
12
  qualifier ::= ( '-' pre )? ( '+' build )?
package/semver.js CHANGED
@@ -21,6 +21,9 @@ exports.SEMVER_SPEC_VERSION = '2.0.0';
21
21
  var MAX_LENGTH = 256;
22
22
  var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
23
23
 
24
+ // Max safe segment length for coercion.
25
+ var MAX_SAFE_COMPONENT_LENGTH = 16;
26
+
24
27
  // The actual regexps go on exports.re
25
28
  var re = exports.re = [];
26
29
  var src = exports.src = [];
@@ -156,6 +159,15 @@ src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
156
159
  var XRANGELOOSE = R++;
157
160
  src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
158
161
 
162
+ // Coercion.
163
+ // Extract anything that could conceivably be a part of a valid semver
164
+ var COERCE = R++;
165
+ src[COERCE] = '(?:^|[^\\d])' +
166
+ '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' +
167
+ '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
168
+ '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
169
+ '(?:$|[^\\d])';
170
+
159
171
  // Tilde ranges.
160
172
  // Meaning is "reasonably at or greater than"
161
173
  var LONETILDE = R++;
@@ -233,7 +245,10 @@ for (var i = 0; i < R; i++) {
233
245
  }
234
246
 
235
247
  exports.parse = parse;
236
- function parse(version, loose) {
248
+ function parse(version, options) {
249
+ if (!options || typeof options !== 'object')
250
+ options = { loose: !!options, includePrerelease: false }
251
+
237
252
  if (version instanceof SemVer)
238
253
  return version;
239
254
 
@@ -243,35 +258,37 @@ function parse(version, loose) {
243
258
  if (version.length > MAX_LENGTH)
244
259
  return null;
245
260
 
246
- var r = loose ? re[LOOSE] : re[FULL];
261
+ var r = options.loose ? re[LOOSE] : re[FULL];
247
262
  if (!r.test(version))
248
263
  return null;
249
264
 
250
265
  try {
251
- return new SemVer(version, loose);
266
+ return new SemVer(version, options);
252
267
  } catch (er) {
253
268
  return null;
254
269
  }
255
270
  }
256
271
 
257
272
  exports.valid = valid;
258
- function valid(version, loose) {
259
- var v = parse(version, loose);
273
+ function valid(version, options) {
274
+ var v = parse(version, options);
260
275
  return v ? v.version : null;
261
276
  }
262
277
 
263
278
 
264
279
  exports.clean = clean;
265
- function clean(version, loose) {
266
- var s = parse(version.trim().replace(/^[=v]+/, ''), loose);
280
+ function clean(version, options) {
281
+ var s = parse(version.trim().replace(/^[=v]+/, ''), options);
267
282
  return s ? s.version : null;
268
283
  }
269
284
 
270
285
  exports.SemVer = SemVer;
271
286
 
272
- function SemVer(version, loose) {
287
+ function SemVer(version, options) {
288
+ if (!options || typeof options !== 'object')
289
+ options = { loose: !!options, includePrerelease: false }
273
290
  if (version instanceof SemVer) {
274
- if (version.loose === loose)
291
+ if (version.loose === options.loose)
275
292
  return version;
276
293
  else
277
294
  version = version.version;
@@ -283,11 +300,13 @@ function SemVer(version, loose) {
283
300
  throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters')
284
301
 
285
302
  if (!(this instanceof SemVer))
286
- return new SemVer(version, loose);
303
+ return new SemVer(version, options);
304
+
305
+ debug('SemVer', version, options);
306
+ this.options = options;
307
+ this.loose = !!options.loose;
287
308
 
288
- debug('SemVer', version, loose);
289
- this.loose = loose;
290
- var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
309
+ var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]);
291
310
 
292
311
  if (!m)
293
312
  throw new TypeError('Invalid Version: ' + version);
@@ -337,16 +356,16 @@ SemVer.prototype.toString = function() {
337
356
  };
338
357
 
339
358
  SemVer.prototype.compare = function(other) {
340
- debug('SemVer.compare', this.version, this.loose, other);
359
+ debug('SemVer.compare', this.version, this.options, other);
341
360
  if (!(other instanceof SemVer))
342
- other = new SemVer(other, this.loose);
361
+ other = new SemVer(other, this.options);
343
362
 
344
363
  return this.compareMain(other) || this.comparePre(other);
345
364
  };
346
365
 
347
366
  SemVer.prototype.compareMain = function(other) {
348
367
  if (!(other instanceof SemVer))
349
- other = new SemVer(other, this.loose);
368
+ other = new SemVer(other, this.options);
350
369
 
351
370
  return compareIdentifiers(this.major, other.major) ||
352
371
  compareIdentifiers(this.minor, other.minor) ||
@@ -355,7 +374,7 @@ SemVer.prototype.compareMain = function(other) {
355
374
 
356
375
  SemVer.prototype.comparePre = function(other) {
357
376
  if (!(other instanceof SemVer))
358
- other = new SemVer(other, this.loose);
377
+ other = new SemVer(other, this.options);
359
378
 
360
379
  // NOT having a prerelease is > having one
361
380
  if (this.prerelease.length && !other.prerelease.length)
@@ -646,19 +665,23 @@ function cmp(a, op, b, loose) {
646
665
  }
647
666
 
648
667
  exports.Comparator = Comparator;
649
- function Comparator(comp, loose) {
668
+ function Comparator(comp, options) {
669
+ if (!options || typeof options !== 'object')
670
+ options = { loose: !!options, includePrerelease: false }
671
+
650
672
  if (comp instanceof Comparator) {
651
- if (comp.loose === loose)
673
+ if (comp.loose === !!options.loose)
652
674
  return comp;
653
675
  else
654
676
  comp = comp.value;
655
677
  }
656
678
 
657
679
  if (!(this instanceof Comparator))
658
- return new Comparator(comp, loose);
680
+ return new Comparator(comp, options);
659
681
 
660
- debug('comparator', comp, loose);
661
- this.loose = loose;
682
+ debug('comparator', comp, options);
683
+ this.options = options;
684
+ this.loose = !!options.loose;
662
685
  this.parse(comp);
663
686
 
664
687
  if (this.semver === ANY)
@@ -671,7 +694,7 @@ function Comparator(comp, loose) {
671
694
 
672
695
  var ANY = {};
673
696
  Comparator.prototype.parse = function(comp) {
674
- var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
697
+ var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
675
698
  var m = comp.match(r);
676
699
 
677
700
  if (!m)
@@ -685,7 +708,7 @@ Comparator.prototype.parse = function(comp) {
685
708
  if (!m[2])
686
709
  this.semver = ANY;
687
710
  else
688
- this.semver = new SemVer(m[2], this.loose);
711
+ this.semver = new SemVer(m[2], this.options.loose);
689
712
  };
690
713
 
691
714
  Comparator.prototype.toString = function() {
@@ -693,30 +716,33 @@ Comparator.prototype.toString = function() {
693
716
  };
694
717
 
695
718
  Comparator.prototype.test = function(version) {
696
- debug('Comparator.test', version, this.loose);
719
+ debug('Comparator.test', version, this.options.loose);
697
720
 
698
721
  if (this.semver === ANY)
699
722
  return true;
700
723
 
701
724
  if (typeof version === 'string')
702
- version = new SemVer(version, this.loose);
725
+ version = new SemVer(version, this.options);
703
726
 
704
- return cmp(version, this.operator, this.semver, this.loose);
727
+ return cmp(version, this.operator, this.semver, this.options);
705
728
  };
706
729
 
707
- Comparator.prototype.intersects = function(comp, loose) {
730
+ Comparator.prototype.intersects = function(comp, options) {
708
731
  if (!(comp instanceof Comparator)) {
709
732
  throw new TypeError('a Comparator is required');
710
733
  }
711
734
 
735
+ if (!options || typeof options !== 'object')
736
+ options = { loose: !!options, includePrerelease: false }
737
+
712
738
  var rangeTmp;
713
739
 
714
740
  if (this.operator === '') {
715
- rangeTmp = new Range(comp.value, loose);
716
- return satisfies(this.value, rangeTmp, loose);
741
+ rangeTmp = new Range(comp.value, options);
742
+ return satisfies(this.value, rangeTmp, options);
717
743
  } else if (comp.operator === '') {
718
- rangeTmp = new Range(this.value, loose);
719
- return satisfies(comp.semver, rangeTmp, loose);
744
+ rangeTmp = new Range(this.value, options);
745
+ return satisfies(comp.semver, rangeTmp, options);
720
746
  }
721
747
 
722
748
  var sameDirectionIncreasing =
@@ -730,11 +756,11 @@ Comparator.prototype.intersects = function(comp, loose) {
730
756
  (this.operator === '>=' || this.operator === '<=') &&
731
757
  (comp.operator === '>=' || comp.operator === '<=');
732
758
  var oppositeDirectionsLessThan =
733
- cmp(this.semver, '<', comp.semver, loose) &&
759
+ cmp(this.semver, '<', comp.semver, options) &&
734
760
  ((this.operator === '>=' || this.operator === '>') &&
735
761
  (comp.operator === '<=' || comp.operator === '<'));
736
762
  var oppositeDirectionsGreaterThan =
737
- cmp(this.semver, '>', comp.semver, loose) &&
763
+ cmp(this.semver, '>', comp.semver, options) &&
738
764
  ((this.operator === '<=' || this.operator === '<') &&
739
765
  (comp.operator === '>=' || comp.operator === '>'));
740
766
 
@@ -745,23 +771,29 @@ Comparator.prototype.intersects = function(comp, loose) {
745
771
 
746
772
 
747
773
  exports.Range = Range;
748
- function Range(range, loose) {
774
+ function Range(range, options) {
775
+ if (!options || typeof options !== 'object')
776
+ options = { loose: !!options, includePrerelease: false }
777
+
749
778
  if (range instanceof Range) {
750
- if (range.loose === loose) {
779
+ if (range.loose === !!options.loose &&
780
+ range.includePrerelease === !!options.includePrerelease) {
751
781
  return range;
752
782
  } else {
753
- return new Range(range.raw, loose);
783
+ return new Range(range.raw, options);
754
784
  }
755
785
  }
756
786
 
757
787
  if (range instanceof Comparator) {
758
- return new Range(range.value, loose);
788
+ return new Range(range.value, options);
759
789
  }
760
790
 
761
791
  if (!(this instanceof Range))
762
- return new Range(range, loose);
792
+ return new Range(range, options);
763
793
 
764
- this.loose = loose;
794
+ this.options = options;
795
+ this.loose = !!options.loose;
796
+ this.includePrerelease = !!options.includePrerelease
765
797
 
766
798
  // First, split based on boolean or ||
767
799
  this.raw = range;
@@ -791,9 +823,8 @@ Range.prototype.toString = function() {
791
823
  };
792
824
 
793
825
  Range.prototype.parseRange = function(range) {
794
- var loose = this.loose;
826
+ var loose = this.options.loose;
795
827
  range = range.trim();
796
- debug('range', range, loose);
797
828
  // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
798
829
  var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
799
830
  range = range.replace(hr, hyphenReplace);
@@ -816,22 +847,22 @@ Range.prototype.parseRange = function(range) {
816
847
 
817
848
  var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
818
849
  var set = range.split(' ').map(function(comp) {
819
- return parseComparator(comp, loose);
820
- }).join(' ').split(/\s+/);
821
- if (this.loose) {
850
+ return parseComparator(comp, this.options);
851
+ }, this).join(' ').split(/\s+/);
852
+ if (this.options.loose) {
822
853
  // in loose mode, throw out any that are not valid comparators
823
854
  set = set.filter(function(comp) {
824
855
  return !!comp.match(compRe);
825
856
  });
826
857
  }
827
858
  set = set.map(function(comp) {
828
- return new Comparator(comp, loose);
829
- });
859
+ return new Comparator(comp, this.options);
860
+ }, this);
830
861
 
831
862
  return set;
832
863
  };
833
864
 
834
- Range.prototype.intersects = function(range, loose) {
865
+ Range.prototype.intersects = function(range, options) {
835
866
  if (!(range instanceof Range)) {
836
867
  throw new TypeError('a Range is required');
837
868
  }
@@ -840,7 +871,7 @@ Range.prototype.intersects = function(range, loose) {
840
871
  return thisComparators.every(function(thisComparator) {
841
872
  return range.set.some(function(rangeComparators) {
842
873
  return rangeComparators.every(function(rangeComparator) {
843
- return thisComparator.intersects(rangeComparator, loose);
874
+ return thisComparator.intersects(rangeComparator, options);
844
875
  });
845
876
  });
846
877
  });
@@ -849,8 +880,8 @@ Range.prototype.intersects = function(range, loose) {
849
880
 
850
881
  // Mostly just for testing and legacy API reasons
851
882
  exports.toComparators = toComparators;
852
- function toComparators(range, loose) {
853
- return new Range(range, loose).set.map(function(comp) {
883
+ function toComparators(range, options) {
884
+ return new Range(range, options).set.map(function(comp) {
854
885
  return comp.map(function(c) {
855
886
  return c.value;
856
887
  }).join(' ').trim().split(' ');
@@ -860,15 +891,15 @@ function toComparators(range, loose) {
860
891
  // comprised of xranges, tildes, stars, and gtlt's at this point.
861
892
  // already replaced the hyphen ranges
862
893
  // turn into a set of JUST comparators.
863
- function parseComparator(comp, loose) {
864
- debug('comp', comp);
865
- comp = replaceCarets(comp, loose);
894
+ function parseComparator(comp, options) {
895
+ debug('comp', comp, options);
896
+ comp = replaceCarets(comp, options);
866
897
  debug('caret', comp);
867
- comp = replaceTildes(comp, loose);
898
+ comp = replaceTildes(comp, options);
868
899
  debug('tildes', comp);
869
- comp = replaceXRanges(comp, loose);
900
+ comp = replaceXRanges(comp, options);
870
901
  debug('xrange', comp);
871
- comp = replaceStars(comp, loose);
902
+ comp = replaceStars(comp, options);
872
903
  debug('stars', comp);
873
904
  return comp;
874
905
  }
@@ -883,14 +914,16 @@ function isX(id) {
883
914
  // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
884
915
  // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
885
916
  // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
886
- function replaceTildes(comp, loose) {
917
+ function replaceTildes(comp, options) {
887
918
  return comp.trim().split(/\s+/).map(function(comp) {
888
- return replaceTilde(comp, loose);
919
+ return replaceTilde(comp, options);
889
920
  }).join(' ');
890
921
  }
891
922
 
892
- function replaceTilde(comp, loose) {
893
- var r = loose ? re[TILDELOOSE] : re[TILDE];
923
+ function replaceTilde(comp, options) {
924
+ if (!options || typeof options !== 'object')
925
+ options = { loose: !!options, includePrerelease: false }
926
+ var r = options.loose ? re[TILDELOOSE] : re[TILDE];
894
927
  return comp.replace(r, function(_, M, m, p, pr) {
895
928
  debug('tilde', comp, _, M, m, p, pr);
896
929
  var ret;
@@ -924,15 +957,17 @@ function replaceTilde(comp, loose) {
924
957
  // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
925
958
  // ^1.2.3 --> >=1.2.3 <2.0.0
926
959
  // ^1.2.0 --> >=1.2.0 <2.0.0
927
- function replaceCarets(comp, loose) {
960
+ function replaceCarets(comp, options) {
928
961
  return comp.trim().split(/\s+/).map(function(comp) {
929
- return replaceCaret(comp, loose);
962
+ return replaceCaret(comp, options);
930
963
  }).join(' ');
931
964
  }
932
965
 
933
- function replaceCaret(comp, loose) {
934
- debug('caret', comp, loose);
935
- var r = loose ? re[CARETLOOSE] : re[CARET];
966
+ function replaceCaret(comp, options) {
967
+ debug('caret', comp, options);
968
+ if (!options || typeof options !== 'object')
969
+ options = { loose: !!options, includePrerelease: false }
970
+ var r = options.loose ? re[CARETLOOSE] : re[CARET];
936
971
  return comp.replace(r, function(_, M, m, p, pr) {
937
972
  debug('caret', comp, _, M, m, p, pr);
938
973
  var ret;
@@ -979,16 +1014,18 @@ function replaceCaret(comp, loose) {
979
1014
  });
980
1015
  }
981
1016
 
982
- function replaceXRanges(comp, loose) {
983
- debug('replaceXRanges', comp, loose);
1017
+ function replaceXRanges(comp, options) {
1018
+ debug('replaceXRanges', comp, options);
984
1019
  return comp.split(/\s+/).map(function(comp) {
985
- return replaceXRange(comp, loose);
1020
+ return replaceXRange(comp, options);
986
1021
  }).join(' ');
987
1022
  }
988
1023
 
989
- function replaceXRange(comp, loose) {
1024
+ function replaceXRange(comp, options) {
990
1025
  comp = comp.trim();
991
- var r = loose ? re[XRANGELOOSE] : re[XRANGE];
1026
+ if (!options || typeof options !== 'object')
1027
+ options = { loose: !!options, includePrerelease: false }
1028
+ var r = options.loose ? re[XRANGELOOSE] : re[XRANGE];
992
1029
  return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
993
1030
  debug('xRange', comp, ret, gtlt, M, m, p, pr);
994
1031
  var xM = isX(M);
@@ -1052,8 +1089,8 @@ function replaceXRange(comp, loose) {
1052
1089
 
1053
1090
  // Because * is AND-ed with everything else in the comparator,
1054
1091
  // and '' means "any version", just remove the *s entirely.
1055
- function replaceStars(comp, loose) {
1056
- debug('replaceStars', comp, loose);
1092
+ function replaceStars(comp, options) {
1093
+ debug('replaceStars', comp, options);
1057
1094
  // Looseness is ignored here. star is always as loose as it gets!
1058
1095
  return comp.trim().replace(re[STAR], '');
1059
1096
  }
@@ -1097,22 +1134,25 @@ Range.prototype.test = function(version) {
1097
1134
  return false;
1098
1135
 
1099
1136
  if (typeof version === 'string')
1100
- version = new SemVer(version, this.loose);
1137
+ version = new SemVer(version, this.options);
1101
1138
 
1102
1139
  for (var i = 0; i < this.set.length; i++) {
1103
- if (testSet(this.set[i], version))
1140
+ if (testSet(this.set[i], version, this.options))
1104
1141
  return true;
1105
1142
  }
1106
1143
  return false;
1107
1144
  };
1108
1145
 
1109
- function testSet(set, version) {
1146
+ function testSet(set, version, options) {
1110
1147
  for (var i = 0; i < set.length; i++) {
1111
1148
  if (!set[i].test(version))
1112
1149
  return false;
1113
1150
  }
1114
1151
 
1115
- if (version.prerelease.length) {
1152
+ if (!options)
1153
+ options = {}
1154
+
1155
+ if (version.prerelease.length && !options.includePrerelease) {
1116
1156
  // Find the set of versions that are allowed to have prereleases
1117
1157
  // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
1118
1158
  // That should allow `1.2.3-pr.2` to pass.
@@ -1140,9 +1180,9 @@ function testSet(set, version) {
1140
1180
  }
1141
1181
 
1142
1182
  exports.satisfies = satisfies;
1143
- function satisfies(version, range, loose) {
1183
+ function satisfies(version, range, options) {
1144
1184
  try {
1145
- range = new Range(range, loose);
1185
+ range = new Range(range, options);
1146
1186
  } catch (er) {
1147
1187
  return false;
1148
1188
  }
@@ -1150,15 +1190,19 @@ function satisfies(version, range, loose) {
1150
1190
  }
1151
1191
 
1152
1192
  exports.maxSatisfying = maxSatisfying;
1153
- function maxSatisfying(versions, range, loose) {
1193
+ function maxSatisfying(versions, range, options) {
1154
1194
  var max = null;
1155
1195
  var maxSV = null;
1156
- var rangeObj = new Range(range, loose);
1196
+ try {
1197
+ var rangeObj = new Range(range, options);
1198
+ } catch (er) {
1199
+ return null;
1200
+ }
1157
1201
  versions.forEach(function (v) {
1158
- if (rangeObj.test(v)) { // satisfies(v, range, loose)
1202
+ if (rangeObj.test(v)) { // satisfies(v, range, options)
1159
1203
  if (!max || maxSV.compare(v) === -1) { // compare(max, v, true)
1160
1204
  max = v;
1161
- maxSV = new SemVer(max, loose);
1205
+ maxSV = new SemVer(max, options);
1162
1206
  }
1163
1207
  }
1164
1208
  })
@@ -1166,15 +1210,19 @@ function maxSatisfying(versions, range, loose) {
1166
1210
  }
1167
1211
 
1168
1212
  exports.minSatisfying = minSatisfying;
1169
- function minSatisfying(versions, range, loose) {
1213
+ function minSatisfying(versions, range, options) {
1170
1214
  var min = null;
1171
1215
  var minSV = null;
1172
- var rangeObj = new Range(range, loose);
1216
+ try {
1217
+ var rangeObj = new Range(range, options);
1218
+ } catch (er) {
1219
+ return null;
1220
+ }
1173
1221
  versions.forEach(function (v) {
1174
- if (rangeObj.test(v)) { // satisfies(v, range, loose)
1222
+ if (rangeObj.test(v)) { // satisfies(v, range, options)
1175
1223
  if (!min || minSV.compare(v) === 1) { // compare(min, v, true)
1176
1224
  min = v;
1177
- minSV = new SemVer(min, loose);
1225
+ minSV = new SemVer(min, options);
1178
1226
  }
1179
1227
  }
1180
1228
  })
@@ -1182,11 +1230,11 @@ function minSatisfying(versions, range, loose) {
1182
1230
  }
1183
1231
 
1184
1232
  exports.validRange = validRange;
1185
- function validRange(range, loose) {
1233
+ function validRange(range, options) {
1186
1234
  try {
1187
1235
  // Return '*' instead of '' so that truthiness works.
1188
1236
  // This will throw if it's invalid anyway
1189
- return new Range(range, loose).range || '*';
1237
+ return new Range(range, options).range || '*';
1190
1238
  } catch (er) {
1191
1239
  return null;
1192
1240
  }
@@ -1194,20 +1242,20 @@ function validRange(range, loose) {
1194
1242
 
1195
1243
  // Determine if version is less than all the versions possible in the range
1196
1244
  exports.ltr = ltr;
1197
- function ltr(version, range, loose) {
1198
- return outside(version, range, '<', loose);
1245
+ function ltr(version, range, options) {
1246
+ return outside(version, range, '<', options);
1199
1247
  }
1200
1248
 
1201
1249
  // Determine if version is greater than all the versions possible in the range.
1202
1250
  exports.gtr = gtr;
1203
- function gtr(version, range, loose) {
1204
- return outside(version, range, '>', loose);
1251
+ function gtr(version, range, options) {
1252
+ return outside(version, range, '>', options);
1205
1253
  }
1206
1254
 
1207
1255
  exports.outside = outside;
1208
- function outside(version, range, hilo, loose) {
1209
- version = new SemVer(version, loose);
1210
- range = new Range(range, loose);
1256
+ function outside(version, range, hilo, options) {
1257
+ version = new SemVer(version, options);
1258
+ range = new Range(range, options);
1211
1259
 
1212
1260
  var gtfn, ltefn, ltfn, comp, ecomp;
1213
1261
  switch (hilo) {
@@ -1230,7 +1278,7 @@ function outside(version, range, hilo, loose) {
1230
1278
  }
1231
1279
 
1232
1280
  // If it satisifes the range it is not outside
1233
- if (satisfies(version, range, loose)) {
1281
+ if (satisfies(version, range, options)) {
1234
1282
  return false;
1235
1283
  }
1236
1284
 
@@ -1249,9 +1297,9 @@ function outside(version, range, hilo, loose) {
1249
1297
  }
1250
1298
  high = high || comparator;
1251
1299
  low = low || comparator;
1252
- if (gtfn(comparator.semver, high.semver, loose)) {
1300
+ if (gtfn(comparator.semver, high.semver, options)) {
1253
1301
  high = comparator;
1254
- } else if (ltfn(comparator.semver, low.semver, loose)) {
1302
+ } else if (ltfn(comparator.semver, low.semver, options)) {
1255
1303
  low = comparator;
1256
1304
  }
1257
1305
  });
@@ -1275,14 +1323,30 @@ function outside(version, range, hilo, loose) {
1275
1323
  }
1276
1324
 
1277
1325
  exports.prerelease = prerelease;
1278
- function prerelease(version, loose) {
1279
- var parsed = parse(version, loose);
1326
+ function prerelease(version, options) {
1327
+ var parsed = parse(version, options);
1280
1328
  return (parsed && parsed.prerelease.length) ? parsed.prerelease : null;
1281
1329
  }
1282
1330
 
1283
1331
  exports.intersects = intersects;
1284
- function intersects(r1, r2, loose) {
1285
- r1 = new Range(r1, loose)
1286
- r2 = new Range(r2, loose)
1332
+ function intersects(r1, r2, options) {
1333
+ r1 = new Range(r1, options)
1334
+ r2 = new Range(r2, options)
1287
1335
  return r1.intersects(r2)
1288
1336
  }
1337
+
1338
+ exports.coerce = coerce;
1339
+ function coerce(version) {
1340
+ if (version instanceof SemVer)
1341
+ return version;
1342
+
1343
+ if (typeof version !== 'string')
1344
+ return null;
1345
+
1346
+ var match = version.match(re[COERCE]);
1347
+
1348
+ if (match == null)
1349
+ return null;
1350
+
1351
+ return parse((match[1] || '0') + '.' + (match[2] || '0') + '.' + (match[3] || '0'));
1352
+ }