@gravity-ui/gateway 4.11.1 → 4.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -549,6 +549,10 @@ function createGrpcAction({ root, credentials }, endpoints, config, serviceKey,
549
549
  const timeout = (_c = (_b = (_a = actionConfig === null || actionConfig === void 0 ? void 0 : actionConfig.timeout) !== null && _a !== void 0 ? _a : config === null || config === void 0 ? void 0 : config.timeout) !== null && _b !== void 0 ? _b : options === null || options === void 0 ? void 0 : options.timeout) !== null && _c !== void 0 ? _c : constants_1.DEFAULT_TIMEOUT;
550
550
  let serviceOptions = createServiceOptions(timeout);
551
551
  const { body = null } = params !== null && params !== void 0 ? params : { body: args };
552
+ // protobufjs >=7.5.5 rejects null/undefined request payloads with
553
+ // ".<Type>: object expected" (any message with fields; >=8.x even for
554
+ // empty messages). An empty request body must be sent as {}.
555
+ const requestBody = body !== null && body !== void 0 ? body : {};
552
556
  const serviceMetadata = createMetadata({
553
557
  options,
554
558
  actionConfig,
@@ -573,7 +577,7 @@ function createGrpcAction({ root, credentials }, endpoints, config, serviceKey,
573
577
  debugHeaders: (0, common_2.sanitizeDebugHeaders)(debugHeaders),
574
578
  });
575
579
  const actionCall = service[action].bind(service);
576
- const stream = actionCall(body, serviceMetadata, serviceOptions);
580
+ const stream = actionCall(requestBody, serviceMetadata, serviceOptions);
577
581
  stopListeningForAbort = (0, grpc_1.listenForAbort)({
578
582
  signal: abortSignal,
579
583
  config,
@@ -666,7 +670,7 @@ function createGrpcAction({ root, credentials }, endpoints, config, serviceKey,
666
670
  let actionCall = service[action].bind(service);
667
671
  const callAction = () => {
668
672
  let trailingMetadata = {};
669
- const call = actionCall(body, serviceMetadata, serviceOptions, async (error, response) => {
673
+ const call = actionCall(requestBody, serviceMetadata, serviceOptions, async (error, response) => {
670
674
  var _a, _b;
671
675
  const endRequestTime = Date.now();
672
676
  requestData.requestTime = endRequestTime - startRequestTime;
@@ -1,10 +1,11 @@
1
- import { ApiActionConfig, ApiByScope, ApiServiceMixedActionConfig, GatewayConfig, GatewayRequest, GatewayResponse, SchemasByScope } from '../models/common';
1
+ import { ApiActionConfig, ApiByScope, ApiServiceMixedActionConfig, GatewayConfig, GatewayRequest, GatewayResponse, SchemasByScope, SendStats } from '../models/common';
2
2
  import { GatewayContext } from '../models/context';
3
3
  import { AppErrorConstructor } from '../models/error';
4
4
  import type { GrpcContext } from './grpc';
5
5
  export declare function createMixedAction<TSchema extends SchemasByScope, Context extends GatewayContext, Req extends GatewayRequest<Context>, Res extends GatewayResponse>(config: ApiServiceMixedActionConfig<Context, Req, Res, any, any, any>, api: ApiByScope<TSchema, Context, Req, Res>, serviceName: string, actionName: string, extra: {
6
6
  config: GatewayConfig<Context, Req, Res>;
7
7
  grpcContext: GrpcContext;
8
+ sendStats?: SendStats<Context>;
8
9
  }, ErrorConstructor: AppErrorConstructor): (actionConfig: ApiActionConfig<Context, any>) => Promise<{
9
10
  responseData: any;
10
11
  debugHeaders: {};
@@ -16,9 +16,23 @@ const constants_1 = require("../constants");
16
16
  const common_1 = require("../utils/common");
17
17
  const create_context_api_1 = require("../utils/create-context-api");
18
18
  const parse_error_1 = require("../utils/parse-error");
19
+ const redact_sensitive_headers_1 = require("../utils/redact-sensitive-headers");
20
+ function getMixedResponseSize(data, ctx, ErrorConstructor) {
21
+ var _a;
22
+ let responseSize = 0;
23
+ try {
24
+ responseSize = constants_1.ECMA_STRING_SIZE * ((_a = JSON.stringify(data)) === null || _a === void 0 ? void 0 : _a.length);
25
+ }
26
+ catch (error) {
27
+ (0, common_1.handleError)(ErrorConstructor, error, ctx, 'Calculate response size failed');
28
+ }
29
+ return responseSize;
30
+ }
19
31
  function createMixedAction(config, api, serviceName, actionName, extra, ErrorConstructor) {
20
32
  return async (actionConfig) => {
33
+ var _a, _b, _c;
21
34
  const { args } = actionConfig, context = __rest(actionConfig, ["args"]);
35
+ const { requestId, headers: requestHeaders, ctx: parentCtx, userId } = actionConfig;
22
36
  const ctx = actionConfig.ctx.create(`Gateway ${serviceName} ${actionName} [mixed]`, {
23
37
  tags: {
24
38
  action: actionName,
@@ -27,15 +41,30 @@ function createMixedAction(config, api, serviceName, actionName, extra, ErrorCon
27
41
  },
28
42
  });
29
43
  const contextApi = (0, create_context_api_1.generateContextApi)(api, Object.assign(Object.assign({}, context), { ctx }));
44
+ const startRequestTime = Date.now();
45
+ const requestData = {
46
+ timestamp: startRequestTime,
47
+ service: serviceName,
48
+ action: actionName,
49
+ requestId: requestId || '',
50
+ requestMethod: '',
51
+ requestUrl: '',
52
+ traceId: ((_a = ctx.getTraceId) === null || _a === void 0 ? void 0 : _a.call(ctx)) || '',
53
+ userId: userId || '',
54
+ };
30
55
  try {
31
56
  const responseData = await config(contextApi, args, Object.assign(Object.assign({ headers: actionConfig.headers, lang: actionConfig.headers[constants_1.DEFAULT_LANG_HEADER] || constants_1.Lang.Ru, ctx }, extra), { abortSignal: actionConfig.abortSignal }));
32
57
  ctx.log('Request completed');
58
+ (_b = extra.sendStats) === null || _b === void 0 ? void 0 : _b.call(extra, Object.assign(Object.assign({}, requestData), { requestTime: Date.now() - startRequestTime, responseSize: getMixedResponseSize(responseData, ctx, ErrorConstructor), restStatus: 200 }), (0, redact_sensitive_headers_1.redactSensitiveHeaders)(parentCtx, requestHeaders), parentCtx, { debugHeaders: {} });
33
59
  return {
34
60
  responseData,
35
61
  debugHeaders: {},
36
62
  };
37
63
  }
38
64
  catch (e) {
65
+ const errorData = e instanceof Object && 'error' in e ? e.error : e;
66
+ const restStatus = (errorData === null || errorData === void 0 ? void 0 : errorData.status) || 500;
67
+ (_c = extra.sendStats) === null || _c === void 0 ? void 0 : _c.call(extra, Object.assign(Object.assign({}, requestData), { requestTime: Date.now() - startRequestTime, responseSize: getMixedResponseSize(errorData, ctx, ErrorConstructor), restStatus }), (0, redact_sensitive_headers_1.redactSensitiveHeaders)(parentCtx, requestHeaders), parentCtx, { debugHeaders: {} });
39
68
  if (e instanceof Object && 'error' in e) {
40
69
  (0, common_1.handleError)(ErrorConstructor, e, ctx, 'Request failed', {
41
70
  actionName,
package/build/index.js CHANGED
@@ -69,7 +69,7 @@ function createApiAction(schema, config, serviceKey, actionName, api, grpcContex
69
69
  const env = config.env || '';
70
70
  if (isMixedActionConfig(action)) {
71
71
  const resultServiceName = serviceName || serviceKey;
72
- return (0, mixed_1.createMixedAction)(action, api, resultServiceName, actionName, { config, grpcContext }, config.ErrorConstructor);
72
+ return (0, mixed_1.createMixedAction)(action, api, resultServiceName, actionName, { config, grpcContext, sendStats: config.sendStats }, config.ErrorConstructor);
73
73
  }
74
74
  const endpointsConfig = lodash_1.default.get(serviceSchema.endpoints, [installation, env]);
75
75
  if (isRestActionConfig(action)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/gateway",
3
- "version": "4.11.1",
3
+ "version": "4.12.1",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "build/index.js",
@@ -46,7 +46,7 @@
46
46
  "axios-retry": "^3.9.1",
47
47
  "lodash": "^4.17.21",
48
48
  "object-sizeof": "^2.6.5",
49
- "protobufjs": "^7.2.5",
49
+ "protobufjs": "^7.6.4",
50
50
  "uuid": "^9.0.0"
51
51
  },
52
52
  "devDependencies": {
@@ -0,0 +1,182 @@
1
+ diff --git a/node_modules/protobufjs/Oops.rej b/node_modules/protobufjs/Oops.rej
2
+ new file mode 100644
3
+ index 0000000..2dd05fc
4
+ --- /dev/null
5
+ +++ b/node_modules/protobufjs/Oops.rej
6
+ @@ -0,0 +1,78 @@
7
+ +@@ -242,31 +242,12 @@
8
+ + if (!nested)
9
+ + type._edition = edition;
10
+ +
11
+ +- // gateway patch: record key/value types of map-entry nested types so that
12
+ +- // map fields restored from a descriptor (reflection) become real MapFields.
13
+ +- var mapTypes = {};
14
+ +- if (descriptor.nestedType)
15
+ +- for (i = 0; i < descriptor.nestedType.length; ++i)
16
+ +- if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry && descriptor.nestedType[i].field.length === 2)
17
+ +- mapTypes[descriptor.nestedType[i].name] = [
18
+ +- fromDescriptorType(descriptor.nestedType[i].field[0].type),
19
+ +- descriptor.nestedType[i].field[1].typeName ? descriptor.nestedType[i].field[1].typeName : fromDescriptorType(descriptor.nestedType[i].field[1].type)
20
+ +- ];
21
+ +-
22
+ + /* Oneofs */ if (descriptor.oneofDecl)
23
+ + for (i = 0; i < descriptor.oneofDecl.length; ++i)
24
+ + type.add(OneOf.fromDescriptor(descriptor.oneofDecl[i]));
25
+ + /* Fields */ if (descriptor.field)
26
+ + for (i = 0; i < descriptor.field.length; ++i) {
27
+ +- var fieldTypeName = descriptor.field[i].typeName;
28
+ +- var mapKv = fieldTypeName ? mapTypes[fieldTypeName] : undefined;
29
+ +- if (fieldTypeName && !mapKv) {
30
+ +- // after reflection the typeName may be just the short name
31
+ +- var nameParts = fieldTypeName.split("." + type.name + ".");
32
+ +- if (nameParts.length === 2)
33
+ +- mapKv = mapTypes[nameParts[1]];
34
+ +- }
35
+ +- var field = Field.fromDescriptor(descriptor.field[i], edition, true, mapKv);
36
+ ++ var field = Field.fromDescriptor(descriptor.field[i], edition, true);
37
+ + type.add(field);
38
+ + if (descriptor.field[i].hasOwnProperty("oneofIndex")) // eslint-disable-line no-prototype-builtins
39
+ + type.oneofsArray[descriptor.field[i].oneofIndex].add(field);
40
+ +@@ -276,10 +257,9 @@
41
+ + type.add(Field.fromDescriptor(descriptor.extension[i], edition, true));
42
+ + /* Nested types */ if (descriptor.nestedType)
43
+ + for (i = 0; i < descriptor.nestedType.length; ++i) {
44
+ +- // map-entry types are reconstructed as MapFields above (gateway patch)
45
+ +- if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry && descriptor.nestedType[i].field.length === 2)
46
+ +- continue;
47
+ + type.add(Type.fromDescriptor(descriptor.nestedType[i], edition, true, depth + 1));
48
+ ++ if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry)
49
+ ++ type.setOption("map_entry", true);
50
+ + }
51
+ + /* Nested enums */ if (descriptor.enumType)
52
+ + for (i = 0; i < descriptor.enumType.length; ++i)
53
+ +@@ -430,10 +410,9 @@
54
+ + * @param {IFieldDescriptorProto|Reader|Uint8Array} descriptor Descriptor
55
+ + * @param {string} [edition="proto2"] The syntax or edition to use
56
+ + * @param {boolean} [nested=false] Whether or not this is a top-level object
57
+ +- * @param {string[]} [mapKv] Key & value types for a map field (gateway patch)
58
+ +- * @returns {Field|MapField} Field instance
59
+ ++ * @returns {Field} Field instance
60
+ + */
61
+ +-Field.fromDescriptor = function fromDescriptor(descriptor, edition, nested, mapKv) {
62
+ ++Field.fromDescriptor = function fromDescriptor(descriptor, edition, nested) {
63
+ +
64
+ + // Decode the descriptor message if specified as a buffer:
65
+ + if (typeof descriptor.length === "number")
66
+ +@@ -468,16 +447,8 @@
67
+ + throw Error("illegal type name: " + extendee);
68
+ + } else
69
+ + extendee = undefined;
70
+ +- // gateway patch: protobufjs expects camelCased field names, while descriptors
71
+ +- // (reflection) carry the original proto names; build a MapField for map fields.
72
+ +- var fieldName = $protobuf.util.camelCase(descriptor.name.length ? descriptor.name : "field" + descriptor.number);
73
+ +- var field = mapKv ? new MapField(
74
+ +- fieldName,
75
+ +- descriptor.number,
76
+ +- mapKv[0],
77
+ +- mapKv[1]
78
+ +- ) : new Field(
79
+ +- fieldName,
80
+ ++ var field = new Field(
81
+ ++ descriptor.name.length ? descriptor.name : "field" + descriptor.number,
82
+ + descriptor.number,
83
+ + fieldType,
84
+ + fieldRule,
85
+ diff --git a/node_modules/protobufjs/ext/descriptor/index.js b/node_modules/protobufjs/ext/descriptor/index.js
86
+ index 6ea795b..cdb50c1 100644
87
+ --- a/node_modules/protobufjs/ext/descriptor/index.js
88
+ +++ b/node_modules/protobufjs/ext/descriptor/index.js
89
+ @@ -242,12 +242,31 @@ Type.fromDescriptor = function fromDescriptor(descriptor, edition, nested, depth
90
+ if (!nested)
91
+ type._edition = edition;
92
+
93
+ + // gateway patch: record key/value types of map-entry nested types so that
94
+ + // map fields restored from a descriptor (reflection) become real MapFields.
95
+ + var mapTypes = {};
96
+ + if (descriptor.nestedType)
97
+ + for (i = 0; i < descriptor.nestedType.length; ++i)
98
+ + if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry && descriptor.nestedType[i].field.length === 2)
99
+ + mapTypes[descriptor.nestedType[i].name] = [
100
+ + fromDescriptorType(descriptor.nestedType[i].field[0].type),
101
+ + descriptor.nestedType[i].field[1].typeName ? descriptor.nestedType[i].field[1].typeName : fromDescriptorType(descriptor.nestedType[i].field[1].type)
102
+ + ];
103
+ +
104
+ /* Oneofs */ if (descriptor.oneofDecl)
105
+ for (i = 0; i < descriptor.oneofDecl.length; ++i)
106
+ type.add(OneOf.fromDescriptor(descriptor.oneofDecl[i]));
107
+ /* Fields */ if (descriptor.field)
108
+ for (i = 0; i < descriptor.field.length; ++i) {
109
+ - var field = Field.fromDescriptor(descriptor.field[i], edition, true);
110
+ + var fieldTypeName = descriptor.field[i].typeName;
111
+ + var mapKv = fieldTypeName ? mapTypes[fieldTypeName] : undefined;
112
+ + if (fieldTypeName && !mapKv) {
113
+ + // after reflection the typeName may be just the short name
114
+ + var nameParts = fieldTypeName.split("." + type.name + ".");
115
+ + if (nameParts.length === 2)
116
+ + mapKv = mapTypes[nameParts[1]];
117
+ + }
118
+ + var field = Field.fromDescriptor(descriptor.field[i], edition, true, mapKv);
119
+ type.add(field);
120
+ if (descriptor.field[i].hasOwnProperty("oneofIndex")) // eslint-disable-line no-prototype-builtins
121
+ type.oneofsArray[descriptor.field[i].oneofIndex].add(field);
122
+ @@ -257,9 +276,10 @@ Type.fromDescriptor = function fromDescriptor(descriptor, edition, nested, depth
123
+ type.add(Field.fromDescriptor(descriptor.extension[i], edition, true));
124
+ /* Nested types */ if (descriptor.nestedType)
125
+ for (i = 0; i < descriptor.nestedType.length; ++i) {
126
+ + // map-entry types are reconstructed as MapFields above (gateway patch)
127
+ + if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry && descriptor.nestedType[i].field.length === 2)
128
+ + continue;
129
+ type.add(Type.fromDescriptor(descriptor.nestedType[i], edition, true, depth + 1));
130
+ - if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry)
131
+ - type.setOption("map_entry", true);
132
+ }
133
+ /* Nested enums */ if (descriptor.enumType)
134
+ for (i = 0; i < descriptor.enumType.length; ++i)
135
+ @@ -410,9 +430,10 @@ Type.prototype.toDescriptor = function toDescriptor(edition) {
136
+ * @param {IFieldDescriptorProto|Reader|Uint8Array} descriptor Descriptor
137
+ * @param {string} [edition="proto2"] The syntax or edition to use
138
+ * @param {boolean} [nested=false] Whether or not this is a top-level object
139
+ - * @returns {Field} Field instance
140
+ + * @param {string[]} [mapKv] Key & value types for a map field (gateway patch)
141
+ + * @returns {Field|MapField} Field instance
142
+ */
143
+ -Field.fromDescriptor = function fromDescriptor(descriptor, edition, nested) {
144
+ +Field.fromDescriptor = function fromDescriptor(descriptor, edition, nested, mapKv) {
145
+
146
+ // Decode the descriptor message if specified as a buffer:
147
+ if (typeof descriptor.length === "number")
148
+ @@ -447,8 +468,16 @@ Field.fromDescriptor = function fromDescriptor(descriptor, edition, nested) {
149
+ throw Error("illegal type name: " + extendee);
150
+ } else
151
+ extendee = undefined;
152
+ - var field = new Field(
153
+ - descriptor.name.length ? descriptor.name : "field" + descriptor.number,
154
+ + // gateway patch: protobufjs expects camelCased field names, while descriptors
155
+ + // (reflection) carry the original proto names; build a MapField for map fields.
156
+ + var fieldName = $protobuf.util.camelCase(descriptor.name.length ? descriptor.name : "field" + descriptor.number);
157
+ + var field = mapKv ? new MapField(
158
+ + fieldName,
159
+ + descriptor.number,
160
+ + mapKv[0],
161
+ + mapKv[1]
162
+ + ) : new Field(
163
+ + fieldName,
164
+ descriptor.number,
165
+ fieldType,
166
+ fieldRule,
167
+ @@ -909,7 +938,14 @@ function fromDescriptorOptionsRecursive(obj, type) {
168
+ function fromDescriptorOptions(options, type) {
169
+ if (!options)
170
+ return undefined;
171
+ - return fromDescriptorOptionsRecursive(type.toObject(options), type);
172
+ + var val = fromDescriptorOptionsRecursive(type.toObject(options), type);
173
+ + // gateway patch: keep options that are not declared on the Options type
174
+ + // (e.g. custom proto options) so they survive a reflection round-trip.
175
+ + for (var option in options)
176
+ + if (Object.prototype.hasOwnProperty.call(options, option) &&
177
+ + !type._fieldsArray.some(function (f) { return f.name === option; }))
178
+ + val[underScore(option)] = options[option];
179
+ + return val;
180
+ }
181
+
182
+ function toDescriptorOptionsRecursive(obj, type) {
@@ -1,107 +0,0 @@
1
- diff --git a/node_modules/protobufjs/ext/descriptor/index.js b/node_modules/protobufjs/ext/descriptor/index.js
2
- index 6aafd2a..b8e9f58 100644
3
- --- a/node_modules/protobufjs/ext/descriptor/index.js
4
- +++ b/node_modules/protobufjs/ext/descriptor/index.js
5
- @@ -204,6 +204,8 @@ Type.fromDescriptor = function fromDescriptor(descriptor, syntax) {
6
- if (typeof descriptor.length === "number")
7
- descriptor = exports.DescriptorProto.decode(descriptor);
8
-
9
- + // record mapTypes for map fields
10
- + var mapTypes = {};
11
- // Create the message type
12
- var type = new Type(descriptor.name.length ? descriptor.name : "Type" + unnamedMessageIndex++, fromDescriptorOptions(descriptor.options, exports.MessageOptions)),
13
- i;
14
- @@ -211,9 +213,34 @@ Type.fromDescriptor = function fromDescriptor(descriptor, syntax) {
15
- /* Oneofs */ if (descriptor.oneofDecl)
16
- for (i = 0; i < descriptor.oneofDecl.length; ++i)
17
- type.add(OneOf.fromDescriptor(descriptor.oneofDecl[i]));
18
- + /* Nested types */ if (descriptor.nestedType)
19
- + for (i = 0; i < descriptor.nestedType.length; ++i) {
20
- + if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry && descriptor.nestedType[i].field.length === 2){
21
- + mapTypes[descriptor.nestedType[i].name] = [fromDescriptorType(descriptor.nestedType[i].field[0].type), descriptor.nestedType[i].field[1].typeName ? descriptor.nestedType[i].field[1].typeName : fromDescriptorType(descriptor.nestedType[i].field[1].type)];
22
- + }else{
23
- + type.add(Type.fromDescriptor(descriptor.nestedType[i], syntax));
24
- + }
25
- + }
26
- /* Fields */ if (descriptor.field)
27
- for (i = 0; i < descriptor.field.length; ++i) {
28
- - var field = Field.fromDescriptor(descriptor.field[i], syntax);
29
- + var field = null;
30
- + while(!field) {
31
- + if(descriptor.field[i].typeName) {
32
- + // after reflection in typeName maybe just short type name
33
- + var foundedKvType = mapTypes[descriptor.field[i].typeName];
34
- + if (!foundedKvType) {
35
- + var nameParts = descriptor.field[i].typeName.split("."+type.name+".");
36
- + if (nameParts.length===2) {
37
- + foundedKvType = mapTypes[nameParts[1]];
38
- + }
39
- + }
40
- + if(foundedKvType) {
41
- + field = Field.fromDescriptor(descriptor.field[i], syntax, foundedKvType);
42
- + break;
43
- + }
44
- + }
45
- + field = Field.fromDescriptor(descriptor.field[i], syntax);
46
- + }
47
- type.add(field);
48
- if (descriptor.field[i].hasOwnProperty("oneofIndex")) // eslint-disable-line no-prototype-builtins
49
- type.oneofsArray[descriptor.field[i].oneofIndex].add(field);
50
- @@ -221,12 +248,6 @@ Type.fromDescriptor = function fromDescriptor(descriptor, syntax) {
51
- /* Extension fields */ if (descriptor.extension)
52
- for (i = 0; i < descriptor.extension.length; ++i)
53
- type.add(Field.fromDescriptor(descriptor.extension[i], syntax));
54
- - /* Nested types */ if (descriptor.nestedType)
55
- - for (i = 0; i < descriptor.nestedType.length; ++i) {
56
- - type.add(Type.fromDescriptor(descriptor.nestedType[i], syntax));
57
- - if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry)
58
- - type.setOption("map_entry", true);
59
- - }
60
- /* Nested enums */ if (descriptor.enumType)
61
- for (i = 0; i < descriptor.enumType.length; ++i)
62
- type.add(Enum.fromDescriptor(descriptor.enumType[i]));
63
- @@ -375,9 +396,10 @@ var numberRe = /^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/;
64
- * Creates a field from a descriptor.
65
- * @param {IFieldDescriptorProto|Reader|Uint8Array} descriptor Descriptor
66
- * @param {string} [syntax="proto2"] Syntax
67
- - * @returns {Field} Field instance
68
- + * @param {string[]} mapKv Key & value types for map field
69
- + * @returns {Field|MapField} Field instance
70
- */
71
- -Field.fromDescriptor = function fromDescriptor(descriptor, syntax) {
72
- +Field.fromDescriptor = function fromDescriptor(descriptor, syntax, mapKv) {
73
-
74
- // Decode the descriptor message if specified as a buffer:
75
- if (typeof descriptor.length === "number")
76
- @@ -407,8 +429,16 @@ Field.fromDescriptor = function fromDescriptor(descriptor, syntax) {
77
- if (descriptor.extendee !== undefined) {
78
- extendee = extendee.length ? extendee : undefined;
79
- }
80
- - var field = new Field(
81
- - descriptor.name.length ? descriptor.name : "field" + descriptor.number,
82
- +
83
- + var rawFieldName = descriptor.name.length ? descriptor.name : "field" + descriptor.number;
84
- + var fieldName = $protobuf.util.camelCase(rawFieldName);
85
- + var field = mapKv ? new MapField(
86
- + fieldName,
87
- + descriptor.number,
88
- + mapKv[0],
89
- + mapKv[1]
90
- + ) : new Field(
91
- + fieldName,
92
- descriptor.number,
93
- fieldType,
94
- fieldRule,
95
- @@ -816,6 +846,12 @@ function fromDescriptorOptions(options, type) {
96
- val = field.resolvedType.valuesById[val];
97
- out.push(underScore(key), val);
98
- }
99
- +
100
- + for (var option in options) {
101
- + if (!type._fieldsArray.find(({name}) => name === option) && options.hasOwnProperty(option)) {
102
- + out.push(underScore(option), options[option]);
103
- + }
104
- + }
105
- return out.length ? $protobuf.util.toObject(out) : undefined;
106
- }
107
-