| 122 | } |
| 123 | |
| 124 | private async installPackage(pkgWithVersion: string, prefix: string) { |
| 125 | const npmCachedModulePath = pathToFileURL(join(prefix, 'node_modules', this.pkg, 'dist', 'index.js')).toString() |
| 126 | if (existsSync(prefix)) return npmCachedModulePath |
| 127 | |
| 128 | process.stdout.write(dim(`Fetching latest updates for this subcommand...\n`)) |
| 129 | |
| 130 | const installCmdArgs = [ |
| 131 | 'install', |
| 132 | pkgWithVersion, |
| 133 | '--no-save', |
| 134 | '--prefix', |
| 135 | prefix, |
| 136 | '--userconfig', |
| 137 | prefix, |
| 138 | '--loglevel', |
| 139 | 'error', |
| 140 | ] |
| 141 | debug(`running install cmd: npm ${installCmdArgs.join(' ')}`) |
| 142 | |
| 143 | try { |
| 144 | // Ensure the prefix directory exists |
| 145 | await fs.mkdir(prefix, { recursive: true }) |
| 146 | // Note: Using execa this way ensure proper argument encoding for whitespaces |
| 147 | await execa.default('npm', installCmdArgs, { |
| 148 | stdout: 'ignore', |
| 149 | stderr: 'inherit', |
| 150 | cwd: prefix, |
| 151 | env: process.env, |
| 152 | }) |
| 153 | return npmCachedModulePath |
| 154 | } catch (e: unknown) { |
| 155 | debug(`install via npm failed: ${e}`) |
| 156 | throw new NpmInstallError(e) |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | private handleError(error: unknown) { |
| 161 | process.exitCode = 1 |