import { EventEmitter } from 'events'; import * as PolkaFactory from 'polka'; import { Logger } from '@cirrusct/logging'; import { MiddlewareLoader, RootHandler, WebServerContext } from './middleware'; import { HttpServerInstanceManager } from './HttpServerInstanceManager'; import { Router } from './routing'; import { WebServerOptions, Middleware, HttpsServerOptions, Polka, OnErrorHandler, OnNoMatchHandler, HttpServerInstance, } from './types'; import { sslConfigToHttpsServerOptions } from './lib'; export class WebServer { private _polka: Polka; private _httpServerInstanceManager: HttpServerInstanceManager; private _middlewareLoader: MiddlewareLoader; private _eventEmitter: EventEmitter = new EventEmitter(); private _rootHandler: RootHandler; constructor( private logger: Logger, private options?: WebServerOptions, onError?: OnErrorHandler, onNoMatch?: OnNoMatchHandler ) { this._polka = PolkaFactory({ onError, onNoMatch }) as Polka; this._rootHandler = new RootHandler(this._polka, logger); } public get context(): WebServerContext { return this._rootHandler.context; } public get router(): Router { return this._rootHandler.router; } public get middleware(): MiddlewareLoader { if (!this._middlewareLoader) { this._middlewareLoader = new MiddlewareLoader(this._polka); } return this._middlewareLoader; } public use(base: string | Middleware, ...mw: Middleware[]): this { this.middleware.use(base, ...mw); return this; } public get instanceManager(): HttpServerInstanceManager { if (!this._httpServerInstanceManager) { const startup = this.options.startup; if (startup) { let sslServerOptions: HttpsServerOptions; if (startup.https) { if (!this.options.ssl) { throw new Error('Cannot Start HTTPS/SSL Server. SSL config not defined.'); } sslServerOptions = sslConfigToHttpsServerOptions(this.options.ssl); } this._httpServerInstanceManager = new HttpServerInstanceManager( this._polka, startup, this.logger, sslServerOptions ); this._httpServerInstanceManager.onListening(this.emitOnListening); } else { throw new Error('No Servers defined in config startup.'); } } return this._httpServerInstanceManager; } public start() { try { this.instanceManager.start(); } catch (e) { throw new Error(`Could not start WebServer: ${e.message}`); } } private emitOnListening = (instance: HttpServerInstance) => { this._eventEmitter.emit('listening', instance); }; public onListening = (listener: (instance: HttpServerInstance) => void) => { this._eventEmitter.on('listening', listener); }; }