UNPKG

@nestjs/microservices

Version:

Nest - modern, fast, powerful node.js web framework (@microservices)

136 lines (135 loc) 7.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ListenersController = void 0; const shared_utils_1 = require("@nestjs/common/utils/shared.utils"); const context_id_factory_1 = require("@nestjs/core/helpers/context-id-factory"); const execution_context_host_1 = require("@nestjs/core/helpers/execution-context-host"); const constants_1 = require("@nestjs/core/injector/constants"); const metadata_scanner_1 = require("@nestjs/core/metadata-scanner"); const request_constants_1 = require("@nestjs/core/router/request/request-constants"); const rxjs_1 = require("rxjs"); const request_context_host_1 = require("./context/request-context-host"); const rpc_metadata_constants_1 = require("./context/rpc-metadata-constants"); const listener_metadata_explorer_1 = require("./listener-metadata-explorer"); const server_1 = require("./server"); class ListenersController { constructor(clientsContainer, contextCreator, container, injector, clientFactory, exceptionFiltersContext) { this.clientsContainer = clientsContainer; this.contextCreator = contextCreator; this.container = container; this.injector = injector; this.clientFactory = clientFactory; this.exceptionFiltersContext = exceptionFiltersContext; this.metadataExplorer = new listener_metadata_explorer_1.ListenerMetadataExplorer(new metadata_scanner_1.MetadataScanner()); this.exceptionFiltersCache = new WeakMap(); } registerPatternHandlers(instanceWrapper, server, moduleKey) { const { instance } = instanceWrapper; const isStatic = instanceWrapper.isDependencyTreeStatic(); const patternHandlers = this.metadataExplorer.explore(instance); const moduleRef = this.container.getModuleByKey(moduleKey); const defaultCallMetadata = server instanceof server_1.ServerGrpc ? rpc_metadata_constants_1.DEFAULT_GRPC_CALLBACK_METADATA : rpc_metadata_constants_1.DEFAULT_CALLBACK_METADATA; patternHandlers .filter(({ transport }) => (0, shared_utils_1.isUndefined)(transport) || (0, shared_utils_1.isUndefined)(server.transportId) || transport === server.transportId) .forEach(({ pattern, targetCallback, methodKey, extras, isEventHandler }) => { if (isStatic) { const proxy = this.contextCreator.create(instance, targetCallback, moduleKey, methodKey, constants_1.STATIC_CONTEXT, undefined, defaultCallMetadata); if (isEventHandler) { const eventHandler = (...args) => { var _a; const originalArgs = args; const [dataOrContextHost] = originalArgs; if (dataOrContextHost instanceof request_context_host_1.RequestContextHost) { args = args.slice(1, args.length); } const originalReturnValue = proxy(...args); const returnedValueWrapper = (_a = eventHandler.next) === null || _a === void 0 ? void 0 : _a.call(eventHandler, ...originalArgs); returnedValueWrapper === null || returnedValueWrapper === void 0 ? void 0 : returnedValueWrapper.then(returnedValue => this.connectIfStream(returnedValue)); return originalReturnValue; }; return server.addHandler(pattern, eventHandler, isEventHandler, extras); } else { return server.addHandler(pattern, proxy, isEventHandler, extras); } } const asyncHandler = this.createRequestScopedHandler(instanceWrapper, pattern, moduleRef, moduleKey, methodKey, defaultCallMetadata); server.addHandler(pattern, asyncHandler, isEventHandler, extras); }); } assignClientsToProperties(instance) { for (const { property, metadata, } of this.metadataExplorer.scanForClientHooks(instance)) { const client = this.clientFactory.create(metadata); this.clientsContainer.addClient(client); this.assignClientToInstance(instance, property, client); } } assignClientToInstance(instance, property, client) { Reflect.set(instance, property, client); } createRequestScopedHandler(wrapper, pattern, moduleRef, moduleKey, methodKey, defaultCallMetadata = rpc_metadata_constants_1.DEFAULT_CALLBACK_METADATA) { const collection = moduleRef.controllers; const { instance } = wrapper; const requestScopedHandler = async (...args) => { var _a; try { let contextId; let [dataOrContextHost] = args; if (dataOrContextHost instanceof request_context_host_1.RequestContextHost) { contextId = this.getContextId(dataOrContextHost); args.shift(); } else { const [data, reqCtx] = args; const request = request_context_host_1.RequestContextHost.create(pattern, data, reqCtx); contextId = this.getContextId(request); this.container.registerRequestProvider(request, contextId); dataOrContextHost = request; } const contextInstance = await this.injector.loadPerContext(instance, moduleRef, collection, contextId); const proxy = this.contextCreator.create(contextInstance, contextInstance[methodKey], moduleKey, methodKey, contextId, wrapper.id, defaultCallMetadata); (_a = requestScopedHandler.next) === null || _a === void 0 ? void 0 : _a.call(requestScopedHandler, dataOrContextHost, ...args); return proxy(...args); } catch (err) { let exceptionFilter = this.exceptionFiltersCache.get(instance[methodKey]); if (!exceptionFilter) { exceptionFilter = this.exceptionFiltersContext.create(instance, instance[methodKey], moduleKey); this.exceptionFiltersCache.set(instance[methodKey], exceptionFilter); } const host = new execution_context_host_1.ExecutionContextHost(args); host.setType('rpc'); return exceptionFilter.handle(err, host); } }; return requestScopedHandler; } getContextId(request) { const contextId = context_id_factory_1.ContextIdFactory.getByRequest(request); if (!request[request_constants_1.REQUEST_CONTEXT_ID]) { Object.defineProperty(request, request_constants_1.REQUEST_CONTEXT_ID, { value: contextId, enumerable: false, writable: false, configurable: false, }); this.container.registerRequestProvider(request, contextId); } return contextId; } connectIfStream(source) { if (!source) { return; } const connectableSource = (0, rxjs_1.connectable)(source, { connector: () => new rxjs_1.Subject(), resetOnDisconnect: false, }); connectableSource.connect(); } } exports.ListenersController = ListenersController;