import { PackageJson , PackageJsonWithDepsAndDevDeps } from './PackageJson' ; import { readPackageJson , writePackageJson } from './PackageJsonHelper' ; import { commandLog } from '../helpers' ; import { sync as spawnSync } from 'cross-spawn' ; const logger = console ; export abstract class JsPackageManager { public abstract readonly type : 'npm' | 'yarn1' | 'yarn2' ; public abstract initPackageJson ( ) ; public abstract getRunEzbCommand ( ) ; public abstract getRunCommand ( command ) ; /**
     * Install dependecies listed in package.json
     */ public installDependencies ( ) { commandLog ( 'Installing dependencies' ) ; } public addEzbCommandInScripts ( ) { const ezbCmd = `npx ts-node-dev src/index.ts` ; this . addScripts ( { ezb : ezbCmd , start : ezbCmd , build : `tsc` , 'build:watch' : 'tsc -w' , } ) ; } public addScripts ( scripts ) { const packageJson = this . retrievePackageJson ( ) ; writePackageJson ( { ... packageJson , scripts : { ... packageJson . scripts , ... scripts , } , } ) ; } /**
     * Read the `package.json` file available in the directory the command was call from
     * If there is no `package.json` it will create one.
     */ public retrievePackageJson ( ) { let packageJson = readPackageJson ( ) ; if ( ! packageJson ) { this . initPackageJson ( ) ; packageJson = readPackageJson ( ) || { } ; } return { ... packageJson , dependencies : { ... packageJson . dependencies } , devDependencies : { ... packageJson . devDependencies } , } ; } public executeCommand ( command , args , stdio ? ) { const commandResult = spawnSync ( command , args , { stdio : stdio ?? 'pipe' , encoding : 'utf-8' , } ) ; if ( commandResult . status !== 0 ) { throw new Error ( commandResult . stderr ?? '' ) ; } return commandResult . stdout ?? '' ; } param { Object } options param { Array } dependencies example public addDependencies ( options , dependencies ) { const { skipInstall } = options ; if ( skipInstall ) { const { packageJson } = options ; const dependenciesMap = dependencies . reduce ( ( acc , dep ) => { const [ packageName , packageVersion ] = getPackageDetails ( dep ) ; return { ... acc , [ packageName ] : packageVersion } ; } , { } ) ; if ( options . installAsDevDependencies ) { packageJson . devDependencies = { ... packageJson . devDependencies , ... dependenciesMap , } ; } else { packageJson . dependencies = { ... packageJson . dependencies , ... dependenciesMap , } ; } writePackageJson ( packageJson ) ; } else { try { this . runAddDeps ( dependencies , options . installAsDevDependencies ?? true ) ; } catch ( e ) { logger . error ( 'An error occurred while installing dependencies.' ) ; logger . log ( e . message ) ; process . exit ( 1 ) ; } } } protected abstract runAddDeps ( dependencies , installAsDevDependencies ) ; } export function getPackageDetails ( pkg ) { const idx = pkg . lastIndexOf ( '@' ) ; if ( idx <= 0 ) { return [ pkg , undefined ] ; } const packageName = pkg . slice ( 0 , idx ) ; const packageVersion = pkg . slice ( idx + 1 ) ; return [ packageName , packageVersion ] ; }