semver
Advanced tools
Comparing version 7.3.2 to 7.5.2
@@ -26,10 +26,15 @@ #!/usr/bin/env node | ||
let identifierBase | ||
const semver = require('../') | ||
const parseOptions = require('../internal/parse-options') | ||
let reverse = false | ||
const options = {} | ||
let options = {} | ||
const main = () => { | ||
if (!argv.length) return help() | ||
if (!argv.length) { | ||
return help() | ||
} | ||
while (argv.length) { | ||
@@ -39,4 +44,5 @@ let a = argv.shift() | ||
if (indexOfEqualSign !== -1) { | ||
const value = a.slice(indexOfEqualSign + 1) | ||
a = a.slice(0, indexOfEqualSign) | ||
argv.unshift(a.slice(indexOfEqualSign + 1)) | ||
argv.unshift(value) | ||
} | ||
@@ -73,2 +79,8 @@ switch (a) { | ||
break | ||
case '-n': | ||
identifierBase = argv.shift() | ||
if (identifierBase === 'false') { | ||
identifierBase = false | ||
} | ||
break | ||
case '-c': case '--coerce': | ||
@@ -91,3 +103,3 @@ coerce = true | ||
const options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl } | ||
options = parseOptions({ loose, includePrerelease, rtl }) | ||
@@ -99,4 +111,8 @@ versions = versions.map((v) => { | ||
}) | ||
if (!versions.length) return fail() | ||
if (inc && (versions.length !== 1 || range.length)) { return failInc() } | ||
if (!versions.length) { | ||
return fail() | ||
} | ||
if (inc && (versions.length !== 1 || range.length)) { | ||
return failInc() | ||
} | ||
@@ -107,3 +123,5 @@ for (let i = 0, l = range.length; i < l; i++) { | ||
}) | ||
if (!versions.length) return fail() | ||
if (!versions.length) { | ||
return fail() | ||
} | ||
} | ||
@@ -113,3 +131,2 @@ return success(versions) | ||
const failInc = () => { | ||
@@ -129,4 +146,6 @@ console.error('--inc can only be used on a single version with no range') | ||
}).map((v) => { | ||
return inc ? semver.inc(v, inc, options, identifier) : v | ||
}).forEach((v, i, _) => { console.log(v) }) | ||
return inc ? semver.inc(v, inc, options, identifier, identifierBase) : v | ||
}).forEach((v, i, _) => { | ||
console.log(v) | ||
}) | ||
} | ||
@@ -173,2 +192,7 @@ | ||
-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 | ||
@@ -175,0 +199,0 @@ all supplied ranges, and prints all satisfying versions. |
@@ -7,9 +7,5 @@ const ANY = Symbol('SemVer ANY') | ||
} | ||
constructor (comp, options) { | ||
if (!options || typeof options !== 'object') { | ||
options = { | ||
loose: !!options, | ||
includePrerelease: false | ||
} | ||
} | ||
options = parseOptions(options) | ||
@@ -24,2 +20,3 @@ if (comp instanceof Comparator) { | ||
comp = comp.trim().split(/\s+/).join(' ') | ||
debug('comparator', comp, options) | ||
@@ -87,9 +84,2 @@ this.options = options | ||
if (!options || typeof options !== 'object') { | ||
options = { | ||
loose: !!options, | ||
includePrerelease: false | ||
} | ||
} | ||
if (this.operator === '') { | ||
@@ -107,28 +97,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 | ||
} | ||
@@ -139,3 +140,4 @@ } | ||
const {re, t} = require('../internal/re') | ||
const parseOptions = require('../internal/parse-options') | ||
const { safeRe: re, t } = require('../internal/re') | ||
const cmp = require('../functions/cmp') | ||
@@ -142,0 +144,0 @@ const debug = require('../internal/debug') |
module.exports = { | ||
SemVer: require('./semver.js'), | ||
Range: require('./range.js'), | ||
Comparator: require('./comparator.js') | ||
Comparator: require('./comparator.js'), | ||
} |
// hoisted class for cyclic dependency | ||
class Range { | ||
constructor (range, options) { | ||
if (!options || typeof options !== 'object') { | ||
options = { | ||
loose: !!options, | ||
includePrerelease: false | ||
} | ||
} | ||
options = parseOptions(options) | ||
@@ -34,8 +29,15 @@ if (range instanceof Range) { | ||
// 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 | ||
.split(/\s*\|\|\s*/) | ||
.trim() | ||
.split(/\s+/) | ||
.join(' ') | ||
// First, split on || | ||
this.set = this.raw | ||
.split('||') | ||
// map the range to a 2d array of comparators | ||
.map(range => this.parseRange(range.trim())) | ||
.map(r => this.parseRange(r)) | ||
// throw out any comparator lists that are empty | ||
@@ -47,5 +49,23 @@ // 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}`) | ||
} | ||
// if we have any that are not the null set, throw out null sets. | ||
if (this.set.length > 1) { | ||
// keep the first one, in case they're all null sets | ||
const first = this.set[0] | ||
this.set = this.set.filter(c => !isNullSet(c[0])) | ||
if (this.set.length === 0) { | ||
this.set = [first] | ||
} else if (this.set.length > 1) { | ||
// if we have any that are *, then the range is just * | ||
for (const c of this.set) { | ||
if (c.length === 1 && isAny(c[0])) { | ||
this.set = [c] | ||
break | ||
} | ||
} | ||
} | ||
} | ||
this.format() | ||
@@ -56,5 +76,3 @@ } | ||
this.range = this.set | ||
.map((comps) => { | ||
return comps.join(' ').trim() | ||
}) | ||
.map((comps) => comps.join(' ').trim()) | ||
.join('||') | ||
@@ -70,4 +88,14 @@ .trim() | ||
parseRange (range) { | ||
// memoize range parsing for performance. | ||
// this is a very hot path, and fully deterministic. | ||
const memoOpts = | ||
(this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | | ||
(this.options.loose && FLAG_LOOSE) | ||
const memoKey = memoOpts + ':' + range | ||
const cached = cache.get(memoKey) | ||
if (cached) { | ||
return cached | ||
} | ||
const loose = this.options.loose | ||
range = range.trim() | ||
// `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` | ||
@@ -79,3 +107,3 @@ const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] | ||
range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) | ||
debug('comparator trim', range, re[t.COMPARATORTRIM]) | ||
debug('comparator trim', range) | ||
@@ -88,10 +116,6 @@ // `~ 1.2.3` => `~1.2.3` | ||
// normalize spaces | ||
range = range.split(/\s+/).join(' ') | ||
// At this point, the range is completely trimmed and | ||
// ready to be split into comparators. | ||
const compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] | ||
return range | ||
let rangeList = range | ||
.split(' ') | ||
@@ -101,6 +125,32 @@ .map(comp => parseComparator(comp, this.options)) | ||
.split(/\s+/) | ||
// >=0.0.0 is equivalent to * | ||
.map(comp => replaceGTE0(comp, this.options)) | ||
if (loose) { | ||
// in loose mode, throw out any that are not valid comparators | ||
.filter(this.options.loose ? comp => !!comp.match(compRe) : () => true) | ||
.map(comp => new Comparator(comp, this.options)) | ||
rangeList = rangeList.filter(comp => { | ||
debug('loose invalid filter', comp, this.options) | ||
return !!comp.match(re[t.COMPARATORLOOSE]) | ||
}) | ||
} | ||
debug('range list', rangeList) | ||
// if any comparators are the null set, then replace with JUST null set | ||
// if more than one comparator, remove any * comparators | ||
// also, don't include the same comparator more than once | ||
const rangeMap = new Map() | ||
const comparators = rangeList.map(comp => new Comparator(comp, this.options)) | ||
for (const comp of comparators) { | ||
if (isNullSet(comp)) { | ||
return [comp] | ||
} | ||
rangeMap.set(comp.value, comp) | ||
} | ||
if (rangeMap.size > 1 && rangeMap.has('')) { | ||
rangeMap.delete('') | ||
} | ||
const result = [...rangeMap.values()] | ||
cache.set(memoKey, result) | ||
return result | ||
} | ||
@@ -152,4 +202,9 @@ | ||
} | ||
module.exports = Range | ||
const LRU = require('lru-cache') | ||
const cache = new LRU({ max: 1000 }) | ||
const parseOptions = require('../internal/parse-options') | ||
const Comparator = require('./comparator') | ||
@@ -159,9 +214,13 @@ const debug = require('../internal/debug') | ||
const { | ||
re, | ||
safeRe: re, | ||
t, | ||
comparatorTrimReplace, | ||
tildeTrimReplace, | ||
caretTrimReplace | ||
caretTrimReplace, | ||
} = require('../internal/re') | ||
const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants') | ||
const isNullSet = c => c.value === '<0.0.0-0' | ||
const isAny = c => c.value === '' | ||
// take a set of comparators and determine whether there | ||
@@ -209,6 +268,10 @@ // exists a version which can satisfy it | ||
// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 | ||
const replaceTildes = (comp, options) => | ||
comp.trim().split(/\s+/).map((comp) => { | ||
return replaceTilde(comp, options) | ||
}).join(' ') | ||
// ~0.0.1 --> >=0.0.1 <0.1.0-0 | ||
const replaceTildes = (comp, options) => { | ||
return comp | ||
.trim() | ||
.split(/\s+/) | ||
.map((c) => replaceTilde(c, options)) | ||
.join(' ') | ||
} | ||
@@ -249,6 +312,11 @@ const replaceTilde = (comp, options) => { | ||
// ^1.2.0 --> >=1.2.0 <2.0.0-0 | ||
const replaceCarets = (comp, options) => | ||
comp.trim().split(/\s+/).map((comp) => { | ||
return replaceCaret(comp, options) | ||
}).join(' ') | ||
// ^0.0.1 --> >=0.0.1 <0.0.2-0 | ||
// ^0.1.0 --> >=0.1.0 <0.2.0-0 | ||
const replaceCarets = (comp, options) => { | ||
return comp | ||
.trim() | ||
.split(/\s+/) | ||
.map((c) => replaceCaret(c, options)) | ||
.join(' ') | ||
} | ||
@@ -310,5 +378,6 @@ const replaceCaret = (comp, options) => { | ||
debug('replaceXRanges', comp, options) | ||
return comp.split(/\s+/).map((comp) => { | ||
return replaceXRange(comp, options) | ||
}).join(' ') | ||
return comp | ||
.split(/\s+/) | ||
.map((c) => replaceXRange(c, options)) | ||
.join(' ') | ||
} | ||
@@ -373,4 +442,5 @@ | ||
if (gtlt === '<') | ||
if (gtlt === '<') { | ||
pr = '-0' | ||
} | ||
@@ -396,3 +466,5 @@ ret = `${gtlt + M}.${m}.${p}${pr}` | ||
// 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], '') | ||
} | ||
@@ -402,3 +474,4 @@ | ||
debug('replaceGTE0', comp, options) | ||
return comp.trim() | ||
return comp | ||
.trim() | ||
.replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') | ||
@@ -441,3 +514,3 @@ } | ||
return (`${from} ${to}`).trim() | ||
return `${from} ${to}`.trim() | ||
} | ||
@@ -444,0 +517,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') | ||
const parseOptions = require('../internal/parse-options') | ||
const { compareIdentifiers } = require('../internal/identifiers') | ||
class SemVer { | ||
constructor (version, options) { | ||
if (!options || typeof options !== 'object') { | ||
options = { | ||
loose: !!options, | ||
includePrerelease: false | ||
} | ||
} | ||
options = parseOptions(options) | ||
if (version instanceof SemVer) { | ||
@@ -22,3 +19,3 @@ if (version.loose === !!options.loose && | ||
} else if (typeof version !== 'string') { | ||
throw new TypeError(`Invalid Version: ${version}`) | ||
throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) | ||
} | ||
@@ -182,3 +179,3 @@ | ||
// down to pre-release. premajor and prepatch work the same way. | ||
inc (release, identifier) { | ||
inc (release, identifier, identifierBase) { | ||
switch (release) { | ||
@@ -190,3 +187,3 @@ case 'premajor': | ||
this.major++ | ||
this.inc('pre', identifier) | ||
this.inc('pre', identifier, identifierBase) | ||
break | ||
@@ -197,3 +194,3 @@ case 'preminor': | ||
this.minor++ | ||
this.inc('pre', identifier) | ||
this.inc('pre', identifier, identifierBase) | ||
break | ||
@@ -205,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 | ||
@@ -213,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 | ||
@@ -258,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 { | ||
@@ -272,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) | ||
} | ||
@@ -279,17 +285,23 @@ } | ||
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 | ||
if (this.prerelease[0] === identifier) { | ||
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 | ||
@@ -296,0 +308,0 @@ } |
@@ -11,13 +11,17 @@ const eq = require('./eq') | ||
case '===': | ||
if (typeof a === 'object') | ||
if (typeof a === 'object') { | ||
a = a.version | ||
if (typeof b === 'object') | ||
} | ||
if (typeof b === 'object') { | ||
b = b.version | ||
} | ||
return a === b | ||
case '!==': | ||
if (typeof a === 'object') | ||
if (typeof a === 'object') { | ||
a = a.version | ||
if (typeof b === 'object') | ||
} | ||
if (typeof b === 'object') { | ||
b = b.version | ||
} | ||
return a !== b | ||
@@ -24,0 +28,0 @@ |
const SemVer = require('../classes/semver') | ||
const parse = require('./parse') | ||
const {re, t} = require('../internal/re') | ||
const { safeRe: re, t } = require('../internal/re') | ||
@@ -46,4 +46,5 @@ const coerce = (version, options) => { | ||
if (match === null) | ||
if (match === null) { | ||
return null | ||
} | ||
@@ -50,0 +51,0 @@ return parse(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, 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 | ||
@@ -10,3 +11,6 @@ options = undefined | ||
try { | ||
return new SemVer(version, options).inc(release, identifier).version | ||
return new SemVer( | ||
version instanceof SemVer ? version.version : version, | ||
options | ||
).inc(release, identifier, identifierBase).version | ||
} catch (er) { | ||
@@ -13,0 +17,0 @@ return null |
@@ -1,34 +0,13 @@ | ||
const {MAX_LENGTH} = require('../internal/constants') | ||
const { re, t } = require('../internal/re') | ||
const SemVer = require('../classes/semver') | ||
const parse = (version, options) => { | ||
if (!options || typeof options !== 'object') { | ||
options = { | ||
loose: !!options, | ||
includePrerelease: false | ||
} | ||
} | ||
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 | ||
} | ||
@@ -35,0 +14,0 @@ } |
123
index.js
// just pre-load all the stuff that index.js lazily exports | ||
const internalRe = require('./internal/re') | ||
const constants = require('./internal/constants') | ||
const SemVer = require('./classes/semver') | ||
const identifiers = require('./internal/identifiers') | ||
const parse = require('./functions/parse') | ||
const valid = require('./functions/valid') | ||
const clean = require('./functions/clean') | ||
const inc = require('./functions/inc') | ||
const diff = require('./functions/diff') | ||
const major = require('./functions/major') | ||
const minor = require('./functions/minor') | ||
const patch = require('./functions/patch') | ||
const prerelease = require('./functions/prerelease') | ||
const compare = require('./functions/compare') | ||
const rcompare = require('./functions/rcompare') | ||
const compareLoose = require('./functions/compare-loose') | ||
const compareBuild = require('./functions/compare-build') | ||
const sort = require('./functions/sort') | ||
const rsort = require('./functions/rsort') | ||
const gt = require('./functions/gt') | ||
const lt = require('./functions/lt') | ||
const eq = require('./functions/eq') | ||
const neq = require('./functions/neq') | ||
const gte = require('./functions/gte') | ||
const lte = require('./functions/lte') | ||
const cmp = require('./functions/cmp') | ||
const coerce = require('./functions/coerce') | ||
const Comparator = require('./classes/comparator') | ||
const Range = require('./classes/range') | ||
const satisfies = require('./functions/satisfies') | ||
const toComparators = require('./ranges/to-comparators') | ||
const maxSatisfying = require('./ranges/max-satisfying') | ||
const minSatisfying = require('./ranges/min-satisfying') | ||
const minVersion = require('./ranges/min-version') | ||
const validRange = require('./ranges/valid') | ||
const outside = require('./ranges/outside') | ||
const gtr = require('./ranges/gtr') | ||
const ltr = require('./ranges/ltr') | ||
const intersects = require('./ranges/intersects') | ||
const simplifyRange = require('./ranges/simplify') | ||
const subset = require('./ranges/subset') | ||
module.exports = { | ||
parse, | ||
valid, | ||
clean, | ||
inc, | ||
diff, | ||
major, | ||
minor, | ||
patch, | ||
prerelease, | ||
compare, | ||
rcompare, | ||
compareLoose, | ||
compareBuild, | ||
sort, | ||
rsort, | ||
gt, | ||
lt, | ||
eq, | ||
neq, | ||
gte, | ||
lte, | ||
cmp, | ||
coerce, | ||
Comparator, | ||
Range, | ||
satisfies, | ||
toComparators, | ||
maxSatisfying, | ||
minSatisfying, | ||
minVersion, | ||
validRange, | ||
outside, | ||
gtr, | ||
ltr, | ||
intersects, | ||
simplifyRange, | ||
subset, | ||
SemVer, | ||
re: internalRe.re, | ||
src: internalRe.src, | ||
tokens: internalRe.t, | ||
SEMVER_SPEC_VERSION: require('./internal/constants').SEMVER_SPEC_VERSION, | ||
SemVer: require('./classes/semver'), | ||
compareIdentifiers: require('./internal/identifiers').compareIdentifiers, | ||
rcompareIdentifiers: require('./internal/identifiers').rcompareIdentifiers, | ||
parse: require('./functions/parse'), | ||
valid: require('./functions/valid'), | ||
clean: require('./functions/clean'), | ||
inc: require('./functions/inc'), | ||
diff: require('./functions/diff'), | ||
major: require('./functions/major'), | ||
minor: require('./functions/minor'), | ||
patch: require('./functions/patch'), | ||
prerelease: require('./functions/prerelease'), | ||
compare: require('./functions/compare'), | ||
rcompare: require('./functions/rcompare'), | ||
compareLoose: require('./functions/compare-loose'), | ||
compareBuild: require('./functions/compare-build'), | ||
sort: require('./functions/sort'), | ||
rsort: require('./functions/rsort'), | ||
gt: require('./functions/gt'), | ||
lt: require('./functions/lt'), | ||
eq: require('./functions/eq'), | ||
neq: require('./functions/neq'), | ||
gte: require('./functions/gte'), | ||
lte: require('./functions/lte'), | ||
cmp: require('./functions/cmp'), | ||
coerce: require('./functions/coerce'), | ||
Comparator: require('./classes/comparator'), | ||
Range: require('./classes/range'), | ||
satisfies: require('./functions/satisfies'), | ||
toComparators: require('./ranges/to-comparators'), | ||
maxSatisfying: require('./ranges/max-satisfying'), | ||
minSatisfying: require('./ranges/min-satisfying'), | ||
minVersion: require('./ranges/min-version'), | ||
validRange: require('./ranges/valid'), | ||
outside: require('./ranges/outside'), | ||
gtr: require('./ranges/gtr'), | ||
ltr: require('./ranges/ltr'), | ||
intersects: require('./ranges/intersects'), | ||
simplifyRange: require('./ranges/simplify'), | ||
subset: require('./ranges/subset'), | ||
SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, | ||
RELEASE_TYPES: constants.RELEASE_TYPES, | ||
compareIdentifiers: identifiers.compareIdentifiers, | ||
rcompareIdentifiers: identifiers.rcompareIdentifiers, | ||
} |
@@ -7,3 +7,3 @@ // Note: this is the semver.org version of the spec that it implements | ||
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || | ||
/* istanbul ignore next */ 9007199254740991 | ||
/* istanbul ignore next */ 9007199254740991 | ||
@@ -13,7 +13,20 @@ // Max safe segment length for coercion. | ||
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, | ||
} |
@@ -22,3 +22,3 @@ const numeric = /^[0-9]+$/ | ||
compareIdentifiers, | ||
rcompareIdentifiers | ||
rcompareIdentifiers, | ||
} |
@@ -7,2 +7,3 @@ const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants') | ||
const re = exports.re = [] | ||
const safeRe = exports.safeRe = [] | ||
const src = exports.src = [] | ||
@@ -13,7 +14,17 @@ 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++ | ||
debug(index, value) | ||
debug(name, index, value) | ||
t[name] = index | ||
src[index] = value | ||
re[index] = new RegExp(value, isGlobal ? 'g' : undefined) | ||
safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined) | ||
} | ||
@@ -183,3 +194,3 @@ | ||
// >=0.0.0 is like a star | ||
createToken('GTE0', '^\\s*>=\\s*0\.0\.0\\s*$') | ||
createToken('GTE0PRE', '^\\s*>=\\s*0\.0\.0-0\\s*$') | ||
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$') | ||
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$') |
{ | ||
"name": "semver", | ||
"version": "7.3.2", | ||
"version": "7.5.2", | ||
"description": "The semantic version parser used by npm.", | ||
@@ -9,31 +9,80 @@ "main": "index.js", | ||
"snap": "tap", | ||
"preversion": "npm test", | ||
"postversion": "npm publish", | ||
"postpublish": "git push origin --follow-tags" | ||
"lint": "eslint \"**/*.js\"", | ||
"postlint": "template-oss-check", | ||
"lintfix": "npm run lint -- --fix", | ||
"posttest": "npm run lint", | ||
"template-oss-apply": "template-oss-apply --force" | ||
}, | ||
"devDependencies": { | ||
"tap": "^14.10.7" | ||
"@npmcli/eslint-config": "^4.0.0", | ||
"@npmcli/template-oss": "4.15.1", | ||
"tap": "^16.0.0" | ||
}, | ||
"license": "ISC", | ||
"repository": "https://github.com/npm/node-semver", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/npm/node-semver.git" | ||
}, | ||
"bin": { | ||
"semver": "./bin/semver.js" | ||
"semver": "bin/semver.js" | ||
}, | ||
"files": [ | ||
"bin/**/*.js", | ||
"range.bnf", | ||
"classes/**/*.js", | ||
"functions/**/*.js", | ||
"internal/**/*.js", | ||
"ranges/**/*.js", | ||
"bin/", | ||
"lib/", | ||
"classes/", | ||
"functions/", | ||
"internal/", | ||
"ranges/", | ||
"index.js", | ||
"preload.js" | ||
"preload.js", | ||
"range.bnf" | ||
], | ||
"tap": { | ||
"check-coverage": true, | ||
"coverage-map": "map.js" | ||
"timeout": 30, | ||
"coverage-map": "map.js", | ||
"nyc-arg": [ | ||
"--exclude", | ||
"tap-snapshots/**" | ||
] | ||
}, | ||
"engines": { | ||
"node": ">=10" | ||
}, | ||
"dependencies": { | ||
"lru-cache": "^6.0.0" | ||
}, | ||
"author": "GitHub Inc.", | ||
"templateOSS": { | ||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", | ||
"version": "4.15.1", | ||
"engines": ">=10", | ||
"ciVersions": [ | ||
"10.0.0", | ||
"10.x", | ||
"12.x", | ||
"14.x", | ||
"16.x", | ||
"18.x" | ||
], | ||
"npmSpec": "8", | ||
"distPaths": [ | ||
"classes/", | ||
"functions/", | ||
"internal/", | ||
"ranges/", | ||
"index.js", | ||
"preload.js", | ||
"range.bnf" | ||
], | ||
"allowPaths": [ | ||
"/classes/", | ||
"/functions/", | ||
"/internal/", | ||
"/ranges/", | ||
"/index.js", | ||
"/preload.js", | ||
"/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 |
@@ -22,2 +22,3 @@ const SemVer = require('../classes/semver') | ||
let setMin = null | ||
comparators.forEach((comparator) => { | ||
@@ -37,4 +38,4 @@ // Clone to avoid manipulating the comparator's semver object. | ||
case '>=': | ||
if (!minver || gt(minver, compver)) { | ||
minver = compver | ||
if (!setMin || gt(compver, setMin)) { | ||
setMin = compver | ||
} | ||
@@ -51,2 +52,5 @@ break | ||
}) | ||
if (setMin && (!minver || gt(minver, setMin))) { | ||
minver = setMin | ||
} | ||
} | ||
@@ -53,0 +57,0 @@ |
const SemVer = require('../classes/semver') | ||
const Comparator = require('../classes/comparator') | ||
const {ANY} = Comparator | ||
const { ANY } = Comparator | ||
const Range = require('../classes/range') | ||
@@ -35,3 +35,3 @@ const satisfies = require('../functions/satisfies') | ||
// If it satisifes the range it is not outside | ||
// If it satisfies the range it is not outside | ||
if (satisfies(version, range, options)) { | ||
@@ -38,0 +38,0 @@ return false |
@@ -8,3 +8,3 @@ // given a set of versions and a range, create a "simplified" range | ||
const set = [] | ||
let min = null | ||
let first = null | ||
let prev = null | ||
@@ -16,27 +16,30 @@ const v = versions.sort((a, b) => compare(a, b, options)) | ||
prev = version | ||
if (!min) | ||
min = version | ||
if (!first) { | ||
first = version | ||
} | ||
} else { | ||
if (prev) { | ||
set.push([min, prev]) | ||
set.push([first, prev]) | ||
} | ||
prev = null | ||
min = null | ||
first = null | ||
} | ||
} | ||
if (min) | ||
set.push([min, null]) | ||
if (first) { | ||
set.push([first, null]) | ||
} | ||
const ranges = [] | ||
for (const [min, max] of set) { | ||
if (min === max) | ||
if (min === max) { | ||
ranges.push(min) | ||
else if (!max && min === v[0]) | ||
} else if (!max && min === v[0]) { | ||
ranges.push('*') | ||
else if (!max) | ||
} else if (!max) { | ||
ranges.push(`>=${min}`) | ||
else if (min === v[0]) | ||
} else if (min === v[0]) { | ||
ranges.push(`<=${max}`) | ||
else | ||
} else { | ||
ranges.push(`${min} - ${max}`) | ||
} | ||
} | ||
@@ -43,0 +46,0 @@ const simplified = ranges.join(' || ') |
const Range = require('../classes/range.js') | ||
const { ANY } = require('../classes/comparator.js') | ||
const Comparator = require('../classes/comparator.js') | ||
const { ANY } = Comparator | ||
const satisfies = require('../functions/satisfies.js') | ||
@@ -7,3 +8,5 @@ const compare = require('../functions/compare.js') | ||
// Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: | ||
// - Every simple range `r1, r2, ...` is a subset of some `R1, R2, ...` | ||
// - Every simple range `r1, r2, ...` is a null set, OR | ||
// - Every simple range `r1, r2, ...` which is not a null set is a subset of | ||
// some `R1, R2, ...` | ||
// | ||
@@ -13,3 +16,7 @@ // Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: | ||
// - If C is only the ANY comparator, return true | ||
// - Else return false | ||
// - Else if in prerelease mode, return false | ||
// - else replace c with `[>=0.0.0]` | ||
// - If C is only the ANY comparator | ||
// - if in prerelease mode, return true | ||
// - else replace C with `[>=0.0.0]` | ||
// - Let EQ be the set of = comparators in c | ||
@@ -20,2 +27,3 @@ // - If EQ is more than one, return true (null set) | ||
// - If GT and LT, and GT.semver > LT.semver, return true (null set) | ||
// - If any C is a = range, and GT or LT are set, return false | ||
// - If EQ | ||
@@ -27,11 +35,18 @@ // - If GT, and EQ does not satisfy GT, return true (null set) | ||
// - If GT | ||
// - If GT is lower than any > or >= comp in C, return false | ||
// - If GT.semver is lower than any > or >= comp in C, return false | ||
// - If GT is >=, and GT.semver does not satisfy every C, return false | ||
// - If GT.semver has a prerelease, and not in prerelease mode | ||
// - If no C has a prerelease and the GT.semver tuple, return false | ||
// - If LT | ||
// - If LT.semver is greater than that of any > comp in C, return false | ||
// - If LT.semver is greater than any < or <= comp in C, return false | ||
// - If LT is <=, and LT.semver does not satisfy every C, return false | ||
// - If any C is a = range, and GT or LT are set, return false | ||
// - If GT.semver has a prerelease, and not in prerelease mode | ||
// - If no C has a prerelease and the LT.semver tuple, return false | ||
// - Else return true | ||
const subset = (sub, dom, options) => { | ||
const subset = (sub, dom, options = {}) => { | ||
if (sub === dom) { | ||
return true | ||
} | ||
sub = new Range(sub, options) | ||
@@ -45,4 +60,5 @@ dom = new Range(dom, options) | ||
sawNonNull = sawNonNull || isSub !== null | ||
if (isSub) | ||
if (isSub) { | ||
continue OUTER | ||
} | ||
} | ||
@@ -53,4 +69,5 @@ // the null set is a subset of everything, but null simple ranges in | ||
// then it is a subset. | ||
if (sawNonNull) | ||
if (sawNonNull) { | ||
return false | ||
} | ||
} | ||
@@ -60,19 +77,43 @@ return true | ||
const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] | ||
const minimumVersion = [new Comparator('>=0.0.0')] | ||
const simpleSubset = (sub, dom, options) => { | ||
if (sub.length === 1 && sub[0].semver === ANY) | ||
return dom.length === 1 && dom[0].semver === ANY | ||
if (sub === dom) { | ||
return true | ||
} | ||
if (sub.length === 1 && sub[0].semver === ANY) { | ||
if (dom.length === 1 && dom[0].semver === ANY) { | ||
return true | ||
} else if (options.includePrerelease) { | ||
sub = minimumVersionWithPreRelease | ||
} else { | ||
sub = minimumVersion | ||
} | ||
} | ||
if (dom.length === 1 && dom[0].semver === ANY) { | ||
if (options.includePrerelease) { | ||
return true | ||
} else { | ||
dom = minimumVersion | ||
} | ||
} | ||
const eqSet = new Set() | ||
let gt, lt | ||
for (const c of sub) { | ||
if (c.operator === '>' || c.operator === '>=') | ||
if (c.operator === '>' || c.operator === '>=') { | ||
gt = higherGT(gt, c, options) | ||
else if (c.operator === '<' || c.operator === '<=') | ||
} else if (c.operator === '<' || c.operator === '<=') { | ||
lt = lowerLT(lt, c, options) | ||
else | ||
} else { | ||
eqSet.add(c.semver) | ||
} | ||
} | ||
if (eqSet.size > 1) | ||
if (eqSet.size > 1) { | ||
return null | ||
} | ||
@@ -82,6 +123,7 @@ let gtltComp | ||
gtltComp = compare(gt.semver, lt.semver, options) | ||
if (gtltComp > 0) | ||
if (gtltComp > 0) { | ||
return null | ||
else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) | ||
} else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) { | ||
return null | ||
} | ||
} | ||
@@ -91,12 +133,16 @@ | ||
for (const eq of eqSet) { | ||
if (gt && !satisfies(eq, String(gt), options)) | ||
if (gt && !satisfies(eq, String(gt), options)) { | ||
return null | ||
} | ||
if (lt && !satisfies(eq, String(lt), options)) | ||
if (lt && !satisfies(eq, String(lt), options)) { | ||
return null | ||
} | ||
for (const c of dom) { | ||
if (!satisfies(eq, String(c), options)) | ||
if (!satisfies(eq, String(c), options)) { | ||
return false | ||
} | ||
} | ||
return true | ||
@@ -107,2 +153,16 @@ } | ||
let hasDomLT, hasDomGT | ||
// if the subset has a prerelease, we need a comparator in the superset | ||
// with the same tuple and a prerelease, or it's not a subset | ||
let needDomLTPre = lt && | ||
!options.includePrerelease && | ||
lt.semver.prerelease.length ? lt.semver : false | ||
let needDomGTPre = gt && | ||
!options.includePrerelease && | ||
gt.semver.prerelease.length ? gt.semver : false | ||
// exception: <1.2.3-0 is the same as <1.2.3 | ||
if (needDomLTPre && needDomLTPre.prerelease.length === 1 && | ||
lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { | ||
needDomLTPre = false | ||
} | ||
for (const c of dom) { | ||
@@ -112,19 +172,40 @@ hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>=' | ||
if (gt) { | ||
if (needDomGTPre) { | ||
if (c.semver.prerelease && c.semver.prerelease.length && | ||
c.semver.major === needDomGTPre.major && | ||
c.semver.minor === needDomGTPre.minor && | ||
c.semver.patch === needDomGTPre.patch) { | ||
needDomGTPre = false | ||
} | ||
} | ||
if (c.operator === '>' || c.operator === '>=') { | ||
higher = higherGT(gt, c, options) | ||
if (higher === c) | ||
if (higher === c && higher !== gt) { | ||
return false | ||
} else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) | ||
} | ||
} else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) { | ||
return false | ||
} | ||
} | ||
if (lt) { | ||
if (needDomLTPre) { | ||
if (c.semver.prerelease && c.semver.prerelease.length && | ||
c.semver.major === needDomLTPre.major && | ||
c.semver.minor === needDomLTPre.minor && | ||
c.semver.patch === needDomLTPre.patch) { | ||
needDomLTPre = false | ||
} | ||
} | ||
if (c.operator === '<' || c.operator === '<=') { | ||
lower = lowerLT(lt, c, options) | ||
if (lower === c) | ||
if (lower === c && lower !== lt) { | ||
return false | ||
} else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) | ||
} | ||
} else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) { | ||
return false | ||
} | ||
} | ||
if (!c.operator && (lt || gt) && gtltComp !== 0) | ||
if (!c.operator && (lt || gt) && gtltComp !== 0) { | ||
return false | ||
} | ||
} | ||
@@ -135,8 +216,17 @@ | ||
// Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 | ||
if (gt && hasDomLT && !lt && gtltComp !== 0) | ||
if (gt && hasDomLT && !lt && gtltComp !== 0) { | ||
return false | ||
} | ||
if (lt && hasDomGT && !gt && gtltComp !== 0) | ||
if (lt && hasDomGT && !gt && gtltComp !== 0) { | ||
return false | ||
} | ||
// we needed a prerelease range in a specific tuple, but didn't get one | ||
// then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, | ||
// because it includes prereleases in the 1.2.3 tuple | ||
if (needDomGTPre || needDomLTPre) { | ||
return false | ||
} | ||
return true | ||
@@ -147,4 +237,5 @@ } | ||
const higherGT = (a, b, options) => { | ||
if (!a) | ||
if (!a) { | ||
return b | ||
} | ||
const comp = compare(a.semver, b.semver, options) | ||
@@ -159,4 +250,5 @@ return comp > 0 ? a | ||
const lowerLT = (a, b, options) => { | ||
if (!a) | ||
if (!a) { | ||
return b | ||
} | ||
const comp = compare(a.semver, b.semver, options) | ||
@@ -163,0 +255,0 @@ return comp < 0 ? a |
@@ -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 | ||
@@ -269,3 +301,5 @@ | ||
* `*` := `>=0.0.0` (Any version satisfies) | ||
* `*` := `>=0.0.0` (Any non-prerelease version satisfies, unless | ||
`includePrerelease` is specified, in which case any version at all | ||
satisfies) | ||
* `1.x` := `>=1.0.0 <2.0.0-0` (Matching major version) | ||
@@ -517,2 +551,36 @@ * `1.2.x` := `>=1.2.0 <1.3.0-0` (Matching major and minor versions) | ||
## 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 | ||
@@ -571,1 +639,2 @@ | ||
* `require('semver/ranges/valid')` | ||
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
92605
2059
1
636
0
1
3
+ Addedlru-cache@^6.0.0
+ Addedlru-cache@6.0.0(transitive)
+ Addedyallist@4.0.0(transitive)