UNPKG

@team-supercharge/nest-amqp

Version:
227 lines (226 loc) 10.8 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 QueueModule_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueueModule = void 0; const common_1 = require("@nestjs/common"); const core_1 = require("@nestjs/core"); const unknown_element_exception_1 = require("@nestjs/core/errors/exceptions/unknown-element.exception"); const class_validator_1 = require("class-validator"); const service_1 = require("./service"); const explorer_1 = require("./explorer"); const constant_1 = require("./constant"); const util_1 = require("./util"); const toString = Object.prototype.toString; let QueueModule = QueueModule_1 = class QueueModule { constructor(moduleOptions, queueService, listenerExplorer, moduleRef) { this.moduleOptions = moduleOptions; this.queueService = queueService; this.listenerExplorer = listenerExplorer; this.moduleRef = moduleRef; } static forRoot(connectionUri, options = {}) { const queueModuleOptionsProviders = []; const connectionProviders = []; const connectionOptionsProviders = []; if (toString.call(connectionUri) === '[object Array]') { queueModuleOptionsProviders.push(QueueModule_1.getQueueModuleOptionsProvider(options)); for (const connectionOptions of connectionUri) { connectionOptionsProviders.push(QueueModule_1.getAMQPConnectionOptionsProvider(connectionOptions, connectionOptions.name)); connectionProviders.push(QueueModule_1.getConnectionProvider(connectionOptions.name)); } } else { const moduleOptions = typeof connectionUri === 'string' ? Object.assign(Object.assign({}, options), { connectionUri }) : connectionUri; queueModuleOptionsProviders.push(QueueModule_1.getQueueModuleOptionsProvider(moduleOptions)); connectionOptionsProviders.push(QueueModule_1.getAMQPConnectionOptionsProvider(moduleOptions)); connectionProviders.push(QueueModule_1.getConnectionProvider(constant_1.AMQP_DEFAULT_CONNECTION_TOKEN)); } Object.assign(QueueModule_1.moduleDefinition, { global: !!options.isGlobal, providers: [ ...queueModuleOptionsProviders, ...QueueModule_1.moduleDefinition.providers, ...connectionOptionsProviders, ...connectionProviders, ], }); return QueueModule_1.moduleDefinition; } static forRootAsync(options) { // TODO - allow for multiple connections const connectionProviders = [QueueModule_1.getConnectionProvider(constant_1.AMQP_DEFAULT_CONNECTION_TOKEN)]; const asyncProviders = this.createAsyncProviders(options); Object.assign(QueueModule_1.moduleDefinition, { global: !!options.isGlobal, imports: options.imports, providers: [...asyncProviders, ...QueueModule_1.moduleDefinition.providers, ...connectionProviders], }); return QueueModule_1.moduleDefinition; } static forFeature() { return QueueModule_1.moduleDefinition; } static createAsyncProviders(options) { if (!options.useClass && !options.useExisting && !options.useFactory) { throw new Error('Must provide factory, class or existing provider'); } if (options.useExisting || options.useFactory) { return [this.createAsyncQueueModuleOptionsProvider(options), this.createAsyncAMQConnectionsOptionsProvider(options)]; } const useClass = options.useClass; return [ this.createAsyncQueueModuleOptionsProvider(options), this.createAsyncAMQConnectionsOptionsProvider(options), { provide: useClass, useClass, }, ]; } static createAsyncQueueModuleOptionsProvider(options) { var _a; if (options.useFactory) { return { provide: constant_1.QUEUE_MODULE_OPTIONS, useFactory: options.useFactory, inject: options.inject || [], }; } const inject = [(_a = options.useClass) !== null && _a !== void 0 ? _a : options.useExisting]; return { provide: constant_1.QUEUE_MODULE_OPTIONS, useFactory: async (factory) => factory.createQueueModuleOptions(), inject, }; } static createAsyncAMQConnectionsOptionsProvider(options) { var _a; if (options.useFactory) { return { provide: util_1.getAMQConnectionOptionsToken(constant_1.AMQP_DEFAULT_CONNECTION_TOKEN), inject: options.inject || [], useFactory: async (...args) => { const moduleOptions = await options.useFactory(...args); const useValue = QueueModule_1.getConnectionOptions(moduleOptions); util_1.AMQConnectionOptionsStorage.add(constant_1.AMQP_DEFAULT_CONNECTION_TOKEN, useValue); return moduleOptions; }, }; } const inject = [(_a = options.useClass) !== null && _a !== void 0 ? _a : options.useExisting]; return { provide: util_1.getAMQConnectionOptionsToken(constant_1.AMQP_DEFAULT_CONNECTION_TOKEN), useFactory: async (optionsFactory) => { const moduleOptions = await optionsFactory.createQueueModuleOptions(); const useValue = QueueModule_1.getConnectionOptions(moduleOptions); util_1.AMQConnectionOptionsStorage.add(constant_1.AMQP_DEFAULT_CONNECTION_TOKEN, useValue); return moduleOptions; }, inject, }; } /** * Creates a connection provider with the given name * * @param {string} connection Name of the connection * * @returns {Provider} Named Connection provider * * @private * @static */ static getConnectionProvider(connection = constant_1.AMQP_DEFAULT_CONNECTION_TOKEN) { return { provide: util_1.getAMQConnectionToken(connection), useFactory: async (options) => service_1.AMQPService.createConnection(options, connection), inject: [util_1.getAMQConnectionOptionsToken(connection)], }; } static getQueueModuleOptionsProvider(options) { return { provide: constant_1.QUEUE_MODULE_OPTIONS, useValue: options, }; } static getAMQPConnectionOptionsProvider(options, connection = constant_1.AMQP_DEFAULT_CONNECTION_TOKEN) { const provide = util_1.getAMQConnectionOptionsToken(connection); const useValue = QueueModule_1.getConnectionOptions(options); util_1.AMQConnectionOptionsStorage.add(connection, useValue); return { provide, useValue }; } static getConnectionOptions(options) { const { connectionOptions, connectionUri, throwExceptionOnConnectionError } = options; return Object.assign(Object.assign({ connectionUri }, (class_validator_1.isDefined(connectionOptions) ? { connectionOptions } : {})), (class_validator_1.isDefined(throwExceptionOnConnectionError) ? { throwExceptionOnConnectionError } : {})); } // istanbul ignore next async onModuleInit() { logger.log('initializing queue module'); if (this.moduleOptions.logger) { util_1.Logger.overrideLogger(this.moduleOptions.logger); } // find everything marked with @Listen const listeners = this.listenerExplorer.explore(); await this.attachListeners(listeners); service_1.AMQPService.eventEmitter.on(constant_1.AMQP_CONNECTION_RECONNECT, () => { logger.log('reattaching receivers to connection'); this.queueService.clearSenderAndReceiverLinks(); this.attachListeners(listeners) .then(() => logger.log('receivers reattached')) .catch(error => logger.error('error while reattaching listeners', error)); }); logger.log('queue module initialized'); } async onModuleDestroy() { logger.log('destroying queue module'); await this.queueService.shutdown(); logger.log('queue module destroyed'); } // istanbul ignore next async attachListeners(listeners) { // set up listeners for (const listener of listeners) { logger.debug(`attaching listener for @Listen: ${JSON.stringify(listener)}`); // fetch instance from DI framework let target; try { target = this.moduleRef.get(listener.target, { strict: false }); } catch (err) { if (err instanceof unknown_element_exception_1.UnknownElementException) { target = this.moduleRef.get(listener.targetName, { strict: false }); } else { throw err; } } await this.queueService.listen(listener.source, listener.callback.bind(target), listener.options, listener.connection); } } }; QueueModule.moduleDefinition = { global: false, module: QueueModule_1, providers: [service_1.AMQPService, service_1.QueueService, core_1.MetadataScanner, explorer_1.ListenerExplorer, service_1.ObjectValidatorService], exports: [service_1.QueueService], }; QueueModule = QueueModule_1 = __decorate([ common_1.Module({}), __param(0, common_1.Inject(constant_1.QUEUE_MODULE_OPTIONS)), __metadata("design:paramtypes", [Object, service_1.QueueService, explorer_1.ListenerExplorer, core_1.ModuleRef]) ], QueueModule); exports.QueueModule = QueueModule; const logger = new util_1.Logger(util_1.getLoggerContext(QueueModule.name));