UNPKG

vulcain-corejs

Version:
264 lines (262 loc) 10.5 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments)).next()); }); }; const apiKeyService_1 = require("./defaults/services/apiKeyService"); const preloader_1 = require("./preloader"); const hystrixSSEStream_1 = require("./commands/http/hystrixSSEStream"); const localAdapter_1 = require("./bus/localAdapter"); const Path = require("path"); const schema_1 = require("./schemas/schema"); const containers_1 = require("./di/containers"); const files_1 = require("./utils/files"); const expressAdapter_1 = require("./servers/express/expressAdapter"); require("reflect-metadata"); const annotations_1 = require("./di/annotations"); const conventions_1 = require("./utils/conventions"); const provider_1 = require("./providers/memory/provider"); const requestContext_1 = require("./servers/requestContext"); require("./defaults/serviceExplorer"); // Don't remove (auto register) require("./defaults/dependencyExplorer"); // Don't remove (auto register) require("./pipeline/scopeDescriptors"); // Don't remove (auto register) const system_1 = require("./configurations/globals/system"); const expressAuthentication_1 = require("./servers/express/expressAuthentication"); /** * Application base class * * @export * @abstract * @class Application */ class Application { /** * Create new application * @param path Files base path for components discovery * @param container Global component container * @param app (optional)Server adapter */ constructor(domainName, container) { /** * Ignore invalid bearer token * * @type {boolean} * @memberOf Application */ this.ignoreInvalidBearerToken = false; domainName = domainName; if (!domainName) { throw new Error("Domain name is required."); } system_1.System.defaultDomainName = domainName; system_1.System.log.info(null, "Starting application"); this._executablePath = Path.dirname(module.filename); this._basePath = this.findBasePath(); // Ensure initializing this first const test = system_1.System.isDevelopment; this._container = container || new containers_1.Container(); this._container.injectTransient(provider_1.MemoryProvider, annotations_1.DefaultServiceNames.Provider); this._container.injectInstance(this, annotations_1.DefaultServiceNames.Application); this._container.injectSingleton(expressAuthentication_1.ExpressAuthentication, annotations_1.DefaultServiceNames.Authentication); this._domain = new schema_1.Domain(domainName, this._container); this._container.injectInstance(this.domain, annotations_1.DefaultServiceNames.Domain); } /** * Enable api key authentication * * @param {string} apiKeyServiceName Vulcain service name * @param {string} [version="1.0"] Service version * * @memberOf Application */ enableApiKeyAuthentication(apiKeyServiceName, version = "1.0") { this.container.injectScoped(apiKeyService_1.ApiKeyService, annotations_1.DefaultServiceNames.ApiKeyService, apiKeyServiceName, version); } /** * Set the user to use in local development * * @param {UserContext} user * @returns */ setTestUser(user) { user = user || requestContext_1.RequestContext.TestUser; if (!user.id || !user.name || !user.scopes) { throw new Error("Invalid test user - Properties must be set."); } if (!system_1.System.isTestEnvironnment) { system_1.System.log.info(null, "Warning : TestUser ignored"); return; } this._container.injectInstance(user, annotations_1.DefaultServiceNames.TestUser); } /** * Called when the server adapter is started * * @param {*} server * @param {*} adapter * * @memberOf Application */ onServerStarted(server, adapter) { } /** * Current component container * @returns {Container} */ get container() { return this._container; } /** * Get the current domain model * @returns {Domain} */ get domain() { return this._domain; } findBasePath() { let parent = module.parent; while (parent.parent) { parent = parent.parent; } return Path.dirname(parent.filename); } startHystrixStream() { if (!this.enableHystrixStream) { return; } this.adapter.useMiddleware("get", conventions_1.Conventions.instance.defaultHystrixPath, (request, response) => { response.append('Content-Type', 'text/event-stream;charset=UTF-8'); response.append('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate'); response.append('Pragma', 'no-cache'); system_1.System.log.info(null, "get hystrix.stream"); let subscription = hystrixSSEStream_1.HystrixSSEStream.toObservable().subscribe(function onNext(sseData) { response.write('data: ' + sseData + '\n\n'); }, function onError(error) { system_1.System.log.info(null, "hystrixstream: error"); }, function onComplete() { system_1.System.log.info(null, "end hystrix.stream"); return response.end(); }); request.on("close", () => { system_1.System.log.info(null, "close hystrix.stream"); subscription.dispose(); }); return subscription; }); } /** * Define all scopes used in this service * * @protected * @param {ScopesDescriptor} scopes Scope definitions manager - Use scopes.defineScope for each scope * * @memberOf Application */ defineScopes(scopes) { } /** * Override this method to initialize default containers * * @protected * @param {IContainer} container */ initializeDefaultServices(container) { } /** * Override this method to add your custom services * * @protected * @param {IContainer} container */ initializeServices(container) { } /** * Called before the server adapter is started * * @protected * @param {AbstractAdapter} abstractAdapter */ initializeServerAdapter(abstractAdapter) { } /** * Initialize and start application * * @param {number} port */ start(port) { return __awaiter(this, void 0, void 0, function* () { try { this.initializeDefaultServices(this.container); let local = new localAdapter_1.LocalAdapter(); let eventBus = this.container.get(annotations_1.DefaultServiceNames.EventBusAdapter, true); if (!eventBus) { this.container.injectInstance(local, annotations_1.DefaultServiceNames.EventBusAdapter); eventBus = local; } let commandBus = this.container.get(annotations_1.DefaultServiceNames.ActionBusAdapter, true); if (!commandBus) { this.container.injectInstance(local, annotations_1.DefaultServiceNames.ActionBusAdapter); commandBus = local; } yield eventBus.startAsync(); yield commandBus.startAsync(); this.registerComponents(); this.initializeServices(this.container); preloader_1.Preloader.instance.runPreloads(this.container, this._domain); let scopes = this.container.get(annotations_1.DefaultServiceNames.ScopesDescriptor); this.defineScopes(scopes); let descriptors = this.container.get(annotations_1.DefaultServiceNames.ServiceDescriptors); descriptors.createHandlersTable(); this.adapter = this.container.get(annotations_1.DefaultServiceNames.ServerAdapter, true); if (!this.adapter) { this.adapter = new expressAdapter_1.ExpressAdapter(this.domain.name, this._container, this); this.container.injectInstance(this.adapter, annotations_1.DefaultServiceNames.ServerAdapter); this.initializeServerAdapter(this.adapter); this.adapter.initialize(); } this.startHystrixStream(); this.adapter.start(port); } catch (err) { system_1.System.log.error(null, err, "ERROR when starting application"); process.exit(2); } }); } registerComponents() { this.registerRecursive(Path.join(this._executablePath, "defaults/models")); this.registerRecursive(Path.join(this._executablePath, "defaults/handlers")); this.registerRecursive(Path.join(this._executablePath, "defaults/services")); let path = conventions_1.Conventions.instance.defaultApplicationFolder; this.registerRecursive(Path.join(this._basePath, path)); } /** * Discover models components * @param path Where to find models component relative to base path (default=/api/models) * @returns {Container} */ registerRecursive(path) { if (!Path.isAbsolute(path)) { path = Path.join(this._basePath, path); } files_1.Files.traverse(path); return this._container; } /** * Inject all components from a specific folder (relative to the current folder) * * @protected * @param {string} path Folder path * @returns The current container */ injectFrom(path) { if (!Path.isAbsolute(path)) { path = Path.join(this._basePath, path); } this._container.injectFrom(path); return this._container; } } exports.Application = Application; //# sourceMappingURL=application.js.map