Created
May 25, 2024 16:05
-
-
Save natew/7340b6098bc6e62f9d6f89a3cef06dc1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { promises as fs } from 'node:fs' | |
import * as path from 'node:path' | |
import { exec } from 'node:child_process' | |
import os from 'node:os' | |
interface PackageJson { | |
profile?: { [key: string]: any } | |
[key: string]: any | |
} | |
const main = async (name: string) => { | |
const packageJsonPath = path.join(process.cwd(), 'package.json') | |
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8') | |
const packageJson: PackageJson = JSON.parse(packageJsonContent) | |
const profile = packageJson.profile && packageJson.profile[name] | |
if (!profile) { | |
console.info(`Profile "${name}" not found in package.json`) | |
return | |
} | |
if (profile.applied) { | |
// Profile is applied, remove it | |
Object.keys(profile.resolutions).forEach((key) => { | |
if (packageJson.resolutions && packageJson.resolutions[key]) { | |
delete packageJson.resolutions[key] | |
} | |
}) | |
profile.applied = false | |
} else { | |
// Profile is not applied, merge it | |
if (!packageJson.resolutions) packageJson.resolutions = {} | |
const processedResolutions = processResolutions(profile.resolutions) | |
packageJson.resolutions = mergeDeep(packageJson.resolutions, processedResolutions) | |
profile.applied = true | |
} | |
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8') | |
console.info(`Profile "${name}" has been ${profile.applied ? 'applied' : 'removed'}.`) | |
exec('yarn', (error, stdout, stderr) => { | |
if (error) { | |
console.error(`Error executing yarn: ${error.message}`) | |
} else if (stderr) { | |
console.error(`yarn stderr: ${stderr}`) | |
} else { | |
console.info(`yarn stdout: ${stdout}`) | |
} | |
}) | |
} | |
// Example usage: pass the profile name as a command-line argument | |
const args = process.argv.slice(2) | |
if (args.length !== 1) { | |
console.error('Usage: ts-node script.ts <profile-name>') | |
process.exit(1) | |
} | |
const profileName = args[0] | |
main(profileName).catch((err) => console.error(err)) | |
const mergeDeep = (target: any, source: any) => { | |
const isObject = (obj: any) => obj && typeof obj === 'object' | |
if (!isObject(target) || !isObject(source)) return source | |
Object.keys(source).forEach((key) => { | |
const targetValue = target[key] | |
const sourceValue = source[key] | |
if (Array.isArray(targetValue) && Array.isArray(sourceValue)) { | |
target[key] = targetValue.concat(sourceValue) | |
} else if (isObject(targetValue) && isObject(sourceValue)) { | |
target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue) | |
} else { | |
target[key] = sourceValue | |
} | |
}) | |
return target | |
} | |
const replaceTildeWithHomePath = (value: string) => { | |
const homePath = os.homedir() | |
return value.replace(/^portal:~\//, `portal:${homePath}/`) | |
} | |
const processResolutions = (resolutions: { [key: string]: string }) => { | |
const processedResolutions: { [key: string]: string } = {} | |
Object.keys(resolutions).forEach((key) => { | |
processedResolutions[key] = replaceTildeWithHomePath(resolutions[key]) | |
}) | |
return processedResolutions | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment