1import { execSync } from 'child_process'; 2 3export type PackageManagerName = 'npm' | 'pnpm' | 'yarn' | 'bun'; 4 5/** Determine which package manager to use for installing dependencies based on how the process was started. */ 6export function resolvePackageManager(): PackageManagerName { 7 // Attempt to detect if the user started the command using `yarn` or `pnpm` 8 const userAgent = process.env.npm_config_user_agent; 9 10 if (userAgent?.startsWith('yarn')) { 11 return 'yarn'; 12 } else if (userAgent?.startsWith('pnpm')) { 13 return 'pnpm'; 14 } else if (userAgent?.startsWith('npm')) { 15 return 'npm'; 16 } else if (userAgent?.startsWith('bun')) { 17 return 'bun'; 18 } 19 20 // Try availability 21 if (isPackageManagerAvailable('yarn')) { 22 return 'yarn'; 23 } else if (isPackageManagerAvailable('pnpm')) { 24 return 'pnpm'; 25 } else if (isPackageManagerAvailable('bun')) { 26 return 'bun'; 27 } 28 29 return 'npm'; 30} 31 32function isPackageManagerAvailable(manager: PackageManagerName): boolean { 33 try { 34 execSync(`${manager} --version`, { stdio: 'ignore' }); 35 return true; 36 } catch {} 37 return false; 38} 39 40export function formatRunCommand(manager: PackageManagerName, cmd: string) { 41 switch (manager) { 42 case 'pnpm': 43 return `pnpm run ${cmd}`; 44 case 'yarn': 45 return `yarn ${cmd}`; 46 case 'bun': 47 return `bun run ${cmd}`; 48 case 'npm': 49 default: 50 return `npm run ${cmd}`; 51 } 52} 53