UNPKG

5.5 kBJavaScriptView Raw
1"use strict";
2/*
3 * Copyright 2019 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18Object.defineProperty(exports, "__esModule", { value: true });
19exports.loadPackageDefinition = exports.makeClientConstructor = void 0;
20const client_1 = require("./client");
21/**
22 * Map with short names for each of the requester maker functions. Used in
23 * makeClientConstructor
24 * @private
25 */
26const requesterFuncs = {
27 unary: client_1.Client.prototype.makeUnaryRequest,
28 server_stream: client_1.Client.prototype.makeServerStreamRequest,
29 client_stream: client_1.Client.prototype.makeClientStreamRequest,
30 bidi: client_1.Client.prototype.makeBidiStreamRequest,
31};
32/**
33 * Returns true, if given key is included in the blacklisted
34 * keys.
35 * @param key key for check, string.
36 */
37function isPrototypePolluted(key) {
38 return ['__proto__', 'prototype', 'constructor'].includes(key);
39}
40/**
41 * Creates a constructor for a client with the given methods, as specified in
42 * the methods argument. The resulting class will have an instance method for
43 * each method in the service, which is a partial application of one of the
44 * [Client]{@link grpc.Client} request methods, depending on `requestSerialize`
45 * and `responseSerialize`, with the `method`, `serialize`, and `deserialize`
46 * arguments predefined.
47 * @param methods An object mapping method names to
48 * method attributes
49 * @param serviceName The fully qualified name of the service
50 * @param classOptions An options object.
51 * @return New client constructor, which is a subclass of
52 * {@link grpc.Client}, and has the same arguments as that constructor.
53 */
54function makeClientConstructor(methods, serviceName, classOptions) {
55 if (!classOptions) {
56 classOptions = {};
57 }
58 class ServiceClientImpl extends client_1.Client {
59 }
60 Object.keys(methods).forEach((name) => {
61 if (isPrototypePolluted(name)) {
62 return;
63 }
64 const attrs = methods[name];
65 let methodType;
66 // TODO(murgatroid99): Verify that we don't need this anymore
67 if (typeof name === 'string' && name.charAt(0) === '$') {
68 throw new Error('Method names cannot start with $');
69 }
70 if (attrs.requestStream) {
71 if (attrs.responseStream) {
72 methodType = 'bidi';
73 }
74 else {
75 methodType = 'client_stream';
76 }
77 }
78 else {
79 if (attrs.responseStream) {
80 methodType = 'server_stream';
81 }
82 else {
83 methodType = 'unary';
84 }
85 }
86 const serialize = attrs.requestSerialize;
87 const deserialize = attrs.responseDeserialize;
88 const methodFunc = partial(requesterFuncs[methodType], attrs.path, serialize, deserialize);
89 ServiceClientImpl.prototype[name] = methodFunc;
90 // Associate all provided attributes with the method
91 Object.assign(ServiceClientImpl.prototype[name], attrs);
92 if (attrs.originalName && !isPrototypePolluted(attrs.originalName)) {
93 ServiceClientImpl.prototype[attrs.originalName] =
94 ServiceClientImpl.prototype[name];
95 }
96 });
97 ServiceClientImpl.service = methods;
98 ServiceClientImpl.serviceName = serviceName;
99 return ServiceClientImpl;
100}
101exports.makeClientConstructor = makeClientConstructor;
102function partial(fn, path, serialize, deserialize) {
103 // eslint-disable-next-line @typescript-eslint/no-explicit-any
104 return function (...args) {
105 return fn.call(this, path, serialize, deserialize, ...args);
106 };
107}
108function isProtobufTypeDefinition(obj) {
109 return 'format' in obj;
110}
111/**
112 * Load a gRPC package definition as a gRPC object hierarchy.
113 * @param packageDef The package definition object.
114 * @return The resulting gRPC object.
115 */
116function loadPackageDefinition(packageDef) {
117 const result = {};
118 for (const serviceFqn in packageDef) {
119 if (Object.prototype.hasOwnProperty.call(packageDef, serviceFqn)) {
120 const service = packageDef[serviceFqn];
121 const nameComponents = serviceFqn.split('.');
122 if (nameComponents.some((comp) => isPrototypePolluted(comp))) {
123 continue;
124 }
125 const serviceName = nameComponents[nameComponents.length - 1];
126 let current = result;
127 for (const packageName of nameComponents.slice(0, -1)) {
128 if (!current[packageName]) {
129 current[packageName] = {};
130 }
131 current = current[packageName];
132 }
133 if (isProtobufTypeDefinition(service)) {
134 current[serviceName] = service;
135 }
136 else {
137 current[serviceName] = makeClientConstructor(service, serviceName, {});
138 }
139 }
140 }
141 return result;
142}
143exports.loadPackageDefinition = loadPackageDefinition;
144//# sourceMappingURL=make-client.js.map
\No newline at end of file