import { lstatSync, mkdirSync, realpathSync, rmSync, symlinkSync, unlinkSync } from 'node:fs' import path from 'node:path' import { spawnSync } from 'node:child_process' import { fileURLToPath } from 'node:url' const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') const consumers = [ path.resolve(packageRoot, '../cmvr-iot-ui'), path.resolve(packageRoot, '../cmvr-iot-aima'), path.resolve(packageRoot, '../changan-inspection') ] const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm' const pnpmCommand = process.platform === 'win32' ? 'pnpm.cmd' : 'pnpm' const shouldUnlink = process.argv.includes('--unlink') function run(command, args, cwd) { const executable = process.platform === 'win32' ? process.env.ComSpec : command const commandArgs = process.platform === 'win32' ? ['/d', '/s', '/c', [command, ...args].join(' ')] : args const env = { ...process.env } delete env.npm_config_verify_deps_before_run const result = spawnSync(executable, commandArgs, { cwd, stdio: 'inherit', env }) if (result.error) throw result.error if (result.status !== 0) process.exit(result.status ?? 1) } function removePackageLink(linkedPackage) { try { const stats = lstatSync(linkedPackage) if (stats.isSymbolicLink()) unlinkSync(linkedPackage) else rmSync(linkedPackage, { recursive: true, force: true }) } catch (error) { if (error.code !== 'ENOENT') throw error } } if (shouldUnlink) { for (const consumer of consumers) { const linkedPackage = path.join(consumer, 'node_modules/@cmvr/iot-common') removePackageLink(linkedPackage) run(pnpmCommand, ['install', '--offline', '--frozen-lockfile'], consumer) console.log(`[restored] ${path.basename(consumer)} -> published dependency`) } process.exit(0) } const linkOptions = [ '--ignore-scripts', '--package-lock=false', '--audit=false', '--fund=false', '--legacy-peer-deps' ] run(npmCommand, ['link', ...linkOptions], packageRoot) for (const consumer of consumers) { const linkedPackage = path.join(consumer, 'node_modules/@cmvr/iot-common') removePackageLink(linkedPackage) mkdirSync(path.dirname(linkedPackage), { recursive: true }) symlinkSync(packageRoot, linkedPackage, process.platform === 'win32' ? 'junction' : 'dir') console.log(`[linked] ${path.basename(consumer)} -> ${realpathSync(linkedPackage)}`) }