+31
@@ -1,5 +1,36 @@
|
||||
# changes log
|
||||
|
||||
## 6.2.0
|
||||
|
||||
* Coerce numbers to strings when passed to semver.coerce()
|
||||
* Add `rtl` option to coerce from right to left
|
||||
|
||||
## 6.1.3
|
||||
|
||||
* Handle X-ranges properly in includePrerelease mode
|
||||
|
||||
## 6.1.2
|
||||
|
||||
* Do not throw when testing invalid version strings
|
||||
|
||||
## 6.1.1
|
||||
|
||||
* Add options support for semver.coerce()
|
||||
* Handle undefined version passed to Range.test
|
||||
|
||||
## 6.1.0
|
||||
|
||||
* Add semver.compareBuild function
|
||||
* Support `*` in semver.intersects
|
||||
|
||||
## 6.0
|
||||
|
||||
* Fix `intersects` logic.
|
||||
|
||||
This is technically a bug fix, but since it is also a change to behavior
|
||||
that may require users updating their code, it is marked as a major
|
||||
version increment.
|
||||
|
||||
## 5.7
|
||||
|
||||
* Add `minVersion` method
|
||||
|
||||
+35
-4
@@ -4,7 +4,7 @@ semver(1) -- The semantic versioner for npm
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install --save semver
|
||||
npm install semver
|
||||
````
|
||||
|
||||
## Usage
|
||||
@@ -60,6 +60,12 @@ Options:
|
||||
Coerce a string into SemVer if possible
|
||||
(does not imply --loose)
|
||||
|
||||
--rtl
|
||||
Coerce version strings right to left
|
||||
|
||||
--ltr
|
||||
Coerce version strings left to right (default)
|
||||
|
||||
Program exits successfully if any valid version satisfies
|
||||
all supplied ranges, and prints all satisfying versions.
|
||||
|
||||
@@ -231,7 +237,7 @@ comparator. Allows minor-level changes if not.
|
||||
|
||||
#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4`
|
||||
|
||||
Allows changes that do not modify the left-most non-zero digit in the
|
||||
Allows changes that do not modify the left-most non-zero element in the
|
||||
`[major, minor, patch]` tuple. In other words, this allows patch and
|
||||
minor updates for versions `1.0.0` and above, patch updates for
|
||||
versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`.
|
||||
@@ -354,6 +360,9 @@ strings that they parse.
|
||||
`v2` is greater. Sorts in ascending order if passed to `Array.sort()`.
|
||||
* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions
|
||||
in descending order when passed to `Array.sort()`.
|
||||
* `compareBuild(v1, v2)`: The same as `compare` but considers `build` when two versions
|
||||
are equal. Sorts in ascending order if passed to `Array.sort()`.
|
||||
`v2` is greater. Sorts in ascending order if passed to `Array.sort()`.
|
||||
* `diff(v1, v2)`: Returns difference between two versions by the release type
|
||||
(`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`),
|
||||
or null if the versions are the same.
|
||||
@@ -396,7 +405,7 @@ range, use the `satisfies(version, range)` function.
|
||||
|
||||
### Coercion
|
||||
|
||||
* `coerce(version)`: Coerces a string to semver if possible
|
||||
* `coerce(version, options)`: Coerces a string to semver if possible
|
||||
|
||||
This aims to provide a very forgiving translation of a non-semver string to
|
||||
semver. It looks for the first digit in a string, and consumes all
|
||||
@@ -408,5 +417,27 @@ surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes
|
||||
is not valid). The maximum length for any semver component considered for
|
||||
coercion is 16 characters; longer components will be ignored
|
||||
(`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any
|
||||
semver component is `Number.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value
|
||||
semver component is `Integer.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value
|
||||
components are invalid (`9999999999999999.4.7.4` is likely invalid).
|
||||
|
||||
If the `options.rtl` flag is set, then `coerce` will return the right-most
|
||||
coercible tuple that does not share an ending index with a longer coercible
|
||||
tuple. For example, `1.2.3.4` will return `2.3.4` in rtl mode, not
|
||||
`4.0.0`. `1.2.3/4` will return `4.0.0`, because the `4` is not a part of
|
||||
any other overlapping SemVer tuple.
|
||||
|
||||
### Clean
|
||||
|
||||
* `clean(version)`: Clean a string to be a valid semver if possible
|
||||
|
||||
This will return a cleaned and trimmed semver version. If the provided version is not valid a null will be returned. This does not work for ranges.
|
||||
|
||||
ex.
|
||||
* `s.clean(' = v 2.1.5foo')`: `null`
|
||||
* `s.clean(' = v 2.1.5foo', { loose: true })`: `'2.1.5-foo'`
|
||||
* `s.clean(' = v 2.1.5-foo')`: `null`
|
||||
* `s.clean(' = v 2.1.5-foo', { loose: true })`: `'2.1.5-foo'`
|
||||
* `s.clean('=v2.1.5')`: `'2.1.5'`
|
||||
* `s.clean(' =v2.1.5')`: `2.1.5`
|
||||
* `s.clean(' 2.1.5 ')`: `'2.1.5'`
|
||||
* `s.clean('~1.0.0')`: `null`
|
||||
|
||||
+16
-2
@@ -19,6 +19,8 @@ var includePrerelease = false
|
||||
|
||||
var coerce = false
|
||||
|
||||
var rtl = false
|
||||
|
||||
var identifier
|
||||
|
||||
var semver = require('../semver')
|
||||
@@ -71,6 +73,12 @@ function main () {
|
||||
case '-c': case '--coerce':
|
||||
coerce = true
|
||||
break
|
||||
case '--rtl':
|
||||
rtl = true
|
||||
break
|
||||
case '--ltr':
|
||||
rtl = false
|
||||
break
|
||||
case '-h': case '--help': case '-?':
|
||||
return help()
|
||||
default:
|
||||
@@ -79,10 +87,10 @@ function main () {
|
||||
}
|
||||
}
|
||||
|
||||
var options = { loose: loose, includePrerelease: includePrerelease }
|
||||
var options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl }
|
||||
|
||||
versions = versions.map(function (v) {
|
||||
return coerce ? (semver.coerce(v) || { version: v }).version : v
|
||||
return coerce ? (semver.coerce(v, options) || { version: v }).version : v
|
||||
}).filter(function (v) {
|
||||
return semver.valid(v)
|
||||
})
|
||||
@@ -149,6 +157,12 @@ function help () {
|
||||
' Coerce a string into SemVer if possible',
|
||||
' (does not imply --loose)',
|
||||
'',
|
||||
'--rtl',
|
||||
' Coerce version strings right to left',
|
||||
'',
|
||||
'--ltr',
|
||||
' Coerce version strings left to right (default)',
|
||||
'',
|
||||
'Program exits successfully if any valid version satisfies',
|
||||
'all supplied ranges, and prints all satisfying versions.',
|
||||
'',
|
||||
+15
-15
@@ -1,29 +1,29 @@
|
||||
{
|
||||
"_from": "semver@^5.5.0",
|
||||
"_id": "semver@5.7.1",
|
||||
"_from": "semver@^6.1.0",
|
||||
"_id": "semver@6.3.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"_location": "/semver",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "semver@^5.5.0",
|
||||
"raw": "semver@^6.1.0",
|
||||
"name": "semver",
|
||||
"escapedName": "semver",
|
||||
"rawSpec": "^5.5.0",
|
||||
"rawSpec": "^6.1.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^5.5.0"
|
||||
"fetchSpec": "^6.1.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/cross-spawn"
|
||||
"/@actions/tool-cache"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"_shasum": "a954f931aeba508d307bbf069eff0c01c96116f7",
|
||||
"_spec": "semver@^5.5.0",
|
||||
"_where": "/Users/yuanrong.man/projects/setup-ossutil/node_modules/cross-spawn",
|
||||
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"_shasum": "ee0a64c8af5e8ceea67687b133761e1becbd1d3d",
|
||||
"_spec": "semver@^6.1.0",
|
||||
"_where": "/workspace/setup-ossutil/node_modules/@actions/tool-cache",
|
||||
"bin": {
|
||||
"semver": "./bin/semver"
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/npm/node-semver/issues"
|
||||
@@ -32,7 +32,7 @@
|
||||
"deprecated": false,
|
||||
"description": "The semantic version parser used by npm.",
|
||||
"devDependencies": {
|
||||
"tap": "^13.0.0-rc.18"
|
||||
"tap": "^14.3.1"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
@@ -48,7 +48,7 @@
|
||||
"url": "git+https://github.com/npm/node-semver.git"
|
||||
},
|
||||
"scripts": {
|
||||
"postpublish": "git push origin --all; git push origin --tags",
|
||||
"postpublish": "git push origin --follow-tags",
|
||||
"postversion": "npm publish",
|
||||
"preversion": "npm test",
|
||||
"test": "tap"
|
||||
@@ -56,5 +56,5 @@
|
||||
"tap": {
|
||||
"check-coverage": true
|
||||
},
|
||||
"version": "5.7.1"
|
||||
"version": "6.3.0"
|
||||
}
|
||||
|
||||
+248
-135
@@ -29,75 +29,80 @@ var MAX_SAFE_COMPONENT_LENGTH = 16
|
||||
// The actual regexps go on exports.re
|
||||
var re = exports.re = []
|
||||
var src = exports.src = []
|
||||
var t = exports.tokens = {}
|
||||
var R = 0
|
||||
|
||||
function tok (n) {
|
||||
t[n] = R++
|
||||
}
|
||||
|
||||
// The following Regular Expressions can be used for tokenizing,
|
||||
// validating, and parsing SemVer version strings.
|
||||
|
||||
// ## Numeric Identifier
|
||||
// A single `0`, or a non-zero digit followed by zero or more digits.
|
||||
|
||||
var NUMERICIDENTIFIER = R++
|
||||
src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'
|
||||
var NUMERICIDENTIFIERLOOSE = R++
|
||||
src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'
|
||||
tok('NUMERICIDENTIFIER')
|
||||
src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*'
|
||||
tok('NUMERICIDENTIFIERLOOSE')
|
||||
src[t.NUMERICIDENTIFIERLOOSE] = '[0-9]+'
|
||||
|
||||
// ## Non-numeric Identifier
|
||||
// Zero or more digits, followed by a letter or hyphen, and then zero or
|
||||
// more letters, digits, or hyphens.
|
||||
|
||||
var NONNUMERICIDENTIFIER = R++
|
||||
src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'
|
||||
tok('NONNUMERICIDENTIFIER')
|
||||
src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'
|
||||
|
||||
// ## Main Version
|
||||
// Three dot-separated numeric identifiers.
|
||||
|
||||
var MAINVERSION = R++
|
||||
src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
|
||||
'(' + src[NUMERICIDENTIFIER] + ')\\.' +
|
||||
'(' + src[NUMERICIDENTIFIER] + ')'
|
||||
tok('MAINVERSION')
|
||||
src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' +
|
||||
'(' + src[t.NUMERICIDENTIFIER] + ')\\.' +
|
||||
'(' + src[t.NUMERICIDENTIFIER] + ')'
|
||||
|
||||
var MAINVERSIONLOOSE = R++
|
||||
src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
|
||||
'(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
|
||||
'(' + src[NUMERICIDENTIFIERLOOSE] + ')'
|
||||
tok('MAINVERSIONLOOSE')
|
||||
src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' +
|
||||
'(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' +
|
||||
'(' + src[t.NUMERICIDENTIFIERLOOSE] + ')'
|
||||
|
||||
// ## Pre-release Version Identifier
|
||||
// A numeric identifier, or a non-numeric identifier.
|
||||
|
||||
var PRERELEASEIDENTIFIER = R++
|
||||
src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
|
||||
'|' + src[NONNUMERICIDENTIFIER] + ')'
|
||||
tok('PRERELEASEIDENTIFIER')
|
||||
src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] +
|
||||
'|' + src[t.NONNUMERICIDENTIFIER] + ')'
|
||||
|
||||
var PRERELEASEIDENTIFIERLOOSE = R++
|
||||
src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
|
||||
'|' + src[NONNUMERICIDENTIFIER] + ')'
|
||||
tok('PRERELEASEIDENTIFIERLOOSE')
|
||||
src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] +
|
||||
'|' + src[t.NONNUMERICIDENTIFIER] + ')'
|
||||
|
||||
// ## Pre-release Version
|
||||
// Hyphen, followed by one or more dot-separated pre-release version
|
||||
// identifiers.
|
||||
|
||||
var PRERELEASE = R++
|
||||
src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
|
||||
'(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'
|
||||
tok('PRERELEASE')
|
||||
src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] +
|
||||
'(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))'
|
||||
|
||||
var PRERELEASELOOSE = R++
|
||||
src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
|
||||
'(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'
|
||||
tok('PRERELEASELOOSE')
|
||||
src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] +
|
||||
'(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))'
|
||||
|
||||
// ## Build Metadata Identifier
|
||||
// Any combination of digits, letters, or hyphens.
|
||||
|
||||
var BUILDIDENTIFIER = R++
|
||||
src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'
|
||||
tok('BUILDIDENTIFIER')
|
||||
src[t.BUILDIDENTIFIER] = '[0-9A-Za-z-]+'
|
||||
|
||||
// ## Build Metadata
|
||||
// Plus sign, followed by one or more period-separated build metadata
|
||||
// identifiers.
|
||||
|
||||
var BUILD = R++
|
||||
src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
|
||||
'(?:\\.' + src[BUILDIDENTIFIER] + ')*))'
|
||||
tok('BUILD')
|
||||
src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] +
|
||||
'(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))'
|
||||
|
||||
// ## Full Version String
|
||||
// A main version, followed optionally by a pre-release version and
|
||||
@@ -108,129 +113,133 @@ src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
|
||||
// capturing group, because it should not ever be used in version
|
||||
// comparison.
|
||||
|
||||
var FULL = R++
|
||||
var FULLPLAIN = 'v?' + src[MAINVERSION] +
|
||||
src[PRERELEASE] + '?' +
|
||||
src[BUILD] + '?'
|
||||
tok('FULL')
|
||||
tok('FULLPLAIN')
|
||||
src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] +
|
||||
src[t.PRERELEASE] + '?' +
|
||||
src[t.BUILD] + '?'
|
||||
|
||||
src[FULL] = '^' + FULLPLAIN + '$'
|
||||
src[t.FULL] = '^' + src[t.FULLPLAIN] + '$'
|
||||
|
||||
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
|
||||
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
|
||||
// common in the npm registry.
|
||||
var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
|
||||
src[PRERELEASELOOSE] + '?' +
|
||||
src[BUILD] + '?'
|
||||
tok('LOOSEPLAIN')
|
||||
src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] +
|
||||
src[t.PRERELEASELOOSE] + '?' +
|
||||
src[t.BUILD] + '?'
|
||||
|
||||
var LOOSE = R++
|
||||
src[LOOSE] = '^' + LOOSEPLAIN + '$'
|
||||
tok('LOOSE')
|
||||
src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$'
|
||||
|
||||
var GTLT = R++
|
||||
src[GTLT] = '((?:<|>)?=?)'
|
||||
tok('GTLT')
|
||||
src[t.GTLT] = '((?:<|>)?=?)'
|
||||
|
||||
// Something like "2.*" or "1.2.x".
|
||||
// Note that "x.x" is a valid xRange identifer, meaning "any version"
|
||||
// Only the first item is strictly required.
|
||||
var XRANGEIDENTIFIERLOOSE = R++
|
||||
src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'
|
||||
var XRANGEIDENTIFIER = R++
|
||||
src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'
|
||||
tok('XRANGEIDENTIFIERLOOSE')
|
||||
src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'
|
||||
tok('XRANGEIDENTIFIER')
|
||||
src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*'
|
||||
|
||||
var XRANGEPLAIN = R++
|
||||
src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
|
||||
'(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
|
||||
'(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
|
||||
'(?:' + src[PRERELEASE] + ')?' +
|
||||
src[BUILD] + '?' +
|
||||
tok('XRANGEPLAIN')
|
||||
src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' +
|
||||
'(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' +
|
||||
'(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' +
|
||||
'(?:' + src[t.PRERELEASE] + ')?' +
|
||||
src[t.BUILD] + '?' +
|
||||
')?)?'
|
||||
|
||||
var XRANGEPLAINLOOSE = R++
|
||||
src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
|
||||
'(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
|
||||
'(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
|
||||
'(?:' + src[PRERELEASELOOSE] + ')?' +
|
||||
src[BUILD] + '?' +
|
||||
tok('XRANGEPLAINLOOSE')
|
||||
src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +
|
||||
'(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +
|
||||
'(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +
|
||||
'(?:' + src[t.PRERELEASELOOSE] + ')?' +
|
||||
src[t.BUILD] + '?' +
|
||||
')?)?'
|
||||
|
||||
var XRANGE = R++
|
||||
src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'
|
||||
var XRANGELOOSE = R++
|
||||
src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'
|
||||
tok('XRANGE')
|
||||
src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$'
|
||||
tok('XRANGELOOSE')
|
||||
src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$'
|
||||
|
||||
// Coercion.
|
||||
// Extract anything that could conceivably be a part of a valid semver
|
||||
var COERCE = R++
|
||||
src[COERCE] = '(?:^|[^\\d])' +
|
||||
tok('COERCE')
|
||||
src[t.COERCE] = '(^|[^\\d])' +
|
||||
'(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' +
|
||||
'(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
|
||||
'(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
|
||||
'(?:$|[^\\d])'
|
||||
tok('COERCERTL')
|
||||
re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g')
|
||||
|
||||
// Tilde ranges.
|
||||
// Meaning is "reasonably at or greater than"
|
||||
var LONETILDE = R++
|
||||
src[LONETILDE] = '(?:~>?)'
|
||||
tok('LONETILDE')
|
||||
src[t.LONETILDE] = '(?:~>?)'
|
||||
|
||||
var TILDETRIM = R++
|
||||
src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'
|
||||
re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g')
|
||||
tok('TILDETRIM')
|
||||
src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+'
|
||||
re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g')
|
||||
var tildeTrimReplace = '$1~'
|
||||
|
||||
var TILDE = R++
|
||||
src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'
|
||||
var TILDELOOSE = R++
|
||||
src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'
|
||||
tok('TILDE')
|
||||
src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$'
|
||||
tok('TILDELOOSE')
|
||||
src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$'
|
||||
|
||||
// Caret ranges.
|
||||
// Meaning is "at least and backwards compatible with"
|
||||
var LONECARET = R++
|
||||
src[LONECARET] = '(?:\\^)'
|
||||
tok('LONECARET')
|
||||
src[t.LONECARET] = '(?:\\^)'
|
||||
|
||||
var CARETTRIM = R++
|
||||
src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'
|
||||
re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g')
|
||||
tok('CARETTRIM')
|
||||
src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+'
|
||||
re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g')
|
||||
var caretTrimReplace = '$1^'
|
||||
|
||||
var CARET = R++
|
||||
src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'
|
||||
var CARETLOOSE = R++
|
||||
src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'
|
||||
tok('CARET')
|
||||
src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$'
|
||||
tok('CARETLOOSE')
|
||||
src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$'
|
||||
|
||||
// A simple gt/lt/eq thing, or just "" to indicate "any version"
|
||||
var COMPARATORLOOSE = R++
|
||||
src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'
|
||||
var COMPARATOR = R++
|
||||
src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'
|
||||
tok('COMPARATORLOOSE')
|
||||
src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$'
|
||||
tok('COMPARATOR')
|
||||
src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$'
|
||||
|
||||
// An expression to strip any whitespace between the gtlt and the thing
|
||||
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
|
||||
var COMPARATORTRIM = R++
|
||||
src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
|
||||
'\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'
|
||||
tok('COMPARATORTRIM')
|
||||
src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] +
|
||||
'\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')'
|
||||
|
||||
// this one has to use the /g flag
|
||||
re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g')
|
||||
re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g')
|
||||
var comparatorTrimReplace = '$1$2$3'
|
||||
|
||||
// Something like `1.2.3 - 1.2.4`
|
||||
// Note that these all use the loose form, because they'll be
|
||||
// checked against either the strict or loose comparator form
|
||||
// later.
|
||||
var HYPHENRANGE = R++
|
||||
src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
|
||||
tok('HYPHENRANGE')
|
||||
src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' +
|
||||
'\\s+-\\s+' +
|
||||
'(' + src[XRANGEPLAIN] + ')' +
|
||||
'(' + src[t.XRANGEPLAIN] + ')' +
|
||||
'\\s*$'
|
||||
|
||||
var HYPHENRANGELOOSE = R++
|
||||
src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
|
||||
tok('HYPHENRANGELOOSE')
|
||||
src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' +
|
||||
'\\s+-\\s+' +
|
||||
'(' + src[XRANGEPLAINLOOSE] + ')' +
|
||||
'(' + src[t.XRANGEPLAINLOOSE] + ')' +
|
||||
'\\s*$'
|
||||
|
||||
// Star ranges basically just allow anything at all.
|
||||
var STAR = R++
|
||||
src[STAR] = '(<|>)?=?\\s*\\*'
|
||||
tok('STAR')
|
||||
src[t.STAR] = '(<|>)?=?\\s*\\*'
|
||||
|
||||
// Compile to actual regexp objects.
|
||||
// All are flag-free, unless they were created above with a flag.
|
||||
@@ -262,7 +271,7 @@ function parse (version, options) {
|
||||
return null
|
||||
}
|
||||
|
||||
var r = options.loose ? re[LOOSE] : re[FULL]
|
||||
var r = options.loose ? re[t.LOOSE] : re[t.FULL]
|
||||
if (!r.test(version)) {
|
||||
return null
|
||||
}
|
||||
@@ -317,7 +326,7 @@ function SemVer (version, options) {
|
||||
this.options = options
|
||||
this.loose = !!options.loose
|
||||
|
||||
var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL])
|
||||
var m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])
|
||||
|
||||
if (!m) {
|
||||
throw new TypeError('Invalid Version: ' + version)
|
||||
@@ -425,6 +434,30 @@ SemVer.prototype.comparePre = function (other) {
|
||||
} while (++i)
|
||||
}
|
||||
|
||||
SemVer.prototype.compareBuild = function (other) {
|
||||
if (!(other instanceof SemVer)) {
|
||||
other = new SemVer(other, this.options)
|
||||
}
|
||||
|
||||
var i = 0
|
||||
do {
|
||||
var a = this.build[i]
|
||||
var b = other.build[i]
|
||||
debug('prerelease compare', i, a, b)
|
||||
if (a === undefined && b === undefined) {
|
||||
return 0
|
||||
} else if (b === undefined) {
|
||||
return 1
|
||||
} else if (a === undefined) {
|
||||
return -1
|
||||
} else if (a === b) {
|
||||
continue
|
||||
} else {
|
||||
return compareIdentifiers(a, b)
|
||||
}
|
||||
} while (++i)
|
||||
}
|
||||
|
||||
// preminor will bump the version up to the next minor release, and immediately
|
||||
// down to pre-release. premajor and prepatch work the same way.
|
||||
SemVer.prototype.inc = function (release, identifier) {
|
||||
@@ -619,6 +652,13 @@ function compareLoose (a, b) {
|
||||
return compare(a, b, true)
|
||||
}
|
||||
|
||||
exports.compareBuild = compareBuild
|
||||
function compareBuild (a, b, loose) {
|
||||
var versionA = new SemVer(a, loose)
|
||||
var versionB = new SemVer(b, loose)
|
||||
return versionA.compare(versionB) || versionA.compareBuild(versionB)
|
||||
}
|
||||
|
||||
exports.rcompare = rcompare
|
||||
function rcompare (a, b, loose) {
|
||||
return compare(b, a, loose)
|
||||
@@ -627,14 +667,14 @@ function rcompare (a, b, loose) {
|
||||
exports.sort = sort
|
||||
function sort (list, loose) {
|
||||
return list.sort(function (a, b) {
|
||||
return exports.compare(a, b, loose)
|
||||
return exports.compareBuild(a, b, loose)
|
||||
})
|
||||
}
|
||||
|
||||
exports.rsort = rsort
|
||||
function rsort (list, loose) {
|
||||
return list.sort(function (a, b) {
|
||||
return exports.rcompare(a, b, loose)
|
||||
return exports.compareBuild(b, a, loose)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -747,14 +787,14 @@ function Comparator (comp, options) {
|
||||
|
||||
var ANY = {}
|
||||
Comparator.prototype.parse = function (comp) {
|
||||
var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]
|
||||
var r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
|
||||
var m = comp.match(r)
|
||||
|
||||
if (!m) {
|
||||
throw new TypeError('Invalid comparator: ' + comp)
|
||||
}
|
||||
|
||||
this.operator = m[1]
|
||||
this.operator = m[1] !== undefined ? m[1] : ''
|
||||
if (this.operator === '=') {
|
||||
this.operator = ''
|
||||
}
|
||||
@@ -774,12 +814,16 @@ Comparator.prototype.toString = function () {
|
||||
Comparator.prototype.test = function (version) {
|
||||
debug('Comparator.test', version, this.options.loose)
|
||||
|
||||
if (this.semver === ANY) {
|
||||
if (this.semver === ANY || version === ANY) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (typeof version === 'string') {
|
||||
version = new SemVer(version, this.options)
|
||||
try {
|
||||
version = new SemVer(version, this.options)
|
||||
} catch (er) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return cmp(version, this.operator, this.semver, this.options)
|
||||
@@ -800,9 +844,15 @@ Comparator.prototype.intersects = function (comp, options) {
|
||||
var rangeTmp
|
||||
|
||||
if (this.operator === '') {
|
||||
if (this.value === '') {
|
||||
return true
|
||||
}
|
||||
rangeTmp = new Range(comp.value, options)
|
||||
return satisfies(this.value, rangeTmp, options)
|
||||
} else if (comp.operator === '') {
|
||||
if (comp.value === '') {
|
||||
return true
|
||||
}
|
||||
rangeTmp = new Range(this.value, options)
|
||||
return satisfies(comp.semver, rangeTmp, options)
|
||||
}
|
||||
@@ -892,18 +942,18 @@ Range.prototype.parseRange = function (range) {
|
||||
var loose = this.options.loose
|
||||
range = range.trim()
|
||||
// `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
|
||||
var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]
|
||||
var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]
|
||||
range = range.replace(hr, hyphenReplace)
|
||||
debug('hyphen replace', range)
|
||||
// `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
|
||||
range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace)
|
||||
debug('comparator trim', range, re[COMPARATORTRIM])
|
||||
range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace)
|
||||
debug('comparator trim', range, re[t.COMPARATORTRIM])
|
||||
|
||||
// `~ 1.2.3` => `~1.2.3`
|
||||
range = range.replace(re[TILDETRIM], tildeTrimReplace)
|
||||
range = range.replace(re[t.TILDETRIM], tildeTrimReplace)
|
||||
|
||||
// `^ 1.2.3` => `^1.2.3`
|
||||
range = range.replace(re[CARETTRIM], caretTrimReplace)
|
||||
range = range.replace(re[t.CARETTRIM], caretTrimReplace)
|
||||
|
||||
// normalize spaces
|
||||
range = range.split(/\s+/).join(' ')
|
||||
@@ -911,7 +961,7 @@ Range.prototype.parseRange = function (range) {
|
||||
// At this point, the range is completely trimmed and
|
||||
// ready to be split into comparators.
|
||||
|
||||
var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]
|
||||
var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
|
||||
var set = range.split(' ').map(function (comp) {
|
||||
return parseComparator(comp, this.options)
|
||||
}, this).join(' ').split(/\s+/)
|
||||
@@ -934,16 +984,40 @@ Range.prototype.intersects = function (range, options) {
|
||||
}
|
||||
|
||||
return this.set.some(function (thisComparators) {
|
||||
return thisComparators.every(function (thisComparator) {
|
||||
return range.set.some(function (rangeComparators) {
|
||||
return rangeComparators.every(function (rangeComparator) {
|
||||
return thisComparator.intersects(rangeComparator, options)
|
||||
})
|
||||
return (
|
||||
isSatisfiable(thisComparators, options) &&
|
||||
range.set.some(function (rangeComparators) {
|
||||
return (
|
||||
isSatisfiable(rangeComparators, options) &&
|
||||
thisComparators.every(function (thisComparator) {
|
||||
return rangeComparators.every(function (rangeComparator) {
|
||||
return thisComparator.intersects(rangeComparator, options)
|
||||
})
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// take a set of comparators and determine whether there
|
||||
// exists a version which can satisfy it
|
||||
function isSatisfiable (comparators, options) {
|
||||
var result = true
|
||||
var remainingComparators = comparators.slice()
|
||||
var testComparator = remainingComparators.pop()
|
||||
|
||||
while (result && remainingComparators.length) {
|
||||
result = remainingComparators.every(function (otherComparator) {
|
||||
return testComparator.intersects(otherComparator, options)
|
||||
})
|
||||
|
||||
testComparator = remainingComparators.pop()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Mostly just for testing and legacy API reasons
|
||||
exports.toComparators = toComparators
|
||||
function toComparators (range, options) {
|
||||
@@ -987,7 +1061,7 @@ function replaceTildes (comp, options) {
|
||||
}
|
||||
|
||||
function replaceTilde (comp, options) {
|
||||
var r = options.loose ? re[TILDELOOSE] : re[TILDE]
|
||||
var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]
|
||||
return comp.replace(r, function (_, M, m, p, pr) {
|
||||
debug('tilde', comp, _, M, m, p, pr)
|
||||
var ret
|
||||
@@ -1028,7 +1102,7 @@ function replaceCarets (comp, options) {
|
||||
|
||||
function replaceCaret (comp, options) {
|
||||
debug('caret', comp, options)
|
||||
var r = options.loose ? re[CARETLOOSE] : re[CARET]
|
||||
var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET]
|
||||
return comp.replace(r, function (_, M, m, p, pr) {
|
||||
debug('caret', comp, _, M, m, p, pr)
|
||||
var ret
|
||||
@@ -1087,7 +1161,7 @@ function replaceXRanges (comp, options) {
|
||||
|
||||
function replaceXRange (comp, options) {
|
||||
comp = comp.trim()
|
||||
var r = options.loose ? re[XRANGELOOSE] : re[XRANGE]
|
||||
var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]
|
||||
return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
|
||||
debug('xRange', comp, ret, gtlt, M, m, p, pr)
|
||||
var xM = isX(M)
|
||||
@@ -1099,10 +1173,14 @@ function replaceXRange (comp, options) {
|
||||
gtlt = ''
|
||||
}
|
||||
|
||||
// if we're including prereleases in the match, then we need
|
||||
// to fix this to -0, the lowest possible prerelease value
|
||||
pr = options.includePrerelease ? '-0' : ''
|
||||
|
||||
if (xM) {
|
||||
if (gtlt === '>' || gtlt === '<') {
|
||||
// nothing is allowed
|
||||
ret = '<0.0.0'
|
||||
ret = '<0.0.0-0'
|
||||
} else {
|
||||
// nothing is forbidden
|
||||
ret = '*'
|
||||
@@ -1139,11 +1217,12 @@ function replaceXRange (comp, options) {
|
||||
}
|
||||
}
|
||||
|
||||
ret = gtlt + M + '.' + m + '.' + p
|
||||
ret = gtlt + M + '.' + m + '.' + p + pr
|
||||
} else if (xm) {
|
||||
ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
|
||||
ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr
|
||||
} else if (xp) {
|
||||
ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
|
||||
ret = '>=' + M + '.' + m + '.0' + pr +
|
||||
' <' + M + '.' + (+m + 1) + '.0' + pr
|
||||
}
|
||||
|
||||
debug('xRange return', ret)
|
||||
@@ -1157,10 +1236,10 @@ function replaceXRange (comp, options) {
|
||||
function replaceStars (comp, options) {
|
||||
debug('replaceStars', comp, options)
|
||||
// Looseness is ignored here. star is always as loose as it gets!
|
||||
return comp.trim().replace(re[STAR], '')
|
||||
return comp.trim().replace(re[t.STAR], '')
|
||||
}
|
||||
|
||||
// This function is passed to string.replace(re[HYPHENRANGE])
|
||||
// This function is passed to string.replace(re[t.HYPHENRANGE])
|
||||
// M, m, patch, prerelease, build
|
||||
// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
|
||||
// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
|
||||
@@ -1200,7 +1279,11 @@ Range.prototype.test = function (version) {
|
||||
}
|
||||
|
||||
if (typeof version === 'string') {
|
||||
version = new SemVer(version, this.options)
|
||||
try {
|
||||
version = new SemVer(version, this.options)
|
||||
} catch (er) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.set.length; i++) {
|
||||
@@ -1462,22 +1545,52 @@ function intersects (r1, r2, options) {
|
||||
}
|
||||
|
||||
exports.coerce = coerce
|
||||
function coerce (version) {
|
||||
function coerce (version, options) {
|
||||
if (version instanceof SemVer) {
|
||||
return version
|
||||
}
|
||||
|
||||
if (typeof version === 'number') {
|
||||
version = String(version)
|
||||
}
|
||||
|
||||
if (typeof version !== 'string') {
|
||||
return null
|
||||
}
|
||||
|
||||
var match = version.match(re[COERCE])
|
||||
options = options || {}
|
||||
|
||||
if (match == null) {
|
||||
var match = null
|
||||
if (!options.rtl) {
|
||||
match = version.match(re[t.COERCE])
|
||||
} else {
|
||||
// Find the right-most coercible string that does not share
|
||||
// a terminus with a more left-ward coercible string.
|
||||
// Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4'
|
||||
//
|
||||
// Walk through the string checking with a /g regexp
|
||||
// Manually set the index so as to pick up overlapping matches.
|
||||
// Stop when we get a match that ends at the string end, since no
|
||||
// coercible string can be more right-ward without the same terminus.
|
||||
var next
|
||||
while ((next = re[t.COERCERTL].exec(version)) &&
|
||||
(!match || match.index + match[0].length !== version.length)
|
||||
) {
|
||||
if (!match ||
|
||||
next.index + next[0].length !== match.index + match[0].length) {
|
||||
match = next
|
||||
}
|
||||
re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length
|
||||
}
|
||||
// leave it in a clean state
|
||||
re[t.COERCERTL].lastIndex = -1
|
||||
}
|
||||
|
||||
if (match === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return parse(match[1] +
|
||||
'.' + (match[2] || '0') +
|
||||
'.' + (match[3] || '0'))
|
||||
return parse(match[2] +
|
||||
'.' + (match[3] || '0') +
|
||||
'.' + (match[4] || '0'), options)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user