import _ from 'lodash'; import rimRaf from 'rimraf'; import path from 'path'; import { fork } from 'child_process'; import { CREDENTIALS } from '../functional/config.functional'; import { HTTP_STATUS } from '../../src/lib/constants'; import { IVerdaccioConfig, IServerBridge, IServerProcess } from '../types'; export default class VerdaccioProcess implements IServerProcess { private bridge: IServerBridge; private config: IVerdaccioConfig; private childFork: any; private isDebug: boolean; private silence: boolean; private cleanStore: boolean; public constructor( config: IVerdaccioConfig, bridge: IServerBridge, silence = true, isDebug = false, cleanStore = true ) { this.config = config; this.bridge = bridge; this.silence = silence; this.isDebug = isDebug; this.cleanStore = cleanStore; } public init(verdaccioPath = '../../bin/verdaccio'): Promise { return new Promise((resolve, reject) => { if (this.cleanStore) { rimRaf(this.config.storagePath, (err) => { if (_.isNil(err) === false) { reject(err); } this._start(verdaccioPath, resolve, reject); }); } else { this._start(verdaccioPath, resolve, reject); } }); } private _start(verdaccioPath: string, resolve: Function, reject: Function) { const verdaccioRegisterWrap: string = path.join(__dirname, verdaccioPath); let childOptions = { silent: true }; if (this.isDebug) { // @ts-ignore const debugPort = parseInt(this.config.port, 10) + 5; childOptions = Object.assign({}, childOptions, { execArgv: [`--inspect=${debugPort}`] }); } const { configPath, port } = this.config; this.childFork = fork( verdaccioRegisterWrap, ['-c', configPath, '-l', port as string], childOptions ); this.childFork.on('message', (msg) => { // verdaccio_started is a message that comes from verdaccio in debug mode that notify has been started if ('verdaccio_started' in msg) { this.bridge .debug() .status(HTTP_STATUS.OK) .then((body) => { this.bridge .auth(CREDENTIALS.user, CREDENTIALS.password) .status(HTTP_STATUS.CREATED) .body_ok(new RegExp(CREDENTIALS.user)) .then(() => resolve([this, body.pid]), reject); }, reject); } }); this.childFork.on('error', (err) => reject([err, this])); this.childFork.on('disconnect', (err) => reject([err, this])); this.childFork.on('exit', (err) => reject([err, this])); } public stop(): void { return this.childFork.kill('SIGINT'); } }