UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

288 lines • 8.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QualifierRank = exports.TokenType = void 0; exports.tokenize = tokenize; exports.qualifierRank = qualifierRank; exports.compare = compare; exports.parse = parse; exports.isVersion = isVersion; exports.parsePrefixRange = parsePrefixRange; exports.parseMavenBasedRange = parseMavenBasedRange; exports.parseSingleVersionRange = parseSingleVersionRange; exports.isValid = isValid; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const regex_1 = require("../../../util/regex"); exports.TokenType = { Number: 1, String: 2, }; function iterateChars(str, cb) { let prev = null; let next = null; for (let i = 0; i < str.length; i += 1) { next = str.charAt(i); cb(prev, next); prev = next; } cb(prev, null); } function isSeparator(char) { return (0, regex_1.regEx)(/^[-._+]$/i).test(char); } function isDigit(char) { return (0, regex_1.regEx)(/^\d$/).test(char); } function isLetter(char) { return !isSeparator(char) && !isDigit(char); } function isTransition(prevChar, nextChar) { return ((isDigit(prevChar) && isLetter(nextChar)) || (isLetter(prevChar) && isDigit(nextChar))); } function tokenize(versionStr) { let result = []; let currentVal = ''; function yieldToken() { if (result) { const val = currentVal; if ((0, regex_1.regEx)(/^\d+$/).test(val)) { result.push({ type: exports.TokenType.Number, val: parseInt(val, 10), }); } else { result.push({ type: exports.TokenType.String, val, }); } } } iterateChars(versionStr, (prevChar, nextChar) => { if (nextChar === null) { yieldToken(); } else if (isSeparator(nextChar)) { if (prevChar && !isSeparator(prevChar)) { yieldToken(); currentVal = ''; } else { result = null; } } else if (prevChar !== null && isTransition(prevChar, nextChar)) { yieldToken(); currentVal = nextChar; } else { currentVal = currentVal.concat(nextChar); } }); return result; } exports.QualifierRank = { Dev: -1, Default: 0, RC: 1, Snapshot: 2, Final: 3, GA: 4, Release: 5, SP: 6, }; function qualifierRank(input) { const val = input.toLowerCase(); if (val === 'dev') { return exports.QualifierRank.Dev; } if (val === 'rc' || val === 'cr') { return exports.QualifierRank.RC; } if (val === 'snapshot') { return exports.QualifierRank.Snapshot; } if (val === 'ga') { return exports.QualifierRank.GA; } if (val === 'final') { return exports.QualifierRank.Final; } if (val === 'release' || val === 'latest' || val === 'sr') { return exports.QualifierRank.Release; } if (val === 'sp') { return exports.QualifierRank.SP; } return exports.QualifierRank.Default; } function stringTokenCmp(left, right) { const leftRank = qualifierRank(left); const rightRank = qualifierRank(right); if (leftRank === 0 && rightRank === 0) { if (left < right) { return -1; } if (left > right) { return 1; } } else { if (leftRank < rightRank) { return -1; } if (leftRank > rightRank) { return 1; } } return 0; } function tokenCmp(left, right) { if (left === null) { if (right?.type === exports.TokenType.String) { return 1; } return -1; } if (right === null) { if (left.type === exports.TokenType.String) { return -1; } return 1; } if (left.type === exports.TokenType.Number && right.type === exports.TokenType.Number) { if (left.val < right.val) { return -1; } if (left.val > right.val) { return 1; } } else if (typeof left.val === 'string' && typeof right.val === 'string') { return stringTokenCmp(left.val, right.val); } else if (right.type === exports.TokenType.Number) { return -1; } else if (left.type === exports.TokenType.Number) { return 1; } return 0; } function compare(left, right) { const leftTokens = tokenize(left) ?? []; const rightTokens = tokenize(right) ?? []; const length = Math.max(leftTokens.length, rightTokens.length); for (let idx = 0; idx < length; idx += 1) { const leftToken = leftTokens[idx] || null; const rightToken = rightTokens[idx] || null; const cmpResult = tokenCmp(leftToken, rightToken); if (cmpResult !== 0) { return cmpResult; } } return 0; } function parse(input) { if (!input) { return null; } if (!(0, regex_1.regEx)(/^[-._+a-zA-Z0-9]+$/i).test(input)) { return null; } if ((0, regex_1.regEx)(/^latest\.?/i).test(input)) { return null; } const tokens = tokenize(input); // istanbul ignore if: should not happen if (!tokens?.length) { return null; } return tokens; } function isVersion(input) { return !!parse(input); } function parsePrefixRange(input) { if (!input) { return null; } if (input.trim() === '+') { return { tokens: [] }; } const postfixRegex = (0, regex_1.regEx)(/[^-._+][-._]\+$/); if (postfixRegex.test(input)) { const prefixValue = input.replace((0, regex_1.regEx)(/[-._]\+$/), ''); const tokens = tokenize(prefixValue); if (tokens) { return { tokens }; } } return null; } const mavenBasedRangeRegex = (0, regex_1.regEx)(/^(?<leftBoundStr>[[\](]\s*)(?<leftVal>[-._+a-zA-Z0-9]*?)(?<separator>\s*,\s*)(?<rightVal>[-._+a-zA-Z0-9]*?)(?<rightBoundStr>\s*[[\])])$/); function parseMavenBasedRange(input) { if (!input) { return null; } const matchGroups = mavenBasedRangeRegex.exec(input)?.groups; if (matchGroups) { const { leftBoundStr, separator, rightBoundStr } = matchGroups; let leftVal = matchGroups.leftVal; let rightVal = matchGroups.rightVal; if (!leftVal) { leftVal = null; } if (!rightVal) { rightVal = null; } const isVersionLeft = is_1.default.string(leftVal) && isVersion(leftVal); const isVersionRight = is_1.default.string(rightVal) && isVersion(rightVal); if ((leftVal === null || isVersionLeft) && (rightVal === null || isVersionRight)) { if (isVersionLeft && isVersionRight && leftVal && rightVal && compare(leftVal, rightVal) === 1) { return null; } const leftBound = leftBoundStr.trim() === '[' ? 'inclusive' : 'exclusive'; const rightBound = rightBoundStr.trim() === ']' ? 'inclusive' : 'exclusive'; return { leftBound, leftBoundStr, leftVal, separator, rightBound, rightBoundStr, rightVal, }; } } return null; } const singleVersionRangeRegex = (0, regex_1.regEx)(/^\[\s*(?<val>[-._+a-zA-Z0-9]*?)\s*\]$/); function parseSingleVersionRange(input) { const matchGroups = singleVersionRangeRegex.exec(input)?.groups; if (!matchGroups) { return null; } const { val } = matchGroups; if (!isVersion(val)) { return null; } return { val }; } function isValid(str) { if (!str) { return false; } return (isVersion(str) || !!parsePrefixRange(str) || !!parseMavenBasedRange(str) || !!parseSingleVersionRange(str)); } //# sourceMappingURL=compare.js.map