UNPKG

vulcain-corejs

Version:
271 lines (269 loc) 10.8 kB
"use strict"; const expressAuthentication_1 = require('./servers/expressAuthentication'); const apiKeyService_1 = require('./auth/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/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'); /** * 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) { 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.Authentication, 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.injectInstance(new apiKeyService_1.ApiKeyService(this.container, apiKeyServiceName, version), annotations_1.DefaultServiceNames.ApiKeyService); } /** * 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 */ 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; }); } 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) { 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; } eventBus.startAsync().then(() => { commandBus.startAsync().then(() => { try { this.registerModelsInternal(); this.registerServicesInternal(); this.registerHandlersInternal(); 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); } }); }); } registerModelsInternal() { this.registerModels(Path.join(this._executablePath, "defaults/models")); let path = conventions_1.Conventions.instance.defaultModelsFolderPattern.replace("${base}", conventions_1.Conventions.instance.defaultApplicationFolder); this.registerModels(Path.join(this._basePath, path)); } /** * 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; } /** * Discover models components * @param path Where to find models component relative to base path (default=/api/models) * @returns {Container} */ registerModels(path) { if (!Path.isAbsolute(path)) { path = Path.join(this._basePath, path); } files_1.Files.traverse(path); return this._container; } registerHandlersInternal() { this.registerHandlers(Path.join(this._executablePath, "defaults/handlers")); let path = conventions_1.Conventions.instance.defaultHandlersFolderPattern.replace("${base}", conventions_1.Conventions.instance.defaultApplicationFolder); this.registerHandlers(Path.join(this._basePath, path)); } /** * Discover models components * @param path Where to find models component relative to base path (default=/api/models) * @returns {Container} */ registerHandlers(path) { if (!Path.isAbsolute(path)) { path = Path.join(this._basePath, path); } files_1.Files.traverse(path); return this._container; } registerServicesInternal() { this.registerServices(Path.join(this._executablePath, "defaults/services")); let path = conventions_1.Conventions.instance.defaultServicesFolderPattern.replace("${base}", conventions_1.Conventions.instance.defaultApplicationFolder); this.registerServices(Path.join(this._basePath, path)); } /** * Discover service components * @param path Where to find services component relative to base path (default=/core/services) * @returns {Container} */ registerServices(path) { if (!Path.isAbsolute(path)) { path = Path.join(this._basePath, path); } files_1.Files.traverse(path); return this._container; } } exports.Application = Application; //# sourceMappingURL=application.js.map