1"use strict"; 2var __importDefault = (this && this.__importDefault) || function (mod) { 3 return (mod && mod.__esModule) ? mod : { "default": mod }; 4}; 5Object.defineProperty(exports, "__esModule", { value: true }); 6exports.NpmPackageManager = void 0; 7const json_file_1 = __importDefault(require("@expo/json-file")); 8const npm_package_arg_1 = __importDefault(require("npm-package-arg")); 9const path_1 = __importDefault(require("path")); 10const BasePackageManager_1 = require("./BasePackageManager"); 11const nodeWorkspaces_1 = require("../utils/nodeWorkspaces"); 12const spawn_1 = require("../utils/spawn"); 13class NpmPackageManager extends BasePackageManager_1.BasePackageManager { 14 constructor() { 15 super(...arguments); 16 this.name = 'npm'; 17 this.bin = 'npm'; 18 this.lockFile = nodeWorkspaces_1.NPM_LOCK_FILE; 19 } 20 workspaceRoot() { 21 const root = (0, nodeWorkspaces_1.findYarnOrNpmWorkspaceRoot)(this.ensureCwdDefined('workspaceRoot')); 22 if (root) { 23 return new NpmPackageManager({ 24 ...this.options, 25 silent: this.silent, 26 log: this.log, 27 cwd: root, 28 }); 29 } 30 return null; 31 } 32 addAsync(namesOrFlags = []) { 33 if (!namesOrFlags.length) { 34 return this.installAsync(); 35 } 36 const { flags, versioned, unversioned } = this.parsePackageSpecs(namesOrFlags); 37 return (0, spawn_1.createPendingSpawnAsync)(() => this.updatePackageFileAsync(versioned, 'dependencies'), () => !unversioned.length 38 ? this.runAsync(['install', ...flags]) 39 : this.runAsync(['install', '--save', ...flags, ...unversioned.map((spec) => spec.raw)])); 40 } 41 addDevAsync(namesOrFlags = []) { 42 if (!namesOrFlags.length) { 43 return this.installAsync(); 44 } 45 const { flags, versioned, unversioned } = this.parsePackageSpecs(namesOrFlags); 46 return (0, spawn_1.createPendingSpawnAsync)(() => this.updatePackageFileAsync(versioned, 'devDependencies'), () => !unversioned.length 47 ? this.runAsync(['install', ...flags]) 48 : this.runAsync([ 49 'install', 50 '--save-dev', 51 ...flags, 52 ...unversioned.map((spec) => spec.raw), 53 ])); 54 } 55 addGlobalAsync(namesOrFlags = []) { 56 if (!namesOrFlags.length) { 57 return this.installAsync(); 58 } 59 return this.runAsync(['install', '--global', ...namesOrFlags]); 60 } 61 removeAsync(namesOrFlags) { 62 return this.runAsync(['uninstall', ...namesOrFlags]); 63 } 64 removeDevAsync(namesOrFlags) { 65 return this.runAsync(['uninstall', '--save-dev', ...namesOrFlags]); 66 } 67 removeGlobalAsync(namesOrFlags) { 68 return this.runAsync(['uninstall', '--global', ...namesOrFlags]); 69 } 70 /** 71 * Parse all package specifications from the names or flag list. 72 * The result from this method can be used for `.updatePackageFileAsync`. 73 */ 74 parsePackageSpecs(namesOrFlags) { 75 const result = { flags: [], versioned: [], unversioned: [] }; 76 namesOrFlags 77 .map((name) => { 78 if (name.trim().startsWith('-')) { 79 result.flags.push(name); 80 return null; 81 } 82 return (0, npm_package_arg_1.default)(name); 83 }) 84 .forEach((spec) => { 85 // When using a dist-tag version of a library, we need to consider it as "unversioned". 86 // Doing so will install that version with `npm install --save(-dev)`, and resolve the dist-tag properly. 87 if (spec && spec.rawSpec && spec.type !== 'tag') { 88 result.versioned.push(spec); 89 } 90 else if (spec) { 91 result.unversioned.push(spec); 92 } 93 }); 94 return result; 95 } 96 /** 97 * Older npm versions have issues with mismatched nested dependencies when adding exact versions. 98 * This propagates as issues like mismatched `@expo/config-pugins` versions. 99 * As a workaround, we update the `package.json` directly and run `npm install`. 100 */ 101 async updatePackageFileAsync(packageSpecs, packageType) { 102 if (!packageSpecs.length) { 103 return; 104 } 105 const pkgPath = path_1.default.join(this.options.cwd?.toString() || '.', 'package.json'); 106 const pkg = await json_file_1.default.readAsync(pkgPath); 107 packageSpecs.forEach((spec) => { 108 pkg[packageType] = pkg[packageType] || {}; 109 pkg[packageType][spec.name] = spec.rawSpec; 110 }); 111 await json_file_1.default.writeAsync(pkgPath, pkg, { json5: false }); 112 } 113} 114exports.NpmPackageManager = NpmPackageManager; 115//# sourceMappingURL=NpmPackageManager.js.map