UNPKG

@antora/content-classifier

Version:

Organizes aggregated content into a virtual file catalog for use in an Antora documentation pipeline.

79 lines (72 loc) 2.46 kB
'use strict' const NUMBERS = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'] const { isInteger } = Number /** * An augmented semantic version comparison function. * * Augments the semantic version comparison algorithm with the following enhancements: * * * Discard the leading "v" character, if present and the version string is a semantic version. * * Compare non-semantic versions as strings in reverse alphabetical order (e.g., xenial comes before trusty). * * Compare semantic versions in descending order (e.g., 2.0.0 comes before 1.0.0). * * This function assumes that the string is a semantic version if it begins with a number (or a "v" * followed by a number) and contains a "." character or it's a parsable number. * * @param {String} a - The left version string. * @param {String} b - The right version string. * @returns 0 if the versions match, -1 if a is greater, or 1 if b is greater. */ function versionCompareDesc (a, b) { if (a === b) return 0 if (a && b) { const semverA = resolveSemver(a) const semverB = resolveSemver(b) if (semverA) return semverB ? -semverCompare(semverA, semverB) : 1 return semverB ? -1 : -2 * a.localeCompare(b, 'en', { numeric: true }) } return a ? 1 : -1 } function resolveSemver (str) { const chr0 = str.charAt() if (chr0 === 'v') { if (isDigit(str.charAt(1)) && (str = str.substr(1)) && (~str.indexOf('.') || isDigit(str.charAt()))) { return str } } else if (isDigit(chr0) && (~str.indexOf('.') || isInteger(Number(str)))) { return str } } function isDigit (chr) { return NUMBERS.includes(chr) } function semverCompare (a, b) { let preA let preB const preOffsetA = a.indexOf('-') const preOffsetB = b.indexOf('-') if (~preOffsetA) { preA = a.substr(preOffsetA + 1) a = a.substr(0, preOffsetA) } if (~preOffsetB) { preB = b.substr(preOffsetB + 1) b = b.substr(0, preOffsetB) } const numsA = a.split('.') const numsB = b.split('.') for (let i = 0; i < 3; i++) { const numA = Number(numsA[i] ?? 0) const numB = Number(numsB[i] ?? 0) if (numA > numB) return 1 if (numB > numA) return -1 if (Number.isNaN(numA)) { if (!Number.isNaN(numB)) return -1 } else if (Number.isNaN(numB)) { return 1 } } if (preA == null) return preB == null ? 0 : 1 return preB == null ? -1 : preA.localeCompare(preB, 'en', { numeric: true }) } module.exports = versionCompareDesc