UNPKG

@golevelup/nestjs-rabbitmq

Version:
167 lines 9.65 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var RabbitMQModule_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.RabbitMQModule = void 0; const nestjs_discovery_1 = require("@golevelup/nestjs-discovery"); const common_1 = require("@nestjs/common"); const constants_1 = require("@nestjs/common/constants"); const external_context_creator_1 = require("@nestjs/core/helpers/external-context-creator"); const lodash_1 = require("lodash"); const connection_1 = require("./amqp/connection"); const connectionManager_1 = require("./amqp/connectionManager"); const utils_1 = require("./amqp/utils"); const rabbitmq_module_definition_1 = require("./rabbitmq-module-definition"); const rabbitmq_constants_1 = require("./rabbitmq.constants"); const rabbitmq_decorators_1 = require("./rabbitmq.decorators"); const rabbitmq_factory_1 = require("./rabbitmq.factory"); let RabbitMQModule = RabbitMQModule_1 = class RabbitMQModule extends rabbitmq_module_definition_1.ConfigurableModuleClass { constructor(discover, externalContextCreator, rpcParamsFactory, connectionManager, config) { super(); this.discover = discover; this.externalContextCreator = externalContextCreator; this.rpcParamsFactory = rpcParamsFactory; this.connectionManager = connectionManager; this.logger = (config === null || config === void 0 ? void 0 : config.logger) || new common_1.Logger(RabbitMQModule_1.name); } static async AmqpConnectionFactory(config) { const logger = (config === null || config === void 0 ? void 0 : config.logger) || new common_1.Logger(RabbitMQModule_1.name); if (config == undefined) { logger.log('RabbitMQ config not provided, skipping connection initialization.'); return undefined; } config.uri = (0, utils_1.converUriConfigObjectsToUris)(config.uri); (0, utils_1.validateRabbitMqUris)(config.uri); const connection = new connection_1.AmqpConnection(config); this.connectionManager.addConnection(connection); await connection.init(); logger.log('Successfully connected to RabbitMQ'); return connection; } static attach(connection) { return { module: RabbitMQModule_1, providers: [ { provide: connection_1.AmqpConnection, useValue: connection, }, rabbitmq_factory_1.RabbitRpcParamsFactory, ], exports: [connection_1.AmqpConnection], }; } async onApplicationShutdown() { var _a, _b; (_b = (_a = this.logger).verbose) === null || _b === void 0 ? void 0 : _b.call(_a, 'Closing AMQP Connections'); await this.connectionManager.close(); this.connectionManager.clearConnections(); RabbitMQModule_1.bootstrapped = false; } async setupHandler(connection, discoveredMethod, config, handler) { var _a, _b, _c; const handlerDisplayName = `${discoveredMethod.parentClass.name}.${discoveredMethod.methodName} {${config.type}} -> ${((_a = config.queueOptions) === null || _a === void 0 ? void 0 : _a.channel) ? `${config.queueOptions.channel}::` : ''}${config.exchange}::${config.routingKey}::${config.queue || 'amqpgen'}`; if (config.type === 'rpc' && !connection.configuration.enableDirectReplyTo) { this.logger.warn(`Direct Reply-To Functionality is disabled. RPC handler ${handlerDisplayName} will not be registered`); return; } this.logger.log(handlerDisplayName); switch (config.type) { case 'rpc': return connection.createRpc(handler, config); case 'subscribe': if (config.batchOptions) { return connection.createBatchSubscriber(handler, config, (_b = config === null || config === void 0 ? void 0 : config.queueOptions) === null || _b === void 0 ? void 0 : _b.consumerOptions); } return connection.createSubscriber(handler, config, discoveredMethod.methodName, (_c = config === null || config === void 0 ? void 0 : config.queueOptions) === null || _c === void 0 ? void 0 : _c.consumerOptions); default: throw new Error(`Unable to set up handler ${handlerDisplayName}. Unexpected handler type ${config.type}.`); } } async onApplicationBootstrap() { if (RabbitMQModule_1.bootstrapped) { return; } RabbitMQModule_1.bootstrapped = true; for (const connection of this.connectionManager.getConnections()) { if (!connection.configuration.registerHandlers) { this.logger.log('Skipping RabbitMQ Handlers due to configuration. This application instance will not receive messages over RabbitMQ'); continue; } this.logger.log('Initializing RabbitMQ Handlers'); let rabbitMeta = await this.discover.providerMethodsWithMetaAtKey(rabbitmq_constants_1.RABBIT_HANDLER); if (connection.configuration.enableControllerDiscovery) { this.logger.log('Searching for RabbitMQ Handlers in Controllers. You can not use NestJS HTTP-Requests in these controllers!'); rabbitMeta = rabbitMeta.concat(await this.discover.controllerMethodsWithMetaAtKey(rabbitmq_constants_1.RABBIT_HANDLER)); } const grouped = (0, lodash_1.groupBy)(rabbitMeta, (x) => x.discoveredMethod.parentClass.name); const providerKeys = Object.keys(grouped); for (const key of providerKeys) { this.logger.log(`Registering rabbitmq handlers from ${key}`); await Promise.all(grouped[key].map(async ({ discoveredMethod, meta: config }) => { if (config.connection && config.connection !== connection.configuration.name) { return; } const handler = this.externalContextCreator.create(discoveredMethod.parentClass.instance, discoveredMethod.handler, discoveredMethod.methodName, constants_1.ROUTE_ARGS_METADATA, this.rpcParamsFactory, undefined, // contextId undefined, // inquirerId undefined, // options rabbitmq_constants_1.RABBIT_CONTEXT_TYPE_KEY); const moduleHandlerConfigRaw = connection.configuration.handlers[config.name || connection.configuration.defaultHandler || '']; const moduleHandlerConfigs = Array.isArray(moduleHandlerConfigRaw) ? moduleHandlerConfigRaw : [moduleHandlerConfigRaw]; await Promise.all(moduleHandlerConfigs.map((moduleHandlerConfig) => { const mergedConfig = Object.assign(Object.assign({}, config), moduleHandlerConfig); return this.setupHandler(connection, discoveredMethod, mergedConfig, handler); })); })); } } } }; RabbitMQModule.connectionManager = new connectionManager_1.AmqpConnectionManager(); RabbitMQModule.bootstrapped = false; RabbitMQModule = RabbitMQModule_1 = __decorate([ (0, common_1.Module)({ imports: [nestjs_discovery_1.DiscoveryModule], providers: [ { provide: connectionManager_1.AmqpConnectionManager, useFactory: async (config) => { await RabbitMQModule_1.AmqpConnectionFactory(config); return RabbitMQModule_1.connectionManager; }, inject: [rabbitmq_constants_1.RABBIT_CONFIG_TOKEN], }, { provide: connection_1.AmqpConnection, useFactory: async (config, connectionManager) => { return connectionManager.getConnection((config === null || config === void 0 ? void 0 : config.name) || 'default'); }, inject: [rabbitmq_constants_1.RABBIT_CONFIG_TOKEN, connectionManager_1.AmqpConnectionManager], }, rabbitmq_factory_1.RabbitRpcParamsFactory, ], exports: [connectionManager_1.AmqpConnectionManager, connection_1.AmqpConnection], }), __param(4, (0, rabbitmq_decorators_1.InjectRabbitMQConfig)()), __metadata("design:paramtypes", [nestjs_discovery_1.DiscoveryService, external_context_creator_1.ExternalContextCreator, rabbitmq_factory_1.RabbitRpcParamsFactory, connectionManager_1.AmqpConnectionManager, Object]) ], RabbitMQModule); exports.RabbitMQModule = RabbitMQModule; //# sourceMappingURL=rabbitmq.module.js.map