(
packageName: string,
targetPath: string,
options: { registry?: string; version?: string } = {},
)
| 491 | * Install a plugin from npm using a global cache (exported for testing) |
| 492 | */ |
| 493 | export async function installFromNpm( |
| 494 | packageName: string, |
| 495 | targetPath: string, |
| 496 | options: { registry?: string; version?: string } = {}, |
| 497 | ): Promise<void> { |
| 498 | const npmCachePath = join(getPluginsDirectory(), 'npm-cache') |
| 499 | |
| 500 | await getFsImplementation().mkdir(npmCachePath) |
| 501 | |
| 502 | const packageSpec = options.version |
| 503 | ? `${packageName}@${options.version}` |
| 504 | : packageName |
| 505 | const packagePath = join(npmCachePath, 'node_modules', packageName) |
| 506 | const needsInstall = !(await pathExists(packagePath)) |
| 507 | |
| 508 | if (needsInstall) { |
| 509 | logForDebugging(`Installing npm package ${packageSpec} to cache`) |
| 510 | const args = ['install', packageSpec, '--prefix', npmCachePath] |
| 511 | if (options.registry) { |
| 512 | args.push('--registry', options.registry) |
| 513 | } |
| 514 | const result = await execFileNoThrow('npm', args, { useCwd: false }) |
| 515 | |
| 516 | if (result.code !== 0) { |
| 517 | throw new Error(`Failed to install npm package: ${result.stderr}`) |
| 518 | } |
| 519 | } |
| 520 | |
| 521 | await copyDir(packagePath, targetPath) |
| 522 | logForDebugging( |
| 523 | `Copied npm package ${packageName} from cache to ${targetPath}`, |
| 524 | ) |
| 525 | } |
| 526 | |
| 527 | /** |
| 528 | * Clone a git repository (exported for testing) |
no test coverage detected