UNPKG

7.75 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.ListenersController = void 0;
4const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
5const context_id_factory_1 = require("@nestjs/core/helpers/context-id-factory");
6const execution_context_host_1 = require("@nestjs/core/helpers/execution-context-host");
7const constants_1 = require("@nestjs/core/injector/constants");
8const metadata_scanner_1 = require("@nestjs/core/metadata-scanner");
9const request_constants_1 = require("@nestjs/core/router/request/request-constants");
10const rxjs_1 = require("rxjs");
11const request_context_host_1 = require("./context/request-context-host");
12const rpc_metadata_constants_1 = require("./context/rpc-metadata-constants");
13const listener_metadata_explorer_1 = require("./listener-metadata-explorer");
14const server_1 = require("./server");
15class ListenersController {
16 constructor(clientsContainer, contextCreator, container, injector, clientFactory, exceptionFiltersContext) {
17 this.clientsContainer = clientsContainer;
18 this.contextCreator = contextCreator;
19 this.container = container;
20 this.injector = injector;
21 this.clientFactory = clientFactory;
22 this.exceptionFiltersContext = exceptionFiltersContext;
23 this.metadataExplorer = new listener_metadata_explorer_1.ListenerMetadataExplorer(new metadata_scanner_1.MetadataScanner());
24 this.exceptionFiltersCache = new WeakMap();
25 }
26 registerPatternHandlers(instanceWrapper, server, moduleKey) {
27 const { instance } = instanceWrapper;
28 const isStatic = instanceWrapper.isDependencyTreeStatic();
29 const patternHandlers = this.metadataExplorer.explore(instance);
30 const moduleRef = this.container.getModuleByKey(moduleKey);
31 const defaultCallMetadata = server instanceof server_1.ServerGrpc
32 ? rpc_metadata_constants_1.DEFAULT_GRPC_CALLBACK_METADATA
33 : rpc_metadata_constants_1.DEFAULT_CALLBACK_METADATA;
34 patternHandlers
35 .filter(({ transport }) => (0, shared_utils_1.isUndefined)(transport) ||
36 (0, shared_utils_1.isUndefined)(server.transportId) ||
37 transport === server.transportId)
38 .reduce((acc, handler) => {
39 var _a;
40 // Optional chaining for backward-compatibility
41 (_a = handler.patterns) === null || _a === void 0 ? void 0 : _a.forEach(pattern => acc.push(Object.assign(Object.assign({}, handler), { patterns: [pattern] })));
42 return acc;
43 }, [])
44 .forEach(({ patterns: [pattern], targetCallback, methodKey, extras, isEventHandler, }) => {
45 if (isStatic) {
46 const proxy = this.contextCreator.create(instance, targetCallback, moduleKey, methodKey, constants_1.STATIC_CONTEXT, undefined, defaultCallMetadata);
47 if (isEventHandler) {
48 const eventHandler = (...args) => {
49 var _a;
50 const originalArgs = args;
51 const [dataOrContextHost] = originalArgs;
52 if (dataOrContextHost instanceof request_context_host_1.RequestContextHost) {
53 args = args.slice(1, args.length);
54 }
55 const originalReturnValue = proxy(...args);
56 const returnedValueWrapper = (_a = eventHandler.next) === null || _a === void 0 ? void 0 : _a.call(eventHandler, ...originalArgs);
57 returnedValueWrapper === null || returnedValueWrapper === void 0 ? void 0 : returnedValueWrapper.then(returnedValue => this.connectIfStream(returnedValue));
58 return originalReturnValue;
59 };
60 return server.addHandler(pattern, eventHandler, isEventHandler, extras);
61 }
62 else {
63 return server.addHandler(pattern, proxy, isEventHandler, extras);
64 }
65 }
66 const asyncHandler = this.createRequestScopedHandler(instanceWrapper, pattern, moduleRef, moduleKey, methodKey, defaultCallMetadata);
67 server.addHandler(pattern, asyncHandler, isEventHandler, extras);
68 });
69 }
70 assignClientsToProperties(instance) {
71 for (const { property, metadata, } of this.metadataExplorer.scanForClientHooks(instance)) {
72 const client = this.clientFactory.create(metadata);
73 this.clientsContainer.addClient(client);
74 this.assignClientToInstance(instance, property, client);
75 }
76 }
77 assignClientToInstance(instance, property, client) {
78 Reflect.set(instance, property, client);
79 }
80 createRequestScopedHandler(wrapper, pattern, moduleRef, moduleKey, methodKey, defaultCallMetadata = rpc_metadata_constants_1.DEFAULT_CALLBACK_METADATA) {
81 const collection = moduleRef.controllers;
82 const { instance } = wrapper;
83 const requestScopedHandler = async (...args) => {
84 var _a;
85 try {
86 let contextId;
87 let [dataOrContextHost] = args;
88 if (dataOrContextHost instanceof request_context_host_1.RequestContextHost) {
89 contextId = this.getContextId(dataOrContextHost);
90 args.shift();
91 }
92 else {
93 const [data, reqCtx] = args;
94 const request = request_context_host_1.RequestContextHost.create(pattern, data, reqCtx);
95 contextId = this.getContextId(request);
96 this.container.registerRequestProvider(request, contextId);
97 dataOrContextHost = request;
98 }
99 const contextInstance = await this.injector.loadPerContext(instance, moduleRef, collection, contextId);
100 const proxy = this.contextCreator.create(contextInstance, contextInstance[methodKey], moduleKey, methodKey, contextId, wrapper.id, defaultCallMetadata);
101 (_a = requestScopedHandler.next) === null || _a === void 0 ? void 0 : _a.call(requestScopedHandler, dataOrContextHost, ...args);
102 return proxy(...args);
103 }
104 catch (err) {
105 let exceptionFilter = this.exceptionFiltersCache.get(instance[methodKey]);
106 if (!exceptionFilter) {
107 exceptionFilter = this.exceptionFiltersContext.create(instance, instance[methodKey], moduleKey);
108 this.exceptionFiltersCache.set(instance[methodKey], exceptionFilter);
109 }
110 const host = new execution_context_host_1.ExecutionContextHost(args);
111 host.setType('rpc');
112 return exceptionFilter.handle(err, host);
113 }
114 };
115 return requestScopedHandler;
116 }
117 getContextId(request) {
118 const contextId = context_id_factory_1.ContextIdFactory.getByRequest(request);
119 if (!request[request_constants_1.REQUEST_CONTEXT_ID]) {
120 Object.defineProperty(request, request_constants_1.REQUEST_CONTEXT_ID, {
121 value: contextId,
122 enumerable: false,
123 writable: false,
124 configurable: false,
125 });
126 this.container.registerRequestProvider(request, contextId);
127 }
128 return contextId;
129 }
130 connectIfStream(source) {
131 if (!source) {
132 return;
133 }
134 const connectableSource = (0, rxjs_1.connectable)(source, {
135 connector: () => new rxjs_1.Subject(),
136 resetOnDisconnect: false,
137 });
138 connectableSource.connect();
139 }
140}
141exports.ListenersController = ListenersController;