UNPKG

apiver

Version:

Advanced API Versioning Without Duplication - Git-like CLI tool for managing multiple API versions in a single codebase

115 lines (102 loc) 3.82 kB
const fs = require('fs-extra'); const path = require('path'); const chalk = require('chalk'); const { decryptAndDecompress } = require('./utils/crypto'); /** * Show patch details * @param {string} patchId - ID of the patch to show */ function showPatch(patchId) { const cwd = process.cwd(); const apiverRoot = path.join(cwd, '.apiver'); const patchesRoot = path.join(apiverRoot, 'patches'); const metaPath = path.join(apiverRoot, 'meta.json'); if (!fs.existsSync(metaPath)) { console.error(chalk.red('No .APIver/meta.json found. Run init first.')); process.exit(1); } // Find the patch file let patchFile = null; const patchFiles = fs.readdirSync(patchesRoot, { withFileTypes: true }) .filter(entry => !entry.isDirectory() && entry.name.endsWith('.patch.apiver')) .map(entry => entry.name); // Check if the patchId is a full filename or just an ID if (patchFiles.includes(`${patchId}.patch.apiver`)) { patchFile = path.join(patchesRoot, `${patchId}.patch.apiver`); } else { // Look for patch ID in the filename for (const file of patchFiles) { if (file.includes(patchId)) { patchFile = path.join(patchesRoot, file); break; } } } // Also check hotfixes if (!patchFile) { const hotfixesDir = path.join(apiverRoot, 'hotfixes'); if (fs.existsSync(hotfixesDir)) { const hotfixFiles = fs.readdirSync(hotfixesDir, { withFileTypes: true }) .filter(entry => !entry.isDirectory()) .map(entry => entry.name); for (const file of hotfixFiles) { if (file.includes(patchId)) { patchFile = path.join(hotfixesDir, file); break; } } } } if (!patchFile) { console.error(chalk.red(`Patch with ID "${patchId}" not found.`)); process.exit(1); } try { const encPatch = fs.readFileSync(patchFile); const patchBuf = decryptAndDecompress(encPatch); const patchObj = JSON.parse(patchBuf.toString('utf8')); // Find associated versions const associatedVersions = []; const meta = fs.readJsonSync(metaPath); // Check versions for (const [ver, info] of Object.entries(meta.versions || {})) { if (info.patchesAfterSnapshot && info.patchesAfterSnapshot.includes(path.basename(patchFile))) { associatedVersions.push(ver); } if (info.snapshot && info.snapshot === path.basename(patchFile)) { associatedVersions.push(ver); } } // Check hotfixes for (const [ver, hotfixArr] of Object.entries(meta.hotfixes || {})) { if (hotfixArr && hotfixArr.includes(path.basename(patchFile))) { associatedVersions.push(ver + ' (hotfix)'); } } console.log(chalk.cyan(`\nPatch: ${path.basename(patchFile)}`)); if (associatedVersions.length > 0) { console.log(chalk.magenta(`Associated version(s): ${associatedVersions.join(', ')}`)); } else { console.log(chalk.magenta('Associated version(s): (none found)')); } // Display changes if (patchObj.changes && patchObj.changes.length > 0) { console.log(chalk.yellow('Changes:')); patchObj.changes.forEach(change => { console.log(chalk.green(` File: ${change.file}`)); console.log(chalk.white(` Diff:\n${change.diff}\n`)); }); } // Display deletes if (patchObj.deletes && patchObj.deletes.length > 0) { console.log(chalk.yellow('Deleted Files:')); patchObj.deletes.forEach(file => { console.log(chalk.red(` ${file}`)); }); } } catch (err) { console.error(chalk.red(`Error reading patch: ${err.message}`)); process.exit(1); } } module.exports = showPatch;