11cb0ef41Sopenharmony_ciconst debug = require('../internal/debug') 21cb0ef41Sopenharmony_ciconst { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants') 31cb0ef41Sopenharmony_ciconst { safeRe: re, t } = require('../internal/re') 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciconst parseOptions = require('../internal/parse-options') 61cb0ef41Sopenharmony_ciconst { compareIdentifiers } = require('../internal/identifiers') 71cb0ef41Sopenharmony_ciclass SemVer { 81cb0ef41Sopenharmony_ci constructor (version, options) { 91cb0ef41Sopenharmony_ci options = parseOptions(options) 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci if (version instanceof SemVer) { 121cb0ef41Sopenharmony_ci if (version.loose === !!options.loose && 131cb0ef41Sopenharmony_ci version.includePrerelease === !!options.includePrerelease) { 141cb0ef41Sopenharmony_ci return version 151cb0ef41Sopenharmony_ci } else { 161cb0ef41Sopenharmony_ci version = version.version 171cb0ef41Sopenharmony_ci } 181cb0ef41Sopenharmony_ci } else if (typeof version !== 'string') { 191cb0ef41Sopenharmony_ci throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) 201cb0ef41Sopenharmony_ci } 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci if (version.length > MAX_LENGTH) { 231cb0ef41Sopenharmony_ci throw new TypeError( 241cb0ef41Sopenharmony_ci `version is longer than ${MAX_LENGTH} characters` 251cb0ef41Sopenharmony_ci ) 261cb0ef41Sopenharmony_ci } 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci debug('SemVer', version, options) 291cb0ef41Sopenharmony_ci this.options = options 301cb0ef41Sopenharmony_ci this.loose = !!options.loose 311cb0ef41Sopenharmony_ci // this isn't actually relevant for versions, but keep it so that we 321cb0ef41Sopenharmony_ci // don't run into trouble passing this.options around. 331cb0ef41Sopenharmony_ci this.includePrerelease = !!options.includePrerelease 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci if (!m) { 381cb0ef41Sopenharmony_ci throw new TypeError(`Invalid Version: ${version}`) 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci this.raw = version 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci // these are actually numbers 441cb0ef41Sopenharmony_ci this.major = +m[1] 451cb0ef41Sopenharmony_ci this.minor = +m[2] 461cb0ef41Sopenharmony_ci this.patch = +m[3] 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci if (this.major > MAX_SAFE_INTEGER || this.major < 0) { 491cb0ef41Sopenharmony_ci throw new TypeError('Invalid major version') 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { 531cb0ef41Sopenharmony_ci throw new TypeError('Invalid minor version') 541cb0ef41Sopenharmony_ci } 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { 571cb0ef41Sopenharmony_ci throw new TypeError('Invalid patch version') 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci // numberify any prerelease numeric ids 611cb0ef41Sopenharmony_ci if (!m[4]) { 621cb0ef41Sopenharmony_ci this.prerelease = [] 631cb0ef41Sopenharmony_ci } else { 641cb0ef41Sopenharmony_ci this.prerelease = m[4].split('.').map((id) => { 651cb0ef41Sopenharmony_ci if (/^[0-9]+$/.test(id)) { 661cb0ef41Sopenharmony_ci const num = +id 671cb0ef41Sopenharmony_ci if (num >= 0 && num < MAX_SAFE_INTEGER) { 681cb0ef41Sopenharmony_ci return num 691cb0ef41Sopenharmony_ci } 701cb0ef41Sopenharmony_ci } 711cb0ef41Sopenharmony_ci return id 721cb0ef41Sopenharmony_ci }) 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci this.build = m[5] ? m[5].split('.') : [] 761cb0ef41Sopenharmony_ci this.format() 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci format () { 801cb0ef41Sopenharmony_ci this.version = `${this.major}.${this.minor}.${this.patch}` 811cb0ef41Sopenharmony_ci if (this.prerelease.length) { 821cb0ef41Sopenharmony_ci this.version += `-${this.prerelease.join('.')}` 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci return this.version 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci toString () { 881cb0ef41Sopenharmony_ci return this.version 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci compare (other) { 921cb0ef41Sopenharmony_ci debug('SemVer.compare', this.version, this.options, other) 931cb0ef41Sopenharmony_ci if (!(other instanceof SemVer)) { 941cb0ef41Sopenharmony_ci if (typeof other === 'string' && other === this.version) { 951cb0ef41Sopenharmony_ci return 0 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci other = new SemVer(other, this.options) 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci if (other.version === this.version) { 1011cb0ef41Sopenharmony_ci return 0 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci return this.compareMain(other) || this.comparePre(other) 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci compareMain (other) { 1081cb0ef41Sopenharmony_ci if (!(other instanceof SemVer)) { 1091cb0ef41Sopenharmony_ci other = new SemVer(other, this.options) 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci return ( 1131cb0ef41Sopenharmony_ci compareIdentifiers(this.major, other.major) || 1141cb0ef41Sopenharmony_ci compareIdentifiers(this.minor, other.minor) || 1151cb0ef41Sopenharmony_ci compareIdentifiers(this.patch, other.patch) 1161cb0ef41Sopenharmony_ci ) 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci comparePre (other) { 1201cb0ef41Sopenharmony_ci if (!(other instanceof SemVer)) { 1211cb0ef41Sopenharmony_ci other = new SemVer(other, this.options) 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci // NOT having a prerelease is > having one 1251cb0ef41Sopenharmony_ci if (this.prerelease.length && !other.prerelease.length) { 1261cb0ef41Sopenharmony_ci return -1 1271cb0ef41Sopenharmony_ci } else if (!this.prerelease.length && other.prerelease.length) { 1281cb0ef41Sopenharmony_ci return 1 1291cb0ef41Sopenharmony_ci } else if (!this.prerelease.length && !other.prerelease.length) { 1301cb0ef41Sopenharmony_ci return 0 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci let i = 0 1341cb0ef41Sopenharmony_ci do { 1351cb0ef41Sopenharmony_ci const a = this.prerelease[i] 1361cb0ef41Sopenharmony_ci const b = other.prerelease[i] 1371cb0ef41Sopenharmony_ci debug('prerelease compare', i, a, b) 1381cb0ef41Sopenharmony_ci if (a === undefined && b === undefined) { 1391cb0ef41Sopenharmony_ci return 0 1401cb0ef41Sopenharmony_ci } else if (b === undefined) { 1411cb0ef41Sopenharmony_ci return 1 1421cb0ef41Sopenharmony_ci } else if (a === undefined) { 1431cb0ef41Sopenharmony_ci return -1 1441cb0ef41Sopenharmony_ci } else if (a === b) { 1451cb0ef41Sopenharmony_ci continue 1461cb0ef41Sopenharmony_ci } else { 1471cb0ef41Sopenharmony_ci return compareIdentifiers(a, b) 1481cb0ef41Sopenharmony_ci } 1491cb0ef41Sopenharmony_ci } while (++i) 1501cb0ef41Sopenharmony_ci } 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci compareBuild (other) { 1531cb0ef41Sopenharmony_ci if (!(other instanceof SemVer)) { 1541cb0ef41Sopenharmony_ci other = new SemVer(other, this.options) 1551cb0ef41Sopenharmony_ci } 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci let i = 0 1581cb0ef41Sopenharmony_ci do { 1591cb0ef41Sopenharmony_ci const a = this.build[i] 1601cb0ef41Sopenharmony_ci const b = other.build[i] 1611cb0ef41Sopenharmony_ci debug('prerelease compare', i, a, b) 1621cb0ef41Sopenharmony_ci if (a === undefined && b === undefined) { 1631cb0ef41Sopenharmony_ci return 0 1641cb0ef41Sopenharmony_ci } else if (b === undefined) { 1651cb0ef41Sopenharmony_ci return 1 1661cb0ef41Sopenharmony_ci } else if (a === undefined) { 1671cb0ef41Sopenharmony_ci return -1 1681cb0ef41Sopenharmony_ci } else if (a === b) { 1691cb0ef41Sopenharmony_ci continue 1701cb0ef41Sopenharmony_ci } else { 1711cb0ef41Sopenharmony_ci return compareIdentifiers(a, b) 1721cb0ef41Sopenharmony_ci } 1731cb0ef41Sopenharmony_ci } while (++i) 1741cb0ef41Sopenharmony_ci } 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci // preminor will bump the version up to the next minor release, and immediately 1771cb0ef41Sopenharmony_ci // down to pre-release. premajor and prepatch work the same way. 1781cb0ef41Sopenharmony_ci inc (release, identifier, identifierBase) { 1791cb0ef41Sopenharmony_ci switch (release) { 1801cb0ef41Sopenharmony_ci case 'premajor': 1811cb0ef41Sopenharmony_ci this.prerelease.length = 0 1821cb0ef41Sopenharmony_ci this.patch = 0 1831cb0ef41Sopenharmony_ci this.minor = 0 1841cb0ef41Sopenharmony_ci this.major++ 1851cb0ef41Sopenharmony_ci this.inc('pre', identifier, identifierBase) 1861cb0ef41Sopenharmony_ci break 1871cb0ef41Sopenharmony_ci case 'preminor': 1881cb0ef41Sopenharmony_ci this.prerelease.length = 0 1891cb0ef41Sopenharmony_ci this.patch = 0 1901cb0ef41Sopenharmony_ci this.minor++ 1911cb0ef41Sopenharmony_ci this.inc('pre', identifier, identifierBase) 1921cb0ef41Sopenharmony_ci break 1931cb0ef41Sopenharmony_ci case 'prepatch': 1941cb0ef41Sopenharmony_ci // If this is already a prerelease, it will bump to the next version 1951cb0ef41Sopenharmony_ci // drop any prereleases that might already exist, since they are not 1961cb0ef41Sopenharmony_ci // relevant at this point. 1971cb0ef41Sopenharmony_ci this.prerelease.length = 0 1981cb0ef41Sopenharmony_ci this.inc('patch', identifier, identifierBase) 1991cb0ef41Sopenharmony_ci this.inc('pre', identifier, identifierBase) 2001cb0ef41Sopenharmony_ci break 2011cb0ef41Sopenharmony_ci // If the input is a non-prerelease version, this acts the same as 2021cb0ef41Sopenharmony_ci // prepatch. 2031cb0ef41Sopenharmony_ci case 'prerelease': 2041cb0ef41Sopenharmony_ci if (this.prerelease.length === 0) { 2051cb0ef41Sopenharmony_ci this.inc('patch', identifier, identifierBase) 2061cb0ef41Sopenharmony_ci } 2071cb0ef41Sopenharmony_ci this.inc('pre', identifier, identifierBase) 2081cb0ef41Sopenharmony_ci break 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci case 'major': 2111cb0ef41Sopenharmony_ci // If this is a pre-major version, bump up to the same major version. 2121cb0ef41Sopenharmony_ci // Otherwise increment major. 2131cb0ef41Sopenharmony_ci // 1.0.0-5 bumps to 1.0.0 2141cb0ef41Sopenharmony_ci // 1.1.0 bumps to 2.0.0 2151cb0ef41Sopenharmony_ci if ( 2161cb0ef41Sopenharmony_ci this.minor !== 0 || 2171cb0ef41Sopenharmony_ci this.patch !== 0 || 2181cb0ef41Sopenharmony_ci this.prerelease.length === 0 2191cb0ef41Sopenharmony_ci ) { 2201cb0ef41Sopenharmony_ci this.major++ 2211cb0ef41Sopenharmony_ci } 2221cb0ef41Sopenharmony_ci this.minor = 0 2231cb0ef41Sopenharmony_ci this.patch = 0 2241cb0ef41Sopenharmony_ci this.prerelease = [] 2251cb0ef41Sopenharmony_ci break 2261cb0ef41Sopenharmony_ci case 'minor': 2271cb0ef41Sopenharmony_ci // If this is a pre-minor version, bump up to the same minor version. 2281cb0ef41Sopenharmony_ci // Otherwise increment minor. 2291cb0ef41Sopenharmony_ci // 1.2.0-5 bumps to 1.2.0 2301cb0ef41Sopenharmony_ci // 1.2.1 bumps to 1.3.0 2311cb0ef41Sopenharmony_ci if (this.patch !== 0 || this.prerelease.length === 0) { 2321cb0ef41Sopenharmony_ci this.minor++ 2331cb0ef41Sopenharmony_ci } 2341cb0ef41Sopenharmony_ci this.patch = 0 2351cb0ef41Sopenharmony_ci this.prerelease = [] 2361cb0ef41Sopenharmony_ci break 2371cb0ef41Sopenharmony_ci case 'patch': 2381cb0ef41Sopenharmony_ci // If this is not a pre-release version, it will increment the patch. 2391cb0ef41Sopenharmony_ci // If it is a pre-release it will bump up to the same patch version. 2401cb0ef41Sopenharmony_ci // 1.2.0-5 patches to 1.2.0 2411cb0ef41Sopenharmony_ci // 1.2.0 patches to 1.2.1 2421cb0ef41Sopenharmony_ci if (this.prerelease.length === 0) { 2431cb0ef41Sopenharmony_ci this.patch++ 2441cb0ef41Sopenharmony_ci } 2451cb0ef41Sopenharmony_ci this.prerelease = [] 2461cb0ef41Sopenharmony_ci break 2471cb0ef41Sopenharmony_ci // This probably shouldn't be used publicly. 2481cb0ef41Sopenharmony_ci // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. 2491cb0ef41Sopenharmony_ci case 'pre': { 2501cb0ef41Sopenharmony_ci const base = Number(identifierBase) ? 1 : 0 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_ci if (!identifier && identifierBase === false) { 2531cb0ef41Sopenharmony_ci throw new Error('invalid increment argument: identifier is empty') 2541cb0ef41Sopenharmony_ci } 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci if (this.prerelease.length === 0) { 2571cb0ef41Sopenharmony_ci this.prerelease = [base] 2581cb0ef41Sopenharmony_ci } else { 2591cb0ef41Sopenharmony_ci let i = this.prerelease.length 2601cb0ef41Sopenharmony_ci while (--i >= 0) { 2611cb0ef41Sopenharmony_ci if (typeof this.prerelease[i] === 'number') { 2621cb0ef41Sopenharmony_ci this.prerelease[i]++ 2631cb0ef41Sopenharmony_ci i = -2 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci } 2661cb0ef41Sopenharmony_ci if (i === -1) { 2671cb0ef41Sopenharmony_ci // didn't increment anything 2681cb0ef41Sopenharmony_ci if (identifier === this.prerelease.join('.') && identifierBase === false) { 2691cb0ef41Sopenharmony_ci throw new Error('invalid increment argument: identifier already exists') 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci this.prerelease.push(base) 2721cb0ef41Sopenharmony_ci } 2731cb0ef41Sopenharmony_ci } 2741cb0ef41Sopenharmony_ci if (identifier) { 2751cb0ef41Sopenharmony_ci // 1.2.0-beta.1 bumps to 1.2.0-beta.2, 2761cb0ef41Sopenharmony_ci // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 2771cb0ef41Sopenharmony_ci let prerelease = [identifier, base] 2781cb0ef41Sopenharmony_ci if (identifierBase === false) { 2791cb0ef41Sopenharmony_ci prerelease = [identifier] 2801cb0ef41Sopenharmony_ci } 2811cb0ef41Sopenharmony_ci if (compareIdentifiers(this.prerelease[0], identifier) === 0) { 2821cb0ef41Sopenharmony_ci if (isNaN(this.prerelease[1])) { 2831cb0ef41Sopenharmony_ci this.prerelease = prerelease 2841cb0ef41Sopenharmony_ci } 2851cb0ef41Sopenharmony_ci } else { 2861cb0ef41Sopenharmony_ci this.prerelease = prerelease 2871cb0ef41Sopenharmony_ci } 2881cb0ef41Sopenharmony_ci } 2891cb0ef41Sopenharmony_ci break 2901cb0ef41Sopenharmony_ci } 2911cb0ef41Sopenharmony_ci default: 2921cb0ef41Sopenharmony_ci throw new Error(`invalid increment argument: ${release}`) 2931cb0ef41Sopenharmony_ci } 2941cb0ef41Sopenharmony_ci this.raw = this.format() 2951cb0ef41Sopenharmony_ci if (this.build.length) { 2961cb0ef41Sopenharmony_ci this.raw += `+${this.build.join('.')}` 2971cb0ef41Sopenharmony_ci } 2981cb0ef41Sopenharmony_ci return this 2991cb0ef41Sopenharmony_ci } 3001cb0ef41Sopenharmony_ci} 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_cimodule.exports = SemVer 303