UNPKG

vulcain-corejs

Version:
196 lines 8.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Path = require("path"); require("reflect-metadata"); const _1 = require("."); const localAdapter_1 = require("./bus/localAdapter"); const dynamicConfiguration_1 = require("./configurations/dynamicConfiguration"); require("./defaults/dependencyExplorer"); // Don't remove (auto register) require("./defaults/serviceExplorer"); // Don't remove (auto register) const annotations_1 = require("./di/annotations"); const containers_1 = require("./di/containers"); const system_1 = require("./globals/system"); require("./graphql/graphQLHandler"); const graphQLHandler_1 = require("./graphql/graphQLHandler"); const annotations_2 = require("./pipeline/handlers/action/annotations"); const vulcainServer_1 = require("./pipeline/vulcainServer"); const preloader_1 = require("./preloader"); // always on first line const domain_1 = require("./schemas/domain"); const conventions_1 = require("./utils/conventions"); const files_1 = require("./utils/files"); const hystrixSSEStream_1 = require("./commands/http/hystrixSSEStream"); const vulcainExecutablePath = __dirname; const applicationPath = Path.dirname(module.parent.parent.filename); /** * 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) { this.domainName = domainName; this._container = _container; this._initialized = false; if (!this.domainName) { throw new Error("Domain name is required."); } system_1.Service.setDomainName(this.domainName); this._container = this._container || new containers_1.Container(); } useMongoProvider(address) { this.container.useMongoProvider(address); return this; } useMemoryProvider(folder) { this.container.useMemoryProvider(folder); return this; } useRabbitmqBus(address) { this.container.useRabbitBusAdapter(address); return this; } useService(name, service, lifeTime) { this.container.inject(name, service, lifeTime); return this; } enableGraphQL(responseType = "graphql") { annotations_2.ActionHandler({ async: false, scope: "?", description: "GraphQL action handler" }, { responseType, system: true })(graphQLHandler_1.GraphQLActionHandler); preloader_1.Preloader.instance.registerHandler((container, domain) => { let graphQLAdapter = container.get(annotations_1.DefaultServiceNames.GraphQLAdapter); container.registerSSEEndpoint(conventions_1.Conventions.instance.defaultGraphQLSubscriptionPath, graphQLAdapter.getSubscriptionHandler()); }); return this; } /** * Current component container * @returns {Container} */ get container() { return this._container; } /** * Get the current domain model * @returns {Domain} */ get domain() { return this._domain; } /** * Only use it for testing. Used start instead */ async init() { if (this._initialized) return; this._initialized = true; await dynamicConfiguration_1.DynamicConfiguration.init().startPolling(); system_1.Service.log.info(null, () => "Starting application"); this._container.injectInstance(this, annotations_1.DefaultServiceNames.Application); this._domain = new domain_1.Domain(this.domainName, this._container); this._container.injectInstance(this._domain, annotations_1.DefaultServiceNames.Domain); this.container.registerHTTPEndpoint("GET", conventions_1.Conventions.instance.defaultHystrixPath, hystrixSSEStream_1.HystrixSSEStream.getHandler()); process.on('unhandledRejection', (reason, p) => { system_1.Service.log.info(null, () => `Unhandled Rejection at ${p} reason ${reason}")`); }); // Stop to receive inputs process.once('SIGTERM', () => { let eventBus = this.container.get(annotations_1.DefaultServiceNames.EventBusAdapter, true); if (eventBus) { eventBus.stopReception(); } let commandBus = this.container.get(annotations_1.DefaultServiceNames.ActionBusAdapter, true); if (commandBus) { commandBus.stopReception(); } this.container.dispose(); }); 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; } this.registerComponents(); preloader_1.Preloader.instance.runPreloads(this.container, this._domain); await eventBus.open(); await commandBus.open(); let scopes = this.container.get(annotations_1.DefaultServiceNames.ScopesDescriptor); this.defineScopeDescriptions(scopes); let descriptors = this.container.get(annotations_1.DefaultServiceNames.ServiceDescriptors); descriptors.getDescriptions(); // ensures handlers table is created this.container.injectSingleton(_1.HandlerProcessor, annotations_1.DefaultServiceNames.HandlerProcessor); } /** * Define all scopes used in this service * * @protected * @param {ScopesDescriptor} scopes Scope definitions manager - Use scopes.defineScope for each scope * * @memberOf Application */ defineScopeDescriptions(scopes) { return this; } /** * Initialize and start application * * @param {number} port */ async start(port) { if (!port) throw new Error("You must provide a port number"); try { await this.init(); let server = new vulcainServer_1.VulcainServer(this.domain.name, this._container); server.start(port); } catch (err) { system_1.Service.log.error(null, err, () => "ERROR when starting application"); process.exit(2); } } registerComponents() { this.registerRecursive(Path.join(vulcainExecutablePath, "defaults")); //let path = Conventions.instance.defaultApplicationFolder; //this.registerRecursive(Path.join(applicationPath, path)); this.registerRecursive(applicationPath); } /** * 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(applicationPath, 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 application */ injectFrom(path) { if (!Path.isAbsolute(path)) { path = Path.join(applicationPath, path); } this._container.injectFrom(path); return this; } } exports.Application = Application; //# sourceMappingURL=application.js.map