Comparing version 7.3.8 to 7.5.1
@@ -26,3 +26,6 @@ #!/usr/bin/env node | ||
let identifierBase | ||
const semver = require('../') | ||
const parseOptions = require('../internal/parse-options') | ||
@@ -75,2 +78,8 @@ let reverse = false | ||
break | ||
case '-n': | ||
identifierBase = argv.shift() | ||
if (identifierBase === 'false') { | ||
identifierBase = false | ||
} | ||
break | ||
case '-c': case '--coerce': | ||
@@ -93,3 +102,3 @@ coerce = true | ||
options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl } | ||
options = parseOptions({ loose, includePrerelease, rtl }) | ||
@@ -133,3 +142,3 @@ versions = versions.map((v) => { | ||
}).map((v) => { | ||
return inc ? semver.inc(v, inc, options, identifier) : v | ||
return inc ? semver.inc(v, inc, options, identifier, identifierBase) : v | ||
}).forEach((v, i, _) => { | ||
@@ -179,2 +188,7 @@ console.log(v) | ||
-n <base> | ||
Base number to be used for the prerelease identifier. | ||
Can be either 0 or 1, or false to omit the number altogether. | ||
Defaults to 0. | ||
Program exits successfully if any valid version satisfies | ||
@@ -181,0 +195,0 @@ all supplied ranges, and prints all satisfying versions. |
@@ -81,9 +81,2 @@ const ANY = Symbol('SemVer ANY') | ||
if (!options || typeof options !== 'object') { | ||
options = { | ||
loose: !!options, | ||
includePrerelease: false, | ||
} | ||
} | ||
if (this.operator === '') { | ||
@@ -101,28 +94,39 @@ if (this.value === '') { | ||
const sameDirectionIncreasing = | ||
(this.operator === '>=' || this.operator === '>') && | ||
(comp.operator === '>=' || comp.operator === '>') | ||
const sameDirectionDecreasing = | ||
(this.operator === '<=' || this.operator === '<') && | ||
(comp.operator === '<=' || comp.operator === '<') | ||
const sameSemVer = this.semver.version === comp.semver.version | ||
const differentDirectionsInclusive = | ||
(this.operator === '>=' || this.operator === '<=') && | ||
(comp.operator === '>=' || comp.operator === '<=') | ||
const oppositeDirectionsLessThan = | ||
cmp(this.semver, '<', comp.semver, options) && | ||
(this.operator === '>=' || this.operator === '>') && | ||
(comp.operator === '<=' || comp.operator === '<') | ||
const oppositeDirectionsGreaterThan = | ||
cmp(this.semver, '>', comp.semver, options) && | ||
(this.operator === '<=' || this.operator === '<') && | ||
(comp.operator === '>=' || comp.operator === '>') | ||
options = parseOptions(options) | ||
return ( | ||
sameDirectionIncreasing || | ||
sameDirectionDecreasing || | ||
(sameSemVer && differentDirectionsInclusive) || | ||
oppositeDirectionsLessThan || | ||
oppositeDirectionsGreaterThan | ||
) | ||
// Special cases where nothing can possibly be lower | ||
if (options.includePrerelease && | ||
(this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { | ||
return false | ||
} | ||
if (!options.includePrerelease && | ||
(this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { | ||
return false | ||
} | ||
// Same direction increasing (> or >=) | ||
if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { | ||
return true | ||
} | ||
// Same direction decreasing (< or <=) | ||
if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { | ||
return true | ||
} | ||
// same SemVer and both sides are inclusive (<= or >=) | ||
if ( | ||
(this.semver.version === comp.semver.version) && | ||
this.operator.includes('=') && comp.operator.includes('=')) { | ||
return true | ||
} | ||
// opposite directions less than | ||
if (cmp(this.semver, '<', comp.semver, options) && | ||
this.operator.startsWith('>') && comp.operator.startsWith('<')) { | ||
return true | ||
} | ||
// opposite directions greater than | ||
if (cmp(this.semver, '>', comp.semver, options) && | ||
this.operator.startsWith('<') && comp.operator.startsWith('>')) { | ||
return true | ||
} | ||
return false | ||
} | ||
@@ -129,0 +133,0 @@ } |
@@ -84,4 +84,6 @@ // hoisted class for cyclic dependency | ||
// this is a very hot path, and fully deterministic. | ||
const memoOpts = Object.keys(this.options).join(',') | ||
const memoKey = `parseRange:${memoOpts}:${range}` | ||
const memoOpts = | ||
(this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | | ||
(this.options.loose && FLAG_LOOSE) | ||
const memoKey = memoOpts + ':' + range | ||
const cached = cache.get(memoKey) | ||
@@ -194,2 +196,3 @@ if (cached) { | ||
} | ||
module.exports = Range | ||
@@ -211,2 +214,3 @@ | ||
} = require('../internal/re') | ||
const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants') | ||
@@ -213,0 +217,0 @@ const isNullSet = c => c.value === '<0.0.0-0' |
@@ -19,3 +19,3 @@ const debug = require('../internal/debug') | ||
} else if (typeof version !== 'string') { | ||
throw new TypeError(`Invalid Version: ${version}`) | ||
throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) | ||
} | ||
@@ -179,3 +179,3 @@ | ||
// down to pre-release. premajor and prepatch work the same way. | ||
inc (release, identifier) { | ||
inc (release, identifier, identifierBase) { | ||
switch (release) { | ||
@@ -187,3 +187,3 @@ case 'premajor': | ||
this.major++ | ||
this.inc('pre', identifier) | ||
this.inc('pre', identifier, identifierBase) | ||
break | ||
@@ -194,3 +194,3 @@ case 'preminor': | ||
this.minor++ | ||
this.inc('pre', identifier) | ||
this.inc('pre', identifier, identifierBase) | ||
break | ||
@@ -202,4 +202,4 @@ case 'prepatch': | ||
this.prerelease.length = 0 | ||
this.inc('patch', identifier) | ||
this.inc('pre', identifier) | ||
this.inc('patch', identifier, identifierBase) | ||
this.inc('pre', identifier, identifierBase) | ||
break | ||
@@ -210,5 +210,5 @@ // If the input is a non-prerelease version, this acts the same as | ||
if (this.prerelease.length === 0) { | ||
this.inc('patch', identifier) | ||
this.inc('patch', identifier, identifierBase) | ||
} | ||
this.inc('pre', identifier) | ||
this.inc('pre', identifier, identifierBase) | ||
break | ||
@@ -255,5 +255,11 @@ | ||
// 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. | ||
case 'pre': | ||
case 'pre': { | ||
const base = Number(identifierBase) ? 1 : 0 | ||
if (!identifier && identifierBase === false) { | ||
throw new Error('invalid increment argument: identifier is empty') | ||
} | ||
if (this.prerelease.length === 0) { | ||
this.prerelease = [0] | ||
this.prerelease = [base] | ||
} else { | ||
@@ -269,3 +275,6 @@ let i = this.prerelease.length | ||
// didn't increment anything | ||
this.prerelease.push(0) | ||
if (identifier === this.prerelease.join('.') && identifierBase === false) { | ||
throw new Error('invalid increment argument: identifier already exists') | ||
} | ||
this.prerelease.push(base) | ||
} | ||
@@ -276,12 +285,16 @@ } | ||
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 | ||
let prerelease = [identifier, base] | ||
if (identifierBase === false) { | ||
prerelease = [identifier] | ||
} | ||
if (compareIdentifiers(this.prerelease[0], identifier) === 0) { | ||
if (isNaN(this.prerelease[1])) { | ||
this.prerelease = [identifier, 0] | ||
this.prerelease = prerelease | ||
} | ||
} else { | ||
this.prerelease = [identifier, 0] | ||
this.prerelease = prerelease | ||
} | ||
} | ||
break | ||
} | ||
default: | ||
@@ -288,0 +301,0 @@ throw new Error(`invalid increment argument: ${release}`) |
@@ -1,23 +0,54 @@ | ||
const parse = require('./parse') | ||
const eq = require('./eq') | ||
const parse = require('./parse.js') | ||
const diff = (version1, version2) => { | ||
if (eq(version1, version2)) { | ||
const v1 = parse(version1, null, true) | ||
const v2 = parse(version2, null, true) | ||
const comparison = v1.compare(v2) | ||
if (comparison === 0) { | ||
return null | ||
} else { | ||
const v1 = parse(version1) | ||
const v2 = parse(version2) | ||
const hasPre = v1.prerelease.length || v2.prerelease.length | ||
const prefix = hasPre ? 'pre' : '' | ||
const defaultResult = hasPre ? 'prerelease' : '' | ||
for (const key in v1) { | ||
if (key === 'major' || key === 'minor' || key === 'patch') { | ||
if (v1[key] !== v2[key]) { | ||
return prefix + key | ||
} | ||
} | ||
} | ||
return defaultResult // may be undefined | ||
} | ||
const v1Higher = comparison > 0 | ||
const highVersion = v1Higher ? v1 : v2 | ||
const lowVersion = v1Higher ? v2 : v1 | ||
const highHasPre = !!highVersion.prerelease.length | ||
// add the `pre` prefix if we are going to a prerelease version | ||
const prefix = highHasPre ? 'pre' : '' | ||
if (v1.major !== v2.major) { | ||
return prefix + 'major' | ||
} | ||
if (v1.minor !== v2.minor) { | ||
return prefix + 'minor' | ||
} | ||
if (v1.patch !== v2.patch) { | ||
return prefix + 'patch' | ||
} | ||
// at this point we know stable versions match but overall versions are not equal, | ||
// so either they are both prereleases, or the lower version is a prerelease | ||
if (highHasPre) { | ||
// high and low are preleases | ||
return 'prerelease' | ||
} | ||
if (lowVersion.patch) { | ||
// anything higher than a patch bump would result in the wrong version | ||
return 'patch' | ||
} | ||
if (lowVersion.minor) { | ||
// anything higher than a minor bump would result in the wrong version | ||
return 'minor' | ||
} | ||
// bumping major/minor/patch all have same result | ||
return 'major' | ||
} | ||
module.exports = diff |
const SemVer = require('../classes/semver') | ||
const inc = (version, release, options, identifier) => { | ||
const inc = (version, release, options, identifier, identifierBase) => { | ||
if (typeof (options) === 'string') { | ||
identifierBase = identifier | ||
identifier = options | ||
@@ -13,3 +14,3 @@ options = undefined | ||
options | ||
).inc(release, identifier).version | ||
).inc(release, identifier, identifierBase).version | ||
} catch (er) { | ||
@@ -16,0 +17,0 @@ return null |
@@ -1,30 +0,13 @@ | ||
const { MAX_LENGTH } = require('../internal/constants') | ||
const { re, t } = require('../internal/re') | ||
const SemVer = require('../classes/semver') | ||
const parseOptions = require('../internal/parse-options') | ||
const parse = (version, options) => { | ||
options = parseOptions(options) | ||
const parse = (version, options, throwErrors = false) => { | ||
if (version instanceof SemVer) { | ||
return version | ||
} | ||
if (typeof version !== 'string') { | ||
return null | ||
} | ||
if (version.length > MAX_LENGTH) { | ||
return null | ||
} | ||
const r = options.loose ? re[t.LOOSE] : re[t.FULL] | ||
if (!r.test(version)) { | ||
return null | ||
} | ||
try { | ||
return new SemVer(version, options) | ||
} catch (er) { | ||
return null | ||
if (!throwErrors) { | ||
return null | ||
} | ||
throw er | ||
} | ||
@@ -31,0 +14,0 @@ } |
@@ -86,4 +86,5 @@ // just pre-load all the stuff that index.js lazily exports | ||
SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, | ||
RELEASE_TYPES: constants.RELEASE_TYPES, | ||
compareIdentifiers: identifiers.compareIdentifiers, | ||
rcompareIdentifiers: identifiers.rcompareIdentifiers, | ||
} |
@@ -12,7 +12,20 @@ // Note: this is the semver.org version of the spec that it implements | ||
const RELEASE_TYPES = [ | ||
'major', | ||
'premajor', | ||
'minor', | ||
'preminor', | ||
'patch', | ||
'prepatch', | ||
'prerelease', | ||
] | ||
module.exports = { | ||
SEMVER_SPEC_VERSION, | ||
MAX_LENGTH, | ||
MAX_SAFE_COMPONENT_LENGTH, | ||
MAX_SAFE_INTEGER, | ||
MAX_SAFE_COMPONENT_LENGTH, | ||
RELEASE_TYPES, | ||
SEMVER_SPEC_VERSION, | ||
FLAG_INCLUDE_PRERELEASE: 0b001, | ||
FLAG_LOOSE: 0b010, | ||
} |
@@ -1,11 +0,15 @@ | ||
// parse out just the options we care about so we always get a consistent | ||
// obj with keys in a consistent order. | ||
const opts = ['includePrerelease', 'loose', 'rtl'] | ||
const parseOptions = options => | ||
!options ? {} | ||
: typeof options !== 'object' ? { loose: true } | ||
: opts.filter(k => options[k]).reduce((o, k) => { | ||
o[k] = true | ||
return o | ||
}, {}) | ||
// parse out just the options we care about | ||
const looseOption = Object.freeze({ loose: true }) | ||
const emptyOpts = Object.freeze({ }) | ||
const parseOptions = options => { | ||
if (!options) { | ||
return emptyOpts | ||
} | ||
if (typeof options !== 'object') { | ||
return looseOption | ||
} | ||
return options | ||
} | ||
module.exports = parseOptions |
{ | ||
"name": "semver", | ||
"version": "7.3.8", | ||
"version": "7.5.1", | ||
"description": "The semantic version parser used by npm.", | ||
@@ -16,4 +16,4 @@ "main": "index.js", | ||
"devDependencies": { | ||
"@npmcli/eslint-config": "^3.0.1", | ||
"@npmcli/template-oss": "4.4.4", | ||
"@npmcli/eslint-config": "^4.0.0", | ||
"@npmcli/template-oss": "4.14.1", | ||
"tap": "^16.0.0" | ||
@@ -57,5 +57,4 @@ }, | ||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", | ||
"version": "4.4.4", | ||
"version": "4.14.1", | ||
"engines": ">=10", | ||
"content": "./scripts", | ||
"ciVersions": [ | ||
@@ -69,2 +68,3 @@ "10.0.0", | ||
], | ||
"npmSpec": "8", | ||
"distPaths": [ | ||
@@ -87,4 +87,5 @@ "classes/", | ||
"/range.bnf" | ||
] | ||
], | ||
"publish": "true" | ||
} | ||
} |
@@ -5,4 +5,4 @@ const Range = require('../classes/range') | ||
r2 = new Range(r2, options) | ||
return r1.intersects(r2) | ||
return r1.intersects(r2, options) | ||
} | ||
module.exports = intersects |
@@ -71,2 +71,5 @@ const Range = require('../classes/range.js') | ||
const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] | ||
const minimumVersion = [new Comparator('>=0.0.0')] | ||
const simpleSubset = (sub, dom, options) => { | ||
@@ -81,5 +84,5 @@ if (sub === dom) { | ||
} else if (options.includePrerelease) { | ||
sub = [new Comparator('>=0.0.0-0')] | ||
sub = minimumVersionWithPreRelease | ||
} else { | ||
sub = [new Comparator('>=0.0.0')] | ||
sub = minimumVersion | ||
} | ||
@@ -92,3 +95,3 @@ } | ||
} else { | ||
dom = [new Comparator('>=0.0.0')] | ||
dom = minimumVersion | ||
} | ||
@@ -95,0 +98,0 @@ } |
@@ -113,2 +113,5 @@ semver(1) -- The semantic versioner for npm | ||
-n <0|1> | ||
This is the base to be used for the prerelease identifier. | ||
-p --include-prerelease | ||
@@ -236,2 +239,31 @@ Always include prerelease versions in range matching | ||
#### Prerelease Identifier Base | ||
The method `.inc` takes an optional parameter 'identifierBase' string | ||
that will let you let your prerelease number as zero-based or one-based. | ||
Set to `false` to omit the prerelease number altogether. | ||
If you do not specify this parameter, it will default to zero-based. | ||
```javascript | ||
semver.inc('1.2.3', 'prerelease', 'beta', '1') | ||
// '1.2.4-beta.1' | ||
``` | ||
```javascript | ||
semver.inc('1.2.3', 'prerelease', 'beta', false) | ||
// '1.2.4-beta' | ||
``` | ||
command-line example: | ||
```bash | ||
$ semver 1.2.3 -i prerelease --preid beta -n 1 | ||
1.2.4-beta.1 | ||
``` | ||
```bash | ||
$ semver 1.2.3 -i prerelease --preid beta -n false | ||
1.2.4-beta | ||
``` | ||
### Advanced Range Syntax | ||
@@ -518,2 +550,36 @@ | ||
## Constants | ||
As a convenience, helper constants are exported to provide information about what `node-semver` supports: | ||
### `RELEASE_TYPES` | ||
- major | ||
- premajor | ||
- minor | ||
- preminor | ||
- patch | ||
- prepatch | ||
- prerelease | ||
``` | ||
const semver = require('semver'); | ||
if (semver.RELEASE_TYPES.includes(arbitraryUserInput)) { | ||
console.log('This is a valid release type!'); | ||
} else { | ||
console.warn('This is NOT a valid release type!'); | ||
} | ||
``` | ||
### `SEMVER_SPEC_VERSION` | ||
2.0.0 | ||
``` | ||
const semver = require('semver'); | ||
console.log('We are currently using the semver specification version:', semver.SEMVER_SPEC_VERSION); | ||
``` | ||
## Exported Modules | ||
@@ -572,1 +638,2 @@ | ||
* `require('semver/ranges/valid')` | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
91379
2025
636
0