bson 4.5.1 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/HISTORY.md +572 -0
  2. package/bower.json +1 -1
  3. package/bson.d.ts +70 -13
  4. package/dist/bson.browser.esm.js +314 -177
  5. package/dist/bson.browser.esm.js.map +1 -1
  6. package/dist/bson.browser.umd.js +317 -176
  7. package/dist/bson.browser.umd.js.map +1 -1
  8. package/dist/bson.bundle.js +317 -176
  9. package/dist/bson.bundle.js.map +1 -1
  10. package/dist/bson.esm.js +314 -177
  11. package/dist/bson.esm.js.map +1 -1
  12. package/lib/binary.js +11 -9
  13. package/lib/binary.js.map +1 -1
  14. package/lib/bson.js +11 -3
  15. package/lib/bson.js.map +1 -1
  16. package/lib/code.js +0 -1
  17. package/lib/code.js.map +1 -1
  18. package/lib/constants.js +5 -1
  19. package/lib/constants.js.map +1 -1
  20. package/lib/db_ref.js +0 -1
  21. package/lib/db_ref.js.map +1 -1
  22. package/lib/decimal128.js +6 -5
  23. package/lib/decimal128.js.map +1 -1
  24. package/lib/double.js +3 -1
  25. package/lib/double.js.map +1 -1
  26. package/lib/ensure_buffer.js +3 -2
  27. package/lib/ensure_buffer.js.map +1 -1
  28. package/lib/error.js +55 -0
  29. package/lib/error.js.map +1 -0
  30. package/lib/extended_json.js +11 -5
  31. package/lib/extended_json.js.map +1 -1
  32. package/lib/int_32.js +4 -2
  33. package/lib/int_32.js.map +1 -1
  34. package/lib/objectid.js +39 -35
  35. package/lib/objectid.js.map +1 -1
  36. package/lib/parser/deserializer.js +131 -53
  37. package/lib/parser/deserializer.js.map +1 -1
  38. package/lib/parser/serializer.js +13 -12
  39. package/lib/parser/serializer.js.map +1 -1
  40. package/lib/regexp.js +9 -2
  41. package/lib/regexp.js.map +1 -1
  42. package/lib/symbol.js +0 -2
  43. package/lib/symbol.js.map +1 -1
  44. package/lib/uuid.js +4 -4
  45. package/lib/uuid.js.map +1 -1
  46. package/lib/uuid_utils.js +2 -1
  47. package/lib/uuid_utils.js.map +1 -1
  48. package/package.json +16 -3
  49. package/src/binary.ts +12 -10
  50. package/src/bson.ts +7 -1
  51. package/src/code.ts +0 -1
  52. package/src/constants.ts +6 -0
  53. package/src/db_ref.ts +0 -1
  54. package/src/decimal128.ts +6 -5
  55. package/src/double.ts +4 -1
  56. package/src/ensure_buffer.ts +3 -2
  57. package/src/error.ts +23 -0
  58. package/src/extended_json.ts +13 -5
  59. package/src/int_32.ts +5 -2
  60. package/src/objectid.ts +40 -43
  61. package/src/parser/deserializer.ts +159 -57
  62. package/src/parser/serializer.ts +13 -12
  63. package/src/regexp.ts +14 -2
  64. package/src/symbol.ts +0 -2
  65. package/src/uuid.ts +4 -4
  66. package/src/uuid_utils.ts +2 -1
package/dist/bson.esm.js CHANGED
@@ -1,5 +1,96 @@
1
1
  import { Buffer } from 'buffer';
2
2
 
3
+ /*! *****************************************************************************
4
+ Copyright (c) Microsoft Corporation.
5
+
6
+ Permission to use, copy, modify, and/or distribute this software for any
7
+ purpose with or without fee is hereby granted.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
16
+ ***************************************************************************** */
17
+
18
+ /* global Reflect, Promise */
19
+ var _extendStatics = function extendStatics(d, b) {
20
+ _extendStatics = Object.setPrototypeOf || {
21
+ __proto__: []
22
+ } instanceof Array && function (d, b) {
23
+ d.__proto__ = b;
24
+ } || function (d, b) {
25
+ for (var p in b) {
26
+ if (b.hasOwnProperty(p)) d[p] = b[p];
27
+ }
28
+ };
29
+
30
+ return _extendStatics(d, b);
31
+ };
32
+
33
+ function __extends(d, b) {
34
+ _extendStatics(d, b);
35
+
36
+ function __() {
37
+ this.constructor = d;
38
+ }
39
+
40
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
41
+ }
42
+
43
+ var _assign = function __assign() {
44
+ _assign = Object.assign || function __assign(t) {
45
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
46
+ s = arguments[i];
47
+
48
+ for (var p in s) {
49
+ if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
50
+ }
51
+ }
52
+
53
+ return t;
54
+ };
55
+
56
+ return _assign.apply(this, arguments);
57
+ };
58
+
59
+ /** @public */
60
+ var BSONError = /** @class */ (function (_super) {
61
+ __extends(BSONError, _super);
62
+ function BSONError(message) {
63
+ var _this = _super.call(this, message) || this;
64
+ Object.setPrototypeOf(_this, BSONError.prototype);
65
+ return _this;
66
+ }
67
+ Object.defineProperty(BSONError.prototype, "name", {
68
+ get: function () {
69
+ return 'BSONError';
70
+ },
71
+ enumerable: false,
72
+ configurable: true
73
+ });
74
+ return BSONError;
75
+ }(Error));
76
+ /** @public */
77
+ var BSONTypeError = /** @class */ (function (_super) {
78
+ __extends(BSONTypeError, _super);
79
+ function BSONTypeError(message) {
80
+ var _this = _super.call(this, message) || this;
81
+ Object.setPrototypeOf(_this, BSONTypeError.prototype);
82
+ return _this;
83
+ }
84
+ Object.defineProperty(BSONTypeError.prototype, "name", {
85
+ get: function () {
86
+ return 'BSONTypeError';
87
+ },
88
+ enumerable: false,
89
+ configurable: true
90
+ });
91
+ return BSONTypeError;
92
+ }(TypeError));
93
+
3
94
  function checkForMath(potentialGlobal) {
4
95
  // eslint-disable-next-line eqeqeq
5
96
  return potentialGlobal && potentialGlobal.Math == Math && potentialGlobal;
@@ -111,7 +202,7 @@ function deprecate(fn, message) {
111
202
  * @param potentialBuffer - The potential buffer
112
203
  * @returns Buffer the input if potentialBuffer is a buffer, or a buffer that
113
204
  * wraps a passed in Uint8Array
114
- * @throws TypeError If anything other than a Buffer or Uint8Array is passed in
205
+ * @throws BSONTypeError If anything other than a Buffer or Uint8Array is passed in
115
206
  */
116
207
  function ensureBuffer(potentialBuffer) {
117
208
  if (ArrayBuffer.isView(potentialBuffer)) {
@@ -120,7 +211,7 @@ function ensureBuffer(potentialBuffer) {
120
211
  if (isAnyArrayBuffer(potentialBuffer)) {
121
212
  return Buffer.from(potentialBuffer);
122
213
  }
123
- throw new TypeError('Must use either Buffer or TypedArray');
214
+ throw new BSONTypeError('Must use either Buffer or TypedArray');
124
215
  }
125
216
 
126
217
  // Validation regex for v4 uuid (validates with or without dashes)
@@ -130,7 +221,7 @@ var uuidValidateString = function (str) {
130
221
  };
131
222
  var uuidHexStringToBuffer = function (hexString) {
132
223
  if (!uuidValidateString(hexString)) {
133
- throw new TypeError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".');
224
+ throw new BSONTypeError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".');
134
225
  }
135
226
  var sanitizedHexString = hexString.replace(/-/g, '');
136
227
  return Buffer.from(sanitizedHexString, 'hex');
@@ -178,7 +269,7 @@ var UUID = /** @class */ (function () {
178
269
  this.id = uuidHexStringToBuffer(input);
179
270
  }
180
271
  else {
181
- throw new TypeError('Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).');
272
+ throw new BSONTypeError('Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).');
182
273
  }
183
274
  }
184
275
  Object.defineProperty(UUID.prototype, "id", {
@@ -218,14 +309,13 @@ var UUID = /** @class */ (function () {
218
309
  };
219
310
  /**
220
311
  * Converts the id into a 36 character (dashes included) hex string, unless a encoding is specified.
221
- * @internal
222
312
  */
223
313
  UUID.prototype.toString = function (encoding) {
224
314
  return encoding ? this.id.toString(encoding) : this.toHexString();
225
315
  };
226
316
  /**
227
- * Converts the id into its JSON string representation. A 36 character (dashes included) hex string in the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
228
- * @internal
317
+ * Converts the id into its JSON string representation.
318
+ * A 36 character (dashes included) hex string in the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
229
319
  */
230
320
  UUID.prototype.toJSON = function () {
231
321
  return this.toHexString();
@@ -337,7 +427,7 @@ var Binary = /** @class */ (function () {
337
427
  !ArrayBuffer.isView(buffer) &&
338
428
  !(buffer instanceof ArrayBuffer) &&
339
429
  !Array.isArray(buffer)) {
340
- throw new TypeError('Binary can only be constructed from string, Buffer, TypedArray, or Array<number>');
430
+ throw new BSONTypeError('Binary can only be constructed from string, Buffer, TypedArray, or Array<number>');
341
431
  }
342
432
  this.sub_type = subType !== null && subType !== void 0 ? subType : Binary.BSON_BINARY_SUBTYPE_DEFAULT;
343
433
  if (buffer == null) {
@@ -369,10 +459,10 @@ var Binary = /** @class */ (function () {
369
459
  Binary.prototype.put = function (byteValue) {
370
460
  // If it's a string and a has more than one character throw an error
371
461
  if (typeof byteValue === 'string' && byteValue.length !== 1) {
372
- throw new TypeError('only accepts single character String');
462
+ throw new BSONTypeError('only accepts single character String');
373
463
  }
374
464
  else if (typeof byteValue !== 'number' && byteValue.length !== 1)
375
- throw new TypeError('only accepts single character Uint8Array or Array');
465
+ throw new BSONTypeError('only accepts single character Uint8Array or Array');
376
466
  // Decode the byte value once
377
467
  var decodedByte;
378
468
  if (typeof byteValue === 'string') {
@@ -385,7 +475,7 @@ var Binary = /** @class */ (function () {
385
475
  decodedByte = byteValue[0];
386
476
  }
387
477
  if (decodedByte < 0 || decodedByte > 255) {
388
- throw new TypeError('only accepts number in a valid unsigned byte range 0-255');
478
+ throw new BSONTypeError('only accepts number in a valid unsigned byte range 0-255');
389
479
  }
390
480
  if (this.buffer.length > this.position) {
391
481
  this.buffer[this.position++] = decodedByte;
@@ -457,11 +547,9 @@ var Binary = /** @class */ (function () {
457
547
  Binary.prototype.length = function () {
458
548
  return this.position;
459
549
  };
460
- /** @internal */
461
550
  Binary.prototype.toJSON = function () {
462
551
  return this.buffer.toString('base64');
463
552
  };
464
- /** @internal */
465
553
  Binary.prototype.toString = function (format) {
466
554
  return this.buffer.toString(format);
467
555
  };
@@ -483,12 +571,11 @@ var Binary = /** @class */ (function () {
483
571
  }
484
572
  };
485
573
  };
486
- /** @internal */
487
574
  Binary.prototype.toUUID = function () {
488
575
  if (this.sub_type === Binary.SUBTYPE_UUID) {
489
576
  return new UUID(this.buffer.slice(0, this.position));
490
577
  }
491
- throw new Error("Binary sub_type \"" + this.sub_type + "\" is not supported for converting to UUID. Only \"" + Binary.SUBTYPE_UUID + "\" is currently supported.");
578
+ throw new BSONError("Binary sub_type \"" + this.sub_type + "\" is not supported for converting to UUID. Only \"" + Binary.SUBTYPE_UUID + "\" is currently supported.");
492
579
  };
493
580
  /** @internal */
494
581
  Binary.fromExtendedJSON = function (doc, options) {
@@ -512,7 +599,7 @@ var Binary = /** @class */ (function () {
512
599
  data = uuidHexStringToBuffer(doc.$uuid);
513
600
  }
514
601
  if (!data) {
515
- throw new TypeError("Unexpected Binary Extended JSON format " + JSON.stringify(doc));
602
+ throw new BSONTypeError("Unexpected Binary Extended JSON format " + JSON.stringify(doc));
516
603
  }
517
604
  return new Binary(data, type);
518
605
  };
@@ -543,6 +630,10 @@ var Binary = /** @class */ (function () {
543
630
  Binary.SUBTYPE_UUID = 4;
544
631
  /** MD5 BSON type */
545
632
  Binary.SUBTYPE_MD5 = 5;
633
+ /** Encrypted BSON type */
634
+ Binary.SUBTYPE_ENCRYPTED = 6;
635
+ /** Column BSON type */
636
+ Binary.SUBTYPE_COLUMN = 7;
546
637
  /** User BSON type */
547
638
  Binary.SUBTYPE_USER_DEFINED = 128;
548
639
  return Binary;
@@ -564,7 +655,6 @@ var Code = /** @class */ (function () {
564
655
  this.code = code;
565
656
  this.scope = scope;
566
657
  }
567
- /** @internal */
568
658
  Code.prototype.toJSON = function () {
569
659
  return { code: this.code, scope: this.scope };
570
660
  };
@@ -636,7 +726,6 @@ var DBRef = /** @class */ (function () {
636
726
  enumerable: false,
637
727
  configurable: true
638
728
  });
639
- /** @internal */
640
729
  DBRef.prototype.toJSON = function () {
641
730
  var o = Object.assign({
642
731
  $ref: this.collection,
@@ -1663,7 +1752,7 @@ function lessThan(left, right) {
1663
1752
  return false;
1664
1753
  }
1665
1754
  function invalidErr(string, message) {
1666
- throw new TypeError("\"" + string + "\" is not a valid Decimal128 string - " + message);
1755
+ throw new BSONTypeError("\"" + string + "\" is not a valid Decimal128 string - " + message);
1667
1756
  }
1668
1757
  /**
1669
1758
  * A class representation of the BSON Decimal128 type.
@@ -1730,7 +1819,7 @@ var Decimal128 = /** @class */ (function () {
1730
1819
  // TODO: implementing a custom parsing for this, or refactoring the regex would yield
1731
1820
  // further gains.
1732
1821
  if (representation.length >= 7000) {
1733
- throw new TypeError('' + representation + ' not a valid Decimal128 string');
1822
+ throw new BSONTypeError('' + representation + ' not a valid Decimal128 string');
1734
1823
  }
1735
1824
  // Results
1736
1825
  var stringMatch = representation.match(PARSE_STRING_REGEXP);
@@ -1738,7 +1827,7 @@ var Decimal128 = /** @class */ (function () {
1738
1827
  var nanMatch = representation.match(PARSE_NAN_REGEXP);
1739
1828
  // Validate the string
1740
1829
  if ((!stringMatch && !infMatch && !nanMatch) || representation.length === 0) {
1741
- throw new TypeError('' + representation + ' not a valid Decimal128 string');
1830
+ throw new BSONTypeError('' + representation + ' not a valid Decimal128 string');
1742
1831
  }
1743
1832
  if (stringMatch) {
1744
1833
  // full_match = stringMatch[0]
@@ -1800,7 +1889,7 @@ var Decimal128 = /** @class */ (function () {
1800
1889
  index = index + 1;
1801
1890
  }
1802
1891
  if (sawRadix && !nDigitsRead)
1803
- throw new TypeError('' + representation + ' not a valid Decimal128 string');
1892
+ throw new BSONTypeError('' + representation + ' not a valid Decimal128 string');
1804
1893
  // Read exponent if exists
1805
1894
  if (representation[index] === 'e' || representation[index] === 'E') {
1806
1895
  // Read exponent digits
@@ -1831,7 +1920,7 @@ var Decimal128 = /** @class */ (function () {
1831
1920
  lastDigit = nDigitsStored - 1;
1832
1921
  significantDigits = nDigits;
1833
1922
  if (significantDigits !== 1) {
1834
- while (representation[firstNonZero + significantDigits - 1] === '0') {
1923
+ while (digits[firstNonZero + significantDigits - 1] === 0) {
1835
1924
  significantDigits = significantDigits - 1;
1836
1925
  }
1837
1926
  }
@@ -2256,10 +2345,12 @@ var Double = /** @class */ (function () {
2256
2345
  Double.prototype.valueOf = function () {
2257
2346
  return this.value;
2258
2347
  };
2259
- /** @internal */
2260
2348
  Double.prototype.toJSON = function () {
2261
2349
  return this.value;
2262
2350
  };
2351
+ Double.prototype.toString = function (radix) {
2352
+ return this.value.toString(radix);
2353
+ };
2263
2354
  /** @internal */
2264
2355
  Double.prototype.toExtendedJSON = function (options) {
2265
2356
  if (options && (options.legacy || (options.relaxed && isFinite(this.value)))) {
@@ -2315,7 +2406,7 @@ var Int32 = /** @class */ (function () {
2315
2406
  if (value instanceof Number) {
2316
2407
  value = value.valueOf();
2317
2408
  }
2318
- this.value = +value;
2409
+ this.value = +value | 0;
2319
2410
  }
2320
2411
  /**
2321
2412
  * Access the number value.
@@ -2325,7 +2416,9 @@ var Int32 = /** @class */ (function () {
2325
2416
  Int32.prototype.valueOf = function () {
2326
2417
  return this.value;
2327
2418
  };
2328
- /** @internal */
2419
+ Int32.prototype.toString = function (radix) {
2420
+ return this.value.toString(radix);
2421
+ };
2329
2422
  Int32.prototype.toJSON = function () {
2330
2423
  return this.value;
2331
2424
  };
@@ -2419,50 +2512,57 @@ var ObjectId = /** @class */ (function () {
2419
2512
  /**
2420
2513
  * Create an ObjectId type
2421
2514
  *
2422
- * @param id - Can be a 24 character hex string, 12 byte binary Buffer, or a number.
2515
+ * @param inputId - Can be a 24 character hex string, 12 byte binary Buffer, or a number.
2423
2516
  */
2424
- function ObjectId(id) {
2517
+ function ObjectId(inputId) {
2425
2518
  if (!(this instanceof ObjectId))
2426
- return new ObjectId(id);
2427
- // Duck-typing to support ObjectId from different npm packages
2428
- if (id instanceof ObjectId) {
2429
- this[kId] = id.id;
2430
- this.__id = id.__id;
2431
- }
2432
- if (typeof id === 'object' && id && 'id' in id) {
2433
- if ('toHexString' in id && typeof id.toHexString === 'function') {
2434
- this[kId] = Buffer.from(id.toHexString(), 'hex');
2519
+ return new ObjectId(inputId);
2520
+ // workingId is set based on type of input and whether valid id exists for the input
2521
+ var workingId;
2522
+ if (typeof inputId === 'object' && inputId && 'id' in inputId) {
2523
+ if (typeof inputId.id !== 'string' && !ArrayBuffer.isView(inputId.id)) {
2524
+ throw new BSONTypeError('Argument passed in must have an id that is of type string or Buffer');
2525
+ }
2526
+ if ('toHexString' in inputId && typeof inputId.toHexString === 'function') {
2527
+ workingId = Buffer.from(inputId.toHexString(), 'hex');
2435
2528
  }
2436
2529
  else {
2437
- this[kId] = typeof id.id === 'string' ? Buffer.from(id.id) : id.id;
2530
+ workingId = inputId.id;
2438
2531
  }
2439
2532
  }
2440
- // The most common use case (blank id, new objectId instance)
2441
- if (id == null || typeof id === 'number') {
2533
+ else {
2534
+ workingId = inputId;
2535
+ }
2536
+ // the following cases use workingId to construct an ObjectId
2537
+ if (workingId == null || typeof workingId === 'number') {
2538
+ // The most common use case (blank id, new objectId instance)
2442
2539
  // Generate a new id
2443
- this[kId] = ObjectId.generate(typeof id === 'number' ? id : undefined);
2444
- // If we are caching the hex string
2445
- if (ObjectId.cacheHexString) {
2446
- this.__id = this.id.toString('hex');
2447
- }
2540
+ this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2448
2541
  }
2449
- if (ArrayBuffer.isView(id) && id.byteLength === 12) {
2450
- this[kId] = ensureBuffer(id);
2542
+ else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
2543
+ this[kId] = ensureBuffer(workingId);
2451
2544
  }
2452
- if (typeof id === 'string') {
2453
- if (id.length === 12) {
2454
- var bytes = Buffer.from(id);
2545
+ else if (typeof workingId === 'string') {
2546
+ if (workingId.length === 12) {
2547
+ var bytes = Buffer.from(workingId);
2455
2548
  if (bytes.byteLength === 12) {
2456
2549
  this[kId] = bytes;
2457
2550
  }
2551
+ else {
2552
+ throw new BSONTypeError('Argument passed in must be a string of 12 bytes');
2553
+ }
2458
2554
  }
2459
- else if (id.length === 24 && checkForHexRegExp.test(id)) {
2460
- this[kId] = Buffer.from(id, 'hex');
2555
+ else if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2556
+ this[kId] = Buffer.from(workingId, 'hex');
2461
2557
  }
2462
2558
  else {
2463
- throw new TypeError('Argument passed in must be a Buffer or string of 12 bytes or a string of 24 hex characters');
2559
+ throw new BSONTypeError('Argument passed in must be a string of 12 bytes or a string of 24 hex characters');
2464
2560
  }
2465
2561
  }
2562
+ else {
2563
+ throw new BSONTypeError('Argument passed in does not match the accepted types');
2564
+ }
2565
+ // If we are caching the hex string
2466
2566
  if (ObjectId.cacheHexString) {
2467
2567
  this.__id = this.id.toString('hex');
2468
2568
  }
@@ -2526,7 +2626,7 @@ var ObjectId = /** @class */ (function () {
2526
2626
  */
2527
2627
  ObjectId.generate = function (time) {
2528
2628
  if ('number' !== typeof time) {
2529
- time = ~~(Date.now() / 1000);
2629
+ time = Math.floor(Date.now() / 1000);
2530
2630
  }
2531
2631
  var inc = ObjectId.getInc();
2532
2632
  var buffer = Buffer.alloc(12);
@@ -2552,7 +2652,6 @@ var ObjectId = /** @class */ (function () {
2552
2652
  * Converts the id into a 24 character hex string for printing
2553
2653
  *
2554
2654
  * @param format - The Buffer toString format parameter.
2555
- * @internal
2556
2655
  */
2557
2656
  ObjectId.prototype.toString = function (format) {
2558
2657
  // Is the id a buffer then use the buffer toString method to return the format
@@ -2560,10 +2659,7 @@ var ObjectId = /** @class */ (function () {
2560
2659
  return this.id.toString(format);
2561
2660
  return this.toHexString();
2562
2661
  };
2563
- /**
2564
- * Converts to its JSON the 24 character hex string representation.
2565
- * @internal
2566
- */
2662
+ /** Converts to its JSON the 24 character hex string representation. */
2567
2663
  ObjectId.prototype.toJSON = function () {
2568
2664
  return this.toHexString();
2569
2665
  };
@@ -2629,7 +2725,7 @@ var ObjectId = /** @class */ (function () {
2629
2725
  ObjectId.createFromHexString = function (hexString) {
2630
2726
  // Throw an error if it's not a valid setup
2631
2727
  if (typeof hexString === 'undefined' || (hexString != null && hexString.length !== 24)) {
2632
- throw new TypeError('Argument passed in must be a single String of 12 bytes or a string of 24 hex characters');
2728
+ throw new BSONTypeError('Argument passed in must be a single String of 12 bytes or a string of 24 hex characters');
2633
2729
  }
2634
2730
  return new ObjectId(Buffer.from(hexString, 'hex'));
2635
2731
  };
@@ -2685,7 +2781,7 @@ var ObjectId = /** @class */ (function () {
2685
2781
  return "new ObjectId(\"" + this.toHexString() + "\")";
2686
2782
  };
2687
2783
  /** @internal */
2688
- ObjectId.index = ~~(Math.random() * 0xffffff);
2784
+ ObjectId.index = Math.floor(Math.random() * 0xffffff);
2689
2785
  return ObjectId;
2690
2786
  }());
2691
2787
  // Deprecated methods
@@ -2720,6 +2816,12 @@ var BSONRegExp = /** @class */ (function () {
2720
2816
  return new BSONRegExp(pattern, options);
2721
2817
  this.pattern = pattern;
2722
2818
  this.options = alphabetize(options !== null && options !== void 0 ? options : '');
2819
+ if (this.pattern.indexOf('\x00') !== -1) {
2820
+ throw new BSONError("BSON Regex patterns cannot contain null bytes, found: " + JSON.stringify(this.pattern));
2821
+ }
2822
+ if (this.options.indexOf('\x00') !== -1) {
2823
+ throw new BSONError("BSON Regex options cannot contain null bytes, found: " + JSON.stringify(this.options));
2824
+ }
2723
2825
  // Validate options
2724
2826
  for (var i = 0; i < this.options.length; i++) {
2725
2827
  if (!(this.options[i] === 'i' ||
@@ -2728,7 +2830,7 @@ var BSONRegExp = /** @class */ (function () {
2728
2830
  this.options[i] === 'l' ||
2729
2831
  this.options[i] === 's' ||
2730
2832
  this.options[i] === 'u')) {
2731
- throw new Error("The regular expression option [" + this.options[i] + "] is not supported");
2833
+ throw new BSONError("The regular expression option [" + this.options[i] + "] is not supported");
2732
2834
  }
2733
2835
  }
2734
2836
  }
@@ -2759,7 +2861,7 @@ var BSONRegExp = /** @class */ (function () {
2759
2861
  if ('$regularExpression' in doc) {
2760
2862
  return new BSONRegExp(doc.$regularExpression.pattern, BSONRegExp.parseOptions(doc.$regularExpression.options));
2761
2863
  }
2762
- throw new TypeError("Unexpected BSONRegExp EJSON object form: " + JSON.stringify(doc));
2864
+ throw new BSONTypeError("Unexpected BSONRegExp EJSON object form: " + JSON.stringify(doc));
2763
2865
  };
2764
2866
  return BSONRegExp;
2765
2867
  }());
@@ -2782,7 +2884,6 @@ var BSONSymbol = /** @class */ (function () {
2782
2884
  BSONSymbol.prototype.valueOf = function () {
2783
2885
  return this.value;
2784
2886
  };
2785
- /** @internal */
2786
2887
  BSONSymbol.prototype.toString = function () {
2787
2888
  return this.value;
2788
2889
  };
@@ -2790,7 +2891,6 @@ var BSONSymbol = /** @class */ (function () {
2790
2891
  BSONSymbol.prototype.inspect = function () {
2791
2892
  return "new BSONSymbol(\"" + this.value + "\")";
2792
2893
  };
2793
- /** @internal */
2794
2894
  BSONSymbol.prototype.toJSON = function () {
2795
2895
  return this.value;
2796
2896
  };
@@ -2810,46 +2910,6 @@ var BSONSymbol = /** @class */ (function () {
2810
2910
  }());
2811
2911
  Object.defineProperty(BSONSymbol.prototype, '_bsontype', { value: 'Symbol' });
2812
2912
 
2813
- /*! *****************************************************************************
2814
- Copyright (c) Microsoft Corporation.
2815
-
2816
- Permission to use, copy, modify, and/or distribute this software for any
2817
- purpose with or without fee is hereby granted.
2818
-
2819
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
2820
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2821
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
2822
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2823
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2824
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2825
- PERFORMANCE OF THIS SOFTWARE.
2826
- ***************************************************************************** */
2827
-
2828
- /* global Reflect, Promise */
2829
- var _extendStatics = function extendStatics(d, b) {
2830
- _extendStatics = Object.setPrototypeOf || {
2831
- __proto__: []
2832
- } instanceof Array && function (d, b) {
2833
- d.__proto__ = b;
2834
- } || function (d, b) {
2835
- for (var p in b) {
2836
- if (b.hasOwnProperty(p)) d[p] = b[p];
2837
- }
2838
- };
2839
-
2840
- return _extendStatics(d, b);
2841
- };
2842
-
2843
- function __extends(d, b) {
2844
- _extendStatics(d, b);
2845
-
2846
- function __() {
2847
- this.constructor = d;
2848
- }
2849
-
2850
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
2851
- }
2852
-
2853
2913
  /** @public */
2854
2914
  var LongWithoutOverridesClass = Long;
2855
2915
  /** @public */
@@ -3064,7 +3124,7 @@ function serializeValue(value, options) {
3064
3124
  var current = props[props.length - 1];
3065
3125
  var leadingSpace = ' '.repeat(leadingPart.length + alreadySeen.length / 2);
3066
3126
  var dashes = '-'.repeat(circularPart.length + (alreadySeen.length + current.length) / 2 - 1);
3067
- throw new TypeError('Converting circular structure to EJSON:\n' +
3127
+ throw new BSONTypeError('Converting circular structure to EJSON:\n' +
3068
3128
  (" " + leadingPart + alreadySeen + circularPart + current + "\n") +
3069
3129
  (" " + leadingSpace + "\\" + dashes + "/"));
3070
3130
  }
@@ -3137,7 +3197,7 @@ var BSON_TYPE_MAPPINGS = {
3137
3197
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3138
3198
  function serializeDocument(doc, options) {
3139
3199
  if (doc == null || typeof doc !== 'object')
3140
- throw new Error('not an object instance');
3200
+ throw new BSONError('not an object instance');
3141
3201
  var bsontype = doc._bsontype;
3142
3202
  if (typeof bsontype === 'undefined') {
3143
3203
  // It's a regular object. Recursively serialize its property values.
@@ -3164,7 +3224,7 @@ function serializeDocument(doc, options) {
3164
3224
  // Copy the object into this library's version of that type.
3165
3225
  var mapper = BSON_TYPE_MAPPINGS[doc._bsontype];
3166
3226
  if (!mapper) {
3167
- throw new TypeError('Unrecognized or invalid _bsontype: ' + doc._bsontype);
3227
+ throw new BSONTypeError('Unrecognized or invalid _bsontype: ' + doc._bsontype);
3168
3228
  }
3169
3229
  outDoc = mapper(outDoc);
3170
3230
  }
@@ -3178,7 +3238,7 @@ function serializeDocument(doc, options) {
3178
3238
  return outDoc.toExtendedJSON(options);
3179
3239
  }
3180
3240
  else {
3181
- throw new Error('_bsontype must be a string, but was: ' + typeof bsontype);
3241
+ throw new BSONError('_bsontype must be a string, but was: ' + typeof bsontype);
3182
3242
  }
3183
3243
  }
3184
3244
  /**
@@ -3213,7 +3273,12 @@ var EJSON;
3213
3273
  finalOptions.strict = !finalOptions.relaxed;
3214
3274
  if (typeof finalOptions.strict === 'boolean')
3215
3275
  finalOptions.relaxed = !finalOptions.strict;
3216
- return JSON.parse(text, function (_key, value) { return deserializeValue(value, finalOptions); });
3276
+ return JSON.parse(text, function (key, value) {
3277
+ if (key.indexOf('\x00') !== -1) {
3278
+ throw new BSONError("BSON Document field names cannot contain null bytes, found: " + JSON.stringify(key));
3279
+ }
3280
+ return deserializeValue(value, finalOptions);
3281
+ });
3217
3282
  }
3218
3283
  EJSON.parse = parse;
3219
3284
  /**
@@ -3471,6 +3536,10 @@ var BSON_BINARY_SUBTYPE_UUID = 3;
3471
3536
  var BSON_BINARY_SUBTYPE_UUID_NEW = 4;
3472
3537
  /** Binary MD5 Type @internal */
3473
3538
  var BSON_BINARY_SUBTYPE_MD5 = 5;
3539
+ /** Encrypted BSON type @internal */
3540
+ var BSON_BINARY_SUBTYPE_ENCRYPTED = 6;
3541
+ /** Column BSON type @internal */
3542
+ var BSON_BINARY_SUBTYPE_COLUMN = 7;
3474
3543
  /** Binary User Defined Type @internal */
3475
3544
  var BSON_BINARY_SUBTYPE_USER_DEFINED = 128;
3476
3545
 
@@ -3715,20 +3784,20 @@ function deserialize$1(buffer, options, isArray) {
3715
3784
  (buffer[index + 2] << 16) |
3716
3785
  (buffer[index + 3] << 24);
3717
3786
  if (size < 5) {
3718
- throw new Error("bson size must be >= 5, is " + size);
3787
+ throw new BSONError("bson size must be >= 5, is " + size);
3719
3788
  }
3720
3789
  if (options.allowObjectSmallerThanBufferSize && buffer.length < size) {
3721
- throw new Error("buffer length " + buffer.length + " must be >= bson size " + size);
3790
+ throw new BSONError("buffer length " + buffer.length + " must be >= bson size " + size);
3722
3791
  }
3723
3792
  if (!options.allowObjectSmallerThanBufferSize && buffer.length !== size) {
3724
- throw new Error("buffer length " + buffer.length + " must === bson size " + size);
3793
+ throw new BSONError("buffer length " + buffer.length + " must === bson size " + size);
3725
3794
  }
3726
3795
  if (size + index > buffer.byteLength) {
3727
- throw new Error("(bson size " + size + " + options.index " + index + " must be <= buffer length " + buffer.byteLength + ")");
3796
+ throw new BSONError("(bson size " + size + " + options.index " + index + " must be <= buffer length " + buffer.byteLength + ")");
3728
3797
  }
3729
3798
  // Illegal end value
3730
3799
  if (buffer[index + size - 1] !== 0) {
3731
- throw new Error("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");
3800
+ throw new BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");
3732
3801
  }
3733
3802
  // Start deserializtion
3734
3803
  return deserializeObject(buffer, index, options, isArray);
@@ -3747,16 +3816,53 @@ function deserializeObject(buffer, index, options, isArray) {
3747
3816
  var promoteBuffers = options['promoteBuffers'] == null ? false : options['promoteBuffers'];
3748
3817
  var promoteLongs = options['promoteLongs'] == null ? true : options['promoteLongs'];
3749
3818
  var promoteValues = options['promoteValues'] == null ? true : options['promoteValues'];
3819
+ // Ensures default validation option if none given
3820
+ var validation = options.validation == null ? { utf8: true } : options.validation;
3821
+ // Shows if global utf-8 validation is enabled or disabled
3822
+ var globalUTFValidation = true;
3823
+ // Reflects utf-8 validation setting regardless of global or specific key validation
3824
+ var validationSetting;
3825
+ // Set of keys either to enable or disable validation on
3826
+ var utf8KeysSet = new Set();
3827
+ // Check for boolean uniformity and empty validation option
3828
+ var utf8ValidatedKeys = validation.utf8;
3829
+ if (typeof utf8ValidatedKeys === 'boolean') {
3830
+ validationSetting = utf8ValidatedKeys;
3831
+ }
3832
+ else {
3833
+ globalUTFValidation = false;
3834
+ var utf8ValidationValues = Object.keys(utf8ValidatedKeys).map(function (key) {
3835
+ return utf8ValidatedKeys[key];
3836
+ });
3837
+ if (utf8ValidationValues.length === 0) {
3838
+ throw new BSONError('UTF-8 validation setting cannot be empty');
3839
+ }
3840
+ if (typeof utf8ValidationValues[0] !== 'boolean') {
3841
+ throw new BSONError('Invalid UTF-8 validation option, must specify boolean values');
3842
+ }
3843
+ validationSetting = utf8ValidationValues[0];
3844
+ // Ensures boolean uniformity in utf-8 validation (all true or all false)
3845
+ if (!utf8ValidationValues.every(function (item) { return item === validationSetting; })) {
3846
+ throw new BSONError('Invalid UTF-8 validation option - keys must be all true or all false');
3847
+ }
3848
+ }
3849
+ // Add keys to set that will either be validated or not based on validationSetting
3850
+ if (!globalUTFValidation) {
3851
+ for (var _i = 0, _a = Object.keys(utf8ValidatedKeys); _i < _a.length; _i++) {
3852
+ var key = _a[_i];
3853
+ utf8KeysSet.add(key);
3854
+ }
3855
+ }
3750
3856
  // Set the start index
3751
3857
  var startIndex = index;
3752
3858
  // Validate that we have at least 4 bytes of buffer
3753
3859
  if (buffer.length < 5)
3754
- throw new Error('corrupt bson message < 5 bytes long');
3860
+ throw new BSONError('corrupt bson message < 5 bytes long');
3755
3861
  // Read the document size
3756
3862
  var size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
3757
3863
  // Ensure buffer is valid size
3758
3864
  if (size < 5 || size > buffer.length)
3759
- throw new Error('corrupt bson message');
3865
+ throw new BSONError('corrupt bson message');
3760
3866
  // Create holding object
3761
3867
  var object = isArray ? [] : {};
3762
3868
  // Used for arrays to skip having to perform utf8 decoding
@@ -3778,8 +3884,17 @@ function deserializeObject(buffer, index, options, isArray) {
3778
3884
  }
3779
3885
  // If are at the end of the buffer there is a problem with the document
3780
3886
  if (i >= buffer.byteLength)
3781
- throw new Error('Bad BSON Document: illegal CString');
3887
+ throw new BSONError('Bad BSON Document: illegal CString');
3888
+ // Represents the key
3782
3889
  var name = isArray ? arrayIndex++ : buffer.toString('utf8', index, i);
3890
+ // shouldValidateKey is true if the key should be validated, false otherwise
3891
+ var shouldValidateKey = true;
3892
+ if (globalUTFValidation || utf8KeysSet.has(name)) {
3893
+ shouldValidateKey = validationSetting;
3894
+ }
3895
+ else {
3896
+ shouldValidateKey = !validationSetting;
3897
+ }
3783
3898
  if (isPossibleDBRef !== false && name[0] === '$') {
3784
3899
  isPossibleDBRef = allowedDBRefKeys.test(name);
3785
3900
  }
@@ -3792,17 +3907,10 @@ function deserializeObject(buffer, index, options, isArray) {
3792
3907
  (buffer[index++] << 24);
3793
3908
  if (stringSize <= 0 ||
3794
3909
  stringSize > buffer.length - index ||
3795
- buffer[index + stringSize - 1] !== 0)
3796
- throw new Error('bad string length in bson');
3797
- value = buffer.toString('utf8', index, index + stringSize - 1);
3798
- for (var i_1 = 0; i_1 < value.length; i_1++) {
3799
- if (value.charCodeAt(i_1) === 0xfffd) {
3800
- if (!validateUtf8(buffer, index, index + stringSize - 1)) {
3801
- throw new Error('Invalid UTF-8 string in BSON document');
3802
- }
3803
- break;
3804
- }
3910
+ buffer[index + stringSize - 1] !== 0) {
3911
+ throw new BSONError('bad string length in bson');
3805
3912
  }
3913
+ value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
3806
3914
  index = index + stringSize;
3807
3915
  }
3808
3916
  else if (elementType === BSON_DATA_OID) {
@@ -3842,7 +3950,7 @@ function deserializeObject(buffer, index, options, isArray) {
3842
3950
  }
3843
3951
  else if (elementType === BSON_DATA_BOOLEAN) {
3844
3952
  if (buffer[index] !== 0 && buffer[index] !== 1)
3845
- throw new Error('illegal boolean type value');
3953
+ throw new BSONError('illegal boolean type value');
3846
3954
  value = buffer[index++] === 1;
3847
3955
  }
3848
3956
  else if (elementType === BSON_DATA_OBJECT) {
@@ -3852,13 +3960,17 @@ function deserializeObject(buffer, index, options, isArray) {
3852
3960
  (buffer[index + 2] << 16) |
3853
3961
  (buffer[index + 3] << 24);
3854
3962
  if (objectSize <= 0 || objectSize > buffer.length - index)
3855
- throw new Error('bad embedded document length in bson');
3963
+ throw new BSONError('bad embedded document length in bson');
3856
3964
  // We have a raw value
3857
3965
  if (raw) {
3858
3966
  value = buffer.slice(index, index + objectSize);
3859
3967
  }
3860
3968
  else {
3861
- value = deserializeObject(buffer, _index, options, false);
3969
+ var objectOptions = options;
3970
+ if (!globalUTFValidation) {
3971
+ objectOptions = _assign(_assign({}, options), { validation: { utf8: shouldValidateKey } });
3972
+ }
3973
+ value = deserializeObject(buffer, _index, objectOptions, false);
3862
3974
  }
3863
3975
  index = index + objectSize;
3864
3976
  }
@@ -3879,12 +3991,15 @@ function deserializeObject(buffer, index, options, isArray) {
3879
3991
  }
3880
3992
  arrayOptions['raw'] = true;
3881
3993
  }
3994
+ if (!globalUTFValidation) {
3995
+ arrayOptions = _assign(_assign({}, arrayOptions), { validation: { utf8: shouldValidateKey } });
3996
+ }
3882
3997
  value = deserializeObject(buffer, _index, arrayOptions, true);
3883
3998
  index = index + objectSize;
3884
3999
  if (buffer[index - 1] !== 0)
3885
- throw new Error('invalid array terminator byte');
4000
+ throw new BSONError('invalid array terminator byte');
3886
4001
  if (index !== stopIndex)
3887
- throw new Error('corrupted array bson');
4002
+ throw new BSONError('corrupted array bson');
3888
4003
  }
3889
4004
  else if (elementType === BSON_DATA_UNDEFINED) {
3890
4005
  value = undefined;
@@ -3940,10 +4055,10 @@ function deserializeObject(buffer, index, options, isArray) {
3940
4055
  var subType = buffer[index++];
3941
4056
  // Did we have a negative binary size, throw
3942
4057
  if (binarySize < 0)
3943
- throw new Error('Negative binary type element size found');
4058
+ throw new BSONError('Negative binary type element size found');
3944
4059
  // Is the length longer than the document
3945
4060
  if (binarySize > buffer.byteLength)
3946
- throw new Error('Binary type size larger than document size');
4061
+ throw new BSONError('Binary type size larger than document size');
3947
4062
  // Decode as raw Buffer object if options specifies it
3948
4063
  if (buffer['slice'] != null) {
3949
4064
  // If we have subtype 2 skip the 4 bytes for the size
@@ -3954,11 +4069,11 @@ function deserializeObject(buffer, index, options, isArray) {
3954
4069
  (buffer[index++] << 16) |
3955
4070
  (buffer[index++] << 24);
3956
4071
  if (binarySize < 0)
3957
- throw new Error('Negative binary type element size found for subtype 0x02');
4072
+ throw new BSONError('Negative binary type element size found for subtype 0x02');
3958
4073
  if (binarySize > totalBinarySize - 4)
3959
- throw new Error('Binary type with subtype 0x02 contains too long binary size');
4074
+ throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3960
4075
  if (binarySize < totalBinarySize - 4)
3961
- throw new Error('Binary type with subtype 0x02 contains too short binary size');
4076
+ throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3962
4077
  }
3963
4078
  if (promoteBuffers && promoteValues) {
3964
4079
  value = buffer.slice(index, index + binarySize);
@@ -3977,11 +4092,11 @@ function deserializeObject(buffer, index, options, isArray) {
3977
4092
  (buffer[index++] << 16) |
3978
4093
  (buffer[index++] << 24);
3979
4094
  if (binarySize < 0)
3980
- throw new Error('Negative binary type element size found for subtype 0x02');
4095
+ throw new BSONError('Negative binary type element size found for subtype 0x02');
3981
4096
  if (binarySize > totalBinarySize - 4)
3982
- throw new Error('Binary type with subtype 0x02 contains too long binary size');
4097
+ throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3983
4098
  if (binarySize < totalBinarySize - 4)
3984
- throw new Error('Binary type with subtype 0x02 contains too short binary size');
4099
+ throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3985
4100
  }
3986
4101
  // Copy the data
3987
4102
  for (i = 0; i < binarySize; i++) {
@@ -4006,7 +4121,7 @@ function deserializeObject(buffer, index, options, isArray) {
4006
4121
  }
4007
4122
  // If are at the end of the buffer there is a problem with the document
4008
4123
  if (i >= buffer.length)
4009
- throw new Error('Bad BSON Document: illegal CString');
4124
+ throw new BSONError('Bad BSON Document: illegal CString');
4010
4125
  // Return the C string
4011
4126
  var source = buffer.toString('utf8', index, i);
4012
4127
  // Create the regexp
@@ -4019,7 +4134,7 @@ function deserializeObject(buffer, index, options, isArray) {
4019
4134
  }
4020
4135
  // If are at the end of the buffer there is a problem with the document
4021
4136
  if (i >= buffer.length)
4022
- throw new Error('Bad BSON Document: illegal CString');
4137
+ throw new BSONError('Bad BSON Document: illegal CString');
4023
4138
  // Return the C string
4024
4139
  var regExpOptions = buffer.toString('utf8', index, i);
4025
4140
  index = i + 1;
@@ -4050,7 +4165,7 @@ function deserializeObject(buffer, index, options, isArray) {
4050
4165
  }
4051
4166
  // If are at the end of the buffer there is a problem with the document
4052
4167
  if (i >= buffer.length)
4053
- throw new Error('Bad BSON Document: illegal CString');
4168
+ throw new BSONError('Bad BSON Document: illegal CString');
4054
4169
  // Return the C string
4055
4170
  var source = buffer.toString('utf8', index, i);
4056
4171
  index = i + 1;
@@ -4062,7 +4177,7 @@ function deserializeObject(buffer, index, options, isArray) {
4062
4177
  }
4063
4178
  // If are at the end of the buffer there is a problem with the document
4064
4179
  if (i >= buffer.length)
4065
- throw new Error('Bad BSON Document: illegal CString');
4180
+ throw new BSONError('Bad BSON Document: illegal CString');
4066
4181
  // Return the C string
4067
4182
  var regExpOptions = buffer.toString('utf8', index, i);
4068
4183
  index = i + 1;
@@ -4076,9 +4191,10 @@ function deserializeObject(buffer, index, options, isArray) {
4076
4191
  (buffer[index++] << 24);
4077
4192
  if (stringSize <= 0 ||
4078
4193
  stringSize > buffer.length - index ||
4079
- buffer[index + stringSize - 1] !== 0)
4080
- throw new Error('bad string length in bson');
4081
- var symbol = buffer.toString('utf8', index, index + stringSize - 1);
4194
+ buffer[index + stringSize - 1] !== 0) {
4195
+ throw new BSONError('bad string length in bson');
4196
+ }
4197
+ var symbol = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
4082
4198
  value = promoteValues ? symbol : new BSONSymbol(symbol);
4083
4199
  index = index + stringSize;
4084
4200
  }
@@ -4106,9 +4222,10 @@ function deserializeObject(buffer, index, options, isArray) {
4106
4222
  (buffer[index++] << 24);
4107
4223
  if (stringSize <= 0 ||
4108
4224
  stringSize > buffer.length - index ||
4109
- buffer[index + stringSize - 1] !== 0)
4110
- throw new Error('bad string length in bson');
4111
- var functionString = buffer.toString('utf8', index, index + stringSize - 1);
4225
+ buffer[index + stringSize - 1] !== 0) {
4226
+ throw new BSONError('bad string length in bson');
4227
+ }
4228
+ var functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
4112
4229
  // If we are evaluating the functions
4113
4230
  if (evalFunctions) {
4114
4231
  // If we have cache enabled let's look for the md5 of the function in the cache
@@ -4133,7 +4250,7 @@ function deserializeObject(buffer, index, options, isArray) {
4133
4250
  (buffer[index++] << 24);
4134
4251
  // Element cannot be shorter than totalSize + stringSize + documentSize + terminator
4135
4252
  if (totalSize < 4 + 4 + 4 + 1) {
4136
- throw new Error('code_w_scope total size shorter minimum expected length');
4253
+ throw new BSONError('code_w_scope total size shorter minimum expected length');
4137
4254
  }
4138
4255
  // Get the code string size
4139
4256
  var stringSize = buffer[index++] |
@@ -4143,10 +4260,11 @@ function deserializeObject(buffer, index, options, isArray) {
4143
4260
  // Check if we have a valid string
4144
4261
  if (stringSize <= 0 ||
4145
4262
  stringSize > buffer.length - index ||
4146
- buffer[index + stringSize - 1] !== 0)
4147
- throw new Error('bad string length in bson');
4263
+ buffer[index + stringSize - 1] !== 0) {
4264
+ throw new BSONError('bad string length in bson');
4265
+ }
4148
4266
  // Javascript function
4149
- var functionString = buffer.toString('utf8', index, index + stringSize - 1);
4267
+ var functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
4150
4268
  // Update parse index position
4151
4269
  index = index + stringSize;
4152
4270
  // Parse the element
@@ -4162,11 +4280,11 @@ function deserializeObject(buffer, index, options, isArray) {
4162
4280
  index = index + objectSize;
4163
4281
  // Check if field length is too short
4164
4282
  if (totalSize < 4 + 4 + objectSize + stringSize) {
4165
- throw new Error('code_w_scope total size is too short, truncating scope');
4283
+ throw new BSONError('code_w_scope total size is too short, truncating scope');
4166
4284
  }
4167
4285
  // Check if totalSize field is too long
4168
4286
  if (totalSize > 4 + 4 + objectSize + stringSize) {
4169
- throw new Error('code_w_scope total size is too long, clips outer document');
4287
+ throw new BSONError('code_w_scope total size is too long, clips outer document');
4170
4288
  }
4171
4289
  // If we are evaluating the functions
4172
4290
  if (evalFunctions) {
@@ -4194,10 +4312,12 @@ function deserializeObject(buffer, index, options, isArray) {
4194
4312
  if (stringSize <= 0 ||
4195
4313
  stringSize > buffer.length - index ||
4196
4314
  buffer[index + stringSize - 1] !== 0)
4197
- throw new Error('bad string length in bson');
4315
+ throw new BSONError('bad string length in bson');
4198
4316
  // Namespace
4199
- if (!validateUtf8(buffer, index, index + stringSize - 1)) {
4200
- throw new Error('Invalid UTF-8 string in BSON document');
4317
+ if (validation != null && validation.utf8) {
4318
+ if (!validateUtf8(buffer, index, index + stringSize - 1)) {
4319
+ throw new BSONError('Invalid UTF-8 string in BSON document');
4320
+ }
4201
4321
  }
4202
4322
  var namespace = buffer.toString('utf8', index, index + stringSize - 1);
4203
4323
  // Update parse index position
@@ -4212,7 +4332,7 @@ function deserializeObject(buffer, index, options, isArray) {
4212
4332
  value = new DBRef(namespace, oid);
4213
4333
  }
4214
4334
  else {
4215
- throw new Error('Detected unknown BSON type ' + elementType.toString(16) + ' for fieldname "' + name + '"');
4335
+ throw new BSONError('Detected unknown BSON type ' + elementType.toString(16) + ' for fieldname "' + name + '"');
4216
4336
  }
4217
4337
  if (name === '__proto__') {
4218
4338
  Object.defineProperty(object, name, {
@@ -4229,8 +4349,8 @@ function deserializeObject(buffer, index, options, isArray) {
4229
4349
  // Check if the deserialization was against a valid array/object
4230
4350
  if (size !== index - startIndex) {
4231
4351
  if (isArray)
4232
- throw new Error('corrupt array bson');
4233
- throw new Error('corrupt object bson');
4352
+ throw new BSONError('corrupt array bson');
4353
+ throw new BSONError('corrupt object bson');
4234
4354
  }
4235
4355
  // if we did not find "$ref", "$id", "$db", or found an extraneous $key, don't make a DBRef
4236
4356
  if (!isPossibleDBRef)
@@ -4259,6 +4379,21 @@ function isolateEval(functionString, functionCache, object) {
4259
4379
  // Set the object
4260
4380
  return functionCache[functionString].bind(object);
4261
4381
  }
4382
+ function getValidatedString(buffer, start, end, shouldValidateUtf8) {
4383
+ var value = buffer.toString('utf8', start, end);
4384
+ // if utf8 validation is on, do the check
4385
+ if (shouldValidateUtf8) {
4386
+ for (var i = 0; i < value.length; i++) {
4387
+ if (value.charCodeAt(i) === 0xfffd) {
4388
+ if (!validateUtf8(buffer, start, end)) {
4389
+ throw new BSONError('Invalid UTF-8 string in BSON document');
4390
+ }
4391
+ break;
4392
+ }
4393
+ }
4394
+ }
4395
+ return value;
4396
+ }
4262
4397
 
4263
4398
  // Copyright (c) 2008, Fair Oaks Labs, Inc.
4264
4399
  function writeIEEE754(buffer, value, offset, endian, mLen, nBytes) {
@@ -4543,7 +4678,7 @@ function serializeObjectId(buffer, key, value, index, isArray) {
4543
4678
  buffer.set(value.id.subarray(0, 12), index);
4544
4679
  }
4545
4680
  else {
4546
- throw new TypeError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
4681
+ throw new BSONTypeError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
4547
4682
  }
4548
4683
  // Adjust index
4549
4684
  return index + 12;
@@ -4582,7 +4717,7 @@ function serializeObject(buffer, key, value, index, checkKeys, depth, serializeF
4582
4717
  if (path === void 0) { path = []; }
4583
4718
  for (var i = 0; i < path.length; i++) {
4584
4719
  if (path[i] === value)
4585
- throw new Error('cyclic dependency detected');
4720
+ throw new BSONError('cyclic dependency detected');
4586
4721
  }
4587
4722
  // Push value to stack
4588
4723
  path.push(value);
@@ -4885,7 +5020,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
4885
5020
  // Is there an override value
4886
5021
  if (value && value.toBSON) {
4887
5022
  if (typeof value.toBSON !== 'function')
4888
- throw new TypeError('toBSON is not a function');
5023
+ throw new BSONTypeError('toBSON is not a function');
4889
5024
  value = value.toBSON();
4890
5025
  }
4891
5026
  if (typeof value === 'string') {
@@ -4895,7 +5030,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
4895
5030
  index = serializeNumber(buffer, key, value, index, true);
4896
5031
  }
4897
5032
  else if (typeof value === 'bigint') {
4898
- throw new TypeError('Unsupported type BigInt, please use Decimal128');
5033
+ throw new BSONTypeError('Unsupported type BigInt, please use Decimal128');
4899
5034
  }
4900
5035
  else if (typeof value === 'boolean') {
4901
5036
  index = serializeBoolean(buffer, key, value, index, true);
@@ -4957,7 +5092,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
4957
5092
  index = serializeMinMax(buffer, key, value, index, true);
4958
5093
  }
4959
5094
  else if (typeof value['_bsontype'] !== 'undefined') {
4960
- throw new TypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
5095
+ throw new BSONTypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
4961
5096
  }
4962
5097
  }
4963
5098
  }
@@ -4999,7 +5134,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
4999
5134
  index = serializeNumber(buffer, key, value, index);
5000
5135
  }
5001
5136
  else if (type === 'bigint' || isBigInt64Array(value) || isBigUInt64Array(value)) {
5002
- throw new TypeError('Unsupported type BigInt, please use Decimal128');
5137
+ throw new BSONTypeError('Unsupported type BigInt, please use Decimal128');
5003
5138
  }
5004
5139
  else if (type === 'boolean') {
5005
5140
  index = serializeBoolean(buffer, key, value, index);
@@ -5056,7 +5191,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
5056
5191
  index = serializeMinMax(buffer, key, value, index);
5057
5192
  }
5058
5193
  else if (typeof value['_bsontype'] !== 'undefined') {
5059
- throw new TypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
5194
+ throw new BSONTypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
5060
5195
  }
5061
5196
  }
5062
5197
  }
@@ -5064,10 +5199,10 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
5064
5199
  // Did we provide a custom serialization method
5065
5200
  if (object.toBSON) {
5066
5201
  if (typeof object.toBSON !== 'function')
5067
- throw new TypeError('toBSON is not a function');
5202
+ throw new BSONTypeError('toBSON is not a function');
5068
5203
  object = object.toBSON();
5069
5204
  if (object != null && typeof object !== 'object')
5070
- throw new TypeError('toBSON function did not return an object');
5205
+ throw new BSONTypeError('toBSON function did not return an object');
5071
5206
  }
5072
5207
  // Iterate over all the keys
5073
5208
  for (var key in object) {
@@ -5075,7 +5210,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
5075
5210
  // Is there an override value
5076
5211
  if (value && value.toBSON) {
5077
5212
  if (typeof value.toBSON !== 'function')
5078
- throw new TypeError('toBSON is not a function');
5213
+ throw new BSONTypeError('toBSON is not a function');
5079
5214
  value = value.toBSON();
5080
5215
  }
5081
5216
  // Check the type of the value
@@ -5103,7 +5238,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
5103
5238
  index = serializeNumber(buffer, key, value, index);
5104
5239
  }
5105
5240
  else if (type === 'bigint') {
5106
- throw new TypeError('Unsupported type BigInt, please use Decimal128');
5241
+ throw new BSONTypeError('Unsupported type BigInt, please use Decimal128');
5107
5242
  }
5108
5243
  else if (type === 'boolean') {
5109
5244
  index = serializeBoolean(buffer, key, value, index);
@@ -5164,7 +5299,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
5164
5299
  index = serializeMinMax(buffer, key, value, index);
5165
5300
  }
5166
5301
  else if (typeof value['_bsontype'] !== 'undefined') {
5167
- throw new TypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
5302
+ throw new BSONTypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
5168
5303
  }
5169
5304
  }
5170
5305
  }
@@ -5337,9 +5472,11 @@ var BSON = {
5337
5472
  serializeWithBufferAndIndex: serializeWithBufferAndIndex,
5338
5473
  deserialize: deserialize,
5339
5474
  calculateObjectSize: calculateObjectSize,
5340
- deserializeStream: deserializeStream
5475
+ deserializeStream: deserializeStream,
5476
+ BSONError: BSONError,
5477
+ BSONTypeError: BSONTypeError
5341
5478
  };
5342
5479
 
5343
5480
  export default BSON;
5344
- export { BSONRegExp, BSONSymbol, BSON_BINARY_SUBTYPE_BYTE_ARRAY, BSON_BINARY_SUBTYPE_DEFAULT, BSON_BINARY_SUBTYPE_FUNCTION, BSON_BINARY_SUBTYPE_MD5, BSON_BINARY_SUBTYPE_USER_DEFINED, BSON_BINARY_SUBTYPE_UUID, BSON_BINARY_SUBTYPE_UUID_NEW, BSON_DATA_ARRAY, BSON_DATA_BINARY, BSON_DATA_BOOLEAN, BSON_DATA_CODE, BSON_DATA_CODE_W_SCOPE, BSON_DATA_DATE, BSON_DATA_DBPOINTER, BSON_DATA_DECIMAL128, BSON_DATA_INT, BSON_DATA_LONG, BSON_DATA_MAX_KEY, BSON_DATA_MIN_KEY, BSON_DATA_NULL, BSON_DATA_NUMBER, BSON_DATA_OBJECT, BSON_DATA_OID, BSON_DATA_REGEXP, BSON_DATA_STRING, BSON_DATA_SYMBOL, BSON_DATA_TIMESTAMP, BSON_DATA_UNDEFINED, BSON_INT32_MAX, BSON_INT32_MIN, BSON_INT64_MAX, BSON_INT64_MIN, Binary, Code, DBRef, Decimal128, Double, EJSON, Int32, Long, LongWithoutOverridesClass, bsonMap as Map, MaxKey, MinKey, ObjectId as ObjectID, ObjectId, Timestamp, UUID, calculateObjectSize, deserialize, deserializeStream, serialize, serializeWithBufferAndIndex, setInternalBufferSize };
5481
+ export { BSONError, BSONRegExp, BSONSymbol, BSONTypeError, BSON_BINARY_SUBTYPE_BYTE_ARRAY, BSON_BINARY_SUBTYPE_COLUMN, BSON_BINARY_SUBTYPE_DEFAULT, BSON_BINARY_SUBTYPE_ENCRYPTED, BSON_BINARY_SUBTYPE_FUNCTION, BSON_BINARY_SUBTYPE_MD5, BSON_BINARY_SUBTYPE_USER_DEFINED, BSON_BINARY_SUBTYPE_UUID, BSON_BINARY_SUBTYPE_UUID_NEW, BSON_DATA_ARRAY, BSON_DATA_BINARY, BSON_DATA_BOOLEAN, BSON_DATA_CODE, BSON_DATA_CODE_W_SCOPE, BSON_DATA_DATE, BSON_DATA_DBPOINTER, BSON_DATA_DECIMAL128, BSON_DATA_INT, BSON_DATA_LONG, BSON_DATA_MAX_KEY, BSON_DATA_MIN_KEY, BSON_DATA_NULL, BSON_DATA_NUMBER, BSON_DATA_OBJECT, BSON_DATA_OID, BSON_DATA_REGEXP, BSON_DATA_STRING, BSON_DATA_SYMBOL, BSON_DATA_TIMESTAMP, BSON_DATA_UNDEFINED, BSON_INT32_MAX, BSON_INT32_MIN, BSON_INT64_MAX, BSON_INT64_MIN, Binary, Code, DBRef, Decimal128, Double, EJSON, Int32, Long, LongWithoutOverridesClass, bsonMap as Map, MaxKey, MinKey, ObjectId as ObjectID, ObjectId, Timestamp, UUID, calculateObjectSize, deserialize, deserializeStream, serialize, serializeWithBufferAndIndex, setInternalBufferSize };
5345
5482
  //# sourceMappingURL=bson.esm.js.map