|
| 1 | +import * as path from "path"; |
| 2 | +import { BasePackageManager } from "./base-package-manager"; |
| 3 | +import { exported } from './common/decorators'; |
| 4 | +import { CACACHE_DIRECTORY_NAME } from "./constants"; |
| 5 | + |
| 6 | +export class PnpmPackageManager extends BasePackageManager { |
| 7 | + |
| 8 | + constructor( |
| 9 | + $childProcess: IChildProcess, |
| 10 | + private $errors: IErrors, |
| 11 | + $fs: IFileSystem, |
| 12 | + $hostInfo: IHostInfo, |
| 13 | + private $httpClient: Server.IHttpClient, |
| 14 | + private $logger: ILogger, |
| 15 | + $pacoteService: IPacoteService |
| 16 | + ) { |
| 17 | + super($childProcess, $fs, $hostInfo, $pacoteService, 'pnpm'); |
| 18 | + } |
| 19 | + |
| 20 | + @exported("pnpm") |
| 21 | + public async install(packageName: string, pathToSave: string, config: INodePackageManagerInstallOptions): Promise<INpmInstallResultInfo> { |
| 22 | + if (config.disableNpmInstall) { |
| 23 | + return; |
| 24 | + } |
| 25 | + if (config.ignoreScripts) { |
| 26 | + config['ignore-scripts'] = true; |
| 27 | + } |
| 28 | + |
| 29 | + const packageJsonPath = path.join(pathToSave, 'package.json'); |
| 30 | + const jsonContentBefore = this.$fs.readJson(packageJsonPath); |
| 31 | + |
| 32 | + const flags = this.getFlagsString(config, true); |
| 33 | + // With pnpm we need to install as "flat" or some imports wont be found |
| 34 | + let params = ['i', '--shamefully-hoist']; |
| 35 | + const isInstallingAllDependencies = packageName === pathToSave; |
| 36 | + if (!isInstallingAllDependencies) { |
| 37 | + params.push(packageName); |
| 38 | + } |
| 39 | + |
| 40 | + params = params.concat(flags); |
| 41 | + const cwd = pathToSave; |
| 42 | + |
| 43 | + try { |
| 44 | + const result = await this.processPackageManagerInstall(packageName, params, { cwd, isInstallingAllDependencies }); |
| 45 | + return result; |
| 46 | + } catch (e) { |
| 47 | + this.$fs.writeJson(packageJsonPath, jsonContentBefore); |
| 48 | + throw e; |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + @exported("pnpm") |
| 53 | + public uninstall(packageName: string, config?: IDictionary<string | boolean>, cwd?: string): Promise<string> { |
| 54 | + // pnpm does not want save option in remove. It saves it by default |
| 55 | + delete config['save']; |
| 56 | + const flags = this.getFlagsString(config, false); |
| 57 | + return this.$childProcess.exec(`pnpm remove ${packageName} ${flags}`, { cwd }); |
| 58 | + } |
| 59 | + |
| 60 | + @exported("pnpm") |
| 61 | + public async view(packageName: string, config: Object): Promise<any> { |
| 62 | + const wrappedConfig = _.extend({}, config, { json: true }); |
| 63 | + |
| 64 | + const flags = this.getFlagsString(wrappedConfig, false); |
| 65 | + let viewResult: any; |
| 66 | + try { |
| 67 | + viewResult = await this.$childProcess.exec(`pnpm info ${packageName} ${flags}`); |
| 68 | + } catch (e) { |
| 69 | + this.$errors.fail(e.message); |
| 70 | + } |
| 71 | + const result = JSON.parse(viewResult); |
| 72 | + return result; |
| 73 | + } |
| 74 | + |
| 75 | + @exported("pnpm") |
| 76 | + public search(filter: string[], config: IDictionary<string | boolean>): Promise<string> { |
| 77 | + const flags = this.getFlagsString(config, false); |
| 78 | + return this.$childProcess.exec(`pnpm search ${filter.join(" ")} ${flags}`); |
| 79 | + } |
| 80 | + |
| 81 | + public async searchNpms(keyword: string): Promise<INpmsResult> { |
| 82 | + const httpRequestResult = await this.$httpClient.httpRequest(`https://api.npms.io/v2/search?q=keywords:${keyword}`); |
| 83 | + const result: INpmsResult = JSON.parse(httpRequestResult.body); |
| 84 | + return result; |
| 85 | + } |
| 86 | + |
| 87 | + @exported("pnpm") |
| 88 | + public async getRegistryPackageData(packageName: string): Promise<any> { |
| 89 | + const registry = await this.$childProcess.exec(`pnpm config get registry`); |
| 90 | + const url = `${registry.trim()}/${packageName}`; |
| 91 | + this.$logger.trace(`Trying to get data from pnpm registry for package ${packageName}, url is: ${url}`); |
| 92 | + const responseData = (await this.$httpClient.httpRequest(url)).body; |
| 93 | + this.$logger.trace(`Successfully received data from pnpm registry for package ${packageName}. Response data is: ${responseData}`); |
| 94 | + const jsonData = JSON.parse(responseData); |
| 95 | + this.$logger.trace(`Successfully parsed data from pnpm registry for package ${packageName}.`); |
| 96 | + return jsonData; |
| 97 | + } |
| 98 | + |
| 99 | + @exported("pnpm") |
| 100 | + public async getCachePath(): Promise<string> { |
| 101 | + const cachePath = await this.$childProcess.exec(`pnpm config get cache`); |
| 102 | + return path.join(cachePath.trim(), CACACHE_DIRECTORY_NAME); |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | +$injector.register("pnpm", PnpmPackageManager); |
0 commit comments