UNPKG

patch-pulse

Version:

Check for outdated npm dependencies

109 lines 4.62 kB
import chalk from 'chalk'; import { shouldSkipPackage } from '../services/config.js'; import { getLatestVersion } from '../services/npm.js'; import { ProgressSpinner } from '../ui/progress.js'; import { getUpdateType } from '../utils/getUpdateType.js'; import { isVersionOutdated } from '../utils/isVersionOutdated.js'; export async function checkDependencyVersions(dependencies, category, config) { if (!dependencies || Object.keys(dependencies).length === 0) { return []; } console.log(chalk.cyan.bold(`${category}:`)); console.log(chalk.cyan('─'.repeat(category.length + 1))); const packageNames = Object.keys(dependencies); const progress = new ProgressSpinner(); progress.start(`Checking ${packageNames.length} packages...`); const concurrencyLimit = 10; const dependencyInfos = []; let completedCount = 0; for (let i = 0; i < packageNames.length; i += concurrencyLimit) { const batch = packageNames.slice(i, i + concurrencyLimit); const batchPromises = batch.map(async (packageName) => { const version = dependencies[packageName]; const isSkipped = shouldSkipPackage({ packageName, config }); let latestVersion; let isOutdated = false; let updateType; if (!isSkipped) { latestVersion = await getLatestVersion(packageName); if (latestVersion) { // Check if the version is outdated (works for both standard semver and version ranges) isOutdated = isVersionOutdated({ current: version, latest: latestVersion, }); updateType = isOutdated ? getUpdateType({ current: version, latest: latestVersion }) : undefined; } } // Update progress for each completed package completedCount++; progress.updateMessage(`Checking ${packageNames.length} packages... (${completedCount}/${packageNames.length})`); return { packageName, currentVersion: version, latestVersion, isOutdated, updateType, isSkipped, category, }; }); const batchResults = await Promise.all(batchPromises); dependencyInfos.push(...batchResults); } progress.stop(); displayResults(dependencyInfos); console.log(); return dependencyInfos; } function displayResults(dependencyInfos) { for (const dep of dependencyInfos) { let status; let versionInfo; if (dep.isSkipped) { status = chalk.gray('SKIPPED'); versionInfo = dep.currentVersion; } else if (!dep.latestVersion) { status = chalk.red('NOT FOUND'); versionInfo = `${dep.currentVersion} (not found on npm registry)`; } else if (['latest', '*'].includes(dep.currentVersion)) { status = chalk.cyan('LATEST TAG'); versionInfo = `${dep.currentVersion}${chalk.cyan(dep.latestVersion)} (actual latest version)`; } else if (!/^\d+\.\d+\.\d+/.test(dep.currentVersion)) { // Handle version ranges if (dep.isOutdated) { const updateTypeColor = { major: chalk.yellow, minor: chalk.magenta, patch: chalk.blue, }[dep.updateType || 'patch']; status = updateTypeColor(`${dep.updateType?.toUpperCase() || 'UPDATE'}`); versionInfo = `${dep.currentVersion}${chalk.cyan(dep.latestVersion)}`; } else { status = chalk.green('UP TO DATE'); versionInfo = dep.currentVersion; } } else if (dep.isOutdated) { const updateTypeColor = { major: chalk.yellow, minor: chalk.magenta, patch: chalk.blue, }[dep.updateType || 'patch']; status = updateTypeColor(`${dep.updateType?.toUpperCase() || 'UPDATE'}`); versionInfo = `${dep.currentVersion}${chalk.cyan(dep.latestVersion)}`; } else { status = chalk.green('UP TO DATE'); versionInfo = dep.currentVersion; } console.log(`${status} ${chalk.white(dep.packageName)} ${chalk.gray(versionInfo)}`); } } //# sourceMappingURL=dependency-checker.js.map