UNPKG

@wagmi/cli

Version:

Manage and generate code from Ethereum ABIs

121 lines (104 loc) 3.21 kB
import { promises as fs } from 'node:fs' import { resolve } from 'node:path' import { execa } from 'execa' export async function getIsPackageInstalled(parameters: { packageName: string cwd?: string }) { const { packageName, cwd = process.cwd() } = parameters try { const packageManager = await getPackageManager() const command = (() => { switch (packageManager) { case 'yarn': return ['why', packageName] case 'bun': return ['pm', 'ls', '--all'] default: return ['ls', packageName] } })() const { stdout } = await execa(packageManager, command, { cwd }) // For Bun, we need to check if the package name is in the output if (packageManager === 'bun') return stdout.includes(packageName) return stdout !== '' } catch (_error) { return false } } export async function getPackageManager(executable?: boolean | undefined) { const userAgent = process.env.npm_config_user_agent if (userAgent) { if (userAgent.includes('pnpm')) return 'pnpm' // The yarn@^3 user agent includes npm, so yarn must be checked first. if (userAgent.includes('yarn')) return 'yarn' if (userAgent.includes('npm')) return executable ? 'npx' : 'npm' if (userAgent.includes('bun')) return executable ? 'bunx' : 'bun' } const packageManager = await detect() if (packageManager === 'npm' && executable) return 'npx' return packageManager } type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun' async function detect( parameters: { cwd?: string; includeGlobalBun?: boolean } = {}, ) { const { cwd, includeGlobalBun } = parameters const type = await getTypeofLockFile(cwd) if (type) { return type } const [hasYarn, hasPnpm, hasBun] = await Promise.all([ hasGlobalInstallation('yarn'), hasGlobalInstallation('pnpm'), includeGlobalBun && hasGlobalInstallation('bun'), ]) if (hasYarn) return 'yarn' if (hasPnpm) return 'pnpm' if (hasBun) return 'bun' return 'npm' } const cache = new Map() function hasGlobalInstallation(pm: PackageManager): Promise<boolean> { const key = `has_global_${pm}` if (cache.has(key)) { return Promise.resolve(cache.get(key)) } return execa(pm, ['--version']) .then((res) => { return /^\d+.\d+.\d+$/.test(res.stdout) }) .then((value) => { cache.set(key, value) return value }) .catch(() => false) } function getTypeofLockFile(cwd = '.'): Promise<PackageManager | null> { const key = `lockfile_${cwd}` if (cache.has(key)) { return Promise.resolve(cache.get(key)) } return Promise.all([ pathExists(resolve(cwd, 'yarn.lock')), pathExists(resolve(cwd, 'package-lock.json')), pathExists(resolve(cwd, 'pnpm-lock.yaml')), pathExists(resolve(cwd, 'bun.lockb')), ]).then(([isYarn, isNpm, isPnpm, isBun]) => { let value: PackageManager | null = null if (isYarn) value = 'yarn' else if (isPnpm) value = 'pnpm' else if (isBun) value = 'bun' else if (isNpm) value = 'npm' cache.set(key, value) return value }) } async function pathExists(p: string) { try { await fs.access(p) return true } catch { return false } }