UNPKG

apisurf

Version:

Analyze API surface changes between npm package versions to catch breaking changes

65 lines (64 loc) 2.77 kB
/** * Determines the type of version bump between two semver versions */ export function getVersionBumpType(fromVersion, toVersion) { // Handle versions with more than 3 parts by considering them as patch suffixes // e.g., 1.0.0.0 -> major=1, minor=0, patch=0, suffix=.0 const normalizeVersion = (version) => { const parts = version.split('.'); if (parts.length < 3) { return { major: NaN, minor: NaN, patch: NaN, hasPrerelease: false, hasFourthPart: false, fourthPart: 0 }; } // For versions with 4+ parts, we need special handling const hasFourthPart = parts.length >= 4; const fourthPart = hasFourthPart ? parseInt(parts[3].split('-')[0]) : 0; return { major: parseInt(parts[0]), minor: parseInt(parts[1]), patch: parseInt(parts[2].split('-')[0]), // Parse patch, removing prerelease hasPrerelease: version.includes('-'), hasFourthPart, fourthPart }; }; const from = normalizeVersion(fromVersion); const to = normalizeVersion(toVersion); // Check if any parsed numbers are NaN if (isNaN(from.major) || isNaN(from.minor) || isNaN(from.patch) || isNaN(to.major) || isNaN(to.minor) || isNaN(to.patch)) { return 'unknown'; } // For prerelease determination: // If either version has a prerelease tag, and the base versions differ by only patch or less, // consider it a prerelease change if (from.hasPrerelease || to.hasPrerelease) { // Check if this is a pure prerelease change (same base version) if (from.major === to.major && from.minor === to.minor && from.patch === to.patch) { return 'prerelease'; } // If moving from stable to prerelease with patch bump (e.g., 1.0.0 -> 1.0.1-alpha) // This is considered a prerelease because the stable version hasn't actually changed yet if (!from.hasPrerelease && to.hasPrerelease) { if (from.major === to.major && from.minor === to.minor) { return 'prerelease'; } } } // Regular version comparison if (to.major > from.major) { return 'major'; } else if (to.major === from.major && to.minor > from.minor) { return 'minor'; } else if (to.major === from.major && to.minor === from.minor && to.patch > from.patch) { return 'patch'; } else if (to.major === from.major && to.minor === from.minor && to.patch === from.patch) { // Handle 4th part versions like 1.0.0.0 -> 1.0.0.1 if (from.hasFourthPart && to.hasFourthPart && to.fourthPart > from.fourthPart) { return 'patch'; } } return 'unknown'; }