181 lines
5.9 KiB
JavaScript
181 lines
5.9 KiB
JavaScript
|
|
#!/usr/bin/env node
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Switch between local and published versions of @wizardconnect packages
|
||
|
|
*
|
||
|
|
* Usage:
|
||
|
|
* node /path/to/wizardconnect/contrib/switch-versions.js [local|published]
|
||
|
|
*
|
||
|
|
* This script modifies package.json in the current working directory to switch
|
||
|
|
* between local file: references and published npm versions of @wizardconnect packages.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
|
||
|
|
import { resolve, dirname } from 'path';
|
||
|
|
import { fileURLToPath } from 'url';
|
||
|
|
import { execSync } from 'child_process';
|
||
|
|
|
||
|
|
const __filename = fileURLToPath(import.meta.url);
|
||
|
|
const __dirname = dirname(__filename);
|
||
|
|
|
||
|
|
// Get the wizardconnect root directory (one level up from contrib)
|
||
|
|
const LIB_ROOT = resolve(__dirname, '..');
|
||
|
|
|
||
|
|
const PACKAGE_SCOPE = '@wizardconnect/';
|
||
|
|
|
||
|
|
// Dynamically discover packages from workspace configuration
|
||
|
|
function discoverPackages() {
|
||
|
|
const packages = {};
|
||
|
|
|
||
|
|
try {
|
||
|
|
const rootPackageJsonPath = resolve(LIB_ROOT, 'package.json');
|
||
|
|
const rootPackageJson = JSON.parse(readFileSync(rootPackageJsonPath, 'utf8'));
|
||
|
|
|
||
|
|
if (rootPackageJson.workspaces) {
|
||
|
|
for (const workspace of rootPackageJson.workspaces) {
|
||
|
|
const workspacePattern = typeof workspace === 'string' ? workspace : workspace.package;
|
||
|
|
const baseDir = workspacePattern.split('*')[0].replace(/\/$/, '');
|
||
|
|
const baseDirPath = resolve(LIB_ROOT, baseDir);
|
||
|
|
|
||
|
|
if (existsSync(baseDirPath)) {
|
||
|
|
const entries = readdirSync(baseDirPath, { withFileTypes: true });
|
||
|
|
for (const entry of entries) {
|
||
|
|
if (entry.isDirectory()) {
|
||
|
|
const workspacePath = `${baseDir}/${entry.name}`;
|
||
|
|
const packageJsonPath = resolve(LIB_ROOT, workspacePath, 'package.json');
|
||
|
|
|
||
|
|
if (existsSync(packageJsonPath)) {
|
||
|
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
||
|
|
if (packageJson.name && packageJson.name.startsWith(PACKAGE_SCOPE)) {
|
||
|
|
packages[packageJson.name] = workspacePath;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error: Could not read workspace configuration:', error.message);
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
return packages;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getLatestPublishedVersions(packages) {
|
||
|
|
const versions = {};
|
||
|
|
|
||
|
|
for (const packageName of Object.keys(packages)) {
|
||
|
|
try {
|
||
|
|
console.log(`Querying npm for latest version of ${packageName}...`);
|
||
|
|
const result = execSync(`npm view ${packageName} version`, {
|
||
|
|
encoding: 'utf8',
|
||
|
|
stdio: ['pipe', 'pipe', 'pipe']
|
||
|
|
});
|
||
|
|
const latestVersion = result.trim();
|
||
|
|
versions[packageName] = latestVersion;
|
||
|
|
console.log(` Found latest version: ${packageName}@${latestVersion}`);
|
||
|
|
} catch (error) {
|
||
|
|
console.warn(` Could not get latest version for ${packageName}: ${error.message}`);
|
||
|
|
// Fall back to local version if npm query fails
|
||
|
|
const packagePath = packages[packageName];
|
||
|
|
const packageJsonPath = resolve(LIB_ROOT, packagePath, 'package.json');
|
||
|
|
if (existsSync(packageJsonPath)) {
|
||
|
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
||
|
|
versions[packageName] = packageJson.version;
|
||
|
|
console.log(` Using local version: ${packageName}@${packageJson.version}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return versions;
|
||
|
|
}
|
||
|
|
|
||
|
|
function switchDeps(deps, packages, mode, versions) {
|
||
|
|
let changed = false;
|
||
|
|
if (!deps) return changed;
|
||
|
|
|
||
|
|
for (const [packageName, localPath] of Object.entries(packages)) {
|
||
|
|
if (!deps[packageName]) continue;
|
||
|
|
|
||
|
|
if (mode === 'local') {
|
||
|
|
const absolutePath = resolve(LIB_ROOT, localPath);
|
||
|
|
deps[packageName] = `file:${absolutePath}`;
|
||
|
|
changed = true;
|
||
|
|
console.log(` ${packageName} -> file:${absolutePath}`);
|
||
|
|
} else {
|
||
|
|
const currentValue = deps[packageName];
|
||
|
|
const newValue = `^${versions[packageName]}`;
|
||
|
|
if (currentValue !== newValue) {
|
||
|
|
deps[packageName] = newValue;
|
||
|
|
changed = true;
|
||
|
|
console.log(` ${packageName} -> ${newValue}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return changed;
|
||
|
|
}
|
||
|
|
|
||
|
|
function main() {
|
||
|
|
const args = process.argv.slice(2);
|
||
|
|
const mode = args[0];
|
||
|
|
|
||
|
|
if (!mode || !['local', 'published'].includes(mode)) {
|
||
|
|
console.error('Usage: node switch-versions.js [local|published]');
|
||
|
|
console.error('');
|
||
|
|
console.error(' local - Switch to local file: references');
|
||
|
|
console.error(' published - Switch to latest published npm versions');
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
const packageJsonPath = resolve(process.cwd(), 'package.json');
|
||
|
|
if (!existsSync(packageJsonPath)) {
|
||
|
|
console.error('Error: No package.json found in current directory');
|
||
|
|
console.error('Please run this script from a project directory that contains package.json');
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
||
|
|
const packages = discoverPackages();
|
||
|
|
|
||
|
|
if (Object.keys(packages).length === 0) {
|
||
|
|
console.error('Error: No @wizardconnect packages found in workspace');
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log(`Found packages: ${Object.keys(packages).join(', ')}`);
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
let versions = {};
|
||
|
|
if (mode === 'published') {
|
||
|
|
versions = getLatestPublishedVersions(packages);
|
||
|
|
console.log('');
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log(`Switching to ${mode} versions:`);
|
||
|
|
const changed =
|
||
|
|
switchDeps(packageJson.dependencies, packages, mode, versions) |
|
||
|
|
switchDeps(packageJson.devDependencies, packages, mode, versions);
|
||
|
|
|
||
|
|
if (!changed) {
|
||
|
|
console.log('No @wizardconnect packages found to switch');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
||
|
|
|
||
|
|
console.log('');
|
||
|
|
console.log(`Successfully switched to ${mode} versions`);
|
||
|
|
console.log('Remember to run "npm install" to update your node_modules');
|
||
|
|
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error:', error.message);
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
main();
|