UNPKG

@hapiness/core

Version:

Project to have a HapiJS (https://hapijs.com/) based framework to create easier NodeJS back-end with some awesome features

226 lines 7.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const di_1 = require("../../core/di"); const hook_1 = require("../../core/hook"); const metadata_1 = require("../../core/metadata"); const module_1 = require("../../core/module"); const hapiness_1 = require("../../core/hapiness"); const enums_1 = require("./enums"); const lifecycle_1 = require("./lifecycle"); const route_1 = require("./route"); const rxjs_1 = require("rxjs"); const hapi_1 = require("hapi"); const core_1 = require("../../core"); class HttpServerExt { static setConfig(config) { return { token: HttpServerExt, config }; } /** * Initialize HapiJS Server * * @param {CoreModule} module * @param {HapiConfig} config * @returns Observable */ onExtensionLoad(module, config) { return rxjs_1.Observable .of(new hapi_1.Server(config.options)) .flatMap(server => rxjs_1.Observable .of(Object.assign({}, config, { options: undefined })) .map(_ => this.formatConnections(_)) .do(_ => _.forEach(connection => server.connection(connection))) .map(_ => server)) .flatMap(server => rxjs_1.Observable .of({ instance: this, token: HttpServerExt, value: server })); } /** * Build Lifecycle components * Add routes by modules * Add Lifecycle handlers * Start HapiJS Server * * @param {CoreModule} module * @param {Server} server * @returns Observable */ onModuleInstantiated(module, server) { return rxjs_1.Observable .from(module_1.ModuleManager.getModules(module)) .flatMap(_ => this.instantiateLifecycle(_, server)) .flatMap(_ => this.registerPlugin(_, server)) .reduce((a, c) => a.concat(c), []) .do(_ => lifecycle_1.LifecycleManager.routeLifecycle(server, _)) .flatMap(_ => server.start()); } /** * Shutdown HapiJS server extension * * @param {CoreModule} module * @param {Server} server * @returns ExtensionShutdown */ onShutdown(module, server) { return { priority: core_1.ExtensionShutdownPriority.IMPORTANT, resolver: rxjs_1.Observable.fromPromise(server.stop()) }; } /** * Format the config provided * to a list of ConnectionOptions * * @param {HapiConfig} config * @returns ConnectionOptions */ formatConnections(config) { return [] .concat(!!config.connections ? config.connections : config) .filter(_ => !!_) .map(_ => _); } /** * Register a HapiJS Plugin * * @param {CoreModule} module * @param {Server} server * @returns Observable */ registerPlugin(module, server) { return this .buildRoutes(module) .filter(_ => !!_ && _.length > 0) .flatMap(routes => rxjs_1.Observable .of(this.registerHandler(routes)) .do(_ => _.attributes = { name: module.name, version: module.version }) .flatMap(_ => rxjs_1.Observable .fromPromise(server.register(_)) .map(__ => routes))) .defaultIfEmpty([]); } /** * Add routes from CoreModule * * @param {CoreRoute[]} module * @returns Observable */ registerHandler(routes = []) { return (server, options, next) => { routes .forEach(_ => { const _server = !!_.labels ? server.select(_.labels) : server; _server.route({ method: _.method, path: _.path, config: Object.assign({ handler: (request, reply) => this.httpHandler(request, reply, _) }, _.config) }); }); next(); }; } /** * Build CoreRoute based on a module * * @param {CoreModule} module * @returns Observable */ buildRoutes(module) { return rxjs_1.Observable .from(route_1.RouteBuilder.buildRoutes(module)) .toArray(); } /** * Trigger the http handler hook * Reply automatically * * @param {Request} request * @param {ReplyNoContinue} reply * @param {CoreRoute} route * @returns void */ httpHandler(request, reply, route) { hook_1.HookManager .triggerHook(enums_1.enumByMethod(request.method).toString(), route.token, request['_hapinessRoute'], [request, reply]) .map(_ => this.formatResponse(_)) .subscribe(_ => { const repl = reply(_.response) .code(this.isValid(_.response) ? _.statusCode : 204); repl.headers = Object.assign(_.headers, repl.headers); }, _ => { hapiness_1.errorHandler(_, request); reply(_); }); } /** * Format response to HTTPHandlerResponse object * * @param {any} data * @returns HTTPHandlerResponse */ formatResponse(data) { return { statusCode: !!data ? data.statusCode || 200 : 200, headers: !!data ? data.headers || {} : {}, response: !!data ? data.response || data : data }; } /** * Check of response is not empty * * @param {any} response * @returns boolean */ isValid(response) { return typeof (response) !== 'undefined' && response !== null; } /** * Initialize and instantiate lifecycle components * * @param {CoreModule} module * @param {Server} server */ instantiateLifecycle(module, server) { return rxjs_1.Observable .from([].concat(module.declarations)) .filter(_ => !!_ && !!metadata_1.extractMetadataByDecorator(_, 'Lifecycle')) .map(_ => ({ metadata: metadata_1.extractMetadataByDecorator(_, 'Lifecycle'), token: _ })) .do(_ => server.ext(_.metadata.event, (request, reply) => { this .eventHandler(_.token, module, request, reply) .subscribe(() => { }, err => hapiness_1.errorHandler(err)); })) .toArray() .map(_ => module); } /** * Lifecycle Event Handler * Instantiate the Lifecycle component * And trigger the hook * * @param {Type<any>} lifecycle * @param {CoreModule} module * @param {Request} request * @param {ReplyWithContinue} reply * @returns Observable */ eventHandler(lifecycle, module, request, reply) { return rxjs_1.Observable .of(lifecycle) .flatMap(lc => di_1.DependencyInjection .instantiateComponent(lc, module.di) .flatMap(_ => hook_1.HookManager .triggerHook(enums_1.LifecycleComponentEnum.OnEvent.toString(), lc, _, [request, reply]))); } } exports.HttpServerExt = HttpServerExt; //# sourceMappingURL=extension.js.map