UNPKG

7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.RpcContextCreator = void 0;
4const constants_1 = require("@nestjs/common/constants");
5const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
6const constants_2 = require("@nestjs/core/guards/constants");
7const context_utils_1 = require("@nestjs/core/helpers/context-utils");
8const handler_metadata_storage_1 = require("@nestjs/core/helpers/handler-metadata-storage");
9const constants_3 = require("@nestjs/core/injector/constants");
10const constants_4 = require("../constants");
11const exceptions_1 = require("../exceptions");
12const rpc_params_factory_1 = require("../factories/rpc-params-factory");
13const rpc_metadata_constants_1 = require("./rpc-metadata-constants");
14class RpcContextCreator {
15 constructor(rpcProxy, exceptionFiltersContext, pipesContextCreator, pipesConsumer, guardsContextCreator, guardsConsumer, interceptorsContextCreator, interceptorsConsumer) {
16 this.rpcProxy = rpcProxy;
17 this.exceptionFiltersContext = exceptionFiltersContext;
18 this.pipesContextCreator = pipesContextCreator;
19 this.pipesConsumer = pipesConsumer;
20 this.guardsContextCreator = guardsContextCreator;
21 this.guardsConsumer = guardsConsumer;
22 this.interceptorsContextCreator = interceptorsContextCreator;
23 this.interceptorsConsumer = interceptorsConsumer;
24 this.contextUtils = new context_utils_1.ContextUtils();
25 this.rpcParamsFactory = new rpc_params_factory_1.RpcParamsFactory();
26 this.handlerMetadataStorage = new handler_metadata_storage_1.HandlerMetadataStorage();
27 }
28 create(instance, callback, moduleKey, methodName, contextId = constants_3.STATIC_CONTEXT, inquirerId, defaultCallMetadata = rpc_metadata_constants_1.DEFAULT_CALLBACK_METADATA) {
29 const contextType = 'rpc';
30 const { argsLength, paramtypes, getParamsMetadata } = this.getMetadata(instance, methodName, defaultCallMetadata, contextType);
31 const exceptionHandler = this.exceptionFiltersContext.create(instance, callback, moduleKey, contextId, inquirerId);
32 const pipes = this.pipesContextCreator.create(instance, callback, moduleKey, contextId, inquirerId);
33 const guards = this.guardsContextCreator.create(instance, callback, moduleKey, contextId, inquirerId);
34 const interceptors = this.interceptorsContextCreator.create(instance, callback, moduleKey, contextId, inquirerId);
35 const paramsMetadata = getParamsMetadata(moduleKey);
36 const paramsOptions = paramsMetadata
37 ? this.contextUtils.mergeParamsMetatypes(paramsMetadata, paramtypes)
38 : [];
39 const fnApplyPipes = this.createPipesFn(pipes, paramsOptions);
40 const fnCanActivate = this.createGuardsFn(guards, instance, callback, contextType);
41 const handler = (initialArgs, args) => async () => {
42 if (fnApplyPipes) {
43 await fnApplyPipes(initialArgs, ...args);
44 return callback.apply(instance, initialArgs);
45 }
46 return callback.apply(instance, args);
47 };
48 return this.rpcProxy.create(async (...args) => {
49 const initialArgs = this.contextUtils.createNullArray(argsLength);
50 fnCanActivate && (await fnCanActivate(args));
51 return this.interceptorsConsumer.intercept(interceptors, args, instance, callback, handler(initialArgs, args), contextType);
52 }, exceptionHandler);
53 }
54 reflectCallbackParamtypes(instance, callback) {
55 return Reflect.getMetadata(constants_1.PARAMTYPES_METADATA, instance, callback.name);
56 }
57 createGuardsFn(guards, instance, callback, contextType) {
58 const canActivateFn = async (args) => {
59 const canActivate = await this.guardsConsumer.tryActivate(guards, args, instance, callback, contextType);
60 if (!canActivate) {
61 throw new exceptions_1.RpcException(constants_2.FORBIDDEN_MESSAGE);
62 }
63 };
64 return guards.length ? canActivateFn : null;
65 }
66 getMetadata(instance, methodName, defaultCallMetadata, contextType) {
67 const cacheMetadata = this.handlerMetadataStorage.get(instance, methodName);
68 if (cacheMetadata) {
69 return cacheMetadata;
70 }
71 const metadata = this.contextUtils.reflectCallbackMetadata(instance, methodName, constants_4.PARAM_ARGS_METADATA) || defaultCallMetadata;
72 const keys = Object.keys(metadata);
73 const argsLength = this.contextUtils.getArgumentsLength(keys, metadata);
74 const paramtypes = this.contextUtils.reflectCallbackParamtypes(instance, methodName);
75 const contextFactory = this.contextUtils.getContextFactory(contextType, instance, instance[methodName]);
76 const getParamsMetadata = (moduleKey) => this.exchangeKeysForValues(keys, metadata, moduleKey, this.rpcParamsFactory, contextFactory);
77 const handlerMetadata = {
78 argsLength,
79 paramtypes,
80 getParamsMetadata,
81 };
82 this.handlerMetadataStorage.set(instance, methodName, handlerMetadata);
83 return handlerMetadata;
84 }
85 exchangeKeysForValues(keys, metadata, moduleContext, paramsFactory, contextFactory) {
86 this.pipesContextCreator.setModuleContext(moduleContext);
87 return keys.map(key => {
88 const { index, data, pipes: pipesCollection } = metadata[key];
89 const pipes = this.pipesContextCreator.createConcreteContext(pipesCollection);
90 const type = this.contextUtils.mapParamType(key);
91 if (key.includes(constants_1.CUSTOM_ROUTE_ARGS_METADATA)) {
92 const { factory } = metadata[key];
93 const customExtractValue = this.contextUtils.getCustomFactory(factory, data, contextFactory);
94 return { index, extractValue: customExtractValue, type, data, pipes };
95 }
96 const numericType = Number(type);
97 const extractValue = (...args) => paramsFactory.exchangeKeyForValue(numericType, data, args);
98 return { index, extractValue, type: numericType, data, pipes };
99 });
100 }
101 createPipesFn(pipes, paramsOptions) {
102 const pipesFn = async (args, ...params) => {
103 const resolveParamValue = async (param) => {
104 const { index, extractValue, type, data, metatype, pipes: paramPipes, } = param;
105 const value = extractValue(...params);
106 args[index] = await this.getParamValue(value, { metatype, type, data }, pipes.concat(paramPipes));
107 };
108 await Promise.all(paramsOptions.map(resolveParamValue));
109 };
110 return paramsOptions.length ? pipesFn : null;
111 }
112 async getParamValue(value, { metatype, type, data }, pipes) {
113 return (0, shared_utils_1.isEmpty)(pipes)
114 ? value
115 : this.pipesConsumer.apply(value, { metatype, type, data }, pipes);
116 }
117}
118exports.RpcContextCreator = RpcContextCreator;