1import { findYarnOrNpmWorkspaceRoot, YARN_LOCK_FILE } from '../utils/nodeWorkspaces'; 2import { createPendingSpawnAsync } from '../utils/spawn'; 3import { isYarnOfflineAsync } from '../utils/yarn'; 4import { BasePackageManager } from './BasePackageManager'; 5 6export class YarnPackageManager extends BasePackageManager { 7 readonly name = 'yarn'; 8 readonly bin = 'yarnpkg'; 9 readonly lockFile = YARN_LOCK_FILE; 10 11 /** Check if Yarn is running in offline mode, and add the `--offline` flag */ 12 private async withOfflineFlagAsync(namesOrFlags: string[]): Promise<string[]> { 13 return (await isYarnOfflineAsync()) ? [...namesOrFlags, '--offline'] : namesOrFlags; 14 } 15 16 workspaceRoot() { 17 const root = findYarnOrNpmWorkspaceRoot(this.ensureCwdDefined('workspaceRoot')); 18 if (root) { 19 return new YarnPackageManager({ 20 ...this.options, 21 silent: this.silent, 22 log: this.log, 23 cwd: root, 24 }); 25 } 26 27 return null; 28 } 29 30 installAsync(flags: string[] = []) { 31 return createPendingSpawnAsync( 32 () => this.withOfflineFlagAsync(['install']), 33 (args) => this.runAsync([...args, ...flags]) 34 ); 35 } 36 37 addAsync(namesOrFlags: string[] = []) { 38 if (!namesOrFlags.length) { 39 return this.installAsync(); 40 } 41 42 return createPendingSpawnAsync( 43 () => this.withOfflineFlagAsync(['add', ...namesOrFlags]), 44 (args) => this.runAsync(args) 45 ); 46 } 47 48 addDevAsync(namesOrFlags: string[] = []) { 49 if (!namesOrFlags.length) { 50 return this.installAsync(); 51 } 52 53 return createPendingSpawnAsync( 54 () => this.withOfflineFlagAsync(['add', '--dev', ...namesOrFlags]), 55 (args) => this.runAsync(args) 56 ); 57 } 58 59 addGlobalAsync(namesOrFlags: string[] = []) { 60 if (!namesOrFlags.length) { 61 return this.installAsync(); 62 } 63 64 return createPendingSpawnAsync( 65 () => this.withOfflineFlagAsync(['global', 'add', ...namesOrFlags]), 66 (args) => this.runAsync(args) 67 ); 68 } 69 70 removeAsync(namesOrFlags: string[]) { 71 return this.runAsync(['remove', ...namesOrFlags]); 72 } 73 74 removeDevAsync(namesOrFlags: string[]) { 75 return this.runAsync(['remove', ...namesOrFlags]); 76 } 77 78 removeGlobalAsync(namesOrFlags: string[]) { 79 return this.runAsync(['global', 'remove', ...namesOrFlags]); 80 } 81} 82