import { ChildProcess , spawn } from 'child_process' ; import fp from 'find-free-port' ; const verdaccioApi = require . resolve ( './verdaccio.js' ) ; const defaultPort = 4873 ; export class Registry { private server ? : ChildProcess = undefined ; private port ? : number = undefined ; async start ( ) { if ( this . server ) { throw new Error ( 'Server already started' ) ; } if ( this . port ) { return this . startWithPort ( this . port ) ; } let tryPort = defaultPort ; while ( ! this . port ) { tryPort = await fp ( tryPort , defaultPort + 10 ) ; try { await this . startWithPort ( tryPort ) ; this . port = tryPort ; } catch { tryPort ++ ; console . log ( `Could not start server, trying again on port ${ tryPort }` ) ; } } } private async startWithPort ( port ) { return new Promise ( ( resolve , reject ) => { this . server = spawn ( process . execPath , [ verdaccioApi , port . toString ( ) ] ) ; if ( ! this . server || ! this . server . stdout || ! this . server . stderr ) { return reject ( ) ; } this . server . stdout . on ( 'data' , data => { if ( data . includes ( 'verdaccio running' ) ) { resolve ( port ) ; } } ) ; this . server . stderr . on ( 'data' , data => { reject ( ) ; } ) ; this . server . on ( 'error' , data => { reject ( ) ; } ) ; } ) ; } stop ( ) { if ( this . server ) { this . server . kill ( ) ; this . server = undefined ; } } /**
     * Reset the state of the registry to an empty registry. Starts server if not already started.
     */ async reset ( ) { this . stop ( ) ; await this . start ( ) ; } /**
     * A helper to get registry URL based on currently used port.
     */ getUrl ( ) { if ( ! this . port ) { throw new Error ( `Can't getRegistryUrl, no valid port assigned.` ) ; } return `http://localhost:${ this . port }` ; } }