ts-proto 1.158.0 → 1.159.0
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.
- package/README.markdown +4 -0
- package/build/generate-async-iterable.js +8 -8
- package/build/generate-struct-wrappers.js +5 -5
- package/build/main.js +31 -30
- package/build/options.js +1 -0
- package/package.json +1 -1
package/README.markdown
CHANGED
|
@@ -289,6 +289,10 @@ Generated code will be placed in the Gradle build directory.
|
|
|
289
289
|
|
|
290
290
|
### Supported options
|
|
291
291
|
|
|
292
|
+
- With `--ts_proto_opt=globalThisPolyfill=true`, ts-proto will include a polyfill for globalThis.
|
|
293
|
+
|
|
294
|
+
Defaults to `false`, i.e. we assume `globalThis` is available.
|
|
295
|
+
|
|
292
296
|
- With `--ts_proto_opt=context=true`, the services will have a Go-style `ctx` parameter, which is useful for tracing/logging/etc. if you're not using node's `async_hooks` api due to performance reasons.
|
|
293
297
|
|
|
294
298
|
- With `--ts_proto_opt=forceLong=long`, all 64-bit numbers will be parsed as instances of `Long` (using the [long](https://www.npmjs.com/package/long) library).
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateDecodeTransform = exports.generateEncodeTransform = void 0;
|
|
4
4
|
const ts_poet_1 = require("ts-poet");
|
|
5
5
|
/** Creates a function to transform a message Source to a Uint8Array Source. */
|
|
6
|
-
function generateEncodeTransform(fullName) {
|
|
6
|
+
function generateEncodeTransform(utils, fullName) {
|
|
7
7
|
return (0, ts_poet_1.code) `
|
|
8
8
|
// encodeTransform encodes a source of message objects.
|
|
9
9
|
// Transform<${fullName}, Uint8Array>
|
|
@@ -11,12 +11,12 @@ function generateEncodeTransform(fullName) {
|
|
|
11
11
|
source: AsyncIterable<${fullName} | ${fullName}[]> | Iterable<${fullName} | ${fullName}[]>
|
|
12
12
|
): AsyncIterable<Uint8Array> {
|
|
13
13
|
for await (const pkt of source) {
|
|
14
|
-
if (Array.isArray(pkt)) {
|
|
15
|
-
for (const p of pkt) {
|
|
14
|
+
if (${utils.globalThis}.Array.isArray(pkt)) {
|
|
15
|
+
for (const p of (pkt as any)) {
|
|
16
16
|
yield* [${fullName}.encode(p).finish()]
|
|
17
17
|
}
|
|
18
18
|
} else {
|
|
19
|
-
yield* [${fullName}.encode(pkt).finish()]
|
|
19
|
+
yield* [${fullName}.encode(pkt as any).finish()]
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -24,7 +24,7 @@ function generateEncodeTransform(fullName) {
|
|
|
24
24
|
}
|
|
25
25
|
exports.generateEncodeTransform = generateEncodeTransform;
|
|
26
26
|
/** Creates a function to transform a Uint8Array Source to a message Source. */
|
|
27
|
-
function generateDecodeTransform(fullName) {
|
|
27
|
+
function generateDecodeTransform(utils, fullName) {
|
|
28
28
|
return (0, ts_poet_1.code) `
|
|
29
29
|
// decodeTransform decodes a source of encoded messages.
|
|
30
30
|
// Transform<Uint8Array, ${fullName}>
|
|
@@ -32,12 +32,12 @@ function generateDecodeTransform(fullName) {
|
|
|
32
32
|
source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>
|
|
33
33
|
): AsyncIterable<${fullName}> {
|
|
34
34
|
for await (const pkt of source) {
|
|
35
|
-
if (Array.isArray(pkt)) {
|
|
36
|
-
for (const p of pkt) {
|
|
35
|
+
if (${utils.globalThis}.Array.isArray(pkt)) {
|
|
36
|
+
for (const p of (pkt as any)) {
|
|
37
37
|
yield* [${fullName}.decode(p)]
|
|
38
38
|
}
|
|
39
39
|
} else {
|
|
40
|
-
yield* [${fullName}.decode(pkt)]
|
|
40
|
+
yield* [${fullName}.decode(pkt as any)]
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -46,7 +46,7 @@ function generateWrapDeep(ctx, fullProtoTypeName, fieldNames) {
|
|
|
46
46
|
result.${fieldNames.numberValue} = value;
|
|
47
47
|
} else if (typeof value === 'string') {
|
|
48
48
|
result.${fieldNames.stringValue} = value;
|
|
49
|
-
} else if (Array.isArray(value)) {
|
|
49
|
+
} else if (${ctx.utils.globalThis}.Array.isArray(value)) {
|
|
50
50
|
result.${fieldNames.listValue} = ListValue.wrap(value);
|
|
51
51
|
} else if (typeof value === 'object') {
|
|
52
52
|
result.${fieldNames.structValue} = Struct.wrap(value);
|
|
@@ -126,7 +126,7 @@ function generateUnwrapDeep(ctx, fullProtoTypeName, fieldNames) {
|
|
|
126
126
|
}
|
|
127
127
|
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
128
128
|
chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "ListValue"}): Array<any> {
|
|
129
|
-
if (message?.hasOwnProperty('values') && Array.isArray(message.values)) {
|
|
129
|
+
if (message?.hasOwnProperty('values') && ${ctx.utils.globalThis}.Array.isArray(message.values)) {
|
|
130
130
|
return message.values.map(Value.unwrap);
|
|
131
131
|
} else {
|
|
132
132
|
return message as any;
|
|
@@ -175,7 +175,7 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
175
175
|
result.kind = {$case: '${fieldNames.numberValue}', ${fieldNames.numberValue}: value};
|
|
176
176
|
} else if (typeof value === 'string') {
|
|
177
177
|
result.kind = {$case: '${fieldNames.stringValue}', ${fieldNames.stringValue}: value};
|
|
178
|
-
} else if (Array.isArray(value)) {
|
|
178
|
+
} else if (${ctx.utils.globalThis}.Array.isArray(value)) {
|
|
179
179
|
result.kind = {$case: '${fieldNames.listValue}', ${fieldNames.listValue}: value};
|
|
180
180
|
} else if (typeof value === 'object') {
|
|
181
181
|
result.kind = {$case: '${fieldNames.structValue}', ${fieldNames.structValue}: value};
|
|
@@ -196,7 +196,7 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
196
196
|
result.${fieldNames.numberValue} = value;
|
|
197
197
|
} else if (typeof value === 'string') {
|
|
198
198
|
result.${fieldNames.stringValue} = value;
|
|
199
|
-
} else if (Array.isArray(value)) {
|
|
199
|
+
} else if (${ctx.utils.globalThis}.Array.isArray(value)) {
|
|
200
200
|
result.${fieldNames.listValue} = value;
|
|
201
201
|
} else if (typeof value === 'object') {
|
|
202
202
|
result.${fieldNames.structValue} = value;
|
|
@@ -295,7 +295,7 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
295
295
|
}
|
|
296
296
|
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
297
297
|
chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "ListValue"}): Array<any> {
|
|
298
|
-
if (message?.hasOwnProperty('values') && Array.isArray(message.values)) {
|
|
298
|
+
if (message?.hasOwnProperty('values') && ${ctx.utils.globalThis}.Array.isArray(message.values)) {
|
|
299
299
|
return message.values;
|
|
300
300
|
} else {
|
|
301
301
|
return message as any;
|
package/build/main.js
CHANGED
|
@@ -121,8 +121,8 @@ function generateFile(ctx, fileDesc) {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
if (options.useAsyncIterable) {
|
|
124
|
-
staticMembers.push((0, generate_async_iterable_1.generateEncodeTransform)(fullName));
|
|
125
|
-
staticMembers.push((0, generate_async_iterable_1.generateDecodeTransform)(fullName));
|
|
124
|
+
staticMembers.push((0, generate_async_iterable_1.generateEncodeTransform)(ctx.utils, fullName));
|
|
125
|
+
staticMembers.push((0, generate_async_iterable_1.generateDecodeTransform)(ctx.utils, fullName));
|
|
126
126
|
}
|
|
127
127
|
if (options.outputJsonMethods) {
|
|
128
128
|
if (options.outputJsonMethods === true || options.outputJsonMethods === "from-only") {
|
|
@@ -273,13 +273,13 @@ function generateFile(ctx, fileDesc) {
|
|
|
273
273
|
exports.generateFile = generateFile;
|
|
274
274
|
/** These are runtime utility methods used by the generated code. */
|
|
275
275
|
function makeUtils(options) {
|
|
276
|
-
const bytes = makeByteUtils();
|
|
276
|
+
const bytes = makeByteUtils(options);
|
|
277
277
|
const longs = makeLongUtils(options, bytes);
|
|
278
278
|
return {
|
|
279
279
|
...bytes,
|
|
280
280
|
...makeDeepPartial(options, longs),
|
|
281
281
|
...makeObjectIdMethods(),
|
|
282
|
-
...makeTimestampMethods(options, longs),
|
|
282
|
+
...makeTimestampMethods(options, longs, bytes),
|
|
283
283
|
...longs,
|
|
284
284
|
...makeComparisonUtils(),
|
|
285
285
|
...makeNiceGrpcServerStreamingMethodResult(),
|
|
@@ -346,7 +346,7 @@ function makeLongUtils(options, bytes) {
|
|
|
346
346
|
`);
|
|
347
347
|
const longToNumber = (0, ts_poet_1.conditionalOutput)("longToNumber", (0, ts_poet_1.code) `
|
|
348
348
|
function longToNumber(long: ${Long}): number {
|
|
349
|
-
if (long.gt(Number.MAX_SAFE_INTEGER)) {
|
|
349
|
+
if (long.gt(${bytes.globalThis}.Number.MAX_SAFE_INTEGER)) {
|
|
350
350
|
throw new ${bytes.globalThis}.Error("Value is larger than Number.MAX_SAFE_INTEGER")
|
|
351
351
|
}
|
|
352
352
|
return long.toNumber();
|
|
@@ -354,12 +354,12 @@ function makeLongUtils(options, bytes) {
|
|
|
354
354
|
`);
|
|
355
355
|
return { numberToLong, longToNumber, longToString, longToBigint, Long };
|
|
356
356
|
}
|
|
357
|
-
function makeByteUtils() {
|
|
358
|
-
const
|
|
357
|
+
function makeByteUtils(options) {
|
|
358
|
+
const globalThisPolyfill = (0, ts_poet_1.conditionalOutput)("gt", (0, ts_poet_1.code) `
|
|
359
359
|
declare const self: any | undefined;
|
|
360
360
|
declare const window: any | undefined;
|
|
361
361
|
declare const global: any | undefined;
|
|
362
|
-
const
|
|
362
|
+
const gt: any = (() => {
|
|
363
363
|
if (typeof globalThis !== "undefined") return globalThis;
|
|
364
364
|
if (typeof self !== "undefined") return self;
|
|
365
365
|
if (typeof window !== "undefined") return window;
|
|
@@ -367,6 +367,7 @@ function makeByteUtils() {
|
|
|
367
367
|
throw "Unable to locate global object";
|
|
368
368
|
})();
|
|
369
369
|
`);
|
|
370
|
+
const globalThis = options.globalThisPolyfill ? globalThisPolyfill : (0, ts_poet_1.conditionalOutput)("globalThis", (0, ts_poet_1.code) ``);
|
|
370
371
|
const bytesFromBase64 = (0, ts_poet_1.conditionalOutput)("bytesFromBase64", (0, ts_poet_1.code) `
|
|
371
372
|
function bytesFromBase64(b64: string): Uint8Array {
|
|
372
373
|
if (${globalThis}.Buffer) {
|
|
@@ -388,7 +389,7 @@ function makeByteUtils() {
|
|
|
388
389
|
} else {
|
|
389
390
|
const bin: string[] = [];
|
|
390
391
|
arr.forEach((byte) => {
|
|
391
|
-
bin.push(String.fromCharCode(byte));
|
|
392
|
+
bin.push(${globalThis}.String.fromCharCode(byte));
|
|
392
393
|
});
|
|
393
394
|
return ${globalThis}.btoa(bin.join(''));
|
|
394
395
|
}
|
|
@@ -459,7 +460,7 @@ function makeObjectIdMethods() {
|
|
|
459
460
|
`);
|
|
460
461
|
return { fromJsonObjectId, fromProtoObjectId, toProtoObjectId };
|
|
461
462
|
}
|
|
462
|
-
function makeTimestampMethods(options, longs) {
|
|
463
|
+
function makeTimestampMethods(options, longs, bytes) {
|
|
463
464
|
const Timestamp = (0, utils_1.impProto)(options, "google/protobuf/timestamp", "Timestamp");
|
|
464
465
|
let seconds = "date.getTime() / 1_000";
|
|
465
466
|
let toNumberCode = "t.seconds";
|
|
@@ -468,11 +469,11 @@ function makeTimestampMethods(options, longs) {
|
|
|
468
469
|
seconds = (0, ts_poet_1.code) `${longs.numberToLong}(date.getTime() / 1_000)`;
|
|
469
470
|
}
|
|
470
471
|
else if (options.forceLong === options_1.LongOption.BIGINT) {
|
|
471
|
-
toNumberCode =
|
|
472
|
+
toNumberCode = (0, ts_poet_1.code) `${bytes.globalThis}.Number(t.seconds.toString())`;
|
|
472
473
|
seconds = (0, ts_poet_1.code) `BigInt(Math.trunc(date.getTime() / 1_000))`;
|
|
473
474
|
}
|
|
474
475
|
else if (options.forceLong === options_1.LongOption.STRING) {
|
|
475
|
-
toNumberCode =
|
|
476
|
+
toNumberCode = (0, ts_poet_1.code) `${bytes.globalThis}.Number(t.seconds)`;
|
|
476
477
|
// Must discard the fractional piece here
|
|
477
478
|
// Otherwise the fraction ends up on the seconds when parsed as a Long
|
|
478
479
|
// (note this only occurs when the string is > 8 characters)
|
|
@@ -482,7 +483,7 @@ function makeTimestampMethods(options, longs) {
|
|
|
482
483
|
const toTimestamp = (0, ts_poet_1.conditionalOutput)("toTimestamp", options.useDate === options_1.DateOption.STRING
|
|
483
484
|
? (0, ts_poet_1.code) `
|
|
484
485
|
function toTimestamp(dateStr: string): ${Timestamp} {
|
|
485
|
-
const date = new Date(dateStr);
|
|
486
|
+
const date = new ${bytes.globalThis}.Date(dateStr);
|
|
486
487
|
const seconds = ${seconds};
|
|
487
488
|
const nanos = (date.getTime() % 1_000) * 1_000_000;
|
|
488
489
|
return { ${maybeTypeField} seconds, nanos };
|
|
@@ -500,23 +501,23 @@ function makeTimestampMethods(options, longs) {
|
|
|
500
501
|
function fromTimestamp(t: ${Timestamp}): string {
|
|
501
502
|
let millis = (${toNumberCode} || 0) * 1_000;
|
|
502
503
|
millis += (t.nanos || 0) / 1_000_000;
|
|
503
|
-
return new Date(millis).toISOString();
|
|
504
|
+
return new ${bytes.globalThis}.Date(millis).toISOString();
|
|
504
505
|
}
|
|
505
506
|
`
|
|
506
507
|
: (0, ts_poet_1.code) `
|
|
507
508
|
function fromTimestamp(t: ${Timestamp}): Date {
|
|
508
509
|
let millis = (${toNumberCode} || 0) * 1_000;
|
|
509
510
|
millis += (t.nanos || 0) / 1_000_000;
|
|
510
|
-
return new Date(millis);
|
|
511
|
+
return new ${bytes.globalThis}.Date(millis);
|
|
511
512
|
}
|
|
512
513
|
`);
|
|
513
514
|
const fromJsonTimestamp = (0, ts_poet_1.conditionalOutput)("fromJsonTimestamp", options.useDate === options_1.DateOption.DATE
|
|
514
515
|
? (0, ts_poet_1.code) `
|
|
515
516
|
function fromJsonTimestamp(o: any): Date {
|
|
516
|
-
if (o instanceof Date) {
|
|
517
|
+
if (o instanceof ${bytes.globalThis}.Date) {
|
|
517
518
|
return o;
|
|
518
519
|
} else if (typeof o === "string") {
|
|
519
|
-
return new Date(o);
|
|
520
|
+
return new ${bytes.globalThis}.Date(o);
|
|
520
521
|
} else {
|
|
521
522
|
return ${fromTimestamp}(Timestamp.fromJSON(o));
|
|
522
523
|
}
|
|
@@ -524,10 +525,10 @@ function makeTimestampMethods(options, longs) {
|
|
|
524
525
|
`
|
|
525
526
|
: (0, ts_poet_1.code) `
|
|
526
527
|
function fromJsonTimestamp(o: any): Timestamp {
|
|
527
|
-
if (o instanceof Date) {
|
|
528
|
+
if (o instanceof ${bytes.globalThis}.Date) {
|
|
528
529
|
return ${toTimestamp}(o);
|
|
529
530
|
} else if (typeof o === "string") {
|
|
530
|
-
return ${toTimestamp}(new Date(o));
|
|
531
|
+
return ${toTimestamp}(new ${bytes.globalThis}.Date(o));
|
|
531
532
|
} else {
|
|
532
533
|
return Timestamp.fromJSON(o);
|
|
533
534
|
}
|
|
@@ -1399,9 +1400,9 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1399
1400
|
const canonicalFromJson = {
|
|
1400
1401
|
["google.protobuf.FieldMask"]: {
|
|
1401
1402
|
paths: (from) => (0, ts_poet_1.code) `typeof(${from}) === 'string'
|
|
1402
|
-
? ${from}.split(",").filter(Boolean)
|
|
1403
|
-
: Array.isArray(${from}?.paths)
|
|
1404
|
-
? ${from}.paths.map(String)
|
|
1403
|
+
? ${from}.split(",").filter(${ctx.utils.globalThis}.Boolean)
|
|
1404
|
+
: ${ctx.utils.globalThis}.Array.isArray(${from}?.paths)
|
|
1405
|
+
? ${from}.paths.map(${ctx.utils.globalThis}.String)
|
|
1405
1406
|
: []`,
|
|
1406
1407
|
},
|
|
1407
1408
|
};
|
|
@@ -1444,7 +1445,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1444
1445
|
return (0, ts_poet_1.code) `${utils.fromJsonObjectId}(${from})`;
|
|
1445
1446
|
}
|
|
1446
1447
|
else if ((0, types_1.isTimestamp)(field) && options.useDate === options_1.DateOption.STRING) {
|
|
1447
|
-
return (0, ts_poet_1.code)
|
|
1448
|
+
return (0, ts_poet_1.code) `${utils.globalThis}.String(${from})`;
|
|
1448
1449
|
}
|
|
1449
1450
|
else if ((0, types_1.isTimestamp)(field) &&
|
|
1450
1451
|
(options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.TIMESTAMP)) {
|
|
@@ -1507,7 +1508,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1507
1508
|
return (0, ts_poet_1.code) `${utils.fromJsonObjectId}(${from})`;
|
|
1508
1509
|
}
|
|
1509
1510
|
else if ((0, types_1.isTimestamp)(valueField) && options.useDate === options_1.DateOption.STRING) {
|
|
1510
|
-
return (0, ts_poet_1.code)
|
|
1511
|
+
return (0, ts_poet_1.code) `${utils.globalThis}.String(${from})`;
|
|
1511
1512
|
}
|
|
1512
1513
|
else if ((0, types_1.isTimestamp)(valueField) &&
|
|
1513
1514
|
(options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.TIMESTAMP)) {
|
|
@@ -1568,12 +1569,12 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1568
1569
|
const fallback = noDefaultValue ? "undefined" : "[]";
|
|
1569
1570
|
const readValueSnippet = readSnippet("e");
|
|
1570
1571
|
if (readValueSnippet.toString() === (0, ts_poet_1.code) `e`.toString()) {
|
|
1571
|
-
chunks.push((0, ts_poet_1.code) `${fieldName}: Array.isArray(${jsonPropertyOptional}) ? [...${jsonProperty}] : [],`);
|
|
1572
|
+
chunks.push((0, ts_poet_1.code) `${fieldName}: ${ctx.utils.globalThis}.Array.isArray(${jsonPropertyOptional}) ? [...${jsonProperty}] : [],`);
|
|
1572
1573
|
}
|
|
1573
1574
|
else {
|
|
1574
1575
|
// Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
|
|
1575
1576
|
chunks.push((0, ts_poet_1.code) `
|
|
1576
|
-
${fieldName}: Array.isArray(${jsonPropertyOptional}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): ${fallback},
|
|
1577
|
+
${fieldName}: ${ctx.utils.globalThis}.Array.isArray(${jsonPropertyOptional}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): ${fallback},
|
|
1577
1578
|
`);
|
|
1578
1579
|
}
|
|
1579
1580
|
}
|
|
@@ -1606,7 +1607,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1606
1607
|
}
|
|
1607
1608
|
else if ((0, types_1.isListValueType)(field)) {
|
|
1608
1609
|
chunks.push((0, ts_poet_1.code) `
|
|
1609
|
-
${fieldName}: Array.isArray(${jsonProperty})
|
|
1610
|
+
${fieldName}: ${ctx.utils.globalThis}.Array.isArray(${jsonProperty})
|
|
1610
1611
|
? ${readSnippet(`${jsonProperty}`)}
|
|
1611
1612
|
: undefined,
|
|
1612
1613
|
`);
|
|
@@ -1988,14 +1989,14 @@ function convertFromObjectKey(ctx, messageDesc, field, variableName) {
|
|
|
1988
1989
|
return (0, ts_poet_1.code) `BigInt(${variableName})`;
|
|
1989
1990
|
}
|
|
1990
1991
|
else if (ctx.options.forceLong === options_1.LongOption.STRING) {
|
|
1991
|
-
return (0, ts_poet_1.code)
|
|
1992
|
+
return (0, ts_poet_1.code) `${ctx.utils.globalThis}.String(${variableName})`;
|
|
1992
1993
|
}
|
|
1993
1994
|
else {
|
|
1994
|
-
return (0, ts_poet_1.code)
|
|
1995
|
+
return (0, ts_poet_1.code) `${ctx.utils.globalThis}.Number(${variableName})`;
|
|
1995
1996
|
}
|
|
1996
1997
|
}
|
|
1997
1998
|
else {
|
|
1998
|
-
return (0, ts_poet_1.code)
|
|
1999
|
+
return (0, ts_poet_1.code) `${ctx.utils.globalThis}.Number(${variableName})`;
|
|
1999
2000
|
}
|
|
2000
2001
|
}
|
|
2001
2002
|
function convertToObjectKey(ctx, messageDesc, field, variableName) {
|
package/build/options.js
CHANGED