@openfeature/flagd-provider 0.7.4 → 0.7.5

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/index.js CHANGED
@@ -1,12 +1,23 @@
1
1
  import * as grpc from '@grpc/grpc-js';
2
- import { GeneralError, FlagNotFoundError, TypeMismatchError, ParseError } from '@openfeature/js-sdk';
2
+ import { ParseError, GeneralError, FlagNotFoundError, TypeMismatchError, StandardResolutionReasons } from '@openfeature/js-sdk';
3
3
  import { GrpcTransport } from '@protobuf-ts/grpc-transport';
4
+ import LRU from 'lru-cache';
5
+ import { MessageType, isJsonObject, typeofJsonValue, reflectionMergePartial, UnknownFieldHandler, WireType, MESSAGE_TYPE } from '@protobuf-ts/runtime';
4
6
  import { ServiceType, stackIntercept } from '@protobuf-ts/runtime-rpc';
5
7
 
8
+ const BASE_EVENT_STREAM_RETRY_BACKOFF_MS = 1000;
9
+ const DEFAULT_MAX_EVENT_STREAM_RETRIES = 5;
10
+ const EVENT_CONFIGURATION_CHANGE = 'configuration_change';
11
+ const EVENT_PROVIDER_READY = 'provider_ready';
12
+ const DEFAULT_MAX_CACHE_SIZE = 1000;
13
+
6
14
  const DEFAULT_CONFIG = {
7
15
  host: 'localhost',
8
16
  port: 8013,
9
17
  tls: false,
18
+ cache: 'lru',
19
+ maxCacheSize: DEFAULT_MAX_CACHE_SIZE,
20
+ maxEventStreamRetries: DEFAULT_MAX_EVENT_STREAM_RETRIES,
10
21
  };
11
22
  var ENV_VAR;
12
23
  (function (ENV_VAR) {
@@ -14,10 +25,13 @@ var ENV_VAR;
14
25
  ENV_VAR["FLAGD_PORT"] = "FLAGD_PORT";
15
26
  ENV_VAR["FLAGD_TLS"] = "FLAGD_TLS";
16
27
  ENV_VAR["FLAGD_SOCKET_PATH"] = "FLAGD_SOCKET_PATH";
28
+ ENV_VAR["FLAGD_CACHE"] = "FLAGD_CACHE";
29
+ ENV_VAR["FLAGD_MAX_CACHE_SIZE"] = "FLAGD_MAX_CACHE_SIZE";
30
+ ENV_VAR["FLAGD_MAX_EVENT_STREAM_RETRIES"] = "FLAGD_MAX_EVENT_STREAM_RETRIES";
17
31
  })(ENV_VAR || (ENV_VAR = {}));
18
32
  const getEnvVarConfig = () => {
19
33
  var _a;
20
- return (Object.assign(Object.assign(Object.assign(Object.assign({}, (process.env[ENV_VAR.FLAGD_HOST] && {
34
+ return (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (process.env[ENV_VAR.FLAGD_HOST] && {
21
35
  host: process.env[ENV_VAR.FLAGD_HOST],
22
36
  })), (Number(process.env[ENV_VAR.FLAGD_PORT]) && {
23
37
  port: Number(process.env[ENV_VAR.FLAGD_PORT]),
@@ -25,6 +39,12 @@ const getEnvVarConfig = () => {
25
39
  tls: ((_a = process.env[ENV_VAR.FLAGD_TLS]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'true',
26
40
  })), (process.env[ENV_VAR.FLAGD_SOCKET_PATH] && {
27
41
  socketPath: process.env[ENV_VAR.FLAGD_SOCKET_PATH],
42
+ })), ((process.env[ENV_VAR.FLAGD_CACHE] === 'lru' || process.env[ENV_VAR.FLAGD_CACHE] === 'disabled') && {
43
+ cache: process.env[ENV_VAR.FLAGD_CACHE],
44
+ })), (process.env[ENV_VAR.FLAGD_MAX_CACHE_SIZE] && {
45
+ maxCacheSize: Number(process.env[ENV_VAR.FLAGD_MAX_CACHE_SIZE]),
46
+ })), (process.env[ENV_VAR.FLAGD_MAX_EVENT_STREAM_RETRIES] && {
47
+ maxEventStreamRetries: Number(process.env[ENV_VAR.FLAGD_MAX_EVENT_STREAM_RETRIES]),
28
48
  })));
29
49
  };
30
50
  function getConfig(options = {}) {
@@ -56,2928 +76,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
56
76
  });
57
77
  }
58
78
 
59
- /**
60
- * Get the type of a JSON value.
61
- * Distinguishes between array, null and object.
62
- */
63
- function typeofJsonValue(value) {
64
- let t = typeof value;
65
- if (t == "object") {
66
- if (Array.isArray(value))
67
- return "array";
68
- if (value === null)
69
- return "null";
70
- }
71
- return t;
72
- }
73
- /**
74
- * Is this a JSON object (instead of an array or null)?
75
- */
76
- function isJsonObject(value) {
77
- return value !== null && typeof value == "object" && !Array.isArray(value);
78
- }
79
-
80
- // lookup table from base64 character to byte
81
- let encTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
82
- // lookup table from base64 character *code* to byte because lookup by number is fast
83
- let decTable = [];
84
- for (let i = 0; i < encTable.length; i++)
85
- decTable[encTable[i].charCodeAt(0)] = i;
86
- // support base64url variants
87
- decTable["-".charCodeAt(0)] = encTable.indexOf("+");
88
- decTable["_".charCodeAt(0)] = encTable.indexOf("/");
89
- /**
90
- * Decodes a base64 string to a byte array.
91
- *
92
- * - ignores white-space, including line breaks and tabs
93
- * - allows inner padding (can decode concatenated base64 strings)
94
- * - does not require padding
95
- * - understands base64url encoding:
96
- * "-" instead of "+",
97
- * "_" instead of "/",
98
- * no padding
99
- */
100
- function base64decode(base64Str) {
101
- // estimate byte size, not accounting for inner padding and whitespace
102
- let es = base64Str.length * 3 / 4;
103
- // if (es % 3 !== 0)
104
- // throw new Error('invalid base64 string');
105
- if (base64Str[base64Str.length - 2] == '=')
106
- es -= 2;
107
- else if (base64Str[base64Str.length - 1] == '=')
108
- es -= 1;
109
- let bytes = new Uint8Array(es), bytePos = 0, // position in byte array
110
- groupPos = 0, // position in base64 group
111
- b, // current byte
112
- p = 0 // previous byte
113
- ;
114
- for (let i = 0; i < base64Str.length; i++) {
115
- b = decTable[base64Str.charCodeAt(i)];
116
- if (b === undefined) {
117
- // noinspection FallThroughInSwitchStatementJS
118
- switch (base64Str[i]) {
119
- case '=':
120
- groupPos = 0; // reset state when padding found
121
- case '\n':
122
- case '\r':
123
- case '\t':
124
- case ' ':
125
- continue; // skip white-space, and padding
126
- default:
127
- throw Error(`invalid base64 string.`);
128
- }
129
- }
130
- switch (groupPos) {
131
- case 0:
132
- p = b;
133
- groupPos = 1;
134
- break;
135
- case 1:
136
- bytes[bytePos++] = p << 2 | (b & 48) >> 4;
137
- p = b;
138
- groupPos = 2;
139
- break;
140
- case 2:
141
- bytes[bytePos++] = (p & 15) << 4 | (b & 60) >> 2;
142
- p = b;
143
- groupPos = 3;
144
- break;
145
- case 3:
146
- bytes[bytePos++] = (p & 3) << 6 | b;
147
- groupPos = 0;
148
- break;
149
- }
150
- }
151
- if (groupPos == 1)
152
- throw Error(`invalid base64 string.`);
153
- return bytes.subarray(0, bytePos);
154
- }
155
- /**
156
- * Encodes a byte array to a base64 string.
157
- * Adds padding at the end.
158
- * Does not insert newlines.
159
- */
160
- function base64encode(bytes) {
161
- let base64 = '', groupPos = 0, // position in base64 group
162
- b, // current byte
163
- p = 0; // carry over from previous byte
164
- for (let i = 0; i < bytes.length; i++) {
165
- b = bytes[i];
166
- switch (groupPos) {
167
- case 0:
168
- base64 += encTable[b >> 2];
169
- p = (b & 3) << 4;
170
- groupPos = 1;
171
- break;
172
- case 1:
173
- base64 += encTable[p | b >> 4];
174
- p = (b & 15) << 2;
175
- groupPos = 2;
176
- break;
177
- case 2:
178
- base64 += encTable[p | b >> 6];
179
- base64 += encTable[b & 63];
180
- groupPos = 0;
181
- break;
182
- }
183
- }
184
- // padding required?
185
- if (groupPos) {
186
- base64 += encTable[p];
187
- base64 += '=';
188
- if (groupPos == 1)
189
- base64 += '=';
190
- }
191
- return base64;
192
- }
193
-
194
- /**
195
- * This handler implements the default behaviour for unknown fields.
196
- * When reading data, unknown fields are stored on the message, in a
197
- * symbol property.
198
- * When writing data, the symbol property is queried and unknown fields
199
- * are serialized into the output again.
200
- */
201
- var UnknownFieldHandler;
202
- (function (UnknownFieldHandler) {
203
- /**
204
- * The symbol used to store unknown fields for a message.
205
- * The property must conform to `UnknownFieldContainer`.
206
- */
207
- UnknownFieldHandler.symbol = Symbol.for("protobuf-ts/unknown");
208
- /**
209
- * Store an unknown field during binary read directly on the message.
210
- * This method is compatible with `BinaryReadOptions.readUnknownField`.
211
- */
212
- UnknownFieldHandler.onRead = (typeName, message, fieldNo, wireType, data) => {
213
- let container = is(message) ? message[UnknownFieldHandler.symbol] : message[UnknownFieldHandler.symbol] = [];
214
- container.push({ no: fieldNo, wireType, data });
215
- };
216
- /**
217
- * Write unknown fields stored for the message to the writer.
218
- * This method is compatible with `BinaryWriteOptions.writeUnknownFields`.
219
- */
220
- UnknownFieldHandler.onWrite = (typeName, message, writer) => {
221
- for (let { no, wireType, data } of UnknownFieldHandler.list(message))
222
- writer.tag(no, wireType).raw(data);
223
- };
224
- /**
225
- * List unknown fields stored for the message.
226
- * Note that there may be multiples fields with the same number.
227
- */
228
- UnknownFieldHandler.list = (message, fieldNo) => {
229
- if (is(message)) {
230
- let all = message[UnknownFieldHandler.symbol];
231
- return fieldNo ? all.filter(uf => uf.no == fieldNo) : all;
232
- }
233
- return [];
234
- };
235
- /**
236
- * Returns the last unknown field by field number.
237
- */
238
- UnknownFieldHandler.last = (message, fieldNo) => UnknownFieldHandler.list(message, fieldNo).slice(-1)[0];
239
- const is = (message) => message && Array.isArray(message[UnknownFieldHandler.symbol]);
240
- })(UnknownFieldHandler || (UnknownFieldHandler = {}));
241
- /**
242
- * Protobuf binary format wire types.
243
- *
244
- * A wire type provides just enough information to find the length of the
245
- * following value.
246
- *
247
- * See https://developers.google.com/protocol-buffers/docs/encoding#structure
248
- */
249
- var WireType;
250
- (function (WireType) {
251
- /**
252
- * Used for int32, int64, uint32, uint64, sint32, sint64, bool, enum
253
- */
254
- WireType[WireType["Varint"] = 0] = "Varint";
255
- /**
256
- * Used for fixed64, sfixed64, double.
257
- * Always 8 bytes with little-endian byte order.
258
- */
259
- WireType[WireType["Bit64"] = 1] = "Bit64";
260
- /**
261
- * Used for string, bytes, embedded messages, packed repeated fields
262
- *
263
- * Only repeated numeric types (types which use the varint, 32-bit,
264
- * or 64-bit wire types) can be packed. In proto3, such fields are
265
- * packed by default.
266
- */
267
- WireType[WireType["LengthDelimited"] = 2] = "LengthDelimited";
268
- /**
269
- * Used for groups
270
- * @deprecated
271
- */
272
- WireType[WireType["StartGroup"] = 3] = "StartGroup";
273
- /**
274
- * Used for groups
275
- * @deprecated
276
- */
277
- WireType[WireType["EndGroup"] = 4] = "EndGroup";
278
- /**
279
- * Used for fixed32, sfixed32, float.
280
- * Always 4 bytes with little-endian byte order.
281
- */
282
- WireType[WireType["Bit32"] = 5] = "Bit32";
283
- })(WireType || (WireType = {}));
284
-
285
- // Copyright 2008 Google Inc. All rights reserved.
286
- //
287
- // Redistribution and use in source and binary forms, with or without
288
- // modification, are permitted provided that the following conditions are
289
- // met:
290
- //
291
- // * Redistributions of source code must retain the above copyright
292
- // notice, this list of conditions and the following disclaimer.
293
- // * Redistributions in binary form must reproduce the above
294
- // copyright notice, this list of conditions and the following disclaimer
295
- // in the documentation and/or other materials provided with the
296
- // distribution.
297
- // * Neither the name of Google Inc. nor the names of its
298
- // contributors may be used to endorse or promote products derived from
299
- // this software without specific prior written permission.
300
- //
301
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
303
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
304
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
305
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
306
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
307
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
308
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
309
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
310
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
311
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
312
- //
313
- // Code generated by the Protocol Buffer compiler is owned by the owner
314
- // of the input file used when generating it. This code is not
315
- // standalone and requires a support library to be linked with it. This
316
- // support library is itself covered by the above license.
317
- /**
318
- * Read a 64 bit varint as two JS numbers.
319
- *
320
- * Returns tuple:
321
- * [0]: low bits
322
- * [0]: high bits
323
- *
324
- * Copyright 2008 Google Inc. All rights reserved.
325
- *
326
- * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/buffer_decoder.js#L175
327
- */
328
- function varint64read() {
329
- let lowBits = 0;
330
- let highBits = 0;
331
- for (let shift = 0; shift < 28; shift += 7) {
332
- let b = this.buf[this.pos++];
333
- lowBits |= (b & 0x7F) << shift;
334
- if ((b & 0x80) == 0) {
335
- this.assertBounds();
336
- return [lowBits, highBits];
337
- }
338
- }
339
- let middleByte = this.buf[this.pos++];
340
- // last four bits of the first 32 bit number
341
- lowBits |= (middleByte & 0x0F) << 28;
342
- // 3 upper bits are part of the next 32 bit number
343
- highBits = (middleByte & 0x70) >> 4;
344
- if ((middleByte & 0x80) == 0) {
345
- this.assertBounds();
346
- return [lowBits, highBits];
347
- }
348
- for (let shift = 3; shift <= 31; shift += 7) {
349
- let b = this.buf[this.pos++];
350
- highBits |= (b & 0x7F) << shift;
351
- if ((b & 0x80) == 0) {
352
- this.assertBounds();
353
- return [lowBits, highBits];
354
- }
355
- }
356
- throw new Error('invalid varint');
357
- }
358
- /**
359
- * Write a 64 bit varint, given as two JS numbers, to the given bytes array.
360
- *
361
- * Copyright 2008 Google Inc. All rights reserved.
362
- *
363
- * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/writer.js#L344
364
- */
365
- function varint64write(lo, hi, bytes) {
366
- for (let i = 0; i < 28; i = i + 7) {
367
- const shift = lo >>> i;
368
- const hasNext = !((shift >>> 7) == 0 && hi == 0);
369
- const byte = (hasNext ? shift | 0x80 : shift) & 0xFF;
370
- bytes.push(byte);
371
- if (!hasNext) {
372
- return;
373
- }
374
- }
375
- const splitBits = ((lo >>> 28) & 0x0F) | ((hi & 0x07) << 4);
376
- const hasMoreBits = !((hi >> 3) == 0);
377
- bytes.push((hasMoreBits ? splitBits | 0x80 : splitBits) & 0xFF);
378
- if (!hasMoreBits) {
379
- return;
380
- }
381
- for (let i = 3; i < 31; i = i + 7) {
382
- const shift = hi >>> i;
383
- const hasNext = !((shift >>> 7) == 0);
384
- const byte = (hasNext ? shift | 0x80 : shift) & 0xFF;
385
- bytes.push(byte);
386
- if (!hasNext) {
387
- return;
388
- }
389
- }
390
- bytes.push((hi >>> 31) & 0x01);
391
- }
392
- // constants for binary math
393
- const TWO_PWR_32_DBL$1 = (1 << 16) * (1 << 16);
394
- /**
395
- * Parse decimal string of 64 bit integer value as two JS numbers.
396
- *
397
- * Returns tuple:
398
- * [0]: minus sign?
399
- * [1]: low bits
400
- * [2]: high bits
401
- *
402
- * Copyright 2008 Google Inc.
403
- */
404
- function int64fromString(dec) {
405
- // Check for minus sign.
406
- let minus = dec[0] == '-';
407
- if (minus)
408
- dec = dec.slice(1);
409
- // Work 6 decimal digits at a time, acting like we're converting base 1e6
410
- // digits to binary. This is safe to do with floating point math because
411
- // Number.isSafeInteger(ALL_32_BITS * 1e6) == true.
412
- const base = 1e6;
413
- let lowBits = 0;
414
- let highBits = 0;
415
- function add1e6digit(begin, end) {
416
- // Note: Number('') is 0.
417
- const digit1e6 = Number(dec.slice(begin, end));
418
- highBits *= base;
419
- lowBits = lowBits * base + digit1e6;
420
- // Carry bits from lowBits to
421
- if (lowBits >= TWO_PWR_32_DBL$1) {
422
- highBits = highBits + ((lowBits / TWO_PWR_32_DBL$1) | 0);
423
- lowBits = lowBits % TWO_PWR_32_DBL$1;
424
- }
425
- }
426
- add1e6digit(-24, -18);
427
- add1e6digit(-18, -12);
428
- add1e6digit(-12, -6);
429
- add1e6digit(-6);
430
- return [minus, lowBits, highBits];
431
- }
432
- /**
433
- * Format 64 bit integer value (as two JS numbers) to decimal string.
434
- *
435
- * Copyright 2008 Google Inc.
436
- */
437
- function int64toString(bitsLow, bitsHigh) {
438
- // Skip the expensive conversion if the number is small enough to use the
439
- // built-in conversions.
440
- if (bitsHigh <= 0x1FFFFF) {
441
- return '' + (TWO_PWR_32_DBL$1 * bitsHigh + (bitsLow >>> 0));
442
- }
443
- // What this code is doing is essentially converting the input number from
444
- // base-2 to base-1e7, which allows us to represent the 64-bit range with
445
- // only 3 (very large) digits. Those digits are then trivial to convert to
446
- // a base-10 string.
447
- // The magic numbers used here are -
448
- // 2^24 = 16777216 = (1,6777216) in base-1e7.
449
- // 2^48 = 281474976710656 = (2,8147497,6710656) in base-1e7.
450
- // Split 32:32 representation into 16:24:24 representation so our
451
- // intermediate digits don't overflow.
452
- let low = bitsLow & 0xFFFFFF;
453
- let mid = (((bitsLow >>> 24) | (bitsHigh << 8)) >>> 0) & 0xFFFFFF;
454
- let high = (bitsHigh >> 16) & 0xFFFF;
455
- // Assemble our three base-1e7 digits, ignoring carries. The maximum
456
- // value in a digit at this step is representable as a 48-bit integer, which
457
- // can be stored in a 64-bit floating point number.
458
- let digitA = low + (mid * 6777216) + (high * 6710656);
459
- let digitB = mid + (high * 8147497);
460
- let digitC = (high * 2);
461
- // Apply carries from A to B and from B to C.
462
- let base = 10000000;
463
- if (digitA >= base) {
464
- digitB += Math.floor(digitA / base);
465
- digitA %= base;
466
- }
467
- if (digitB >= base) {
468
- digitC += Math.floor(digitB / base);
469
- digitB %= base;
470
- }
471
- // Convert base-1e7 digits to base-10, with optional leading zeroes.
472
- function decimalFrom1e7(digit1e7, needLeadingZeros) {
473
- let partial = digit1e7 ? String(digit1e7) : '';
474
- if (needLeadingZeros) {
475
- return '0000000'.slice(partial.length) + partial;
476
- }
477
- return partial;
478
- }
479
- return decimalFrom1e7(digitC, /*needLeadingZeros=*/ 0) +
480
- decimalFrom1e7(digitB, /*needLeadingZeros=*/ digitC) +
481
- // If the final 1e7 digit didn't need leading zeros, we would have
482
- // returned via the trivial code path at the top.
483
- decimalFrom1e7(digitA, /*needLeadingZeros=*/ 1);
484
- }
485
- /**
486
- * Write a 32 bit varint, signed or unsigned. Same as `varint64write(0, value, bytes)`
487
- *
488
- * Copyright 2008 Google Inc. All rights reserved.
489
- *
490
- * See https://github.com/protocolbuffers/protobuf/blob/1b18833f4f2a2f681f4e4a25cdf3b0a43115ec26/js/binary/encoder.js#L144
491
- */
492
- function varint32write(value, bytes) {
493
- if (value >= 0) {
494
- // write value as varint 32
495
- while (value > 0x7f) {
496
- bytes.push((value & 0x7f) | 0x80);
497
- value = value >>> 7;
498
- }
499
- bytes.push(value);
500
- }
501
- else {
502
- for (let i = 0; i < 9; i++) {
503
- bytes.push(value & 127 | 128);
504
- value = value >> 7;
505
- }
506
- bytes.push(1);
507
- }
508
- }
509
- /**
510
- * Read an unsigned 32 bit varint.
511
- *
512
- * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/buffer_decoder.js#L220
513
- */
514
- function varint32read() {
515
- let b = this.buf[this.pos++];
516
- let result = b & 0x7F;
517
- if ((b & 0x80) == 0) {
518
- this.assertBounds();
519
- return result;
520
- }
521
- b = this.buf[this.pos++];
522
- result |= (b & 0x7F) << 7;
523
- if ((b & 0x80) == 0) {
524
- this.assertBounds();
525
- return result;
526
- }
527
- b = this.buf[this.pos++];
528
- result |= (b & 0x7F) << 14;
529
- if ((b & 0x80) == 0) {
530
- this.assertBounds();
531
- return result;
532
- }
533
- b = this.buf[this.pos++];
534
- result |= (b & 0x7F) << 21;
535
- if ((b & 0x80) == 0) {
536
- this.assertBounds();
537
- return result;
538
- }
539
- // Extract only last 4 bits
540
- b = this.buf[this.pos++];
541
- result |= (b & 0x0F) << 28;
542
- for (let readBytes = 5; ((b & 0x80) !== 0) && readBytes < 10; readBytes++)
543
- b = this.buf[this.pos++];
544
- if ((b & 0x80) != 0)
545
- throw new Error('invalid varint');
546
- this.assertBounds();
547
- // Result can have 32 bits, convert it to unsigned
548
- return result >>> 0;
549
- }
550
-
551
- function detectBi() {
552
- const dv = new DataView(new ArrayBuffer(8));
553
- const ok = globalThis.BigInt !== undefined
554
- && typeof dv.getBigInt64 === "function"
555
- && typeof dv.getBigUint64 === "function"
556
- && typeof dv.setBigInt64 === "function"
557
- && typeof dv.setBigUint64 === "function";
558
- return ok ? {
559
- MIN: BigInt("-9223372036854775808"),
560
- MAX: BigInt("9223372036854775807"),
561
- UMIN: BigInt("0"),
562
- UMAX: BigInt("18446744073709551615"),
563
- C: BigInt,
564
- V: dv,
565
- } : undefined;
566
- }
567
- const BI = detectBi();
568
- function assertBi(bi) {
569
- if (!bi)
570
- throw new Error("BigInt unavailable, see https://github.com/timostamm/protobuf-ts/blob/v1.0.8/MANUAL.md#bigint-support");
571
- }
572
- // used to validate from(string) input (when bigint is unavailable)
573
- const RE_DECIMAL_STR = /^-?[0-9]+$/;
574
- // constants for binary math
575
- const TWO_PWR_32_DBL = (1 << 16) * (1 << 16);
576
- // base class for PbLong and PbULong provides shared code
577
- class SharedPbLong {
578
- /**
579
- * Create a new instance with the given bits.
580
- */
581
- constructor(lo, hi) {
582
- this.lo = lo | 0;
583
- this.hi = hi | 0;
584
- }
585
- /**
586
- * Is this instance equal to 0?
587
- */
588
- isZero() {
589
- return this.lo == 0 && this.hi == 0;
590
- }
591
- /**
592
- * Convert to a native number.
593
- */
594
- toNumber() {
595
- let result = this.hi * TWO_PWR_32_DBL + (this.lo >>> 0);
596
- if (!Number.isSafeInteger(result))
597
- throw new Error("cannot convert to safe number");
598
- return result;
599
- }
600
- }
601
- /**
602
- * 64-bit unsigned integer as two 32-bit values.
603
- * Converts between `string`, `number` and `bigint` representations.
604
- */
605
- class PbULong extends SharedPbLong {
606
- /**
607
- * Create instance from a `string`, `number` or `bigint`.
608
- */
609
- static from(value) {
610
- if (BI)
611
- // noinspection FallThroughInSwitchStatementJS
612
- switch (typeof value) {
613
- case "string":
614
- if (value == "0")
615
- return this.ZERO;
616
- if (value == "")
617
- throw new Error('string is no integer');
618
- value = BI.C(value);
619
- case "number":
620
- if (value === 0)
621
- return this.ZERO;
622
- value = BI.C(value);
623
- case "bigint":
624
- if (!value)
625
- return this.ZERO;
626
- if (value < BI.UMIN)
627
- throw new Error('signed value for ulong');
628
- if (value > BI.UMAX)
629
- throw new Error('ulong too large');
630
- BI.V.setBigUint64(0, value, true);
631
- return new PbULong(BI.V.getInt32(0, true), BI.V.getInt32(4, true));
632
- }
633
- else
634
- switch (typeof value) {
635
- case "string":
636
- if (value == "0")
637
- return this.ZERO;
638
- value = value.trim();
639
- if (!RE_DECIMAL_STR.test(value))
640
- throw new Error('string is no integer');
641
- let [minus, lo, hi] = int64fromString(value);
642
- if (minus)
643
- throw new Error('signed value');
644
- return new PbULong(lo, hi);
645
- case "number":
646
- if (value == 0)
647
- return this.ZERO;
648
- if (!Number.isSafeInteger(value))
649
- throw new Error('number is no integer');
650
- if (value < 0)
651
- throw new Error('signed value for ulong');
652
- return new PbULong(value, value / TWO_PWR_32_DBL);
653
- }
654
- throw new Error('unknown value ' + typeof value);
655
- }
656
- /**
657
- * Convert to decimal string.
658
- */
659
- toString() {
660
- return BI ? this.toBigInt().toString() : int64toString(this.lo, this.hi);
661
- }
662
- /**
663
- * Convert to native bigint.
664
- */
665
- toBigInt() {
666
- assertBi(BI);
667
- BI.V.setInt32(0, this.lo, true);
668
- BI.V.setInt32(4, this.hi, true);
669
- return BI.V.getBigUint64(0, true);
670
- }
671
- }
672
- /**
673
- * ulong 0 singleton.
674
- */
675
- PbULong.ZERO = new PbULong(0, 0);
676
- /**
677
- * 64-bit signed integer as two 32-bit values.
678
- * Converts between `string`, `number` and `bigint` representations.
679
- */
680
- class PbLong extends SharedPbLong {
681
- /**
682
- * Create instance from a `string`, `number` or `bigint`.
683
- */
684
- static from(value) {
685
- if (BI)
686
- // noinspection FallThroughInSwitchStatementJS
687
- switch (typeof value) {
688
- case "string":
689
- if (value == "0")
690
- return this.ZERO;
691
- if (value == "")
692
- throw new Error('string is no integer');
693
- value = BI.C(value);
694
- case "number":
695
- if (value === 0)
696
- return this.ZERO;
697
- value = BI.C(value);
698
- case "bigint":
699
- if (!value)
700
- return this.ZERO;
701
- if (value < BI.MIN)
702
- throw new Error('ulong too small');
703
- if (value > BI.MAX)
704
- throw new Error('ulong too large');
705
- BI.V.setBigInt64(0, value, true);
706
- return new PbLong(BI.V.getInt32(0, true), BI.V.getInt32(4, true));
707
- }
708
- else
709
- switch (typeof value) {
710
- case "string":
711
- if (value == "0")
712
- return this.ZERO;
713
- value = value.trim();
714
- if (!RE_DECIMAL_STR.test(value))
715
- throw new Error('string is no integer');
716
- let [minus, lo, hi] = int64fromString(value);
717
- let pbl = new PbLong(lo, hi);
718
- return minus ? pbl.negate() : pbl;
719
- case "number":
720
- if (value == 0)
721
- return this.ZERO;
722
- if (!Number.isSafeInteger(value))
723
- throw new Error('number is no integer');
724
- return value > 0
725
- ? new PbLong(value, value / TWO_PWR_32_DBL)
726
- : new PbLong(-value, -value / TWO_PWR_32_DBL).negate();
727
- }
728
- throw new Error('unknown value ' + typeof value);
729
- }
730
- /**
731
- * Do we have a minus sign?
732
- */
733
- isNegative() {
734
- return (this.hi & 0x80000000) !== 0;
735
- }
736
- /**
737
- * Negate two's complement.
738
- * Invert all the bits and add one to the result.
739
- */
740
- negate() {
741
- let hi = ~this.hi, lo = this.lo;
742
- if (lo)
743
- lo = ~lo + 1;
744
- else
745
- hi += 1;
746
- return new PbLong(lo, hi);
747
- }
748
- /**
749
- * Convert to decimal string.
750
- */
751
- toString() {
752
- if (BI)
753
- return this.toBigInt().toString();
754
- if (this.isNegative()) {
755
- let n = this.negate();
756
- return '-' + int64toString(n.lo, n.hi);
757
- }
758
- return int64toString(this.lo, this.hi);
759
- }
760
- /**
761
- * Convert to native bigint.
762
- */
763
- toBigInt() {
764
- assertBi(BI);
765
- BI.V.setInt32(0, this.lo, true);
766
- BI.V.setInt32(4, this.hi, true);
767
- return BI.V.getBigInt64(0, true);
768
- }
769
- }
770
- /**
771
- * long 0 singleton.
772
- */
773
- PbLong.ZERO = new PbLong(0, 0);
774
-
775
- const defaultsRead$1 = {
776
- readUnknownField: true,
777
- readerFactory: bytes => new BinaryReader(bytes),
778
- };
779
- /**
780
- * Make options for reading binary data form partial options.
781
- */
782
- function binaryReadOptions(options) {
783
- return options ? Object.assign(Object.assign({}, defaultsRead$1), options) : defaultsRead$1;
784
- }
785
- class BinaryReader {
786
- constructor(buf, textDecoder) {
787
- this.varint64 = varint64read; // dirty cast for `this`
788
- /**
789
- * Read a `uint32` field, an unsigned 32 bit varint.
790
- */
791
- this.uint32 = varint32read; // dirty cast for `this` and access to protected `buf`
792
- this.buf = buf;
793
- this.len = buf.length;
794
- this.pos = 0;
795
- this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
796
- this.textDecoder = textDecoder !== null && textDecoder !== void 0 ? textDecoder : new TextDecoder("utf-8", {
797
- fatal: true,
798
- ignoreBOM: true,
799
- });
800
- }
801
- /**
802
- * Reads a tag - field number and wire type.
803
- */
804
- tag() {
805
- let tag = this.uint32(), fieldNo = tag >>> 3, wireType = tag & 7;
806
- if (fieldNo <= 0 || wireType < 0 || wireType > 5)
807
- throw new Error("illegal tag: field no " + fieldNo + " wire type " + wireType);
808
- return [fieldNo, wireType];
809
- }
810
- /**
811
- * Skip one element on the wire and return the skipped data.
812
- * Supports WireType.StartGroup since v2.0.0-alpha.23.
813
- */
814
- skip(wireType) {
815
- let start = this.pos;
816
- // noinspection FallThroughInSwitchStatementJS
817
- switch (wireType) {
818
- case WireType.Varint:
819
- while (this.buf[this.pos++] & 0x80) {
820
- // ignore
821
- }
822
- break;
823
- case WireType.Bit64:
824
- this.pos += 4;
825
- case WireType.Bit32:
826
- this.pos += 4;
827
- break;
828
- case WireType.LengthDelimited:
829
- let len = this.uint32();
830
- this.pos += len;
831
- break;
832
- case WireType.StartGroup:
833
- // From descriptor.proto: Group type is deprecated, not supported in proto3.
834
- // But we must still be able to parse and treat as unknown.
835
- let t;
836
- while ((t = this.tag()[1]) !== WireType.EndGroup) {
837
- this.skip(t);
838
- }
839
- break;
840
- default:
841
- throw new Error("cant skip wire type " + wireType);
842
- }
843
- this.assertBounds();
844
- return this.buf.subarray(start, this.pos);
845
- }
846
- /**
847
- * Throws error if position in byte array is out of range.
848
- */
849
- assertBounds() {
850
- if (this.pos > this.len)
851
- throw new RangeError("premature EOF");
852
- }
853
- /**
854
- * Read a `int32` field, a signed 32 bit varint.
855
- */
856
- int32() {
857
- return this.uint32() | 0;
858
- }
859
- /**
860
- * Read a `sint32` field, a signed, zigzag-encoded 32-bit varint.
861
- */
862
- sint32() {
863
- let zze = this.uint32();
864
- // decode zigzag
865
- return (zze >>> 1) ^ -(zze & 1);
866
- }
867
- /**
868
- * Read a `int64` field, a signed 64-bit varint.
869
- */
870
- int64() {
871
- return new PbLong(...this.varint64());
872
- }
873
- /**
874
- * Read a `uint64` field, an unsigned 64-bit varint.
875
- */
876
- uint64() {
877
- return new PbULong(...this.varint64());
878
- }
879
- /**
880
- * Read a `sint64` field, a signed, zig-zag-encoded 64-bit varint.
881
- */
882
- sint64() {
883
- let [lo, hi] = this.varint64();
884
- // decode zig zag
885
- let s = -(lo & 1);
886
- lo = ((lo >>> 1 | (hi & 1) << 31) ^ s);
887
- hi = (hi >>> 1 ^ s);
888
- return new PbLong(lo, hi);
889
- }
890
- /**
891
- * Read a `bool` field, a variant.
892
- */
893
- bool() {
894
- let [lo, hi] = this.varint64();
895
- return lo !== 0 || hi !== 0;
896
- }
897
- /**
898
- * Read a `fixed32` field, an unsigned, fixed-length 32-bit integer.
899
- */
900
- fixed32() {
901
- return this.view.getUint32((this.pos += 4) - 4, true);
902
- }
903
- /**
904
- * Read a `sfixed32` field, a signed, fixed-length 32-bit integer.
905
- */
906
- sfixed32() {
907
- return this.view.getInt32((this.pos += 4) - 4, true);
908
- }
909
- /**
910
- * Read a `fixed64` field, an unsigned, fixed-length 64 bit integer.
911
- */
912
- fixed64() {
913
- return new PbULong(this.sfixed32(), this.sfixed32());
914
- }
915
- /**
916
- * Read a `fixed64` field, a signed, fixed-length 64-bit integer.
917
- */
918
- sfixed64() {
919
- return new PbLong(this.sfixed32(), this.sfixed32());
920
- }
921
- /**
922
- * Read a `float` field, 32-bit floating point number.
923
- */
924
- float() {
925
- return this.view.getFloat32((this.pos += 4) - 4, true);
926
- }
927
- /**
928
- * Read a `double` field, a 64-bit floating point number.
929
- */
930
- double() {
931
- return this.view.getFloat64((this.pos += 8) - 8, true);
932
- }
933
- /**
934
- * Read a `bytes` field, length-delimited arbitrary data.
935
- */
936
- bytes() {
937
- let len = this.uint32();
938
- let start = this.pos;
939
- this.pos += len;
940
- this.assertBounds();
941
- return this.buf.subarray(start, start + len);
942
- }
943
- /**
944
- * Read a `string` field, length-delimited data converted to UTF-8 text.
945
- */
946
- string() {
947
- return this.textDecoder.decode(this.bytes());
948
- }
949
- }
950
-
951
- /**
952
- * assert that condition is true or throw error (with message)
953
- */
954
- function assert(condition, msg) {
955
- if (!condition) {
956
- throw new Error(msg);
957
- }
958
- }
959
- const FLOAT32_MAX = 3.4028234663852886e+38, FLOAT32_MIN = -3.4028234663852886e+38, UINT32_MAX = 0xFFFFFFFF, INT32_MAX = 0X7FFFFFFF, INT32_MIN = -0X80000000;
960
- function assertInt32(arg) {
961
- if (typeof arg !== "number")
962
- throw new Error('invalid int 32: ' + typeof arg);
963
- if (!Number.isInteger(arg) || arg > INT32_MAX || arg < INT32_MIN)
964
- throw new Error('invalid int 32: ' + arg);
965
- }
966
- function assertUInt32(arg) {
967
- if (typeof arg !== "number")
968
- throw new Error('invalid uint 32: ' + typeof arg);
969
- if (!Number.isInteger(arg) || arg > UINT32_MAX || arg < 0)
970
- throw new Error('invalid uint 32: ' + arg);
971
- }
972
- function assertFloat32(arg) {
973
- if (typeof arg !== "number")
974
- throw new Error('invalid float 32: ' + typeof arg);
975
- if (!Number.isFinite(arg))
976
- return;
977
- if (arg > FLOAT32_MAX || arg < FLOAT32_MIN)
978
- throw new Error('invalid float 32: ' + arg);
979
- }
980
-
981
- const defaultsWrite$1 = {
982
- writeUnknownFields: true,
983
- writerFactory: () => new BinaryWriter(),
984
- };
985
- /**
986
- * Make options for writing binary data form partial options.
987
- */
988
- function binaryWriteOptions(options) {
989
- return options ? Object.assign(Object.assign({}, defaultsWrite$1), options) : defaultsWrite$1;
990
- }
991
- class BinaryWriter {
992
- constructor(textEncoder) {
993
- /**
994
- * Previous fork states.
995
- */
996
- this.stack = [];
997
- this.textEncoder = textEncoder !== null && textEncoder !== void 0 ? textEncoder : new TextEncoder();
998
- this.chunks = [];
999
- this.buf = [];
1000
- }
1001
- /**
1002
- * Return all bytes written and reset this writer.
1003
- */
1004
- finish() {
1005
- this.chunks.push(new Uint8Array(this.buf)); // flush the buffer
1006
- let len = 0;
1007
- for (let i = 0; i < this.chunks.length; i++)
1008
- len += this.chunks[i].length;
1009
- let bytes = new Uint8Array(len);
1010
- let offset = 0;
1011
- for (let i = 0; i < this.chunks.length; i++) {
1012
- bytes.set(this.chunks[i], offset);
1013
- offset += this.chunks[i].length;
1014
- }
1015
- this.chunks = [];
1016
- return bytes;
1017
- }
1018
- /**
1019
- * Start a new fork for length-delimited data like a message
1020
- * or a packed repeated field.
1021
- *
1022
- * Must be joined later with `join()`.
1023
- */
1024
- fork() {
1025
- this.stack.push({ chunks: this.chunks, buf: this.buf });
1026
- this.chunks = [];
1027
- this.buf = [];
1028
- return this;
1029
- }
1030
- /**
1031
- * Join the last fork. Write its length and bytes, then
1032
- * return to the previous state.
1033
- */
1034
- join() {
1035
- // get chunk of fork
1036
- let chunk = this.finish();
1037
- // restore previous state
1038
- let prev = this.stack.pop();
1039
- if (!prev)
1040
- throw new Error('invalid state, fork stack empty');
1041
- this.chunks = prev.chunks;
1042
- this.buf = prev.buf;
1043
- // write length of chunk as varint
1044
- this.uint32(chunk.byteLength);
1045
- return this.raw(chunk);
1046
- }
1047
- /**
1048
- * Writes a tag (field number and wire type).
1049
- *
1050
- * Equivalent to `uint32( (fieldNo << 3 | type) >>> 0 )`.
1051
- *
1052
- * Generated code should compute the tag ahead of time and call `uint32()`.
1053
- */
1054
- tag(fieldNo, type) {
1055
- return this.uint32((fieldNo << 3 | type) >>> 0);
1056
- }
1057
- /**
1058
- * Write a chunk of raw bytes.
1059
- */
1060
- raw(chunk) {
1061
- if (this.buf.length) {
1062
- this.chunks.push(new Uint8Array(this.buf));
1063
- this.buf = [];
1064
- }
1065
- this.chunks.push(chunk);
1066
- return this;
1067
- }
1068
- /**
1069
- * Write a `uint32` value, an unsigned 32 bit varint.
1070
- */
1071
- uint32(value) {
1072
- assertUInt32(value);
1073
- // write value as varint 32, inlined for speed
1074
- while (value > 0x7f) {
1075
- this.buf.push((value & 0x7f) | 0x80);
1076
- value = value >>> 7;
1077
- }
1078
- this.buf.push(value);
1079
- return this;
1080
- }
1081
- /**
1082
- * Write a `int32` value, a signed 32 bit varint.
1083
- */
1084
- int32(value) {
1085
- assertInt32(value);
1086
- varint32write(value, this.buf);
1087
- return this;
1088
- }
1089
- /**
1090
- * Write a `bool` value, a variant.
1091
- */
1092
- bool(value) {
1093
- this.buf.push(value ? 1 : 0);
1094
- return this;
1095
- }
1096
- /**
1097
- * Write a `bytes` value, length-delimited arbitrary data.
1098
- */
1099
- bytes(value) {
1100
- this.uint32(value.byteLength); // write length of chunk as varint
1101
- return this.raw(value);
1102
- }
1103
- /**
1104
- * Write a `string` value, length-delimited data converted to UTF-8 text.
1105
- */
1106
- string(value) {
1107
- let chunk = this.textEncoder.encode(value);
1108
- this.uint32(chunk.byteLength); // write length of chunk as varint
1109
- return this.raw(chunk);
1110
- }
1111
- /**
1112
- * Write a `float` value, 32-bit floating point number.
1113
- */
1114
- float(value) {
1115
- assertFloat32(value);
1116
- let chunk = new Uint8Array(4);
1117
- new DataView(chunk.buffer).setFloat32(0, value, true);
1118
- return this.raw(chunk);
1119
- }
1120
- /**
1121
- * Write a `double` value, a 64-bit floating point number.
1122
- */
1123
- double(value) {
1124
- let chunk = new Uint8Array(8);
1125
- new DataView(chunk.buffer).setFloat64(0, value, true);
1126
- return this.raw(chunk);
1127
- }
1128
- /**
1129
- * Write a `fixed32` value, an unsigned, fixed-length 32-bit integer.
1130
- */
1131
- fixed32(value) {
1132
- assertUInt32(value);
1133
- let chunk = new Uint8Array(4);
1134
- new DataView(chunk.buffer).setUint32(0, value, true);
1135
- return this.raw(chunk);
1136
- }
1137
- /**
1138
- * Write a `sfixed32` value, a signed, fixed-length 32-bit integer.
1139
- */
1140
- sfixed32(value) {
1141
- assertInt32(value);
1142
- let chunk = new Uint8Array(4);
1143
- new DataView(chunk.buffer).setInt32(0, value, true);
1144
- return this.raw(chunk);
1145
- }
1146
- /**
1147
- * Write a `sint32` value, a signed, zigzag-encoded 32-bit varint.
1148
- */
1149
- sint32(value) {
1150
- assertInt32(value);
1151
- // zigzag encode
1152
- value = ((value << 1) ^ (value >> 31)) >>> 0;
1153
- varint32write(value, this.buf);
1154
- return this;
1155
- }
1156
- /**
1157
- * Write a `fixed64` value, a signed, fixed-length 64-bit integer.
1158
- */
1159
- sfixed64(value) {
1160
- let chunk = new Uint8Array(8);
1161
- let view = new DataView(chunk.buffer);
1162
- let long = PbLong.from(value);
1163
- view.setInt32(0, long.lo, true);
1164
- view.setInt32(4, long.hi, true);
1165
- return this.raw(chunk);
1166
- }
1167
- /**
1168
- * Write a `fixed64` value, an unsigned, fixed-length 64 bit integer.
1169
- */
1170
- fixed64(value) {
1171
- let chunk = new Uint8Array(8);
1172
- let view = new DataView(chunk.buffer);
1173
- let long = PbULong.from(value);
1174
- view.setInt32(0, long.lo, true);
1175
- view.setInt32(4, long.hi, true);
1176
- return this.raw(chunk);
1177
- }
1178
- /**
1179
- * Write a `int64` value, a signed 64-bit varint.
1180
- */
1181
- int64(value) {
1182
- let long = PbLong.from(value);
1183
- varint64write(long.lo, long.hi, this.buf);
1184
- return this;
1185
- }
1186
- /**
1187
- * Write a `sint64` value, a signed, zig-zag-encoded 64-bit varint.
1188
- */
1189
- sint64(value) {
1190
- let long = PbLong.from(value),
1191
- // zigzag encode
1192
- sign = long.hi >> 31, lo = (long.lo << 1) ^ sign, hi = ((long.hi << 1) | (long.lo >>> 31)) ^ sign;
1193
- varint64write(lo, hi, this.buf);
1194
- return this;
1195
- }
1196
- /**
1197
- * Write a `uint64` value, an unsigned 64-bit varint.
1198
- */
1199
- uint64(value) {
1200
- let long = PbULong.from(value);
1201
- varint64write(long.lo, long.hi, this.buf);
1202
- return this;
1203
- }
1204
- }
1205
-
1206
- const defaultsWrite = {
1207
- emitDefaultValues: false,
1208
- enumAsInteger: false,
1209
- useProtoFieldName: false,
1210
- prettySpaces: 0,
1211
- }, defaultsRead = {
1212
- ignoreUnknownFields: false,
1213
- };
1214
- /**
1215
- * Make options for reading JSON data from partial options.
1216
- */
1217
- function jsonReadOptions(options) {
1218
- return options ? Object.assign(Object.assign({}, defaultsRead), options) : defaultsRead;
1219
- }
1220
- /**
1221
- * Make options for writing JSON data from partial options.
1222
- */
1223
- function jsonWriteOptions(options) {
1224
- return options ? Object.assign(Object.assign({}, defaultsWrite), options) : defaultsWrite;
1225
- }
1226
-
1227
- /**
1228
- * The symbol used as a key on message objects to store the message type.
1229
- *
1230
- * Note that this is an experimental feature - it is here to stay, but
1231
- * implementation details may change without notice.
1232
- */
1233
- const MESSAGE_TYPE = Symbol.for("protobuf-ts/message-type");
1234
-
1235
- /**
1236
- * Converts snake_case to lowerCamelCase.
1237
- *
1238
- * Should behave like protoc:
1239
- * https://github.com/protocolbuffers/protobuf/blob/e8ae137c96444ea313485ed1118c5e43b2099cf1/src/google/protobuf/compiler/java/java_helpers.cc#L118
1240
- */
1241
- function lowerCamelCase(snakeCase) {
1242
- let capNext = false;
1243
- const sb = [];
1244
- for (let i = 0; i < snakeCase.length; i++) {
1245
- let next = snakeCase.charAt(i);
1246
- if (next == '_') {
1247
- capNext = true;
1248
- }
1249
- else if (/\d/.test(next)) {
1250
- sb.push(next);
1251
- capNext = true;
1252
- }
1253
- else if (capNext) {
1254
- sb.push(next.toUpperCase());
1255
- capNext = false;
1256
- }
1257
- else if (i == 0) {
1258
- sb.push(next.toLowerCase());
1259
- }
1260
- else {
1261
- sb.push(next);
1262
- }
1263
- }
1264
- return sb.join('');
1265
- }
1266
-
1267
- /**
1268
- * Scalar value types. This is a subset of field types declared by protobuf
1269
- * enum google.protobuf.FieldDescriptorProto.Type The types GROUP and MESSAGE
1270
- * are omitted, but the numerical values are identical.
1271
- */
1272
- var ScalarType;
1273
- (function (ScalarType) {
1274
- // 0 is reserved for errors.
1275
- // Order is weird for historical reasons.
1276
- ScalarType[ScalarType["DOUBLE"] = 1] = "DOUBLE";
1277
- ScalarType[ScalarType["FLOAT"] = 2] = "FLOAT";
1278
- // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
1279
- // negative values are likely.
1280
- ScalarType[ScalarType["INT64"] = 3] = "INT64";
1281
- ScalarType[ScalarType["UINT64"] = 4] = "UINT64";
1282
- // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
1283
- // negative values are likely.
1284
- ScalarType[ScalarType["INT32"] = 5] = "INT32";
1285
- ScalarType[ScalarType["FIXED64"] = 6] = "FIXED64";
1286
- ScalarType[ScalarType["FIXED32"] = 7] = "FIXED32";
1287
- ScalarType[ScalarType["BOOL"] = 8] = "BOOL";
1288
- ScalarType[ScalarType["STRING"] = 9] = "STRING";
1289
- // Tag-delimited aggregate.
1290
- // Group type is deprecated and not supported in proto3. However, Proto3
1291
- // implementations should still be able to parse the group wire format and
1292
- // treat group fields as unknown fields.
1293
- // TYPE_GROUP = 10,
1294
- // TYPE_MESSAGE = 11, // Length-delimited aggregate.
1295
- // New in version 2.
1296
- ScalarType[ScalarType["BYTES"] = 12] = "BYTES";
1297
- ScalarType[ScalarType["UINT32"] = 13] = "UINT32";
1298
- // TYPE_ENUM = 14,
1299
- ScalarType[ScalarType["SFIXED32"] = 15] = "SFIXED32";
1300
- ScalarType[ScalarType["SFIXED64"] = 16] = "SFIXED64";
1301
- ScalarType[ScalarType["SINT32"] = 17] = "SINT32";
1302
- ScalarType[ScalarType["SINT64"] = 18] = "SINT64";
1303
- })(ScalarType || (ScalarType = {}));
1304
- /**
1305
- * JavaScript representation of 64 bit integral types. Equivalent to the
1306
- * field option "jstype".
1307
- *
1308
- * By default, protobuf-ts represents 64 bit types as `bigint`.
1309
- *
1310
- * You can change the default behaviour by enabling the plugin parameter
1311
- * `long_type_string`, which will represent 64 bit types as `string`.
1312
- *
1313
- * Alternatively, you can change the behaviour for individual fields
1314
- * with the field option "jstype":
1315
- *
1316
- * ```protobuf
1317
- * uint64 my_field = 1 [jstype = JS_STRING];
1318
- * uint64 other_field = 2 [jstype = JS_NUMBER];
1319
- * ```
1320
- */
1321
- var LongType;
1322
- (function (LongType) {
1323
- /**
1324
- * Use JavaScript `bigint`.
1325
- *
1326
- * Field option `[jstype = JS_NORMAL]`.
1327
- */
1328
- LongType[LongType["BIGINT"] = 0] = "BIGINT";
1329
- /**
1330
- * Use JavaScript `string`.
1331
- *
1332
- * Field option `[jstype = JS_STRING]`.
1333
- */
1334
- LongType[LongType["STRING"] = 1] = "STRING";
1335
- /**
1336
- * Use JavaScript `number`.
1337
- *
1338
- * Large values will loose precision.
1339
- *
1340
- * Field option `[jstype = JS_NUMBER]`.
1341
- */
1342
- LongType[LongType["NUMBER"] = 2] = "NUMBER";
1343
- })(LongType || (LongType = {}));
1344
- /**
1345
- * Protobuf 2.1.0 introduced packed repeated fields.
1346
- * Setting the field option `[packed = true]` enables packing.
1347
- *
1348
- * In proto3, all repeated fields are packed by default.
1349
- * Setting the field option `[packed = false]` disables packing.
1350
- *
1351
- * Packed repeated fields are encoded with a single tag,
1352
- * then a length-delimiter, then the element values.
1353
- *
1354
- * Unpacked repeated fields are encoded with a tag and
1355
- * value for each element.
1356
- *
1357
- * `bytes` and `string` cannot be packed.
1358
- */
1359
- var RepeatType;
1360
- (function (RepeatType) {
1361
- /**
1362
- * The field is not repeated.
1363
- */
1364
- RepeatType[RepeatType["NO"] = 0] = "NO";
1365
- /**
1366
- * The field is repeated and should be packed.
1367
- * Invalid for `bytes` and `string`, they cannot be packed.
1368
- */
1369
- RepeatType[RepeatType["PACKED"] = 1] = "PACKED";
1370
- /**
1371
- * The field is repeated but should not be packed.
1372
- * The only valid repeat type for repeated `bytes` and `string`.
1373
- */
1374
- RepeatType[RepeatType["UNPACKED"] = 2] = "UNPACKED";
1375
- })(RepeatType || (RepeatType = {}));
1376
- /**
1377
- * Turns PartialFieldInfo into FieldInfo.
1378
- */
1379
- function normalizeFieldInfo(field) {
1380
- var _a, _b, _c, _d;
1381
- field.localName = (_a = field.localName) !== null && _a !== void 0 ? _a : lowerCamelCase(field.name);
1382
- field.jsonName = (_b = field.jsonName) !== null && _b !== void 0 ? _b : lowerCamelCase(field.name);
1383
- field.repeat = (_c = field.repeat) !== null && _c !== void 0 ? _c : RepeatType.NO;
1384
- field.opt = (_d = field.opt) !== null && _d !== void 0 ? _d : (field.repeat ? false : field.oneof ? false : field.kind == "message");
1385
- return field;
1386
- }
1387
-
1388
- /**
1389
- * Is the given value a valid oneof group?
1390
- *
1391
- * We represent protobuf `oneof` as algebraic data types (ADT) in generated
1392
- * code. But when working with messages of unknown type, the ADT does not
1393
- * help us.
1394
- *
1395
- * This type guard checks if the given object adheres to the ADT rules, which
1396
- * are as follows:
1397
- *
1398
- * 1) Must be an object.
1399
- *
1400
- * 2) Must have a "oneofKind" discriminator property.
1401
- *
1402
- * 3) If "oneofKind" is `undefined`, no member field is selected. The object
1403
- * must not have any other properties.
1404
- *
1405
- * 4) If "oneofKind" is a `string`, the member field with this name is
1406
- * selected.
1407
- *
1408
- * 5) If a member field is selected, the object must have a second property
1409
- * with this name. The property must not be `undefined`.
1410
- *
1411
- * 6) No extra properties are allowed. The object has either one property
1412
- * (no selection) or two properties (selection).
1413
- *
1414
- */
1415
- function isOneofGroup(any) {
1416
- if (typeof any != 'object' || any === null || !any.hasOwnProperty('oneofKind')) {
1417
- return false;
1418
- }
1419
- switch (typeof any.oneofKind) {
1420
- case "string":
1421
- if (any[any.oneofKind] === undefined)
1422
- return false;
1423
- return Object.keys(any).length == 2;
1424
- case "undefined":
1425
- return Object.keys(any).length == 1;
1426
- default:
1427
- return false;
1428
- }
1429
- }
1430
-
1431
- // noinspection JSMethodCanBeStatic
1432
- class ReflectionTypeCheck {
1433
- constructor(info) {
1434
- var _a;
1435
- this.fields = (_a = info.fields) !== null && _a !== void 0 ? _a : [];
1436
- }
1437
- prepare() {
1438
- if (this.data)
1439
- return;
1440
- const req = [], known = [], oneofs = [];
1441
- for (let field of this.fields) {
1442
- if (field.oneof) {
1443
- if (!oneofs.includes(field.oneof)) {
1444
- oneofs.push(field.oneof);
1445
- req.push(field.oneof);
1446
- known.push(field.oneof);
1447
- }
1448
- }
1449
- else {
1450
- known.push(field.localName);
1451
- switch (field.kind) {
1452
- case "scalar":
1453
- case "enum":
1454
- if (!field.opt || field.repeat)
1455
- req.push(field.localName);
1456
- break;
1457
- case "message":
1458
- if (field.repeat)
1459
- req.push(field.localName);
1460
- break;
1461
- case "map":
1462
- req.push(field.localName);
1463
- break;
1464
- }
1465
- }
1466
- }
1467
- this.data = { req, known, oneofs: Object.values(oneofs) };
1468
- }
1469
- /**
1470
- * Is the argument a valid message as specified by the
1471
- * reflection information?
1472
- *
1473
- * Checks all field types recursively. The `depth`
1474
- * specifies how deep into the structure the check will be.
1475
- *
1476
- * With a depth of 0, only the presence of fields
1477
- * is checked.
1478
- *
1479
- * With a depth of 1 or more, the field types are checked.
1480
- *
1481
- * With a depth of 2 or more, the members of map, repeated
1482
- * and message fields are checked.
1483
- *
1484
- * Message fields will be checked recursively with depth - 1.
1485
- *
1486
- * The number of map entries / repeated values being checked
1487
- * is < depth.
1488
- */
1489
- is(message, depth, allowExcessProperties = false) {
1490
- if (depth < 0)
1491
- return true;
1492
- if (message === null || message === undefined || typeof message != 'object')
1493
- return false;
1494
- this.prepare();
1495
- let keys = Object.keys(message), data = this.data;
1496
- // if a required field is missing in arg, this cannot be a T
1497
- if (keys.length < data.req.length || data.req.some(n => !keys.includes(n)))
1498
- return false;
1499
- if (!allowExcessProperties) {
1500
- // if the arg contains a key we dont know, this is not a literal T
1501
- if (keys.some(k => !data.known.includes(k)))
1502
- return false;
1503
- }
1504
- // "With a depth of 0, only the presence and absence of fields is checked."
1505
- // "With a depth of 1 or more, the field types are checked."
1506
- if (depth < 1) {
1507
- return true;
1508
- }
1509
- // check oneof group
1510
- for (const name of data.oneofs) {
1511
- const group = message[name];
1512
- if (!isOneofGroup(group))
1513
- return false;
1514
- if (group.oneofKind === undefined)
1515
- continue;
1516
- const field = this.fields.find(f => f.localName === group.oneofKind);
1517
- if (!field)
1518
- return false; // we found no field, but have a kind, something is wrong
1519
- if (!this.field(group[group.oneofKind], field, allowExcessProperties, depth))
1520
- return false;
1521
- }
1522
- // check types
1523
- for (const field of this.fields) {
1524
- if (field.oneof !== undefined)
1525
- continue;
1526
- if (!this.field(message[field.localName], field, allowExcessProperties, depth))
1527
- return false;
1528
- }
1529
- return true;
1530
- }
1531
- field(arg, field, allowExcessProperties, depth) {
1532
- let repeated = field.repeat;
1533
- switch (field.kind) {
1534
- case "scalar":
1535
- if (arg === undefined)
1536
- return field.opt;
1537
- if (repeated)
1538
- return this.scalars(arg, field.T, depth, field.L);
1539
- return this.scalar(arg, field.T, field.L);
1540
- case "enum":
1541
- if (arg === undefined)
1542
- return field.opt;
1543
- if (repeated)
1544
- return this.scalars(arg, ScalarType.INT32, depth);
1545
- return this.scalar(arg, ScalarType.INT32);
1546
- case "message":
1547
- if (arg === undefined)
1548
- return true;
1549
- if (repeated)
1550
- return this.messages(arg, field.T(), allowExcessProperties, depth);
1551
- return this.message(arg, field.T(), allowExcessProperties, depth);
1552
- case "map":
1553
- if (typeof arg != 'object' || arg === null)
1554
- return false;
1555
- if (depth < 2)
1556
- return true;
1557
- if (!this.mapKeys(arg, field.K, depth))
1558
- return false;
1559
- switch (field.V.kind) {
1560
- case "scalar":
1561
- return this.scalars(Object.values(arg), field.V.T, depth, field.V.L);
1562
- case "enum":
1563
- return this.scalars(Object.values(arg), ScalarType.INT32, depth);
1564
- case "message":
1565
- return this.messages(Object.values(arg), field.V.T(), allowExcessProperties, depth);
1566
- }
1567
- break;
1568
- }
1569
- return true;
1570
- }
1571
- message(arg, type, allowExcessProperties, depth) {
1572
- if (allowExcessProperties) {
1573
- return type.isAssignable(arg, depth);
1574
- }
1575
- return type.is(arg, depth);
1576
- }
1577
- messages(arg, type, allowExcessProperties, depth) {
1578
- if (!Array.isArray(arg))
1579
- return false;
1580
- if (depth < 2)
1581
- return true;
1582
- if (allowExcessProperties) {
1583
- for (let i = 0; i < arg.length && i < depth; i++)
1584
- if (!type.isAssignable(arg[i], depth - 1))
1585
- return false;
1586
- }
1587
- else {
1588
- for (let i = 0; i < arg.length && i < depth; i++)
1589
- if (!type.is(arg[i], depth - 1))
1590
- return false;
1591
- }
1592
- return true;
1593
- }
1594
- scalar(arg, type, longType) {
1595
- let argType = typeof arg;
1596
- switch (type) {
1597
- case ScalarType.UINT64:
1598
- case ScalarType.FIXED64:
1599
- case ScalarType.INT64:
1600
- case ScalarType.SFIXED64:
1601
- case ScalarType.SINT64:
1602
- switch (longType) {
1603
- case LongType.BIGINT:
1604
- return argType == "bigint";
1605
- case LongType.NUMBER:
1606
- return argType == "number" && !isNaN(arg);
1607
- default:
1608
- return argType == "string";
1609
- }
1610
- case ScalarType.BOOL:
1611
- return argType == 'boolean';
1612
- case ScalarType.STRING:
1613
- return argType == 'string';
1614
- case ScalarType.BYTES:
1615
- return arg instanceof Uint8Array;
1616
- case ScalarType.DOUBLE:
1617
- case ScalarType.FLOAT:
1618
- return argType == 'number' && !isNaN(arg);
1619
- default:
1620
- // case ScalarType.UINT32:
1621
- // case ScalarType.FIXED32:
1622
- // case ScalarType.INT32:
1623
- // case ScalarType.SINT32:
1624
- // case ScalarType.SFIXED32:
1625
- return argType == 'number' && Number.isInteger(arg);
1626
- }
1627
- }
1628
- scalars(arg, type, depth, longType) {
1629
- if (!Array.isArray(arg))
1630
- return false;
1631
- if (depth < 2)
1632
- return true;
1633
- if (Array.isArray(arg))
1634
- for (let i = 0; i < arg.length && i < depth; i++)
1635
- if (!this.scalar(arg[i], type, longType))
1636
- return false;
1637
- return true;
1638
- }
1639
- mapKeys(map, type, depth) {
1640
- let keys = Object.keys(map);
1641
- switch (type) {
1642
- case ScalarType.INT32:
1643
- case ScalarType.FIXED32:
1644
- case ScalarType.SFIXED32:
1645
- case ScalarType.SINT32:
1646
- case ScalarType.UINT32:
1647
- return this.scalars(keys.slice(0, depth).map(k => parseInt(k)), type, depth);
1648
- case ScalarType.BOOL:
1649
- return this.scalars(keys.slice(0, depth).map(k => k == 'true' ? true : k == 'false' ? false : k), type, depth);
1650
- default:
1651
- return this.scalars(keys, type, depth, LongType.STRING);
1652
- }
1653
- }
1654
- }
1655
-
1656
- /**
1657
- * Utility method to convert a PbLong or PbUlong to a JavaScript
1658
- * representation during runtime.
1659
- *
1660
- * Works with generated field information, `undefined` is equivalent
1661
- * to `STRING`.
1662
- */
1663
- function reflectionLongConvert(long, type) {
1664
- switch (type) {
1665
- case LongType.BIGINT:
1666
- return long.toBigInt();
1667
- case LongType.NUMBER:
1668
- return long.toNumber();
1669
- default:
1670
- // case undefined:
1671
- // case LongType.STRING:
1672
- return long.toString();
1673
- }
1674
- }
1675
-
1676
- /**
1677
- * Reads proto3 messages in canonical JSON format using reflection information.
1678
- *
1679
- * https://developers.google.com/protocol-buffers/docs/proto3#json
1680
- */
1681
- class ReflectionJsonReader {
1682
- constructor(info) {
1683
- this.info = info;
1684
- }
1685
- prepare() {
1686
- var _a;
1687
- if (this.fMap === undefined) {
1688
- this.fMap = {};
1689
- const fieldsInput = (_a = this.info.fields) !== null && _a !== void 0 ? _a : [];
1690
- for (const field of fieldsInput) {
1691
- this.fMap[field.name] = field;
1692
- this.fMap[field.jsonName] = field;
1693
- this.fMap[field.localName] = field;
1694
- }
1695
- }
1696
- }
1697
- // Cannot parse JSON <type of jsonValue> for <type name>#<fieldName>.
1698
- assert(condition, fieldName, jsonValue) {
1699
- if (!condition) {
1700
- let what = typeofJsonValue(jsonValue);
1701
- if (what == "number" || what == "boolean")
1702
- what = jsonValue.toString();
1703
- throw new Error(`Cannot parse JSON ${what} for ${this.info.typeName}#${fieldName}`);
1704
- }
1705
- }
1706
- /**
1707
- * Reads a message from canonical JSON format into the target message.
1708
- *
1709
- * Repeated fields are appended. Map entries are added, overwriting
1710
- * existing keys.
1711
- *
1712
- * If a message field is already present, it will be merged with the
1713
- * new data.
1714
- */
1715
- read(input, message, options) {
1716
- this.prepare();
1717
- const oneofsHandled = [];
1718
- for (const [jsonKey, jsonValue] of Object.entries(input)) {
1719
- const field = this.fMap[jsonKey];
1720
- if (!field) {
1721
- if (!options.ignoreUnknownFields)
1722
- throw new Error(`Found unknown field while reading ${this.info.typeName} from JSON format. JSON key: ${jsonKey}`);
1723
- continue;
1724
- }
1725
- const localName = field.localName;
1726
- // handle oneof ADT
1727
- let target; // this will be the target for the field value, whether it is member of a oneof or not
1728
- if (field.oneof) {
1729
- // since json objects are unordered by specification, it is not possible to take the last of multiple oneofs
1730
- if (oneofsHandled.includes(field.oneof))
1731
- throw new Error(`Multiple members of the oneof group "${field.oneof}" of ${this.info.typeName} are present in JSON.`);
1732
- oneofsHandled.push(field.oneof);
1733
- target = message[field.oneof] = {
1734
- oneofKind: localName
1735
- };
1736
- }
1737
- else {
1738
- target = message;
1739
- }
1740
- // we have handled oneof above. we just have read the value into `target`.
1741
- if (field.kind == 'map') {
1742
- if (jsonValue === null) {
1743
- continue;
1744
- }
1745
- // check input
1746
- this.assert(isJsonObject(jsonValue), field.name, jsonValue);
1747
- // our target to put map entries into
1748
- const fieldObj = target[localName];
1749
- // read entries
1750
- for (const [jsonObjKey, jsonObjValue] of Object.entries(jsonValue)) {
1751
- this.assert(jsonObjValue !== null, field.name + " map value", null);
1752
- // read value
1753
- let val;
1754
- switch (field.V.kind) {
1755
- case "message":
1756
- val = field.V.T().internalJsonRead(jsonObjValue, options);
1757
- break;
1758
- case "enum":
1759
- val = this.enum(field.V.T(), jsonObjValue, field.name, options.ignoreUnknownFields);
1760
- if (val === false)
1761
- continue;
1762
- break;
1763
- case "scalar":
1764
- val = this.scalar(jsonObjValue, field.V.T, field.V.L, field.name);
1765
- break;
1766
- }
1767
- this.assert(val !== undefined, field.name + " map value", jsonObjValue);
1768
- // read key
1769
- let key = jsonObjKey;
1770
- if (field.K == ScalarType.BOOL)
1771
- key = key == "true" ? true : key == "false" ? false : key;
1772
- key = this.scalar(key, field.K, LongType.STRING, field.name).toString();
1773
- fieldObj[key] = val;
1774
- }
1775
- }
1776
- else if (field.repeat) {
1777
- if (jsonValue === null)
1778
- continue;
1779
- // check input
1780
- this.assert(Array.isArray(jsonValue), field.name, jsonValue);
1781
- // our target to put array entries into
1782
- const fieldArr = target[localName];
1783
- // read array entries
1784
- for (const jsonItem of jsonValue) {
1785
- this.assert(jsonItem !== null, field.name, null);
1786
- let val;
1787
- switch (field.kind) {
1788
- case "message":
1789
- val = field.T().internalJsonRead(jsonItem, options);
1790
- break;
1791
- case "enum":
1792
- val = this.enum(field.T(), jsonItem, field.name, options.ignoreUnknownFields);
1793
- if (val === false)
1794
- continue;
1795
- break;
1796
- case "scalar":
1797
- val = this.scalar(jsonItem, field.T, field.L, field.name);
1798
- break;
1799
- }
1800
- this.assert(val !== undefined, field.name, jsonValue);
1801
- fieldArr.push(val);
1802
- }
1803
- }
1804
- else {
1805
- switch (field.kind) {
1806
- case "message":
1807
- if (jsonValue === null && field.T().typeName != 'google.protobuf.Value') {
1808
- this.assert(field.oneof === undefined, field.name + " (oneof member)", null);
1809
- continue;
1810
- }
1811
- target[localName] = field.T().internalJsonRead(jsonValue, options, target[localName]);
1812
- break;
1813
- case "enum":
1814
- let val = this.enum(field.T(), jsonValue, field.name, options.ignoreUnknownFields);
1815
- if (val === false)
1816
- continue;
1817
- target[localName] = val;
1818
- break;
1819
- case "scalar":
1820
- target[localName] = this.scalar(jsonValue, field.T, field.L, field.name);
1821
- break;
1822
- }
1823
- }
1824
- }
1825
- }
1826
- /**
1827
- * Returns `false` for unrecognized string representations.
1828
- *
1829
- * google.protobuf.NullValue accepts only JSON `null`.
1830
- */
1831
- enum(type, json, fieldName, ignoreUnknownFields) {
1832
- if (type[0] == 'google.protobuf.NullValue')
1833
- assert(json === null, `Unable to parse field ${this.info.typeName}#${fieldName}, enum ${type[0]} only accepts null.`);
1834
- if (json === null)
1835
- // we require 0 to be default value for all enums
1836
- return 0;
1837
- switch (typeof json) {
1838
- case "number":
1839
- assert(Number.isInteger(json), `Unable to parse field ${this.info.typeName}#${fieldName}, enum can only be integral number, got ${json}.`);
1840
- return json;
1841
- case "string":
1842
- let localEnumName = json;
1843
- if (type[2] && json.substring(0, type[2].length) === type[2])
1844
- // lookup without the shared prefix
1845
- localEnumName = json.substring(type[2].length);
1846
- let enumNumber = type[1][localEnumName];
1847
- if (typeof enumNumber === 'undefined' && ignoreUnknownFields) {
1848
- return false;
1849
- }
1850
- assert(typeof enumNumber == "number", `Unable to parse field ${this.info.typeName}#${fieldName}, enum ${type[0]} has no value for "${json}".`);
1851
- return enumNumber;
1852
- }
1853
- assert(false, `Unable to parse field ${this.info.typeName}#${fieldName}, cannot parse enum value from ${typeof json}".`);
1854
- }
1855
- scalar(json, type, longType, fieldName) {
1856
- let e;
1857
- try {
1858
- switch (type) {
1859
- // float, double: JSON value will be a number or one of the special string values "NaN", "Infinity", and "-Infinity".
1860
- // Either numbers or strings are accepted. Exponent notation is also accepted.
1861
- case ScalarType.DOUBLE:
1862
- case ScalarType.FLOAT:
1863
- if (json === null)
1864
- return .0;
1865
- if (json === "NaN")
1866
- return Number.NaN;
1867
- if (json === "Infinity")
1868
- return Number.POSITIVE_INFINITY;
1869
- if (json === "-Infinity")
1870
- return Number.NEGATIVE_INFINITY;
1871
- if (json === "") {
1872
- e = "empty string";
1873
- break;
1874
- }
1875
- if (typeof json == "string" && json.trim().length !== json.length) {
1876
- e = "extra whitespace";
1877
- break;
1878
- }
1879
- if (typeof json != "string" && typeof json != "number") {
1880
- break;
1881
- }
1882
- let float = Number(json);
1883
- if (Number.isNaN(float)) {
1884
- e = "not a number";
1885
- break;
1886
- }
1887
- if (!Number.isFinite(float)) {
1888
- // infinity and -infinity are handled by string representation above, so this is an error
1889
- e = "too large or small";
1890
- break;
1891
- }
1892
- if (type == ScalarType.FLOAT)
1893
- assertFloat32(float);
1894
- return float;
1895
- // int32, fixed32, uint32: JSON value will be a decimal number. Either numbers or strings are accepted.
1896
- case ScalarType.INT32:
1897
- case ScalarType.FIXED32:
1898
- case ScalarType.SFIXED32:
1899
- case ScalarType.SINT32:
1900
- case ScalarType.UINT32:
1901
- if (json === null)
1902
- return 0;
1903
- let int32;
1904
- if (typeof json == "number")
1905
- int32 = json;
1906
- else if (json === "")
1907
- e = "empty string";
1908
- else if (typeof json == "string") {
1909
- if (json.trim().length !== json.length)
1910
- e = "extra whitespace";
1911
- else
1912
- int32 = Number(json);
1913
- }
1914
- if (int32 === undefined)
1915
- break;
1916
- if (type == ScalarType.UINT32)
1917
- assertUInt32(int32);
1918
- else
1919
- assertInt32(int32);
1920
- return int32;
1921
- // int64, fixed64, uint64: JSON value will be a decimal string. Either numbers or strings are accepted.
1922
- case ScalarType.INT64:
1923
- case ScalarType.SFIXED64:
1924
- case ScalarType.SINT64:
1925
- if (json === null)
1926
- return reflectionLongConvert(PbLong.ZERO, longType);
1927
- if (typeof json != "number" && typeof json != "string")
1928
- break;
1929
- return reflectionLongConvert(PbLong.from(json), longType);
1930
- case ScalarType.FIXED64:
1931
- case ScalarType.UINT64:
1932
- if (json === null)
1933
- return reflectionLongConvert(PbULong.ZERO, longType);
1934
- if (typeof json != "number" && typeof json != "string")
1935
- break;
1936
- return reflectionLongConvert(PbULong.from(json), longType);
1937
- // bool:
1938
- case ScalarType.BOOL:
1939
- if (json === null)
1940
- return false;
1941
- if (typeof json !== "boolean")
1942
- break;
1943
- return json;
1944
- // string:
1945
- case ScalarType.STRING:
1946
- if (json === null)
1947
- return "";
1948
- if (typeof json !== "string") {
1949
- e = "extra whitespace";
1950
- break;
1951
- }
1952
- try {
1953
- encodeURIComponent(json);
1954
- }
1955
- catch (e) {
1956
- e = "invalid UTF8";
1957
- break;
1958
- }
1959
- return json;
1960
- // bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
1961
- // Either standard or URL-safe base64 encoding with/without paddings are accepted.
1962
- case ScalarType.BYTES:
1963
- if (json === null || json === "")
1964
- return new Uint8Array(0);
1965
- if (typeof json !== 'string')
1966
- break;
1967
- return base64decode(json);
1968
- }
1969
- }
1970
- catch (error) {
1971
- e = error.message;
1972
- }
1973
- this.assert(false, fieldName + (e ? " - " + e : ""), json);
1974
- }
1975
- }
1976
-
1977
- /**
1978
- * Writes proto3 messages in canonical JSON format using reflection
1979
- * information.
1980
- *
1981
- * https://developers.google.com/protocol-buffers/docs/proto3#json
1982
- */
1983
- class ReflectionJsonWriter {
1984
- constructor(info) {
1985
- var _a;
1986
- this.fields = (_a = info.fields) !== null && _a !== void 0 ? _a : [];
1987
- }
1988
- /**
1989
- * Converts the message to a JSON object, based on the field descriptors.
1990
- */
1991
- write(message, options) {
1992
- const json = {}, source = message;
1993
- for (const field of this.fields) {
1994
- // field is not part of a oneof, simply write as is
1995
- if (!field.oneof) {
1996
- let jsonValue = this.field(field, source[field.localName], options);
1997
- if (jsonValue !== undefined)
1998
- json[options.useProtoFieldName ? field.name : field.jsonName] = jsonValue;
1999
- continue;
2000
- }
2001
- // field is part of a oneof
2002
- const group = source[field.oneof];
2003
- if (group.oneofKind !== field.localName)
2004
- continue; // not selected, skip
2005
- const opt = field.kind == 'scalar' || field.kind == 'enum'
2006
- ? Object.assign(Object.assign({}, options), { emitDefaultValues: true }) : options;
2007
- let jsonValue = this.field(field, group[field.localName], opt);
2008
- assert(jsonValue !== undefined);
2009
- json[options.useProtoFieldName ? field.name : field.jsonName] = jsonValue;
2010
- }
2011
- return json;
2012
- }
2013
- field(field, value, options) {
2014
- let jsonValue = undefined;
2015
- if (field.kind == 'map') {
2016
- assert(typeof value == "object" && value !== null);
2017
- const jsonObj = {};
2018
- switch (field.V.kind) {
2019
- case "scalar":
2020
- for (const [entryKey, entryValue] of Object.entries(value)) {
2021
- const val = this.scalar(field.V.T, entryValue, field.name, false, true);
2022
- assert(val !== undefined);
2023
- jsonObj[entryKey.toString()] = val; // JSON standard allows only (double quoted) string as property key
2024
- }
2025
- break;
2026
- case "message":
2027
- const messageType = field.V.T();
2028
- for (const [entryKey, entryValue] of Object.entries(value)) {
2029
- const val = this.message(messageType, entryValue, field.name, options);
2030
- assert(val !== undefined);
2031
- jsonObj[entryKey.toString()] = val; // JSON standard allows only (double quoted) string as property key
2032
- }
2033
- break;
2034
- case "enum":
2035
- const enumInfo = field.V.T();
2036
- for (const [entryKey, entryValue] of Object.entries(value)) {
2037
- assert(entryValue === undefined || typeof entryValue == 'number');
2038
- const val = this.enum(enumInfo, entryValue, field.name, false, true, options.enumAsInteger);
2039
- assert(val !== undefined);
2040
- jsonObj[entryKey.toString()] = val; // JSON standard allows only (double quoted) string as property key
2041
- }
2042
- break;
2043
- }
2044
- if (options.emitDefaultValues || Object.keys(jsonObj).length > 0)
2045
- jsonValue = jsonObj;
2046
- }
2047
- else if (field.repeat) {
2048
- assert(Array.isArray(value));
2049
- const jsonArr = [];
2050
- switch (field.kind) {
2051
- case "scalar":
2052
- for (let i = 0; i < value.length; i++) {
2053
- const val = this.scalar(field.T, value[i], field.name, field.opt, true);
2054
- assert(val !== undefined);
2055
- jsonArr.push(val);
2056
- }
2057
- break;
2058
- case "enum":
2059
- const enumInfo = field.T();
2060
- for (let i = 0; i < value.length; i++) {
2061
- assert(value[i] === undefined || typeof value[i] == 'number');
2062
- const val = this.enum(enumInfo, value[i], field.name, field.opt, true, options.enumAsInteger);
2063
- assert(val !== undefined);
2064
- jsonArr.push(val);
2065
- }
2066
- break;
2067
- case "message":
2068
- const messageType = field.T();
2069
- for (let i = 0; i < value.length; i++) {
2070
- const val = this.message(messageType, value[i], field.name, options);
2071
- assert(val !== undefined);
2072
- jsonArr.push(val);
2073
- }
2074
- break;
2075
- }
2076
- // add converted array to json output
2077
- if (options.emitDefaultValues || jsonArr.length > 0 || options.emitDefaultValues)
2078
- jsonValue = jsonArr;
2079
- }
2080
- else {
2081
- switch (field.kind) {
2082
- case "scalar":
2083
- jsonValue = this.scalar(field.T, value, field.name, field.opt, options.emitDefaultValues);
2084
- break;
2085
- case "enum":
2086
- jsonValue = this.enum(field.T(), value, field.name, field.opt, options.emitDefaultValues, options.enumAsInteger);
2087
- break;
2088
- case "message":
2089
- jsonValue = this.message(field.T(), value, field.name, options);
2090
- break;
2091
- }
2092
- }
2093
- return jsonValue;
2094
- }
2095
- /**
2096
- * Returns `null` for google.protobuf.NullValue.
2097
- */
2098
- enum(type, value, fieldName, optional, emitDefaultValues, enumAsInteger) {
2099
- if (type[0] == 'google.protobuf.NullValue')
2100
- return null;
2101
- if (value === undefined) {
2102
- assert(optional);
2103
- return undefined;
2104
- }
2105
- if (value === 0 && !emitDefaultValues && !optional)
2106
- // we require 0 to be default value for all enums
2107
- return undefined;
2108
- assert(typeof value == 'number');
2109
- assert(Number.isInteger(value));
2110
- if (enumAsInteger || !type[1].hasOwnProperty(value))
2111
- // if we don't now the enum value, just return the number
2112
- return value;
2113
- if (type[2])
2114
- // restore the dropped prefix
2115
- return type[2] + type[1][value];
2116
- return type[1][value];
2117
- }
2118
- message(type, value, fieldName, options) {
2119
- if (value === undefined)
2120
- return options.emitDefaultValues ? null : undefined;
2121
- return type.internalJsonWrite(value, options);
2122
- }
2123
- scalar(type, value, fieldName, optional, emitDefaultValues) {
2124
- if (value === undefined) {
2125
- assert(optional);
2126
- return undefined;
2127
- }
2128
- const ed = emitDefaultValues || optional;
2129
- // noinspection FallThroughInSwitchStatementJS
2130
- switch (type) {
2131
- // int32, fixed32, uint32: JSON value will be a decimal number. Either numbers or strings are accepted.
2132
- case ScalarType.INT32:
2133
- case ScalarType.SFIXED32:
2134
- case ScalarType.SINT32:
2135
- if (value === 0)
2136
- return ed ? 0 : undefined;
2137
- assertInt32(value);
2138
- return value;
2139
- case ScalarType.FIXED32:
2140
- case ScalarType.UINT32:
2141
- if (value === 0)
2142
- return ed ? 0 : undefined;
2143
- assertUInt32(value);
2144
- return value;
2145
- // float, double: JSON value will be a number or one of the special string values "NaN", "Infinity", and "-Infinity".
2146
- // Either numbers or strings are accepted. Exponent notation is also accepted.
2147
- case ScalarType.FLOAT:
2148
- assertFloat32(value);
2149
- case ScalarType.DOUBLE:
2150
- if (value === 0)
2151
- return ed ? 0 : undefined;
2152
- assert(typeof value == 'number');
2153
- if (Number.isNaN(value))
2154
- return 'NaN';
2155
- if (value === Number.POSITIVE_INFINITY)
2156
- return 'Infinity';
2157
- if (value === Number.NEGATIVE_INFINITY)
2158
- return '-Infinity';
2159
- return value;
2160
- // string:
2161
- case ScalarType.STRING:
2162
- if (value === "")
2163
- return ed ? '' : undefined;
2164
- assert(typeof value == 'string');
2165
- return value;
2166
- // bool:
2167
- case ScalarType.BOOL:
2168
- if (value === false)
2169
- return ed ? false : undefined;
2170
- assert(typeof value == 'boolean');
2171
- return value;
2172
- // JSON value will be a decimal string. Either numbers or strings are accepted.
2173
- case ScalarType.UINT64:
2174
- case ScalarType.FIXED64:
2175
- assert(typeof value == 'number' || typeof value == 'string' || typeof value == 'bigint');
2176
- let ulong = PbULong.from(value);
2177
- if (ulong.isZero() && !ed)
2178
- return undefined;
2179
- return ulong.toString();
2180
- // JSON value will be a decimal string. Either numbers or strings are accepted.
2181
- case ScalarType.INT64:
2182
- case ScalarType.SFIXED64:
2183
- case ScalarType.SINT64:
2184
- assert(typeof value == 'number' || typeof value == 'string' || typeof value == 'bigint');
2185
- let long = PbLong.from(value);
2186
- if (long.isZero() && !ed)
2187
- return undefined;
2188
- return long.toString();
2189
- // bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
2190
- // Either standard or URL-safe base64 encoding with/without paddings are accepted.
2191
- case ScalarType.BYTES:
2192
- assert(value instanceof Uint8Array);
2193
- if (!value.byteLength)
2194
- return ed ? "" : undefined;
2195
- return base64encode(value);
2196
- }
2197
- }
2198
- }
2199
-
2200
- /**
2201
- * Creates the default value for a scalar type.
2202
- */
2203
- function reflectionScalarDefault(type, longType = LongType.STRING) {
2204
- switch (type) {
2205
- case ScalarType.BOOL:
2206
- return false;
2207
- case ScalarType.UINT64:
2208
- case ScalarType.FIXED64:
2209
- return reflectionLongConvert(PbULong.ZERO, longType);
2210
- case ScalarType.INT64:
2211
- case ScalarType.SFIXED64:
2212
- case ScalarType.SINT64:
2213
- return reflectionLongConvert(PbLong.ZERO, longType);
2214
- case ScalarType.DOUBLE:
2215
- case ScalarType.FLOAT:
2216
- return 0.0;
2217
- case ScalarType.BYTES:
2218
- return new Uint8Array(0);
2219
- case ScalarType.STRING:
2220
- return "";
2221
- default:
2222
- // case ScalarType.INT32:
2223
- // case ScalarType.UINT32:
2224
- // case ScalarType.SINT32:
2225
- // case ScalarType.FIXED32:
2226
- // case ScalarType.SFIXED32:
2227
- return 0;
2228
- }
2229
- }
2230
-
2231
- /**
2232
- * Reads proto3 messages in binary format using reflection information.
2233
- *
2234
- * https://developers.google.com/protocol-buffers/docs/encoding
2235
- */
2236
- class ReflectionBinaryReader {
2237
- constructor(info) {
2238
- this.info = info;
2239
- }
2240
- prepare() {
2241
- var _a;
2242
- if (!this.fieldNoToField) {
2243
- const fieldsInput = (_a = this.info.fields) !== null && _a !== void 0 ? _a : [];
2244
- this.fieldNoToField = new Map(fieldsInput.map(field => [field.no, field]));
2245
- }
2246
- }
2247
- /**
2248
- * Reads a message from binary format into the target message.
2249
- *
2250
- * Repeated fields are appended. Map entries are added, overwriting
2251
- * existing keys.
2252
- *
2253
- * If a message field is already present, it will be merged with the
2254
- * new data.
2255
- */
2256
- read(reader, message, options, length) {
2257
- this.prepare();
2258
- const end = length === undefined ? reader.len : reader.pos + length;
2259
- while (reader.pos < end) {
2260
- // read the tag and find the field
2261
- const [fieldNo, wireType] = reader.tag(), field = this.fieldNoToField.get(fieldNo);
2262
- if (!field) {
2263
- let u = options.readUnknownField;
2264
- if (u == "throw")
2265
- throw new Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.info.typeName}`);
2266
- let d = reader.skip(wireType);
2267
- if (u !== false)
2268
- (u === true ? UnknownFieldHandler.onRead : u)(this.info.typeName, message, fieldNo, wireType, d);
2269
- continue;
2270
- }
2271
- // target object for the field we are reading
2272
- let target = message, repeated = field.repeat, localName = field.localName;
2273
- // if field is member of oneof ADT, use ADT as target
2274
- if (field.oneof) {
2275
- target = target[field.oneof];
2276
- // if other oneof member selected, set new ADT
2277
- if (target.oneofKind !== localName)
2278
- target = message[field.oneof] = {
2279
- oneofKind: localName
2280
- };
2281
- }
2282
- // we have handled oneof above, we just have read the value into `target[localName]`
2283
- switch (field.kind) {
2284
- case "scalar":
2285
- case "enum":
2286
- let T = field.kind == "enum" ? ScalarType.INT32 : field.T;
2287
- let L = field.kind == "scalar" ? field.L : undefined;
2288
- if (repeated) {
2289
- let arr = target[localName]; // safe to assume presence of array, oneof cannot contain repeated values
2290
- if (wireType == WireType.LengthDelimited && T != ScalarType.STRING && T != ScalarType.BYTES) {
2291
- let e = reader.uint32() + reader.pos;
2292
- while (reader.pos < e)
2293
- arr.push(this.scalar(reader, T, L));
2294
- }
2295
- else
2296
- arr.push(this.scalar(reader, T, L));
2297
- }
2298
- else
2299
- target[localName] = this.scalar(reader, T, L);
2300
- break;
2301
- case "message":
2302
- if (repeated) {
2303
- let arr = target[localName]; // safe to assume presence of array, oneof cannot contain repeated values
2304
- let msg = field.T().internalBinaryRead(reader, reader.uint32(), options);
2305
- arr.push(msg);
2306
- }
2307
- else
2308
- target[localName] = field.T().internalBinaryRead(reader, reader.uint32(), options, target[localName]);
2309
- break;
2310
- case "map":
2311
- let [mapKey, mapVal] = this.mapEntry(field, reader, options);
2312
- // safe to assume presence of map object, oneof cannot contain repeated values
2313
- target[localName][mapKey] = mapVal;
2314
- break;
2315
- }
2316
- }
2317
- }
2318
- /**
2319
- * Read a map field, expecting key field = 1, value field = 2
2320
- */
2321
- mapEntry(field, reader, options) {
2322
- let length = reader.uint32();
2323
- let end = reader.pos + length;
2324
- let key = undefined; // javascript only allows number or string for object properties
2325
- let val = undefined;
2326
- while (reader.pos < end) {
2327
- let [fieldNo, wireType] = reader.tag();
2328
- switch (fieldNo) {
2329
- case 1:
2330
- if (field.K == ScalarType.BOOL)
2331
- key = reader.bool().toString();
2332
- else
2333
- // long types are read as string, number types are okay as number
2334
- key = this.scalar(reader, field.K, LongType.STRING);
2335
- break;
2336
- case 2:
2337
- switch (field.V.kind) {
2338
- case "scalar":
2339
- val = this.scalar(reader, field.V.T, field.V.L);
2340
- break;
2341
- case "enum":
2342
- val = reader.int32();
2343
- break;
2344
- case "message":
2345
- val = field.V.T().internalBinaryRead(reader, reader.uint32(), options);
2346
- break;
2347
- }
2348
- break;
2349
- default:
2350
- throw new Error(`Unknown field ${fieldNo} (wire type ${wireType}) in map entry for ${this.info.typeName}#${field.name}`);
2351
- }
2352
- }
2353
- if (key === undefined) {
2354
- let keyRaw = reflectionScalarDefault(field.K);
2355
- key = field.K == ScalarType.BOOL ? keyRaw.toString() : keyRaw;
2356
- }
2357
- if (val === undefined)
2358
- switch (field.V.kind) {
2359
- case "scalar":
2360
- val = reflectionScalarDefault(field.V.T, field.V.L);
2361
- break;
2362
- case "enum":
2363
- val = 0;
2364
- break;
2365
- case "message":
2366
- val = field.V.T().create();
2367
- break;
2368
- }
2369
- return [key, val];
2370
- }
2371
- scalar(reader, type, longType) {
2372
- switch (type) {
2373
- case ScalarType.INT32:
2374
- return reader.int32();
2375
- case ScalarType.STRING:
2376
- return reader.string();
2377
- case ScalarType.BOOL:
2378
- return reader.bool();
2379
- case ScalarType.DOUBLE:
2380
- return reader.double();
2381
- case ScalarType.FLOAT:
2382
- return reader.float();
2383
- case ScalarType.INT64:
2384
- return reflectionLongConvert(reader.int64(), longType);
2385
- case ScalarType.UINT64:
2386
- return reflectionLongConvert(reader.uint64(), longType);
2387
- case ScalarType.FIXED64:
2388
- return reflectionLongConvert(reader.fixed64(), longType);
2389
- case ScalarType.FIXED32:
2390
- return reader.fixed32();
2391
- case ScalarType.BYTES:
2392
- return reader.bytes();
2393
- case ScalarType.UINT32:
2394
- return reader.uint32();
2395
- case ScalarType.SFIXED32:
2396
- return reader.sfixed32();
2397
- case ScalarType.SFIXED64:
2398
- return reflectionLongConvert(reader.sfixed64(), longType);
2399
- case ScalarType.SINT32:
2400
- return reader.sint32();
2401
- case ScalarType.SINT64:
2402
- return reflectionLongConvert(reader.sint64(), longType);
2403
- }
2404
- }
2405
- }
2406
-
2407
- /**
2408
- * Writes proto3 messages in binary format using reflection information.
2409
- *
2410
- * https://developers.google.com/protocol-buffers/docs/encoding
2411
- */
2412
- class ReflectionBinaryWriter {
2413
- constructor(info) {
2414
- this.info = info;
2415
- }
2416
- prepare() {
2417
- if (!this.fields) {
2418
- const fieldsInput = this.info.fields ? this.info.fields.concat() : [];
2419
- this.fields = fieldsInput.sort((a, b) => a.no - b.no);
2420
- }
2421
- }
2422
- /**
2423
- * Writes the message to binary format.
2424
- */
2425
- write(message, writer, options) {
2426
- this.prepare();
2427
- for (const field of this.fields) {
2428
- let value, // this will be our field value, whether it is member of a oneof or not
2429
- emitDefault, // whether we emit the default value (only true for oneof members)
2430
- repeated = field.repeat, localName = field.localName;
2431
- // handle oneof ADT
2432
- if (field.oneof) {
2433
- const group = message[field.oneof];
2434
- if (group.oneofKind !== localName)
2435
- continue; // if field is not selected, skip
2436
- value = group[localName];
2437
- emitDefault = true;
2438
- }
2439
- else {
2440
- value = message[localName];
2441
- emitDefault = false;
2442
- }
2443
- // we have handled oneof above. we just have to honor `emitDefault`.
2444
- switch (field.kind) {
2445
- case "scalar":
2446
- case "enum":
2447
- let T = field.kind == "enum" ? ScalarType.INT32 : field.T;
2448
- if (repeated) {
2449
- assert(Array.isArray(value));
2450
- if (repeated == RepeatType.PACKED)
2451
- this.packed(writer, T, field.no, value);
2452
- else
2453
- for (const item of value)
2454
- this.scalar(writer, T, field.no, item, true);
2455
- }
2456
- else if (value === undefined)
2457
- assert(field.opt);
2458
- else
2459
- this.scalar(writer, T, field.no, value, emitDefault || field.opt);
2460
- break;
2461
- case "message":
2462
- if (repeated) {
2463
- assert(Array.isArray(value));
2464
- for (const item of value)
2465
- this.message(writer, options, field.T(), field.no, item);
2466
- }
2467
- else {
2468
- this.message(writer, options, field.T(), field.no, value);
2469
- }
2470
- break;
2471
- case "map":
2472
- assert(typeof value == 'object' && value !== null);
2473
- for (const [key, val] of Object.entries(value))
2474
- this.mapEntry(writer, options, field, key, val);
2475
- break;
2476
- }
2477
- }
2478
- let u = options.writeUnknownFields;
2479
- if (u !== false)
2480
- (u === true ? UnknownFieldHandler.onWrite : u)(this.info.typeName, message, writer);
2481
- }
2482
- mapEntry(writer, options, field, key, value) {
2483
- writer.tag(field.no, WireType.LengthDelimited);
2484
- writer.fork();
2485
- // javascript only allows number or string for object properties
2486
- // we convert from our representation to the protobuf type
2487
- let keyValue = key;
2488
- switch (field.K) {
2489
- case ScalarType.INT32:
2490
- case ScalarType.FIXED32:
2491
- case ScalarType.UINT32:
2492
- case ScalarType.SFIXED32:
2493
- case ScalarType.SINT32:
2494
- keyValue = Number.parseInt(key);
2495
- break;
2496
- case ScalarType.BOOL:
2497
- assert(key == 'true' || key == 'false');
2498
- keyValue = key == 'true';
2499
- break;
2500
- }
2501
- // write key, expecting key field number = 1
2502
- this.scalar(writer, field.K, 1, keyValue, true);
2503
- // write value, expecting value field number = 2
2504
- switch (field.V.kind) {
2505
- case 'scalar':
2506
- this.scalar(writer, field.V.T, 2, value, true);
2507
- break;
2508
- case 'enum':
2509
- this.scalar(writer, ScalarType.INT32, 2, value, true);
2510
- break;
2511
- case 'message':
2512
- this.message(writer, options, field.V.T(), 2, value);
2513
- break;
2514
- }
2515
- writer.join();
2516
- }
2517
- message(writer, options, handler, fieldNo, value) {
2518
- if (value === undefined)
2519
- return;
2520
- handler.internalBinaryWrite(value, writer.tag(fieldNo, WireType.LengthDelimited).fork(), options);
2521
- writer.join();
2522
- }
2523
- /**
2524
- * Write a single scalar value.
2525
- */
2526
- scalar(writer, type, fieldNo, value, emitDefault) {
2527
- let [wireType, method, isDefault] = this.scalarInfo(type, value);
2528
- if (!isDefault || emitDefault) {
2529
- writer.tag(fieldNo, wireType);
2530
- writer[method](value);
2531
- }
2532
- }
2533
- /**
2534
- * Write an array of scalar values in packed format.
2535
- */
2536
- packed(writer, type, fieldNo, value) {
2537
- if (!value.length)
2538
- return;
2539
- assert(type !== ScalarType.BYTES && type !== ScalarType.STRING);
2540
- // write tag
2541
- writer.tag(fieldNo, WireType.LengthDelimited);
2542
- // begin length-delimited
2543
- writer.fork();
2544
- // write values without tags
2545
- let [, method,] = this.scalarInfo(type);
2546
- for (let i = 0; i < value.length; i++)
2547
- writer[method](value[i]);
2548
- // end length delimited
2549
- writer.join();
2550
- }
2551
- /**
2552
- * Get information for writing a scalar value.
2553
- *
2554
- * Returns tuple:
2555
- * [0]: appropriate WireType
2556
- * [1]: name of the appropriate method of IBinaryWriter
2557
- * [2]: whether the given value is a default value
2558
- *
2559
- * If argument `value` is omitted, [2] is always false.
2560
- */
2561
- scalarInfo(type, value) {
2562
- let t = WireType.Varint;
2563
- let m;
2564
- let i = value === undefined;
2565
- let d = value === 0;
2566
- switch (type) {
2567
- case ScalarType.INT32:
2568
- m = "int32";
2569
- break;
2570
- case ScalarType.STRING:
2571
- d = i || !value.length;
2572
- t = WireType.LengthDelimited;
2573
- m = "string";
2574
- break;
2575
- case ScalarType.BOOL:
2576
- d = value === false;
2577
- m = "bool";
2578
- break;
2579
- case ScalarType.UINT32:
2580
- m = "uint32";
2581
- break;
2582
- case ScalarType.DOUBLE:
2583
- t = WireType.Bit64;
2584
- m = "double";
2585
- break;
2586
- case ScalarType.FLOAT:
2587
- t = WireType.Bit32;
2588
- m = "float";
2589
- break;
2590
- case ScalarType.INT64:
2591
- d = i || PbLong.from(value).isZero();
2592
- m = "int64";
2593
- break;
2594
- case ScalarType.UINT64:
2595
- d = i || PbULong.from(value).isZero();
2596
- m = "uint64";
2597
- break;
2598
- case ScalarType.FIXED64:
2599
- d = i || PbULong.from(value).isZero();
2600
- t = WireType.Bit64;
2601
- m = "fixed64";
2602
- break;
2603
- case ScalarType.BYTES:
2604
- d = i || !value.byteLength;
2605
- t = WireType.LengthDelimited;
2606
- m = "bytes";
2607
- break;
2608
- case ScalarType.FIXED32:
2609
- t = WireType.Bit32;
2610
- m = "fixed32";
2611
- break;
2612
- case ScalarType.SFIXED32:
2613
- t = WireType.Bit32;
2614
- m = "sfixed32";
2615
- break;
2616
- case ScalarType.SFIXED64:
2617
- d = i || PbLong.from(value).isZero();
2618
- t = WireType.Bit64;
2619
- m = "sfixed64";
2620
- break;
2621
- case ScalarType.SINT32:
2622
- m = "sint32";
2623
- break;
2624
- case ScalarType.SINT64:
2625
- d = i || PbLong.from(value).isZero();
2626
- m = "sint64";
2627
- break;
2628
- }
2629
- return [t, m, i || d];
2630
- }
2631
- }
2632
-
2633
- /**
2634
- * Creates an instance of the generic message, using the field
2635
- * information.
2636
- */
2637
- function reflectionCreate(type) {
2638
- const msg = {};
2639
- Object.defineProperty(msg, MESSAGE_TYPE, { enumerable: false, value: type });
2640
- for (let field of type.fields) {
2641
- let name = field.localName;
2642
- if (field.opt)
2643
- continue;
2644
- if (field.oneof)
2645
- msg[field.oneof] = { oneofKind: undefined };
2646
- else if (field.repeat)
2647
- msg[name] = [];
2648
- else
2649
- switch (field.kind) {
2650
- case "scalar":
2651
- msg[name] = reflectionScalarDefault(field.T, field.L);
2652
- break;
2653
- case "enum":
2654
- // we require 0 to be default value for all enums
2655
- msg[name] = 0;
2656
- break;
2657
- case "map":
2658
- msg[name] = {};
2659
- break;
2660
- }
2661
- }
2662
- return msg;
2663
- }
2664
-
2665
- /**
2666
- * Copy partial data into the target message.
2667
- *
2668
- * If a singular scalar or enum field is present in the source, it
2669
- * replaces the field in the target.
2670
- *
2671
- * If a singular message field is present in the source, it is merged
2672
- * with the target field by calling mergePartial() of the responsible
2673
- * message type.
2674
- *
2675
- * If a repeated field is present in the source, its values replace
2676
- * all values in the target array, removing extraneous values.
2677
- * Repeated message fields are copied, not merged.
2678
- *
2679
- * If a map field is present in the source, entries are added to the
2680
- * target map, replacing entries with the same key. Entries that only
2681
- * exist in the target remain. Entries with message values are copied,
2682
- * not merged.
2683
- *
2684
- * Note that this function differs from protobuf merge semantics,
2685
- * which appends repeated fields.
2686
- */
2687
- function reflectionMergePartial(info, target, source) {
2688
- let fieldValue, // the field value we are working with
2689
- input = source, output; // where we want our field value to go
2690
- for (let field of info.fields) {
2691
- let name = field.localName;
2692
- if (field.oneof) {
2693
- const group = input[field.oneof]; // this is the oneof`s group in the source
2694
- if ((group === null || group === void 0 ? void 0 : group.oneofKind) == undefined) { // the user is free to omit
2695
- continue; // we skip this field, and all other members too
2696
- }
2697
- fieldValue = group[name]; // our value comes from the the oneof group of the source
2698
- output = target[field.oneof]; // and our output is the oneof group of the target
2699
- output.oneofKind = group.oneofKind; // always update discriminator
2700
- if (fieldValue == undefined) {
2701
- delete output[name]; // remove any existing value
2702
- continue; // skip further work on field
2703
- }
2704
- }
2705
- else {
2706
- fieldValue = input[name]; // we are using the source directly
2707
- output = target; // we want our field value to go directly into the target
2708
- if (fieldValue == undefined) {
2709
- continue; // skip further work on field, existing value is used as is
2710
- }
2711
- }
2712
- if (field.repeat)
2713
- output[name].length = fieldValue.length; // resize target array to match source array
2714
- // now we just work with `fieldValue` and `output` to merge the value
2715
- switch (field.kind) {
2716
- case "scalar":
2717
- case "enum":
2718
- if (field.repeat)
2719
- for (let i = 0; i < fieldValue.length; i++)
2720
- output[name][i] = fieldValue[i]; // not a reference type
2721
- else
2722
- output[name] = fieldValue; // not a reference type
2723
- break;
2724
- case "message":
2725
- let T = field.T();
2726
- if (field.repeat)
2727
- for (let i = 0; i < fieldValue.length; i++)
2728
- output[name][i] = T.create(fieldValue[i]);
2729
- else if (output[name] === undefined)
2730
- output[name] = T.create(fieldValue); // nothing to merge with
2731
- else
2732
- T.mergePartial(output[name], fieldValue);
2733
- break;
2734
- case "map":
2735
- // Map and repeated fields are simply overwritten, not appended or merged
2736
- switch (field.V.kind) {
2737
- case "scalar":
2738
- case "enum":
2739
- Object.assign(output[name], fieldValue); // elements are not reference types
2740
- break;
2741
- case "message":
2742
- let T = field.V.T();
2743
- for (let k of Object.keys(fieldValue))
2744
- output[name][k] = T.create(fieldValue[k]);
2745
- break;
2746
- }
2747
- break;
2748
- }
2749
- }
2750
- }
2751
-
2752
- /**
2753
- * Determines whether two message of the same type have the same field values.
2754
- * Checks for deep equality, traversing repeated fields, oneof groups, maps
2755
- * and messages recursively.
2756
- * Will also return true if both messages are `undefined`.
2757
- */
2758
- function reflectionEquals(info, a, b) {
2759
- if (a === b)
2760
- return true;
2761
- if (!a || !b)
2762
- return false;
2763
- for (let field of info.fields) {
2764
- let localName = field.localName;
2765
- let val_a = field.oneof ? a[field.oneof][localName] : a[localName];
2766
- let val_b = field.oneof ? b[field.oneof][localName] : b[localName];
2767
- switch (field.kind) {
2768
- case "enum":
2769
- case "scalar":
2770
- let t = field.kind == "enum" ? ScalarType.INT32 : field.T;
2771
- if (!(field.repeat
2772
- ? repeatedPrimitiveEq(t, val_a, val_b)
2773
- : primitiveEq(t, val_a, val_b)))
2774
- return false;
2775
- break;
2776
- case "map":
2777
- if (!(field.V.kind == "message"
2778
- ? repeatedMsgEq(field.V.T(), objectValues(val_a), objectValues(val_b))
2779
- : repeatedPrimitiveEq(field.V.kind == "enum" ? ScalarType.INT32 : field.V.T, objectValues(val_a), objectValues(val_b))))
2780
- return false;
2781
- break;
2782
- case "message":
2783
- let T = field.T();
2784
- if (!(field.repeat
2785
- ? repeatedMsgEq(T, val_a, val_b)
2786
- : T.equals(val_a, val_b)))
2787
- return false;
2788
- break;
2789
- }
2790
- }
2791
- return true;
2792
- }
2793
- const objectValues = Object.values;
2794
- function primitiveEq(type, a, b) {
2795
- if (a === b)
2796
- return true;
2797
- if (type !== ScalarType.BYTES)
2798
- return false;
2799
- let ba = a;
2800
- let bb = b;
2801
- if (ba.length !== bb.length)
2802
- return false;
2803
- for (let i = 0; i < ba.length; i++)
2804
- if (ba[i] != bb[i])
2805
- return false;
2806
- return true;
2807
- }
2808
- function repeatedPrimitiveEq(type, a, b) {
2809
- if (a.length !== b.length)
2810
- return false;
2811
- for (let i = 0; i < a.length; i++)
2812
- if (!primitiveEq(type, a[i], b[i]))
2813
- return false;
2814
- return true;
2815
- }
2816
- function repeatedMsgEq(type, a, b) {
2817
- if (a.length !== b.length)
2818
- return false;
2819
- for (let i = 0; i < a.length; i++)
2820
- if (!type.equals(a[i], b[i]))
2821
- return false;
2822
- return true;
2823
- }
2824
-
2825
- /**
2826
- * This standard message type provides reflection-based
2827
- * operations to work with a message.
2828
- */
2829
- class MessageType {
2830
- constructor(name, fields, options) {
2831
- this.defaultCheckDepth = 16;
2832
- this.typeName = name;
2833
- this.fields = fields.map(normalizeFieldInfo);
2834
- this.options = options !== null && options !== void 0 ? options : {};
2835
- this.refTypeCheck = new ReflectionTypeCheck(this);
2836
- this.refJsonReader = new ReflectionJsonReader(this);
2837
- this.refJsonWriter = new ReflectionJsonWriter(this);
2838
- this.refBinReader = new ReflectionBinaryReader(this);
2839
- this.refBinWriter = new ReflectionBinaryWriter(this);
2840
- }
2841
- create(value) {
2842
- let message = reflectionCreate(this);
2843
- if (value !== undefined) {
2844
- reflectionMergePartial(this, message, value);
2845
- }
2846
- return message;
2847
- }
2848
- /**
2849
- * Clone the message.
2850
- *
2851
- * Unknown fields are discarded.
2852
- */
2853
- clone(message) {
2854
- let copy = this.create();
2855
- reflectionMergePartial(this, copy, message);
2856
- return copy;
2857
- }
2858
- /**
2859
- * Determines whether two message of the same type have the same field values.
2860
- * Checks for deep equality, traversing repeated fields, oneof groups, maps
2861
- * and messages recursively.
2862
- * Will also return true if both messages are `undefined`.
2863
- */
2864
- equals(a, b) {
2865
- return reflectionEquals(this, a, b);
2866
- }
2867
- /**
2868
- * Is the given value assignable to our message type
2869
- * and contains no [excess properties](https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks)?
2870
- */
2871
- is(arg, depth = this.defaultCheckDepth) {
2872
- return this.refTypeCheck.is(arg, depth, false);
2873
- }
2874
- /**
2875
- * Is the given value assignable to our message type,
2876
- * regardless of [excess properties](https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks)?
2877
- */
2878
- isAssignable(arg, depth = this.defaultCheckDepth) {
2879
- return this.refTypeCheck.is(arg, depth, true);
2880
- }
2881
- /**
2882
- * Copy partial data into the target message.
2883
- */
2884
- mergePartial(target, source) {
2885
- reflectionMergePartial(this, target, source);
2886
- }
2887
- /**
2888
- * Create a new message from binary format.
2889
- */
2890
- fromBinary(data, options) {
2891
- let opt = binaryReadOptions(options);
2892
- return this.internalBinaryRead(opt.readerFactory(data), data.byteLength, opt);
2893
- }
2894
- /**
2895
- * Read a new message from a JSON value.
2896
- */
2897
- fromJson(json, options) {
2898
- return this.internalJsonRead(json, jsonReadOptions(options));
2899
- }
2900
- /**
2901
- * Read a new message from a JSON string.
2902
- * This is equivalent to `T.fromJson(JSON.parse(json))`.
2903
- */
2904
- fromJsonString(json, options) {
2905
- let value = JSON.parse(json);
2906
- return this.fromJson(value, options);
2907
- }
2908
- /**
2909
- * Write the message to canonical JSON value.
2910
- */
2911
- toJson(message, options) {
2912
- return this.internalJsonWrite(message, jsonWriteOptions(options));
2913
- }
2914
- /**
2915
- * Convert the message to canonical JSON string.
2916
- * This is equivalent to `JSON.stringify(T.toJson(t))`
2917
- */
2918
- toJsonString(message, options) {
2919
- var _a;
2920
- let value = this.toJson(message, options);
2921
- return JSON.stringify(value, null, (_a = options === null || options === void 0 ? void 0 : options.prettySpaces) !== null && _a !== void 0 ? _a : 0);
2922
- }
2923
- /**
2924
- * Write the message to binary format.
2925
- */
2926
- toBinary(message, options) {
2927
- let opt = binaryWriteOptions(options);
2928
- return this.internalBinaryWrite(message, opt.writerFactory(), opt).finish();
2929
- }
2930
- /**
2931
- * This is an internal method. If you just want to read a message from
2932
- * JSON, use `fromJson()` or `fromJsonString()`.
2933
- *
2934
- * Reads JSON value and merges the fields into the target
2935
- * according to protobuf rules. If the target is omitted,
2936
- * a new instance is created first.
2937
- */
2938
- internalJsonRead(json, options, target) {
2939
- if (json !== null && typeof json == "object" && !Array.isArray(json)) {
2940
- let message = target !== null && target !== void 0 ? target : this.create();
2941
- this.refJsonReader.read(json, message, options);
2942
- return message;
2943
- }
2944
- throw new Error(`Unable to parse message ${this.typeName} from JSON ${typeofJsonValue(json)}.`);
2945
- }
2946
- /**
2947
- * This is an internal method. If you just want to write a message
2948
- * to JSON, use `toJson()` or `toJsonString().
2949
- *
2950
- * Writes JSON value and returns it.
2951
- */
2952
- internalJsonWrite(message, options) {
2953
- return this.refJsonWriter.write(message, options);
2954
- }
2955
- /**
2956
- * This is an internal method. If you just want to write a message
2957
- * in binary format, use `toBinary()`.
2958
- *
2959
- * Serializes the message in binary format and appends it to the given
2960
- * writer. Returns passed writer.
2961
- */
2962
- internalBinaryWrite(message, writer, options) {
2963
- this.refBinWriter.write(message, writer, options);
2964
- return writer;
2965
- }
2966
- /**
2967
- * This is an internal method. If you just want to read a message from
2968
- * binary data, use `fromBinary()`.
2969
- *
2970
- * Reads data from binary format and merges the fields into
2971
- * the target according to protobuf rules. If the target is
2972
- * omitted, a new instance is created first.
2973
- */
2974
- internalBinaryRead(reader, length, options, target) {
2975
- let message = target !== null && target !== void 0 ? target : this.create();
2976
- this.refBinReader.read(reader, message, options, length);
2977
- return message;
2978
- }
2979
- }
2980
-
2981
79
  /**
2982
80
  * `NullValue` is a singleton enumeration to represent the null value for the
2983
81
  * `Value` type union.
@@ -4252,13 +1350,29 @@ const Codes = {
4252
1350
  InvalidArgument: 'INVALID_ARGUMENT',
4253
1351
  NotFound: 'NOT_FOUND',
4254
1352
  DataLoss: 'DATA_LOSS',
4255
- Unavailable: 'UNAVAILABLE'
1353
+ Unavailable: 'UNAVAILABLE',
4256
1354
  };
4257
1355
  class GRPCService {
4258
- constructor(config, client) {
4259
- this.onFulfilled = (value) => {
4260
- // no-op, just return the value
4261
- return value;
1356
+ get _cacheActive() {
1357
+ // the cache is "active" (able to be used) if the config enabled it, AND the gRPC stream is live
1358
+ return this._cacheEnabled && this._streamAlive;
1359
+ }
1360
+ constructor(config, client, logger) {
1361
+ var _a;
1362
+ this.logger = logger;
1363
+ this._cacheEnabled = false;
1364
+ this._streamAlive = false;
1365
+ this._streamConnectAttempt = 0;
1366
+ this._streamConnectBackoff = BASE_EVENT_STREAM_RETRY_BACKOFF_MS;
1367
+ // default to false here - reassigned in the constructor if we actaully need to connect
1368
+ this.streamConnection = Promise.resolve(false);
1369
+ this.objectParser = (struct) => {
1370
+ if (struct !== undefined) {
1371
+ return Struct.toJson(struct);
1372
+ }
1373
+ else {
1374
+ throw new ParseError('Object value undefined or missing.');
1375
+ }
4262
1376
  };
4263
1377
  this.onRejected = (err) => {
4264
1378
  // map the errors
@@ -4276,70 +1390,136 @@ class GRPCService {
4276
1390
  }
4277
1391
  };
4278
1392
  const { host, port, tls, socketPath } = config;
4279
- this.client = client
1393
+ this._maxEventStreamRetries = (_a = config.maxEventStreamRetries) !== null && _a !== void 0 ? _a : DEFAULT_MAX_EVENT_STREAM_RETRIES;
1394
+ this._client = client
4280
1395
  ? client
4281
1396
  : new ServiceClient(new GrpcTransport({
4282
1397
  host: socketPath ? `unix://${socketPath}` : `${host}:${port}`,
4283
- channelCredentials: tls
4284
- ? grpc.credentials.createSsl()
4285
- : grpc.credentials.createInsecure(),
1398
+ channelCredentials: tls ? grpc.credentials.createSsl() : grpc.credentials.createInsecure(),
4286
1399
  }));
1400
+ // for now, we only need streaming if the cache is enabled (will need to be pulled out once we support events)
1401
+ if (config.cache === 'lru') {
1402
+ this._cacheEnabled = true;
1403
+ this._cache = new LRU({ maxSize: config.maxCacheSize || DEFAULT_MAX_CACHE_SIZE, sizeCalculation: () => 1 });
1404
+ this.streamConnection = this.connectStream();
1405
+ }
4287
1406
  }
4288
1407
  resolveBoolean(flagKey, context, logger) {
4289
1408
  return __awaiter(this, void 0, void 0, function* () {
4290
- const { response } = yield this.client.resolveBoolean({
4291
- flagKey,
4292
- context: this.convertContext(context, logger),
4293
- }).then(this.onFulfilled, this.onRejected);
4294
- return {
4295
- value: response.value,
4296
- reason: response.reason,
4297
- variant: response.variant,
4298
- };
1409
+ return this.resolve(this._client.resolveBoolean, flagKey, context, logger);
4299
1410
  });
4300
1411
  }
4301
1412
  resolveString(flagKey, context, logger) {
4302
1413
  return __awaiter(this, void 0, void 0, function* () {
4303
- const { response } = yield this.client.resolveString({
4304
- flagKey,
4305
- context: this.convertContext(context, logger),
4306
- }).then(this.onFulfilled, this.onRejected);
4307
- return {
4308
- value: response.value,
4309
- reason: response.reason,
4310
- variant: response.variant,
4311
- };
1414
+ return this.resolve(this._client.resolveString, flagKey, context, logger);
4312
1415
  });
4313
1416
  }
4314
1417
  resolveNumber(flagKey, context, logger) {
4315
1418
  return __awaiter(this, void 0, void 0, function* () {
4316
- const { response } = yield this.client.resolveFloat({
4317
- flagKey,
4318
- context: this.convertContext(context, logger),
4319
- }).then(this.onFulfilled, this.onRejected);
4320
- return {
4321
- value: response.value,
4322
- reason: response.reason,
4323
- variant: response.variant,
4324
- };
1419
+ return this.resolve(this._client.resolveFloat, flagKey, context, logger);
4325
1420
  });
4326
1421
  }
4327
1422
  resolveObject(flagKey, context, logger) {
4328
1423
  return __awaiter(this, void 0, void 0, function* () {
4329
- const { response } = yield this.client.resolveObject({
4330
- flagKey,
4331
- context: this.convertContext(context, logger),
4332
- }).then(this.onFulfilled, this.onRejected);
4333
- if (response.value !== undefined) {
4334
- return {
4335
- value: Struct.toJson(response.value),
4336
- reason: response.reason,
4337
- variant: response.variant,
4338
- };
1424
+ return this.resolve(this._client.resolveObject, flagKey, context, logger, this.objectParser);
1425
+ });
1426
+ }
1427
+ connectStream() {
1428
+ return new Promise((resolve, reject) => {
1429
+ var _a;
1430
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(`${FlagdProvider.name}: connecting stream, attempt ${this._streamConnectAttempt}...`);
1431
+ const stream = this._client.eventStream({});
1432
+ stream.responses.onError(() => {
1433
+ this.handleError(reject);
1434
+ });
1435
+ stream.responses.onComplete(() => {
1436
+ this.handleComplete();
1437
+ });
1438
+ stream.responses.onMessage((message) => {
1439
+ if (message.type === EVENT_PROVIDER_READY) {
1440
+ this.handleProviderReady(resolve);
1441
+ }
1442
+ else if (message.type === EVENT_CONFIGURATION_CHANGE) {
1443
+ this.handleFlagsChanged(message);
1444
+ }
1445
+ });
1446
+ });
1447
+ }
1448
+ handleProviderReady(resolve) {
1449
+ var _a;
1450
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`${FlagdProvider.name}: streaming connection established with flagd`);
1451
+ this._streamAlive = true;
1452
+ this._streamConnectAttempt = 0;
1453
+ this._streamConnectBackoff = BASE_EVENT_STREAM_RETRY_BACKOFF_MS;
1454
+ resolve(true);
1455
+ }
1456
+ handleFlagsChanged(message) {
1457
+ var _a;
1458
+ if (message.data) {
1459
+ const data = Struct.toJson(message.data);
1460
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(`${FlagdProvider.name}: got message: ${JSON.stringify(data, undefined, 2)}`);
1461
+ if (data && typeof data === 'object' && 'flags' in data && (data === null || data === void 0 ? void 0 : data['flags'])) {
1462
+ const flagChangeMessage = data;
1463
+ // remove each changed key from cache
1464
+ Object.keys(flagChangeMessage.flags || []).forEach((key) => {
1465
+ var _a, _b;
1466
+ if ((_a = this._cache) === null || _a === void 0 ? void 0 : _a.delete(key)) {
1467
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`${FlagdProvider.name}: evicted key: ${key} from cache.`);
1468
+ }
1469
+ });
4339
1470
  }
4340
- else {
4341
- throw new ParseError('Object value undefined or missing.');
1471
+ }
1472
+ }
1473
+ handleError(reject) {
1474
+ var _a, _b, _c;
1475
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.error(`${FlagdProvider.name}: streaming connection error, will attempt reconnect...`);
1476
+ (_b = this._cache) === null || _b === void 0 ? void 0 : _b.clear();
1477
+ this._streamAlive = false;
1478
+ // if we haven't reached max attempt, reconnect after backoff
1479
+ if (this._streamConnectAttempt <= this._maxEventStreamRetries) {
1480
+ this._streamConnectAttempt++;
1481
+ setTimeout(() => {
1482
+ this._streamConnectBackoff = this._streamConnectBackoff * 2;
1483
+ this.connectStream();
1484
+ }, this._streamConnectBackoff);
1485
+ }
1486
+ else {
1487
+ // after max attempts, give up
1488
+ const errorMessage = `${FlagdProvider.name}: max stream connect attempts (${this._maxEventStreamRetries} reached)`;
1489
+ (_c = this.logger) === null || _c === void 0 ? void 0 : _c.error(errorMessage);
1490
+ reject(new Error(errorMessage));
1491
+ }
1492
+ }
1493
+ handleComplete() {
1494
+ var _a, _b;
1495
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`${FlagdProvider.name}: streaming connection closed gracefully`);
1496
+ (_b = this._cache) === null || _b === void 0 ? void 0 : _b.clear();
1497
+ this._streamAlive = false;
1498
+ }
1499
+ resolve(resolver, flagKey, context, logger, parser) {
1500
+ var _a, _b;
1501
+ return __awaiter(this, void 0, void 0, function* () {
1502
+ if (this._cacheActive) {
1503
+ const cached = (_a = this._cache) === null || _a === void 0 ? void 0 : _a.get(flagKey);
1504
+ if (cached) {
1505
+ return Object.assign(Object.assign({}, cached), { reason: StandardResolutionReasons.CACHED });
1506
+ }
4342
1507
  }
1508
+ // invoke the passed resolver method
1509
+ const { response } = yield resolver
1510
+ .call(this._client, { flagKey, context: this.convertContext(context, logger) })
1511
+ .then((resolved) => resolved, this.onRejected);
1512
+ const resolved = {
1513
+ // invoke the parser method if passed
1514
+ value: parser ? parser.call(this, response.value) : response.value,
1515
+ reason: response.reason,
1516
+ variant: response.variant,
1517
+ };
1518
+ if (this._cacheActive && response.reason === StandardResolutionReasons.STATIC) {
1519
+ // cache this static value
1520
+ (_b = this._cache) === null || _b === void 0 ? void 0 : _b.set(flagKey, Object.assign({}, resolved));
1521
+ }
1522
+ return resolved;
4343
1523
  });
4344
1524
  }
4345
1525
  convertContext(context, logger) {
@@ -4358,7 +1538,19 @@ class GRPCService {
4358
1538
  }
4359
1539
 
4360
1540
  class FlagdProvider {
4361
- constructor(options, service) {
1541
+ /**
1542
+ * Promise indicating the gRPC stream is connected.
1543
+ *
1544
+ * Can be used in instances where the provider being connected to the event stream is a prerequisite
1545
+ * to execution (e.g. testing). Not necessary for standard usage.
1546
+ *
1547
+ * @returns true if stream connected successfully, false if connection not enabled.
1548
+ */
1549
+ get streamConnection() {
1550
+ return this._service.streamConnection;
1551
+ }
1552
+ constructor(options, service, logger) {
1553
+ this.logger = logger;
4362
1554
  this.metadata = {
4363
1555
  name: 'flagd Provider',
4364
1556
  };
@@ -4367,22 +1559,26 @@ class FlagdProvider {
4367
1559
  logger.error(err === null || err === void 0 ? void 0 : err.stack);
4368
1560
  throw err;
4369
1561
  };
4370
- this._service = service ? service : new GRPCService(getConfig(options));
1562
+ this._service = service ? service : new GRPCService(getConfig(options), undefined, logger);
4371
1563
  }
4372
1564
  resolveBooleanEvaluation(flagKey, _, transformedContext, logger) {
4373
- return this._service.resolveBoolean(flagKey, transformedContext, logger)
1565
+ return this._service
1566
+ .resolveBoolean(flagKey, transformedContext, logger)
4374
1567
  .catch((err) => this.logRejected(err, flagKey, logger));
4375
1568
  }
4376
1569
  resolveStringEvaluation(flagKey, _, transformedContext, logger) {
4377
- return this._service.resolveString(flagKey, transformedContext, logger)
1570
+ return this._service
1571
+ .resolveString(flagKey, transformedContext, logger)
4378
1572
  .catch((err) => this.logRejected(err, flagKey, logger));
4379
1573
  }
4380
1574
  resolveNumberEvaluation(flagKey, _, transformedContext, logger) {
4381
- return this._service.resolveNumber(flagKey, transformedContext, logger)
1575
+ return this._service
1576
+ .resolveNumber(flagKey, transformedContext, logger)
4382
1577
  .catch((err) => this.logRejected(err, flagKey, logger));
4383
1578
  }
4384
1579
  resolveObjectEvaluation(flagKey, _, transformedContext, logger) {
4385
- return this._service.resolveObject(flagKey, transformedContext, logger)
1580
+ return this._service
1581
+ .resolveObject(flagKey, transformedContext, logger)
4386
1582
  .catch((err) => this.logRejected(err, flagKey, logger));
4387
1583
  }
4388
1584
  }