#!/usr/bin/env node --experimental-strip-types /** * Updates version numbers across all package.json files in the monorepo * Usage: node scripts/update-version.ts * Example: node scripts/update-version.ts 3.3.0-beta.1 */ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); interface UpdateResult { success: true; oldVersion: string; newVersion: string; } interface UpdateError { success: false; error: string; } type UpdatePackageResult = UpdateResult | UpdateError; // Get version from command line args const newVersion = process.argv[2]; if (!newVersion) { console.error('Error: Version number required'); console.error('Usage: node scripts/update-version.ts '); console.error('Example: node scripts/update-version.ts 3.3.0-beta.1'); process.exit(1); } // Validate version format (basic check) const versionRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/; if (!versionRegex.test(newVersion)) { console.error(`Error: Invalid version format: ${newVersion}`); console.error('Expected format: X.Y.Z or X.Y.Z-suffix (e.g., 3.3.0-beta.1)'); process.exit(1); } /** * Recursively find all package.json files */ function findPackageJsonFiles(dir: string, files: string[] = []): string[] { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); // Skip node_modules, .git, and other common directories if (entry.isDirectory()) { if (!['node_modules', '.git', '.next', '.turbo', 'build', 'dist'].includes(entry.name)) { findPackageJsonFiles(fullPath, files); } } else if (entry.name === 'package.json') { files.push(fullPath); } } return files; } /** * Update version in a package.json file */ function updatePackageVersion(filePath: string, version: string): UpdatePackageResult { try { const content = fs.readFileSync(filePath, 'utf8'); const pkg = JSON.parse(content); const oldVersion = pkg.version; pkg.version = version; // Write back with same formatting (2 spaces, newline at end) fs.writeFileSync(filePath, JSON.stringify(pkg, null, 2) + '\n', 'utf8'); return { success: true, oldVersion, newVersion: version }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error) }; } } // Main execution console.log(`Updating all package.json files to version ${newVersion}...\n`); const rootDir = path.join(__dirname, '..'); const packageFiles = findPackageJsonFiles(rootDir); let successCount = 0; let failureCount = 0; for (const filePath of packageFiles) { const relativePath = path.relative(rootDir, filePath); const result = updatePackageVersion(filePath, newVersion); if (result.success) { console.log(`✓ ${relativePath}: ${result.oldVersion} → ${result.newVersion}`); successCount++; } else { console.error(`✗ ${relativePath}: ${result.error}`); failureCount++; } } console.log(`\nSummary: ${successCount} updated, ${failureCount} failed`); if (failureCount > 0) { process.exit(1); }