Socket
Socket
Sign inDemoInstall

semver

Package Overview
Dependencies
Maintainers
6
Versions
108
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

semver - npm Package Compare versions

Comparing version 7.3.8 to 7.5.2

18

bin/semver.js

@@ -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.

71

classes/comparator.js

@@ -19,2 +19,3 @@ const ANY = Symbol('SemVer ANY')

comp = comp.trim().split(/\s+/).join(' ')
debug('comparator', comp, options)

@@ -82,9 +83,2 @@ this.options = options

if (!options || typeof options !== 'object') {
options = {
loose: !!options,
includePrerelease: false,
}
}
if (this.operator === '') {

@@ -102,28 +96,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
}

@@ -135,3 +140,3 @@ }

const parseOptions = require('../internal/parse-options')
const { re, t } = require('../internal/re')
const { safeRe: re, t } = require('../internal/re')
const cmp = require('../functions/cmp')

@@ -138,0 +143,0 @@ const debug = require('../internal/debug')

@@ -29,8 +29,15 @@ // hoisted class for cyclic dependency

// First, split based on boolean or ||
// First reduce all whitespace as much as possible so we do not have to rely
// on potentially slow regexes like \s*. This is then stored and used for
// future error messages as well.
this.raw = range
this.set = range
.trim()
.split(/\s+/)
.join(' ')
// First, split on ||
this.set = this.raw
.split('||')
// map the range to a 2d array of comparators
.map(r => this.parseRange(r.trim()))
.map(r => this.parseRange(r))
// throw out any comparator lists that are empty

@@ -42,3 +49,3 @@ // this generally means that it was not a valid range, which is allowed

if (!this.set.length) {
throw new TypeError(`Invalid SemVer Range: ${range}`)
throw new TypeError(`Invalid SemVer Range: ${this.raw}`)
}

@@ -69,5 +76,3 @@

this.range = this.set
.map((comps) => {
return comps.join(' ').trim()
})
.map((comps) => comps.join(' ').trim())
.join('||')

@@ -83,8 +88,8 @@ .trim()

parseRange (range) {
range = range.trim()
// memoize range parsing for performance.
// 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)

@@ -110,5 +115,2 @@ if (cached) {

// normalize spaces
range = range.split(/\s+/).join(' ')
// At this point, the range is completely trimmed and

@@ -198,2 +200,3 @@ // ready to be split into comparators.

}
module.exports = Range

@@ -209,3 +212,3 @@

const {
re,
safeRe: re,
t,

@@ -216,2 +219,3 @@ comparatorTrimReplace,

} = require('../internal/re')
const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants')

@@ -264,6 +268,9 @@ const isNullSet = c => c.value === '<0.0.0-0'

// ~0.0.1 --> >=0.0.1 <0.1.0-0
const replaceTildes = (comp, options) =>
comp.trim().split(/\s+/).map((c) => {
return replaceTilde(c, options)
}).join(' ')
const replaceTildes = (comp, options) => {
return comp
.trim()
.split(/\s+/)
.map((c) => replaceTilde(c, options))
.join(' ')
}

@@ -306,6 +313,9 @@ const replaceTilde = (comp, options) => {

// ^0.1.0 --> >=0.1.0 <0.2.0-0
const replaceCarets = (comp, options) =>
comp.trim().split(/\s+/).map((c) => {
return replaceCaret(c, options)
}).join(' ')
const replaceCarets = (comp, options) => {
return comp
.trim()
.split(/\s+/)
.map((c) => replaceCaret(c, options))
.join(' ')
}

@@ -367,5 +377,6 @@ const replaceCaret = (comp, options) => {

debug('replaceXRanges', comp, options)
return comp.split(/\s+/).map((c) => {
return replaceXRange(c, options)
}).join(' ')
return comp
.split(/\s+/)
.map((c) => replaceXRange(c, options))
.join(' ')
}

@@ -453,3 +464,5 @@

// Looseness is ignored here. star is always as loose as it gets!
return comp.trim().replace(re[t.STAR], '')
return comp
.trim()
.replace(re[t.STAR], '')
}

@@ -459,3 +472,4 @@

debug('replaceGTE0', comp, options)
return comp.trim()
return comp
.trim()
.replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '')

@@ -498,3 +512,3 @@ }

return (`${from} ${to}`).trim()
return `${from} ${to}`.trim()
}

@@ -501,0 +515,0 @@

const debug = require('../internal/debug')
const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants')
const { re, t } = require('../internal/re')
const { safeRe: re, t } = require('../internal/re')

@@ -19,3 +19,3 @@ const parseOptions = require('../internal/parse-options')

} 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,17 +285,23 @@ }

// 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:
throw new Error(`invalid increment argument: ${release}`)
}
this.format()
this.raw = this.version
this.raw = this.format()
if (this.build.length) {
this.raw += `+${this.build.join('.')}`
}
return this

@@ -293,0 +308,0 @@ }

const SemVer = require('../classes/semver')
const parse = require('./parse')
const { re, t } = require('../internal/re')
const { safeRe: re, t } = require('../internal/re')

@@ -5,0 +5,0 @@ const coerce = (version, options) => {

@@ -1,23 +0,65 @@

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
}
}
}
const v1Higher = comparison > 0
const highVersion = v1Higher ? v1 : v2
const lowVersion = v1Higher ? v2 : v1
const highHasPre = !!highVersion.prerelease.length
const lowHasPre = !!lowVersion.prerelease.length
if (lowHasPre && !highHasPre) {
// Going from prerelease -> no prerelease requires some special casing
// If the low version has only a major, then it will always be a major
// Some examples:
// 1.0.0-1 -> 1.0.0
// 1.0.0-1 -> 1.1.1
// 1.0.0-1 -> 2.0.0
if (!lowVersion.patch && !lowVersion.minor) {
return 'major'
}
return defaultResult // may be undefined
// Otherwise it can be determined by checking the high version
if (highVersion.patch) {
// anything higher than a patch bump would result in the wrong version
return 'patch'
}
if (highVersion.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'
}
// 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'
}
// high and low are preleases
return 'prerelease'
}
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

@@ -7,2 +7,3 @@ const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants')

const re = exports.re = []
const safeRe = exports.safeRe = []
const src = exports.src = []

@@ -13,2 +14,11 @@ const t = exports.t = {}

const createToken = (name, value, isGlobal) => {
// Replace all greedy whitespace to prevent regex dos issues. These regex are
// used internally via the safeRe object since all inputs in this library get
// normalized first to trim and collapse all extra whitespace. The original
// regexes are exported for userland consumption and lower level usage. A
// future breaking change could export the safer regex only with a note that
// all input should have extra whitespace removed.
const safe = value
.split('\\s*').join('\\s{0,1}')
.split('\\s+').join('\\s')
const index = R++

@@ -19,2 +29,3 @@ debug(name, index, value)

re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined)
}

@@ -21,0 +32,0 @@

{
"name": "semver",
"version": "7.3.8",
"version": "7.5.2",
"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.15.1",
"tap": "^16.0.0"

@@ -41,3 +41,3 @@ },

"tap": {
"check-coverage": true,
"timeout": 30,
"coverage-map": "map.js",

@@ -58,5 +58,4 @@ "nyc-arg": [

"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"version": "4.4.4",
"version": "4.15.1",
"engines": ">=10",
"content": "./scripts",
"ciVersions": [

@@ -70,2 +69,3 @@ "10.0.0",

],
"npmSpec": "8",
"distPaths": [

@@ -88,4 +88,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')`
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc