semver 5.2.0 → 5.5.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
@@ -1,53 +1,71 @@
1
1
  semver(1) -- The semantic versioner for npm
2
2
  ===========================================
3
3
 
4
+ ## Install
5
+
6
+ ```bash
7
+ npm install --save semver
8
+ ````
9
+
4
10
  ## Usage
5
11
 
6
- $ npm install semver
12
+ As a node module:
7
13
 
8
- semver.valid('1.2.3') // '1.2.3'
9
- semver.valid('a.b.c') // null
10
- semver.clean(' =v1.2.3 ') // '1.2.3'
11
- semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
12
- semver.gt('1.2.3', '9.8.7') // false
13
- semver.lt('1.2.3', '9.8.7') // true
14
+ ```js
15
+ const semver = require('semver')
16
+
17
+ semver.valid('1.2.3') // '1.2.3'
18
+ semver.valid('a.b.c') // null
19
+ semver.clean(' =v1.2.3 ') // '1.2.3'
20
+ semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
21
+ semver.gt('1.2.3', '9.8.7') // false
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'
25
+ ```
14
26
 
15
27
  As a command-line utility:
16
28
 
17
- $ semver -h
29
+ ```
30
+ $ semver -h
31
+
32
+ SemVer 5.3.0
18
33
 
19
- SemVer 5.1.0
34
+ A JavaScript implementation of the http://semver.org/ specification
35
+ Copyright Isaac Z. Schlueter
20
36
 
21
- A JavaScript implementation of the http://semver.org/ specification
22
- Copyright Isaac Z. Schlueter
37
+ Usage: semver [options] <version> [<version> [...]]
38
+ Prints valid versions sorted by SemVer precedence
23
39
 
24
- Usage: semver [options] <version> [<version> [...]]
25
- Prints valid versions sorted by SemVer precedence
40
+ Options:
41
+ -r --range <range>
42
+ Print versions that match the specified range.
26
43
 
27
- Options:
28
- -r --range <range>
29
- Print versions that match the specified range.
44
+ -i --increment [<level>]
45
+ Increment a version by the specified level. Level can
46
+ be one of: major, minor, patch, premajor, preminor,
47
+ prepatch, or prerelease. Default level is 'patch'.
48
+ Only one version may be specified.
30
49
 
31
- -i --increment [<level>]
32
- Increment a version by the specified level. Level can
33
- be one of: major, minor, patch, premajor, preminor,
34
- prepatch, or prerelease. Default level is 'patch'.
35
- Only one version may be specified.
50
+ --preid <identifier>
51
+ Identifier to be used to prefix premajor, preminor,
52
+ prepatch or prerelease version increments.
36
53
 
37
- --preid <identifier>
38
- Identifier to be used to prefix premajor, preminor,
39
- prepatch or prerelease version increments.
54
+ -l --loose
55
+ Interpret versions and ranges loosely
40
56
 
41
- -l --loose
42
- Interpret versions and ranges loosely
57
+ -c --coerce
58
+ Coerce a string into SemVer if possible
59
+ (does not imply --loose)
43
60
 
44
- Program exits successfully if any valid version satisfies
45
- all supplied ranges, and prints all satisfying versions.
61
+ Program exits successfully if any valid version satisfies
62
+ all supplied ranges, and prints all satisfying versions.
46
63
 
47
- If no satisfying versions are found, then exits failure.
64
+ If no satisfying versions are found, then exits failure.
48
65
 
49
- Versions are printed in ascending order, so supplying
50
- multiple versions to the utility will just sort them.
66
+ Versions are printed in ascending order, so supplying
67
+ multiple versions to the utility will just sort them.
68
+ ```
51
69
 
52
70
  ## Versions
53
71
 
@@ -124,20 +142,20 @@ The method `.inc` takes an additional `identifier` string argument that
124
142
  will append the value of the string as a prerelease identifier:
125
143
 
126
144
  ```javascript
127
- > semver.inc('1.2.3', 'prerelease', 'beta')
128
- '1.2.4-beta.0'
145
+ semver.inc('1.2.3', 'prerelease', 'beta')
146
+ // '1.2.4-beta.0'
129
147
  ```
130
148
 
131
149
  command-line example:
132
150
 
133
- ```shell
151
+ ```bash
134
152
  $ semver 1.2.3 -i prerelease --preid beta
135
153
  1.2.4-beta.0
136
154
  ```
137
155
 
138
156
  Which then can be used to increment further:
139
157
 
140
- ```shell
158
+ ```bash
141
159
  $ semver 1.2.4-beta.0 -i prerelease
142
160
  1.2.4-beta.1
143
161
  ```
@@ -294,6 +312,8 @@ strings that they parse.
294
312
  * `major(v)`: Return the major version number.
295
313
  * `minor(v)`: Return the minor version number.
296
314
  * `patch(v)`: Return the patch version number.
315
+ * `intersects(r1, r2, loose)`: Return true if the two supplied ranges
316
+ or comparators intersect.
297
317
 
298
318
  ### Comparison
299
319
 
@@ -317,6 +337,9 @@ strings that they parse.
317
337
  (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`),
318
338
  or null if the versions are the same.
319
339
 
340
+ ### Comparators
341
+
342
+ * `intersects(comparator)`: Return true if the comparators intersect
320
343
 
321
344
  ### Ranges
322
345
 
@@ -325,6 +348,8 @@ strings that they parse.
325
348
  range.
326
349
  * `maxSatisfying(versions, range)`: Return the highest version in the list
327
350
  that satisfies the range, or `null` if none of them do.
351
+ * `minSatisfying(versions, range)`: Return the lowest version in the list
352
+ that satisfies the range, or `null` if none of them do.
328
353
  * `gtr(version, range)`: Return `true` if version is greater than all the
329
354
  versions possible in the range.
330
355
  * `ltr(version, range)`: Return `true` if version is less than all the
@@ -333,6 +358,7 @@ strings that they parse.
333
358
  the bounds of the range in either the high or low direction. The
334
359
  `hilo` argument must be either the string `'>'` or `'<'`. (This is
335
360
  the function called by `gtr` and `ltr`.)
361
+ * `intersects(range)`: Return true if any of the ranges comparators intersect
336
362
 
337
363
  Note that, since ranges may be non-contiguous, a version might not be
338
364
  greater than a range, less than a range, *or* satisfy a range! For
@@ -344,3 +370,19 @@ satisfy the range.
344
370
 
345
371
  If you want to know if a version satisfies or does not satisfy a
346
372
  range, use the `satisfies(version, range)` function.
373
+
374
+ ### Coercion
375
+
376
+ * `coerce(version)`: Coerces a string to semver if possible
377
+
378
+ This aims to provide a very forgiving translation of a non-semver
379
+ string to semver. It looks for the first digit in a string, and
380
+ consumes all remaining characters which satisfy at least a partial semver
381
+ (e.g., `1`, `1.2`, `1.2.3`) up to the max permitted length (256 characters).
382
+ Longer versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`).
383
+ All surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes `3.4.0`).
384
+ Only text which lacks digits will fail coercion (`version one` is not valid).
385
+ The maximum length for any semver component considered for coercion is 16 characters;
386
+ longer components will be ignored (`10000000000000000.4.7.4` becomes `4.7.4`).
387
+ The maximum value for any semver component is `Integer.MAX_SAFE_INTEGER || (2**53 - 1)`;
388
+ higher value components are invalid (`9999999999999999.4.7.4` is likely invalid).
package/bin/semver CHANGED
@@ -12,6 +12,7 @@ var argv = process.argv.slice(2)
12
12
  , inc = null
13
13
  , version = require("../package.json").version
14
14
  , loose = false
15
+ , coerce = false
15
16
  , identifier = undefined
16
17
  , semver = require("../semver")
17
18
  , reverse = false
@@ -54,6 +55,9 @@ function main () {
54
55
  case "-r": case "--range":
55
56
  range.push(argv.shift())
56
57
  break
58
+ case "-c": case "--coerce":
59
+ coerce = true
60
+ break
57
61
  case "-h": case "--help": case "-?":
58
62
  return help()
59
63
  default:
@@ -62,8 +66,10 @@ function main () {
62
66
  }
63
67
  }
64
68
 
65
- versions = versions.filter(function (v) {
66
- return semver.valid(v, loose)
69
+ versions = versions.map(function (v) {
70
+ return coerce ? (semver.coerce(v) || {version: v}).version : v
71
+ }).filter(function (v) {
72
+ return semver.valid(v)
67
73
  })
68
74
  if (!versions.length) return fail()
69
75
  if (inc && (versions.length !== 1 || range.length))
@@ -122,6 +128,10 @@ function help () {
122
128
  ,"-l --loose"
123
129
  ," Interpret versions and ranges loosely"
124
130
  ,""
131
+ ,"-c --coerce"
132
+ ," Coerce a string into SemVer if possible"
133
+ ," (does not imply --loose)"
134
+ ,""
125
135
  ,"Program exits successfully if any valid version satisfies"
126
136
  ,"all supplied ranges, and prints all satisfying versions."
127
137
  ,""
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "semver",
3
- "version": "5.2.0",
3
+ "version": "5.5.0",
4
4
  "description": "The semantic version parser used by npm.",
5
5
  "main": "semver.js",
6
6
  "scripts": {
7
- "test": "tap test/*.js"
7
+ "test": "tap test/*.js --cov -J"
8
8
  },
9
9
  "devDependencies": {
10
- "tap": "^2.0.0"
10
+ "tap": "^10.7.0"
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++;
@@ -314,9 +326,9 @@ function SemVer(version, loose) {
314
326
  else
315
327
  this.prerelease = m[4].split('.').map(function(id) {
316
328
  if (/^[0-9]+$/.test(id)) {
317
- var num = +id
329
+ var num = +id;
318
330
  if (num >= 0 && num < MAX_SAFE_INTEGER)
319
- return num
331
+ return num;
320
332
  }
321
333
  return id;
322
334
  });
@@ -563,7 +575,7 @@ function patch(a, loose) {
563
575
 
564
576
  exports.compare = compare;
565
577
  function compare(a, b, loose) {
566
- return new SemVer(a, loose).compare(b);
578
+ return new SemVer(a, loose).compare(new SemVer(b, loose));
567
579
  }
568
580
 
569
581
  exports.compareLoose = compareLoose;
@@ -704,11 +716,59 @@ Comparator.prototype.test = function(version) {
704
716
  return cmp(version, this.operator, this.semver, this.loose);
705
717
  };
706
718
 
719
+ Comparator.prototype.intersects = function(comp, loose) {
720
+ if (!(comp instanceof Comparator)) {
721
+ throw new TypeError('a Comparator is required');
722
+ }
723
+
724
+ var rangeTmp;
725
+
726
+ if (this.operator === '') {
727
+ rangeTmp = new Range(comp.value, loose);
728
+ return satisfies(this.value, rangeTmp, loose);
729
+ } else if (comp.operator === '') {
730
+ rangeTmp = new Range(this.value, loose);
731
+ return satisfies(comp.semver, rangeTmp, loose);
732
+ }
733
+
734
+ var sameDirectionIncreasing =
735
+ (this.operator === '>=' || this.operator === '>') &&
736
+ (comp.operator === '>=' || comp.operator === '>');
737
+ var sameDirectionDecreasing =
738
+ (this.operator === '<=' || this.operator === '<') &&
739
+ (comp.operator === '<=' || comp.operator === '<');
740
+ var sameSemVer = this.semver.version === comp.semver.version;
741
+ var differentDirectionsInclusive =
742
+ (this.operator === '>=' || this.operator === '<=') &&
743
+ (comp.operator === '>=' || comp.operator === '<=');
744
+ var oppositeDirectionsLessThan =
745
+ cmp(this.semver, '<', comp.semver, loose) &&
746
+ ((this.operator === '>=' || this.operator === '>') &&
747
+ (comp.operator === '<=' || comp.operator === '<'));
748
+ var oppositeDirectionsGreaterThan =
749
+ cmp(this.semver, '>', comp.semver, loose) &&
750
+ ((this.operator === '<=' || this.operator === '<') &&
751
+ (comp.operator === '>=' || comp.operator === '>'));
752
+
753
+ return sameDirectionIncreasing || sameDirectionDecreasing ||
754
+ (sameSemVer && differentDirectionsInclusive) ||
755
+ oppositeDirectionsLessThan || oppositeDirectionsGreaterThan;
756
+ };
757
+
707
758
 
708
759
  exports.Range = Range;
709
760
  function Range(range, loose) {
710
- if ((range instanceof Range) && range.loose === loose)
711
- return range;
761
+ if (range instanceof Range) {
762
+ if (range.loose === loose) {
763
+ return range;
764
+ } else {
765
+ return new Range(range.raw, loose);
766
+ }
767
+ }
768
+
769
+ if (range instanceof Comparator) {
770
+ return new Range(range.value, loose);
771
+ }
712
772
 
713
773
  if (!(this instanceof Range))
714
774
  return new Range(range, loose);
@@ -783,6 +843,22 @@ Range.prototype.parseRange = function(range) {
783
843
  return set;
784
844
  };
785
845
 
846
+ Range.prototype.intersects = function(range, loose) {
847
+ if (!(range instanceof Range)) {
848
+ throw new TypeError('a Range is required');
849
+ }
850
+
851
+ return this.set.some(function(thisComparators) {
852
+ return thisComparators.every(function(thisComparator) {
853
+ return range.set.some(function(rangeComparators) {
854
+ return rangeComparators.every(function(rangeComparator) {
855
+ return thisComparator.intersects(rangeComparator, loose);
856
+ });
857
+ });
858
+ });
859
+ });
860
+ };
861
+
786
862
  // Mostly just for testing and legacy API reasons
787
863
  exports.toComparators = toComparators;
788
864
  function toComparators(range, loose) {
@@ -966,11 +1042,11 @@ function replaceXRange(comp, loose) {
966
1042
  } else if (gtlt === '<=') {
967
1043
  // <=0.7.x is actually <0.8.0, since any 0.7.x should
968
1044
  // pass. Similarly, <=7.x is actually <8.0.0, etc.
969
- gtlt = '<'
1045
+ gtlt = '<';
970
1046
  if (xm)
971
- M = +M + 1
1047
+ M = +M + 1;
972
1048
  else
973
- m = +m + 1
1049
+ m = +m + 1;
974
1050
  }
975
1051
 
976
1052
  ret = gtlt + M + '.' + m + '.' + p;
@@ -1087,11 +1163,42 @@ function satisfies(version, range, loose) {
1087
1163
 
1088
1164
  exports.maxSatisfying = maxSatisfying;
1089
1165
  function maxSatisfying(versions, range, loose) {
1090
- return versions.filter(function(version) {
1091
- return satisfies(version, range, loose);
1092
- }).sort(function(a, b) {
1093
- return rcompare(a, b, loose);
1094
- })[0] || null;
1166
+ var max = null;
1167
+ var maxSV = null;
1168
+ try {
1169
+ var rangeObj = new Range(range, loose);
1170
+ } catch (er) {
1171
+ return null;
1172
+ }
1173
+ versions.forEach(function (v) {
1174
+ if (rangeObj.test(v)) { // satisfies(v, range, loose)
1175
+ if (!max || maxSV.compare(v) === -1) { // compare(max, v, true)
1176
+ max = v;
1177
+ maxSV = new SemVer(max, loose);
1178
+ }
1179
+ }
1180
+ })
1181
+ return max;
1182
+ }
1183
+
1184
+ exports.minSatisfying = minSatisfying;
1185
+ function minSatisfying(versions, range, loose) {
1186
+ var min = null;
1187
+ var minSV = null;
1188
+ try {
1189
+ var rangeObj = new Range(range, loose);
1190
+ } catch (er) {
1191
+ return null;
1192
+ }
1193
+ versions.forEach(function (v) {
1194
+ if (rangeObj.test(v)) { // satisfies(v, range, loose)
1195
+ if (!min || minSV.compare(v) === 1) { // compare(min, v, true)
1196
+ min = v;
1197
+ minSV = new SemVer(min, loose);
1198
+ }
1199
+ }
1200
+ })
1201
+ return min;
1095
1202
  }
1096
1203
 
1097
1204
  exports.validRange = validRange;
@@ -1192,3 +1299,26 @@ function prerelease(version, loose) {
1192
1299
  var parsed = parse(version, loose);
1193
1300
  return (parsed && parsed.prerelease.length) ? parsed.prerelease : null;
1194
1301
  }
1302
+
1303
+ exports.intersects = intersects;
1304
+ function intersects(r1, r2, loose) {
1305
+ r1 = new Range(r1, loose)
1306
+ r2 = new Range(r2, loose)
1307
+ return r1.intersects(r2)
1308
+ }
1309
+
1310
+ exports.coerce = coerce;
1311
+ function coerce(version) {
1312
+ if (version instanceof SemVer)
1313
+ return version;
1314
+
1315
+ if (typeof version !== 'string')
1316
+ return null;
1317
+
1318
+ var match = version.match(re[COERCE]);
1319
+
1320
+ if (match == null)
1321
+ return null;
1322
+
1323
+ return parse((match[1] || '0') + '.' + (match[2] || '0') + '.' + (match[3] || '0'));
1324
+ }