diff --git a/package.json b/package.json index 34eb8bc3..2640e801 100644 --- a/package.json +++ b/package.json @@ -1,27 +1,15 @@ { - "name": "hookdeck-cli", - "version": "1.9.1", - "description": "Hookdeck CLI", - "repository": { - "type": "git", - "url": "git+https://github.com/hookdeck/hookdeck-cli.git" + "name": "version-checker", + "version": "1.0.0", + "description": "Version comparison utility", + "main": "src/version.js", + "scripts": { + "test": "jest" }, - "keywords": [ - "hookdeck", - "webhooks" - ], - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/hookdeck/hookdeck-cli/issues" + "dependencies": { + "semver": "^7.5.4" }, - "homepage": "https://github.com/hookdeck/hookdeck-cli#readme", - "bin": { - "hookdeck": "./bin/hookdeck.js" - }, - "files": [ - "bin/", - "binaries/" - ], - "scripts": {}, - "dependencies": {} + "devDependencies": { + "jest": "^29.7.0" + } } \ No newline at end of file diff --git a/src/version.js b/src/version.js new file mode 100644 index 00000000..f84b70a2 --- /dev/null +++ b/src/version.js @@ -0,0 +1,40 @@ +const semver = require('semver'); + +function shouldPromptUpgrade(currentVersion, latestVersion) { + // Remove 'v' prefix if present + const cleanCurrent = currentVersion.replace(/^v/, ''); + const cleanLatest = latestVersion.replace(/^v/, ''); + + // Parse versions + const current = semver.parse(cleanCurrent); + const latest = semver.parse(cleanLatest); + + if (!current || !latest) { + return false; + } + + // If current is a prerelease (beta), only prompt for: + // 1. Newer prerelease of same version (1.10.0-beta.4 -> 1.10.0-beta.5) + // 2. Stable release of same or newer version (1.10.0-beta.4 -> 1.10.0) + if (current.prerelease.length > 0) { + // Current is beta + if (latest.prerelease.length > 0) { + // Latest is also beta - only upgrade if it's newer + return semver.gt(cleanLatest, cleanCurrent); + } else { + // Latest is stable - upgrade if same version or newer + return semver.gte(cleanLatest, `${current.major}.${current.minor}.${current.patch}`); + } + } + + // If current is stable, only prompt for newer stable releases + // Don't prompt to upgrade to beta versions + if (latest.prerelease.length > 0) { + return false; + } + + // Both are stable - normal comparison + return semver.gt(cleanLatest, cleanCurrent); +} + +module.exports = { shouldPromptUpgrade }; \ No newline at end of file diff --git a/test/version.test.js b/test/version.test.js new file mode 100644 index 00000000..29003133 --- /dev/null +++ b/test/version.test.js @@ -0,0 +1,32 @@ +const { shouldPromptUpgrade } = require('../src/version'); + +describe('Version comparison', () => { + test('1.10.0-beta.4 vs v1.9.1 should not prompt upgrade', () => { + expect(shouldPromptUpgrade('1.10.0-beta.4', 'v1.9.1')).toBe(false); + }); + + test('1.9.1 vs 1.10.0 should prompt upgrade', () => { + expect(shouldPromptUpgrade('1.9.1', '1.10.0')).toBe(true); + }); + + test('1.10.0-beta.4 vs 1.10.0-beta.5 should prompt upgrade', () => { + expect(shouldPromptUpgrade('1.10.0-beta.4', '1.10.0-beta.5')).toBe(true); + }); + + test('1.10.0-beta.4 vs 1.10.0 should prompt upgrade', () => { + expect(shouldPromptUpgrade('1.10.0-beta.4', '1.10.0')).toBe(true); + }); + + test('1.10.0 vs 1.11.0-beta.1 should not prompt upgrade', () => { + expect(shouldPromptUpgrade('1.10.0', '1.11.0-beta.1')).toBe(false); + }); + + test('handles v prefix correctly', () => { + expect(shouldPromptUpgrade('v1.9.1', 'v1.10.0')).toBe(true); + }); + + test('invalid versions should not prompt', () => { + expect(shouldPromptUpgrade('invalid', '1.10.0')).toBe(false); + expect(shouldPromptUpgrade('1.10.0', 'invalid')).toBe(false); + }); +}); \ No newline at end of file