@jmkim85/dev-flow-mcp
Version:
MCP-based Dev Flow - AI-powered development workflow management with 13 essential tools for TDD and context management
178 lines • 5.57 kB
JavaScript
/**
* Centralized Version Management for Dev Flow MCP
* Single source of truth for all version information
*/
import { promises as fs } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
// Cache for version to avoid repeated file reads
let cachedVersion = null;
let cachedPackageJson = null;
/**
* Get the current version from package.json (single source of truth)
*/
export async function getVersion() {
if (cachedVersion !== null) {
return cachedVersion;
}
try {
const packageJson = await getPackageJson();
cachedVersion = packageJson.version;
return cachedVersion; // We know it's not null here
}
catch (error) {
console.error('Warning: Could not read version from package.json:', error);
// Return a fallback version that indicates an error
return '0.0.0-error';
}
}
/**
* Get the full package.json content
*/
export async function getPackageJson() {
if (cachedPackageJson) {
return cachedPackageJson;
}
try {
// Get the directory of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Look for package.json in the project root (go up from src/ or dist/)
const packageJsonPath = join(__dirname, '..', 'package.json');
const packageContent = await fs.readFile(packageJsonPath, 'utf-8');
cachedPackageJson = JSON.parse(packageContent);
return cachedPackageJson;
}
catch (error) {
throw new Error(`Failed to read package.json: ${error}`);
}
}
/**
* Get version with prefix (e.g., "v2.3.0")
*/
export async function getVersionWithPrefix(prefix = 'v') {
const version = await getVersion();
return `${prefix}${version}`;
}
/**
* Get major version only (e.g., "2" from "2.3.0")
*/
export async function getMajorVersion() {
const version = await getVersion();
return version.split('.')[0];
}
/**
* Get major.minor version (e.g., "2.3" from "2.3.0")
*/
export async function getMajorMinorVersion() {
const version = await getVersion();
const parts = version.split('.');
return `${parts[0]}.${parts[1]}`;
}
/**
* Get version info object with various formats
*/
export async function getVersionInfo() {
const packageJson = await getPackageJson();
const version = packageJson.version;
return {
full: version,
withPrefix: `v${version}`,
major: version.split('.')[0],
majorMinor: version.split('.').slice(0, 2).join('.'),
name: packageJson.name,
description: packageJson.description
};
}
/**
* Clear version cache (useful for testing or when package.json changes)
*/
export function clearVersionCache() {
cachedVersion = null;
cachedPackageJson = null;
}
/**
* Validate that version follows semantic versioning
*/
export async function validateVersion() {
try {
const version = await getVersion();
// Check if version follows semver pattern (x.y.z)
const semverPattern = /^\d+\.\d+\.\d+(-[a-zA-Z0-9-]+)?(\+[a-zA-Z0-9-]+)?$/;
if (!semverPattern.test(version)) {
return {
valid: false,
message: `Version "${version}" does not follow semantic versioning (x.y.z)`
};
}
return {
valid: true,
message: `Version "${version}" is valid`
};
}
catch (error) {
return {
valid: false,
message: `Could not validate version: ${error}`
};
}
}
/**
* Get version for display in CLI/UI contexts
*/
export async function getDisplayVersion() {
const versionInfo = await getVersionInfo();
return `${versionInfo.name} ${versionInfo.withPrefix}`;
}
/**
* Get version for server/API contexts
*/
export async function getServerVersion() {
return await getVersion();
}
/**
* Replace version placeholders in text
*/
export async function replaceVersionPlaceholders(text) {
const versionInfo = await getVersionInfo();
return text
.replace(/\[VERSION\]/g, versionInfo.full)
.replace(/\[VERSION_WITH_PREFIX\]/g, versionInfo.withPrefix)
.replace(/\[MAJOR_VERSION\]/g, versionInfo.major)
.replace(/\[MAJOR_MINOR_VERSION\]/g, versionInfo.majorMinor)
.replace(/\[PACKAGE_NAME\]/g, versionInfo.name)
.replace(/\[PACKAGE_DESCRIPTION\]/g, versionInfo.description);
}
/**
* Update version in package.json (for version management scripts)
*/
export async function updateVersion(newVersion) {
try {
const packageJson = await getPackageJson();
packageJson.version = newVersion;
// Get package.json path
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJsonPath = join(__dirname, '..', 'package.json');
// Write updated package.json
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
// Clear cache to force reload
clearVersionCache();
console.log(`✅ Updated version to ${newVersion}`);
}
catch (error) {
throw new Error(`Failed to update version: ${error}`);
}
}
// Export commonly used functions as default
export default {
getVersion,
getVersionWithPrefix,
getVersionInfo,
getDisplayVersion,
getServerVersion,
replaceVersionPlaceholders,
validateVersion,
clearVersionCache
};
//# sourceMappingURL=version-manager.js.map