bson 6.8.0 → 6.10.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.
@@ -1,20 +1,46 @@
1
1
  var BSON = (function (exports) {
2
2
  'use strict';
3
3
 
4
+ const map = new WeakMap();
5
+ const TYPES = {
6
+ ArrayBuffer: '[object ArrayBuffer]',
7
+ SharedArrayBuffer: '[object SharedArrayBuffer]',
8
+ Uint8Array: '[object Uint8Array]',
9
+ BigInt64Array: '[object BigInt64Array]',
10
+ BigUint64Array: '[object BigUint64Array]',
11
+ RegExp: '[object RegExp]',
12
+ Map: '[object Map]',
13
+ Date: '[object Date]'
14
+ };
15
+ function getPrototypeString(value) {
16
+ let str = map.get(value);
17
+ if (!str) {
18
+ str = Object.prototype.toString.call(value);
19
+ if (value !== null && typeof value === 'object') {
20
+ map.set(value, str);
21
+ }
22
+ }
23
+ return str;
24
+ }
4
25
  function isAnyArrayBuffer(value) {
5
- return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes(Object.prototype.toString.call(value));
26
+ const type = getPrototypeString(value);
27
+ return type === TYPES.ArrayBuffer || type === TYPES.SharedArrayBuffer;
6
28
  }
7
29
  function isUint8Array(value) {
8
- return Object.prototype.toString.call(value) === '[object Uint8Array]';
30
+ const type = getPrototypeString(value);
31
+ return type === TYPES.Uint8Array;
9
32
  }
10
33
  function isRegExp(d) {
11
- return Object.prototype.toString.call(d) === '[object RegExp]';
34
+ const type = getPrototypeString(d);
35
+ return type === TYPES.RegExp;
12
36
  }
13
37
  function isMap(d) {
14
- return Object.prototype.toString.call(d) === '[object Map]';
38
+ const type = getPrototypeString(d);
39
+ return type === TYPES.Map;
15
40
  }
16
41
  function isDate(d) {
17
- return Object.prototype.toString.call(d) === '[object Date]';
42
+ const type = getPrototypeString(d);
43
+ return type === TYPES.Date;
18
44
  }
19
45
  function defaultInspect(x, _options) {
20
46
  return JSON.stringify(x, (k, v) => {
@@ -38,6 +64,7 @@ function getStylizeFunction(options) {
38
64
  }
39
65
 
40
66
  const BSON_MAJOR_VERSION = 6;
67
+ const BSON_VERSION_SYMBOL = Symbol.for('@@mdb.bson.version');
41
68
  const BSON_INT32_MAX = 0x7fffffff;
42
69
  const BSON_INT32_MIN = -0x80000000;
43
70
  const BSON_INT64_MAX = Math.pow(2, 63) - 1;
@@ -230,7 +257,7 @@ const nodeJsByteUtils = {
230
257
  stringTag === '[object SharedArrayBuffer]') {
231
258
  return Buffer.from(potentialBuffer);
232
259
  }
233
- throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`);
260
+ throw new BSONError(`Cannot create Buffer from the passed potentialBuffer.`);
234
261
  },
235
262
  allocate(size) {
236
263
  return Buffer.alloc(size);
@@ -288,7 +315,10 @@ const nodeJsByteUtils = {
288
315
  }
289
316
  return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
290
317
  },
291
- randomBytes: nodejsRandomBytes
318
+ randomBytes: nodejsRandomBytes,
319
+ swap32(buffer) {
320
+ return nodeJsByteUtils.toLocalBufferType(buffer).swap32();
321
+ }
292
322
  };
293
323
 
294
324
  function isReactNative() {
@@ -333,7 +363,7 @@ const webByteUtils = {
333
363
  stringTag === '[object SharedArrayBuffer]') {
334
364
  return new Uint8Array(potentialUint8array);
335
365
  }
336
- throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`);
366
+ throw new BSONError(`Cannot make a Uint8Array from passed potentialBuffer.`);
337
367
  },
338
368
  allocate(size) {
339
369
  if (typeof size !== 'number') {
@@ -405,14 +435,30 @@ const webByteUtils = {
405
435
  uint8array.set(bytes, byteOffset);
406
436
  return bytes.byteLength;
407
437
  },
408
- randomBytes: webRandomBytes
438
+ randomBytes: webRandomBytes,
439
+ swap32(buffer) {
440
+ if (buffer.length % 4 !== 0) {
441
+ throw new RangeError('Buffer size must be a multiple of 32-bits');
442
+ }
443
+ for (let i = 0; i < buffer.length; i += 4) {
444
+ const byte0 = buffer[i];
445
+ const byte1 = buffer[i + 1];
446
+ const byte2 = buffer[i + 2];
447
+ const byte3 = buffer[i + 3];
448
+ buffer[i] = byte3;
449
+ buffer[i + 1] = byte2;
450
+ buffer[i + 2] = byte1;
451
+ buffer[i + 3] = byte0;
452
+ }
453
+ return buffer;
454
+ }
409
455
  };
410
456
 
411
457
  const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
412
458
  const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
413
459
 
414
460
  class BSONValue {
415
- get [Symbol.for('@@mdb.bson.version')]() {
461
+ get [BSON_VERSION_SYMBOL]() {
416
462
  return BSON_MAJOR_VERSION;
417
463
  }
418
464
  [Symbol.for('nodejs.util.inspect.custom')](depth, options, inspect) {
@@ -420,6 +466,134 @@ class BSONValue {
420
466
  }
421
467
  }
422
468
 
469
+ const FLOAT = new Float64Array(1);
470
+ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
471
+ FLOAT[0] = -1;
472
+ const isBigEndian = FLOAT_BYTES[7] === 0;
473
+ const NumberUtils = {
474
+ isBigEndian,
475
+ getNonnegativeInt32LE(source, offset) {
476
+ if (source[offset + 3] > 127) {
477
+ throw new RangeError(`Size cannot be negative at offset: ${offset}`);
478
+ }
479
+ return (source[offset] |
480
+ (source[offset + 1] << 8) |
481
+ (source[offset + 2] << 16) |
482
+ (source[offset + 3] << 24));
483
+ },
484
+ getInt32LE(source, offset) {
485
+ return (source[offset] |
486
+ (source[offset + 1] << 8) |
487
+ (source[offset + 2] << 16) |
488
+ (source[offset + 3] << 24));
489
+ },
490
+ getUint32LE(source, offset) {
491
+ return (source[offset] +
492
+ source[offset + 1] * 256 +
493
+ source[offset + 2] * 65536 +
494
+ source[offset + 3] * 16777216);
495
+ },
496
+ getUint32BE(source, offset) {
497
+ return (source[offset + 3] +
498
+ source[offset + 2] * 256 +
499
+ source[offset + 1] * 65536 +
500
+ source[offset] * 16777216);
501
+ },
502
+ getBigInt64LE(source, offset) {
503
+ const lo = NumberUtils.getUint32LE(source, offset);
504
+ const hi = NumberUtils.getUint32LE(source, offset + 4);
505
+ return (BigInt(hi) << BigInt(32)) + BigInt(lo);
506
+ },
507
+ getFloat64LE: isBigEndian
508
+ ? (source, offset) => {
509
+ FLOAT_BYTES[7] = source[offset];
510
+ FLOAT_BYTES[6] = source[offset + 1];
511
+ FLOAT_BYTES[5] = source[offset + 2];
512
+ FLOAT_BYTES[4] = source[offset + 3];
513
+ FLOAT_BYTES[3] = source[offset + 4];
514
+ FLOAT_BYTES[2] = source[offset + 5];
515
+ FLOAT_BYTES[1] = source[offset + 6];
516
+ FLOAT_BYTES[0] = source[offset + 7];
517
+ return FLOAT[0];
518
+ }
519
+ : (source, offset) => {
520
+ FLOAT_BYTES[0] = source[offset];
521
+ FLOAT_BYTES[1] = source[offset + 1];
522
+ FLOAT_BYTES[2] = source[offset + 2];
523
+ FLOAT_BYTES[3] = source[offset + 3];
524
+ FLOAT_BYTES[4] = source[offset + 4];
525
+ FLOAT_BYTES[5] = source[offset + 5];
526
+ FLOAT_BYTES[6] = source[offset + 6];
527
+ FLOAT_BYTES[7] = source[offset + 7];
528
+ return FLOAT[0];
529
+ },
530
+ setInt32BE(destination, offset, value) {
531
+ destination[offset + 3] = value;
532
+ value >>>= 8;
533
+ destination[offset + 2] = value;
534
+ value >>>= 8;
535
+ destination[offset + 1] = value;
536
+ value >>>= 8;
537
+ destination[offset] = value;
538
+ return 4;
539
+ },
540
+ setInt32LE(destination, offset, value) {
541
+ destination[offset] = value;
542
+ value >>>= 8;
543
+ destination[offset + 1] = value;
544
+ value >>>= 8;
545
+ destination[offset + 2] = value;
546
+ value >>>= 8;
547
+ destination[offset + 3] = value;
548
+ return 4;
549
+ },
550
+ setBigInt64LE(destination, offset, value) {
551
+ const mask32bits = BigInt(0xffff_ffff);
552
+ let lo = Number(value & mask32bits);
553
+ destination[offset] = lo;
554
+ lo >>= 8;
555
+ destination[offset + 1] = lo;
556
+ lo >>= 8;
557
+ destination[offset + 2] = lo;
558
+ lo >>= 8;
559
+ destination[offset + 3] = lo;
560
+ let hi = Number((value >> BigInt(32)) & mask32bits);
561
+ destination[offset + 4] = hi;
562
+ hi >>= 8;
563
+ destination[offset + 5] = hi;
564
+ hi >>= 8;
565
+ destination[offset + 6] = hi;
566
+ hi >>= 8;
567
+ destination[offset + 7] = hi;
568
+ return 8;
569
+ },
570
+ setFloat64LE: isBigEndian
571
+ ? (destination, offset, value) => {
572
+ FLOAT[0] = value;
573
+ destination[offset] = FLOAT_BYTES[7];
574
+ destination[offset + 1] = FLOAT_BYTES[6];
575
+ destination[offset + 2] = FLOAT_BYTES[5];
576
+ destination[offset + 3] = FLOAT_BYTES[4];
577
+ destination[offset + 4] = FLOAT_BYTES[3];
578
+ destination[offset + 5] = FLOAT_BYTES[2];
579
+ destination[offset + 6] = FLOAT_BYTES[1];
580
+ destination[offset + 7] = FLOAT_BYTES[0];
581
+ return 8;
582
+ }
583
+ : (destination, offset, value) => {
584
+ FLOAT[0] = value;
585
+ destination[offset] = FLOAT_BYTES[0];
586
+ destination[offset + 1] = FLOAT_BYTES[1];
587
+ destination[offset + 2] = FLOAT_BYTES[2];
588
+ destination[offset + 3] = FLOAT_BYTES[3];
589
+ destination[offset + 4] = FLOAT_BYTES[4];
590
+ destination[offset + 5] = FLOAT_BYTES[5];
591
+ destination[offset + 6] = FLOAT_BYTES[6];
592
+ destination[offset + 7] = FLOAT_BYTES[7];
593
+ return 8;
594
+ }
595
+ };
596
+
423
597
  class Binary extends BSONValue {
424
598
  get _bsontype() {
425
599
  return 'Binary';
@@ -492,7 +666,8 @@ class Binary extends BSONValue {
492
666
  }
493
667
  read(position, length) {
494
668
  length = length && length > 0 ? length : this.position;
495
- return this.buffer.slice(position, position + length);
669
+ const end = position + length;
670
+ return this.buffer.subarray(position, end > this.position ? this.position : end);
496
671
  }
497
672
  value() {
498
673
  return this.buffer.length === this.position
@@ -516,6 +691,9 @@ class Binary extends BSONValue {
516
691
  }
517
692
  toExtendedJSON(options) {
518
693
  options = options || {};
694
+ if (this.sub_type === Binary.SUBTYPE_VECTOR) {
695
+ validateBinaryVector(this);
696
+ }
519
697
  const base64String = ByteUtils.toBase64(this.buffer);
520
698
  const subType = Number(this.sub_type).toString(16);
521
699
  if (options.legacy) {
@@ -533,7 +711,7 @@ class Binary extends BSONValue {
533
711
  }
534
712
  toUUID() {
535
713
  if (this.sub_type === Binary.SUBTYPE_UUID) {
536
- return new UUID(this.buffer.slice(0, this.position));
714
+ return new UUID(this.buffer.subarray(0, this.position));
537
715
  }
538
716
  throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${Binary.SUBTYPE_UUID}" is currently supported.`);
539
717
  }
@@ -575,6 +753,99 @@ class Binary extends BSONValue {
575
753
  const subTypeArg = inspect(this.sub_type, options);
576
754
  return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`;
577
755
  }
756
+ toInt8Array() {
757
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
758
+ throw new BSONError('Binary sub_type is not Vector');
759
+ }
760
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.Int8) {
761
+ throw new BSONError('Binary datatype field is not Int8');
762
+ }
763
+ return new Int8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
764
+ }
765
+ toFloat32Array() {
766
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
767
+ throw new BSONError('Binary sub_type is not Vector');
768
+ }
769
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.Float32) {
770
+ throw new BSONError('Binary datatype field is not Float32');
771
+ }
772
+ const floatBytes = new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
773
+ if (NumberUtils.isBigEndian)
774
+ ByteUtils.swap32(floatBytes);
775
+ return new Float32Array(floatBytes.buffer);
776
+ }
777
+ toPackedBits() {
778
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
779
+ throw new BSONError('Binary sub_type is not Vector');
780
+ }
781
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {
782
+ throw new BSONError('Binary datatype field is not packed bit');
783
+ }
784
+ return new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
785
+ }
786
+ toBits() {
787
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
788
+ throw new BSONError('Binary sub_type is not Vector');
789
+ }
790
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {
791
+ throw new BSONError('Binary datatype field is not packed bit');
792
+ }
793
+ const byteCount = this.length() - 2;
794
+ const bitCount = byteCount * 8 - this.buffer[1];
795
+ const bits = new Int8Array(bitCount);
796
+ for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {
797
+ const byteOffset = (bitOffset / 8) | 0;
798
+ const byte = this.buffer[byteOffset + 2];
799
+ const shift = 7 - (bitOffset % 8);
800
+ const bit = (byte >> shift) & 1;
801
+ bits[bitOffset] = bit;
802
+ }
803
+ return bits;
804
+ }
805
+ static fromInt8Array(array) {
806
+ const buffer = ByteUtils.allocate(array.byteLength + 2);
807
+ buffer[0] = Binary.VECTOR_TYPE.Int8;
808
+ buffer[1] = 0;
809
+ const intBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
810
+ buffer.set(intBytes, 2);
811
+ return new this(buffer, this.SUBTYPE_VECTOR);
812
+ }
813
+ static fromFloat32Array(array) {
814
+ const binaryBytes = ByteUtils.allocate(array.byteLength + 2);
815
+ binaryBytes[0] = Binary.VECTOR_TYPE.Float32;
816
+ binaryBytes[1] = 0;
817
+ const floatBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
818
+ binaryBytes.set(floatBytes, 2);
819
+ if (NumberUtils.isBigEndian)
820
+ ByteUtils.swap32(new Uint8Array(binaryBytes.buffer, 2));
821
+ return new this(binaryBytes, this.SUBTYPE_VECTOR);
822
+ }
823
+ static fromPackedBits(array, padding = 0) {
824
+ const buffer = ByteUtils.allocate(array.byteLength + 2);
825
+ buffer[0] = Binary.VECTOR_TYPE.PackedBit;
826
+ buffer[1] = padding;
827
+ buffer.set(array, 2);
828
+ return new this(buffer, this.SUBTYPE_VECTOR);
829
+ }
830
+ static fromBits(bits) {
831
+ const byteLength = (bits.length + 7) >>> 3;
832
+ const bytes = new Uint8Array(byteLength + 2);
833
+ bytes[0] = Binary.VECTOR_TYPE.PackedBit;
834
+ const remainder = bits.length % 8;
835
+ bytes[1] = remainder === 0 ? 0 : 8 - remainder;
836
+ for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {
837
+ const byteOffset = bitOffset >>> 3;
838
+ const bit = bits[bitOffset];
839
+ if (bit !== 0 && bit !== 1) {
840
+ throw new BSONError(`Invalid bit value at ${bitOffset}: must be 0 or 1, found ${bits[bitOffset]}`);
841
+ }
842
+ if (bit === 0)
843
+ continue;
844
+ const shift = 7 - (bitOffset % 8);
845
+ bytes[byteOffset + 2] |= bit << shift;
846
+ }
847
+ return new this(bytes, Binary.SUBTYPE_VECTOR);
848
+ }
578
849
  }
579
850
  Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0;
580
851
  Binary.BUFFER_SIZE = 256;
@@ -587,7 +858,30 @@ Binary.SUBTYPE_MD5 = 5;
587
858
  Binary.SUBTYPE_ENCRYPTED = 6;
588
859
  Binary.SUBTYPE_COLUMN = 7;
589
860
  Binary.SUBTYPE_SENSITIVE = 8;
861
+ Binary.SUBTYPE_VECTOR = 9;
590
862
  Binary.SUBTYPE_USER_DEFINED = 128;
863
+ Binary.VECTOR_TYPE = Object.freeze({
864
+ Int8: 0x03,
865
+ Float32: 0x27,
866
+ PackedBit: 0x10
867
+ });
868
+ function validateBinaryVector(vector) {
869
+ if (vector.sub_type !== Binary.SUBTYPE_VECTOR)
870
+ return;
871
+ const size = vector.position;
872
+ const datatype = vector.buffer[0];
873
+ const padding = vector.buffer[1];
874
+ if ((datatype === Binary.VECTOR_TYPE.Float32 || datatype === Binary.VECTOR_TYPE.Int8) &&
875
+ padding !== 0) {
876
+ throw new BSONError('Invalid Vector: padding must be zero for int8 and float32 vectors');
877
+ }
878
+ if (datatype === Binary.VECTOR_TYPE.PackedBit && padding !== 0 && size === 2) {
879
+ throw new BSONError('Invalid Vector: padding must be zero for packed bit vectors that are empty');
880
+ }
881
+ if (datatype === Binary.VECTOR_TYPE.PackedBit && padding > 7) {
882
+ throw new BSONError(`Invalid Vector: padding must be a value between 0 and 7. found: ${padding}`);
883
+ }
884
+ }
591
885
  const UUID_BYTE_LENGTH = 16;
592
886
  const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;
593
887
  const UUID_WITH_DASHES = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i;
@@ -1589,7 +1883,7 @@ class Decimal128 extends BSONValue {
1589
1883
  if (typeof bytes === 'string') {
1590
1884
  this.bytes = Decimal128.fromString(bytes).bytes;
1591
1885
  }
1592
- else if (isUint8Array(bytes)) {
1886
+ else if (bytes instanceof Uint8Array || isUint8Array(bytes)) {
1593
1887
  if (bytes.byteLength !== 16) {
1594
1888
  throw new BSONError('Decimal128 must take a Buffer of 16 bytes');
1595
1889
  }
@@ -2199,134 +2493,6 @@ class MinKey extends BSONValue {
2199
2493
  }
2200
2494
  }
2201
2495
 
2202
- const FLOAT = new Float64Array(1);
2203
- const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
2204
- FLOAT[0] = -1;
2205
- const isBigEndian = FLOAT_BYTES[7] === 0;
2206
- const NumberUtils = {
2207
- getNonnegativeInt32LE(source, offset) {
2208
- if (source[offset + 3] > 127) {
2209
- throw new RangeError(`Size cannot be negative at offset: ${offset}`);
2210
- }
2211
- return (source[offset] |
2212
- (source[offset + 1] << 8) |
2213
- (source[offset + 2] << 16) |
2214
- (source[offset + 3] << 24));
2215
- },
2216
- getInt32LE(source, offset) {
2217
- return (source[offset] |
2218
- (source[offset + 1] << 8) |
2219
- (source[offset + 2] << 16) |
2220
- (source[offset + 3] << 24));
2221
- },
2222
- getUint32LE(source, offset) {
2223
- return (source[offset] +
2224
- source[offset + 1] * 256 +
2225
- source[offset + 2] * 65536 +
2226
- source[offset + 3] * 16777216);
2227
- },
2228
- getUint32BE(source, offset) {
2229
- return (source[offset + 3] +
2230
- source[offset + 2] * 256 +
2231
- source[offset + 1] * 65536 +
2232
- source[offset] * 16777216);
2233
- },
2234
- getBigInt64LE(source, offset) {
2235
- const lo = NumberUtils.getUint32LE(source, offset);
2236
- const hi = NumberUtils.getUint32LE(source, offset + 4);
2237
- return (BigInt(hi) << BigInt(32)) + BigInt(lo);
2238
- },
2239
- getFloat64LE: isBigEndian
2240
- ? (source, offset) => {
2241
- FLOAT_BYTES[7] = source[offset];
2242
- FLOAT_BYTES[6] = source[offset + 1];
2243
- FLOAT_BYTES[5] = source[offset + 2];
2244
- FLOAT_BYTES[4] = source[offset + 3];
2245
- FLOAT_BYTES[3] = source[offset + 4];
2246
- FLOAT_BYTES[2] = source[offset + 5];
2247
- FLOAT_BYTES[1] = source[offset + 6];
2248
- FLOAT_BYTES[0] = source[offset + 7];
2249
- return FLOAT[0];
2250
- }
2251
- : (source, offset) => {
2252
- FLOAT_BYTES[0] = source[offset];
2253
- FLOAT_BYTES[1] = source[offset + 1];
2254
- FLOAT_BYTES[2] = source[offset + 2];
2255
- FLOAT_BYTES[3] = source[offset + 3];
2256
- FLOAT_BYTES[4] = source[offset + 4];
2257
- FLOAT_BYTES[5] = source[offset + 5];
2258
- FLOAT_BYTES[6] = source[offset + 6];
2259
- FLOAT_BYTES[7] = source[offset + 7];
2260
- return FLOAT[0];
2261
- },
2262
- setInt32BE(destination, offset, value) {
2263
- destination[offset + 3] = value;
2264
- value >>>= 8;
2265
- destination[offset + 2] = value;
2266
- value >>>= 8;
2267
- destination[offset + 1] = value;
2268
- value >>>= 8;
2269
- destination[offset] = value;
2270
- return 4;
2271
- },
2272
- setInt32LE(destination, offset, value) {
2273
- destination[offset] = value;
2274
- value >>>= 8;
2275
- destination[offset + 1] = value;
2276
- value >>>= 8;
2277
- destination[offset + 2] = value;
2278
- value >>>= 8;
2279
- destination[offset + 3] = value;
2280
- return 4;
2281
- },
2282
- setBigInt64LE(destination, offset, value) {
2283
- const mask32bits = BigInt(4294967295);
2284
- let lo = Number(value & mask32bits);
2285
- destination[offset] = lo;
2286
- lo >>= 8;
2287
- destination[offset + 1] = lo;
2288
- lo >>= 8;
2289
- destination[offset + 2] = lo;
2290
- lo >>= 8;
2291
- destination[offset + 3] = lo;
2292
- let hi = Number((value >> BigInt(32)) & mask32bits);
2293
- destination[offset + 4] = hi;
2294
- hi >>= 8;
2295
- destination[offset + 5] = hi;
2296
- hi >>= 8;
2297
- destination[offset + 6] = hi;
2298
- hi >>= 8;
2299
- destination[offset + 7] = hi;
2300
- return 8;
2301
- },
2302
- setFloat64LE: isBigEndian
2303
- ? (destination, offset, value) => {
2304
- FLOAT[0] = value;
2305
- destination[offset] = FLOAT_BYTES[7];
2306
- destination[offset + 1] = FLOAT_BYTES[6];
2307
- destination[offset + 2] = FLOAT_BYTES[5];
2308
- destination[offset + 3] = FLOAT_BYTES[4];
2309
- destination[offset + 4] = FLOAT_BYTES[3];
2310
- destination[offset + 5] = FLOAT_BYTES[2];
2311
- destination[offset + 6] = FLOAT_BYTES[1];
2312
- destination[offset + 7] = FLOAT_BYTES[0];
2313
- return 8;
2314
- }
2315
- : (destination, offset, value) => {
2316
- FLOAT[0] = value;
2317
- destination[offset] = FLOAT_BYTES[0];
2318
- destination[offset + 1] = FLOAT_BYTES[1];
2319
- destination[offset + 2] = FLOAT_BYTES[2];
2320
- destination[offset + 3] = FLOAT_BYTES[3];
2321
- destination[offset + 4] = FLOAT_BYTES[4];
2322
- destination[offset + 5] = FLOAT_BYTES[5];
2323
- destination[offset + 6] = FLOAT_BYTES[6];
2324
- destination[offset + 7] = FLOAT_BYTES[7];
2325
- return 8;
2326
- }
2327
- };
2328
-
2329
- const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2330
2496
  let PROCESS_UNIQUE = null;
2331
2497
  class ObjectId extends BSONValue {
2332
2498
  get _bsontype() {
@@ -2356,7 +2522,7 @@ class ObjectId extends BSONValue {
2356
2522
  this.buffer = ByteUtils.toLocalBufferType(workingId);
2357
2523
  }
2358
2524
  else if (typeof workingId === 'string') {
2359
- if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2525
+ if (ObjectId.validateHexString(workingId)) {
2360
2526
  this.buffer = ByteUtils.fromHex(workingId);
2361
2527
  }
2362
2528
  else {
@@ -2379,6 +2545,20 @@ class ObjectId extends BSONValue {
2379
2545
  this.__id = ByteUtils.toHex(value);
2380
2546
  }
2381
2547
  }
2548
+ static validateHexString(string) {
2549
+ if (string?.length !== 24)
2550
+ return false;
2551
+ for (let i = 0; i < 24; i++) {
2552
+ const char = string.charCodeAt(i);
2553
+ if ((char >= 48 && char <= 57) ||
2554
+ (char >= 97 && char <= 102) ||
2555
+ (char >= 65 && char <= 70)) {
2556
+ continue;
2557
+ }
2558
+ return false;
2559
+ }
2560
+ return true;
2561
+ }
2382
2562
  toHexString() {
2383
2563
  if (ObjectId.cacheHexString && this.__id) {
2384
2564
  return this.__id;
@@ -2491,6 +2671,8 @@ class ObjectId extends BSONValue {
2491
2671
  static isValid(id) {
2492
2672
  if (id == null)
2493
2673
  return false;
2674
+ if (typeof id === 'string')
2675
+ return ObjectId.validateHexString(id);
2494
2676
  try {
2495
2677
  new ObjectId(id);
2496
2678
  return true;
@@ -2561,7 +2743,7 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
2561
2743
  case 'object':
2562
2744
  if (value != null &&
2563
2745
  typeof value._bsontype === 'string' &&
2564
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
2746
+ value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
2565
2747
  throw new BSONVersionError();
2566
2748
  }
2567
2749
  else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
@@ -2765,6 +2947,12 @@ class Timestamp extends LongWithoutOverridesClass {
2765
2947
  get _bsontype() {
2766
2948
  return 'Timestamp';
2767
2949
  }
2950
+ get i() {
2951
+ return this.low >>> 0;
2952
+ }
2953
+ get t() {
2954
+ return this.high >>> 0;
2955
+ }
2768
2956
  constructor(low) {
2769
2957
  if (low == null) {
2770
2958
  super(0, 0, true);
@@ -2790,10 +2978,10 @@ class Timestamp extends LongWithoutOverridesClass {
2790
2978
  if (i < 0 || Number.isNaN(i)) {
2791
2979
  throw new BSONError('Timestamp constructed from { t, i } must provide a positive i');
2792
2980
  }
2793
- if (t > 4294967295) {
2981
+ if (t > 0xffff_ffff) {
2794
2982
  throw new BSONError('Timestamp constructed from { t, i } must provide t equal or less than uint32 max');
2795
2983
  }
2796
- if (i > 4294967295) {
2984
+ if (i > 0xffff_ffff) {
2797
2985
  throw new BSONError('Timestamp constructed from { t, i } must provide i equal or less than uint32 max');
2798
2986
  }
2799
2987
  super(i, t, true);
@@ -2820,7 +3008,7 @@ class Timestamp extends LongWithoutOverridesClass {
2820
3008
  return new Timestamp(Long.fromString(str, true, optRadix));
2821
3009
  }
2822
3010
  toExtendedJSON() {
2823
- return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } };
3011
+ return { $timestamp: { t: this.t, i: this.i } };
2824
3012
  }
2825
3013
  static fromExtendedJSON(doc) {
2826
3014
  const i = Long.isLong(doc.$timestamp.i)
@@ -2833,8 +3021,8 @@ class Timestamp extends LongWithoutOverridesClass {
2833
3021
  }
2834
3022
  inspect(depth, options, inspect) {
2835
3023
  inspect ??= defaultInspect;
2836
- const t = inspect(this.high >>> 0, options);
2837
- const i = inspect(this.low >>> 0, options);
3024
+ const t = inspect(this.t, options);
3025
+ const i = inspect(this.i, options);
2838
3026
  return `new Timestamp({ t: ${t}, i: ${i} })`;
2839
3027
  }
2840
3028
  }
@@ -2991,7 +3179,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2991
3179
  if (objectSize <= 0 || objectSize > buffer.length - index)
2992
3180
  throw new BSONError('bad embedded document length in bson');
2993
3181
  if (raw) {
2994
- value = buffer.slice(index, index + objectSize);
3182
+ value = buffer.subarray(index, index + objectSize);
2995
3183
  }
2996
3184
  else {
2997
3185
  let objectOptions = options;
@@ -3063,49 +3251,23 @@ function deserializeObject(buffer, index, options, isArray = false) {
3063
3251
  throw new BSONError('Negative binary type element size found');
3064
3252
  if (binarySize > buffer.byteLength)
3065
3253
  throw new BSONError('Binary type size larger than document size');
3066
- if (buffer['slice'] != null) {
3067
- if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3068
- binarySize = NumberUtils.getInt32LE(buffer, index);
3069
- index += 4;
3070
- if (binarySize < 0)
3071
- throw new BSONError('Negative binary type element size found for subtype 0x02');
3072
- if (binarySize > totalBinarySize - 4)
3073
- throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3074
- if (binarySize < totalBinarySize - 4)
3075
- throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3076
- }
3077
- if (promoteBuffers && promoteValues) {
3078
- value = ByteUtils.toLocalBufferType(buffer.slice(index, index + binarySize));
3079
- }
3080
- else {
3081
- value = new Binary(buffer.slice(index, index + binarySize), subType);
3082
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3083
- value = value.toUUID();
3084
- }
3085
- }
3254
+ if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3255
+ binarySize = NumberUtils.getInt32LE(buffer, index);
3256
+ index += 4;
3257
+ if (binarySize < 0)
3258
+ throw new BSONError('Negative binary type element size found for subtype 0x02');
3259
+ if (binarySize > totalBinarySize - 4)
3260
+ throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3261
+ if (binarySize < totalBinarySize - 4)
3262
+ throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3263
+ }
3264
+ if (promoteBuffers && promoteValues) {
3265
+ value = ByteUtils.toLocalBufferType(buffer.subarray(index, index + binarySize));
3086
3266
  }
3087
3267
  else {
3088
- if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3089
- binarySize = NumberUtils.getInt32LE(buffer, index);
3090
- index += 4;
3091
- if (binarySize < 0)
3092
- throw new BSONError('Negative binary type element size found for subtype 0x02');
3093
- if (binarySize > totalBinarySize - 4)
3094
- throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3095
- if (binarySize < totalBinarySize - 4)
3096
- throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3097
- }
3098
- if (promoteBuffers && promoteValues) {
3099
- value = ByteUtils.allocateUnsafe(binarySize);
3100
- for (i = 0; i < binarySize; i++) {
3101
- value[i] = buffer[index + i];
3102
- }
3103
- }
3104
- else {
3105
- value = new Binary(buffer.slice(index, index + binarySize), subType);
3106
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3107
- value = value.toUUID();
3108
- }
3268
+ value = new Binary(buffer.subarray(index, index + binarySize), subType);
3269
+ if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3270
+ value = value.toUUID();
3109
3271
  }
3110
3272
  }
3111
3273
  index = index + binarySize;
@@ -3527,6 +3689,9 @@ function serializeBinary(buffer, key, value, index) {
3527
3689
  size = size - 4;
3528
3690
  index += NumberUtils.setInt32LE(buffer, index, size);
3529
3691
  }
3692
+ if (value.sub_type === Binary.SUBTYPE_VECTOR) {
3693
+ validateBinaryVector(value);
3694
+ }
3530
3695
  if (size <= 16) {
3531
3696
  for (let i = 0; i < size; i++)
3532
3697
  buffer[index + i] = data[i];
@@ -3603,79 +3768,83 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3603
3768
  if (typeof value?.toBSON === 'function') {
3604
3769
  value = value.toBSON();
3605
3770
  }
3606
- if (typeof value === 'string') {
3607
- index = serializeString(buffer, key, value, index);
3608
- }
3609
- else if (typeof value === 'number') {
3610
- index = serializeNumber(buffer, key, value, index);
3611
- }
3612
- else if (typeof value === 'bigint') {
3613
- index = serializeBigInt(buffer, key, value, index);
3614
- }
3615
- else if (typeof value === 'boolean') {
3616
- index = serializeBoolean(buffer, key, value, index);
3617
- }
3618
- else if (value instanceof Date || isDate(value)) {
3619
- index = serializeDate(buffer, key, value, index);
3620
- }
3621
- else if (value === undefined) {
3771
+ const type = typeof value;
3772
+ if (value === undefined) {
3622
3773
  index = serializeNull(buffer, key, value, index);
3623
3774
  }
3624
3775
  else if (value === null) {
3625
3776
  index = serializeNull(buffer, key, value, index);
3626
3777
  }
3627
- else if (isUint8Array(value)) {
3628
- index = serializeBuffer(buffer, key, value, index);
3629
- }
3630
- else if (value instanceof RegExp || isRegExp(value)) {
3631
- index = serializeRegExp(buffer, key, value, index);
3632
- }
3633
- else if (typeof value === 'object' && value._bsontype == null) {
3634
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3778
+ else if (type === 'string') {
3779
+ index = serializeString(buffer, key, value, index);
3635
3780
  }
3636
- else if (typeof value === 'object' &&
3637
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3638
- throw new BSONVersionError();
3781
+ else if (type === 'number') {
3782
+ index = serializeNumber(buffer, key, value, index);
3639
3783
  }
3640
- else if (value._bsontype === 'ObjectId') {
3641
- index = serializeObjectId(buffer, key, value, index);
3784
+ else if (type === 'bigint') {
3785
+ index = serializeBigInt(buffer, key, value, index);
3642
3786
  }
3643
- else if (value._bsontype === 'Decimal128') {
3644
- index = serializeDecimal128(buffer, key, value, index);
3787
+ else if (type === 'boolean') {
3788
+ index = serializeBoolean(buffer, key, value, index);
3645
3789
  }
3646
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3647
- index = serializeLong(buffer, key, value, index);
3790
+ else if (type === 'object' && value._bsontype == null) {
3791
+ if (value instanceof Date || isDate(value)) {
3792
+ index = serializeDate(buffer, key, value, index);
3793
+ }
3794
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3795
+ index = serializeBuffer(buffer, key, value, index);
3796
+ }
3797
+ else if (value instanceof RegExp || isRegExp(value)) {
3798
+ index = serializeRegExp(buffer, key, value, index);
3799
+ }
3800
+ else {
3801
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3802
+ }
3648
3803
  }
3649
- else if (value._bsontype === 'Double') {
3650
- index = serializeDouble(buffer, key, value, index);
3804
+ else if (type === 'object') {
3805
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3806
+ throw new BSONVersionError();
3807
+ }
3808
+ else if (value._bsontype === 'ObjectId') {
3809
+ index = serializeObjectId(buffer, key, value, index);
3810
+ }
3811
+ else if (value._bsontype === 'Decimal128') {
3812
+ index = serializeDecimal128(buffer, key, value, index);
3813
+ }
3814
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3815
+ index = serializeLong(buffer, key, value, index);
3816
+ }
3817
+ else if (value._bsontype === 'Double') {
3818
+ index = serializeDouble(buffer, key, value, index);
3819
+ }
3820
+ else if (value._bsontype === 'Code') {
3821
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3822
+ }
3823
+ else if (value._bsontype === 'Binary') {
3824
+ index = serializeBinary(buffer, key, value, index);
3825
+ }
3826
+ else if (value._bsontype === 'BSONSymbol') {
3827
+ index = serializeSymbol(buffer, key, value, index);
3828
+ }
3829
+ else if (value._bsontype === 'DBRef') {
3830
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3831
+ }
3832
+ else if (value._bsontype === 'BSONRegExp') {
3833
+ index = serializeBSONRegExp(buffer, key, value, index);
3834
+ }
3835
+ else if (value._bsontype === 'Int32') {
3836
+ index = serializeInt32(buffer, key, value, index);
3837
+ }
3838
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3839
+ index = serializeMinMax(buffer, key, value, index);
3840
+ }
3841
+ else if (typeof value._bsontype !== 'undefined') {
3842
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3843
+ }
3651
3844
  }
3652
- else if (typeof value === 'function' && serializeFunctions) {
3845
+ else if (type === 'function' && serializeFunctions) {
3653
3846
  index = serializeFunction(buffer, key, value, index);
3654
3847
  }
3655
- else if (value._bsontype === 'Code') {
3656
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3657
- }
3658
- else if (value._bsontype === 'Binary') {
3659
- index = serializeBinary(buffer, key, value, index);
3660
- }
3661
- else if (value._bsontype === 'BSONSymbol') {
3662
- index = serializeSymbol(buffer, key, value, index);
3663
- }
3664
- else if (value._bsontype === 'DBRef') {
3665
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3666
- }
3667
- else if (value._bsontype === 'BSONRegExp') {
3668
- index = serializeBSONRegExp(buffer, key, value, index);
3669
- }
3670
- else if (value._bsontype === 'Int32') {
3671
- index = serializeInt32(buffer, key, value, index);
3672
- }
3673
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3674
- index = serializeMinMax(buffer, key, value, index);
3675
- }
3676
- else if (typeof value._bsontype !== 'undefined') {
3677
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3678
- }
3679
3848
  }
3680
3849
  }
3681
3850
  else if (object instanceof Map || isMap(object)) {
@@ -3705,7 +3874,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3705
3874
  }
3706
3875
  }
3707
3876
  }
3708
- if (type === 'string') {
3877
+ if (value === undefined) {
3878
+ if (ignoreUndefined === false)
3879
+ index = serializeNull(buffer, key, value, index);
3880
+ }
3881
+ else if (value === null) {
3882
+ index = serializeNull(buffer, key, value, index);
3883
+ }
3884
+ else if (type === 'string') {
3709
3885
  index = serializeString(buffer, key, value, index);
3710
3886
  }
3711
3887
  else if (type === 'number') {
@@ -3717,64 +3893,64 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3717
3893
  else if (type === 'boolean') {
3718
3894
  index = serializeBoolean(buffer, key, value, index);
3719
3895
  }
3720
- else if (value instanceof Date || isDate(value)) {
3721
- index = serializeDate(buffer, key, value, index);
3722
- }
3723
- else if (value === null || (value === undefined && ignoreUndefined === false)) {
3724
- index = serializeNull(buffer, key, value, index);
3725
- }
3726
- else if (isUint8Array(value)) {
3727
- index = serializeBuffer(buffer, key, value, index);
3728
- }
3729
- else if (value instanceof RegExp || isRegExp(value)) {
3730
- index = serializeRegExp(buffer, key, value, index);
3731
- }
3732
3896
  else if (type === 'object' && value._bsontype == null) {
3733
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3734
- }
3735
- else if (typeof value === 'object' &&
3736
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3737
- throw new BSONVersionError();
3738
- }
3739
- else if (value._bsontype === 'ObjectId') {
3740
- index = serializeObjectId(buffer, key, value, index);
3741
- }
3742
- else if (type === 'object' && value._bsontype === 'Decimal128') {
3743
- index = serializeDecimal128(buffer, key, value, index);
3744
- }
3745
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3746
- index = serializeLong(buffer, key, value, index);
3747
- }
3748
- else if (value._bsontype === 'Double') {
3749
- index = serializeDouble(buffer, key, value, index);
3897
+ if (value instanceof Date || isDate(value)) {
3898
+ index = serializeDate(buffer, key, value, index);
3899
+ }
3900
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3901
+ index = serializeBuffer(buffer, key, value, index);
3902
+ }
3903
+ else if (value instanceof RegExp || isRegExp(value)) {
3904
+ index = serializeRegExp(buffer, key, value, index);
3905
+ }
3906
+ else {
3907
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3908
+ }
3750
3909
  }
3751
- else if (value._bsontype === 'Code') {
3752
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3910
+ else if (type === 'object') {
3911
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3912
+ throw new BSONVersionError();
3913
+ }
3914
+ else if (value._bsontype === 'ObjectId') {
3915
+ index = serializeObjectId(buffer, key, value, index);
3916
+ }
3917
+ else if (value._bsontype === 'Decimal128') {
3918
+ index = serializeDecimal128(buffer, key, value, index);
3919
+ }
3920
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3921
+ index = serializeLong(buffer, key, value, index);
3922
+ }
3923
+ else if (value._bsontype === 'Double') {
3924
+ index = serializeDouble(buffer, key, value, index);
3925
+ }
3926
+ else if (value._bsontype === 'Code') {
3927
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3928
+ }
3929
+ else if (value._bsontype === 'Binary') {
3930
+ index = serializeBinary(buffer, key, value, index);
3931
+ }
3932
+ else if (value._bsontype === 'BSONSymbol') {
3933
+ index = serializeSymbol(buffer, key, value, index);
3934
+ }
3935
+ else if (value._bsontype === 'DBRef') {
3936
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3937
+ }
3938
+ else if (value._bsontype === 'BSONRegExp') {
3939
+ index = serializeBSONRegExp(buffer, key, value, index);
3940
+ }
3941
+ else if (value._bsontype === 'Int32') {
3942
+ index = serializeInt32(buffer, key, value, index);
3943
+ }
3944
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3945
+ index = serializeMinMax(buffer, key, value, index);
3946
+ }
3947
+ else if (typeof value._bsontype !== 'undefined') {
3948
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3949
+ }
3753
3950
  }
3754
- else if (typeof value === 'function' && serializeFunctions) {
3951
+ else if (type === 'function' && serializeFunctions) {
3755
3952
  index = serializeFunction(buffer, key, value, index);
3756
3953
  }
3757
- else if (value._bsontype === 'Binary') {
3758
- index = serializeBinary(buffer, key, value, index);
3759
- }
3760
- else if (value._bsontype === 'BSONSymbol') {
3761
- index = serializeSymbol(buffer, key, value, index);
3762
- }
3763
- else if (value._bsontype === 'DBRef') {
3764
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3765
- }
3766
- else if (value._bsontype === 'BSONRegExp') {
3767
- index = serializeBSONRegExp(buffer, key, value, index);
3768
- }
3769
- else if (value._bsontype === 'Int32') {
3770
- index = serializeInt32(buffer, key, value, index);
3771
- }
3772
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3773
- index = serializeMinMax(buffer, key, value, index);
3774
- }
3775
- else if (typeof value._bsontype !== 'undefined') {
3776
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3777
- }
3778
3954
  }
3779
3955
  }
3780
3956
  else {
@@ -3803,7 +3979,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3803
3979
  }
3804
3980
  }
3805
3981
  }
3806
- if (type === 'string') {
3982
+ if (value === undefined) {
3983
+ if (ignoreUndefined === false)
3984
+ index = serializeNull(buffer, key, value, index);
3985
+ }
3986
+ else if (value === null) {
3987
+ index = serializeNull(buffer, key, value, index);
3988
+ }
3989
+ else if (type === 'string') {
3807
3990
  index = serializeString(buffer, key, value, index);
3808
3991
  }
3809
3992
  else if (type === 'number') {
@@ -3815,68 +3998,64 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3815
3998
  else if (type === 'boolean') {
3816
3999
  index = serializeBoolean(buffer, key, value, index);
3817
4000
  }
3818
- else if (value instanceof Date || isDate(value)) {
3819
- index = serializeDate(buffer, key, value, index);
3820
- }
3821
- else if (value === undefined) {
3822
- if (ignoreUndefined === false)
3823
- index = serializeNull(buffer, key, value, index);
3824
- }
3825
- else if (value === null) {
3826
- index = serializeNull(buffer, key, value, index);
3827
- }
3828
- else if (isUint8Array(value)) {
3829
- index = serializeBuffer(buffer, key, value, index);
3830
- }
3831
- else if (value instanceof RegExp || isRegExp(value)) {
3832
- index = serializeRegExp(buffer, key, value, index);
3833
- }
3834
4001
  else if (type === 'object' && value._bsontype == null) {
3835
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3836
- }
3837
- else if (typeof value === 'object' &&
3838
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3839
- throw new BSONVersionError();
3840
- }
3841
- else if (value._bsontype === 'ObjectId') {
3842
- index = serializeObjectId(buffer, key, value, index);
3843
- }
3844
- else if (type === 'object' && value._bsontype === 'Decimal128') {
3845
- index = serializeDecimal128(buffer, key, value, index);
3846
- }
3847
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3848
- index = serializeLong(buffer, key, value, index);
3849
- }
3850
- else if (value._bsontype === 'Double') {
3851
- index = serializeDouble(buffer, key, value, index);
4002
+ if (value instanceof Date || isDate(value)) {
4003
+ index = serializeDate(buffer, key, value, index);
4004
+ }
4005
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
4006
+ index = serializeBuffer(buffer, key, value, index);
4007
+ }
4008
+ else if (value instanceof RegExp || isRegExp(value)) {
4009
+ index = serializeRegExp(buffer, key, value, index);
4010
+ }
4011
+ else {
4012
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4013
+ }
3852
4014
  }
3853
- else if (value._bsontype === 'Code') {
3854
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4015
+ else if (type === 'object') {
4016
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
4017
+ throw new BSONVersionError();
4018
+ }
4019
+ else if (value._bsontype === 'ObjectId') {
4020
+ index = serializeObjectId(buffer, key, value, index);
4021
+ }
4022
+ else if (value._bsontype === 'Decimal128') {
4023
+ index = serializeDecimal128(buffer, key, value, index);
4024
+ }
4025
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
4026
+ index = serializeLong(buffer, key, value, index);
4027
+ }
4028
+ else if (value._bsontype === 'Double') {
4029
+ index = serializeDouble(buffer, key, value, index);
4030
+ }
4031
+ else if (value._bsontype === 'Code') {
4032
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4033
+ }
4034
+ else if (value._bsontype === 'Binary') {
4035
+ index = serializeBinary(buffer, key, value, index);
4036
+ }
4037
+ else if (value._bsontype === 'BSONSymbol') {
4038
+ index = serializeSymbol(buffer, key, value, index);
4039
+ }
4040
+ else if (value._bsontype === 'DBRef') {
4041
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
4042
+ }
4043
+ else if (value._bsontype === 'BSONRegExp') {
4044
+ index = serializeBSONRegExp(buffer, key, value, index);
4045
+ }
4046
+ else if (value._bsontype === 'Int32') {
4047
+ index = serializeInt32(buffer, key, value, index);
4048
+ }
4049
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
4050
+ index = serializeMinMax(buffer, key, value, index);
4051
+ }
4052
+ else if (typeof value._bsontype !== 'undefined') {
4053
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
4054
+ }
3855
4055
  }
3856
- else if (typeof value === 'function' && serializeFunctions) {
4056
+ else if (type === 'function' && serializeFunctions) {
3857
4057
  index = serializeFunction(buffer, key, value, index);
3858
4058
  }
3859
- else if (value._bsontype === 'Binary') {
3860
- index = serializeBinary(buffer, key, value, index);
3861
- }
3862
- else if (value._bsontype === 'BSONSymbol') {
3863
- index = serializeSymbol(buffer, key, value, index);
3864
- }
3865
- else if (value._bsontype === 'DBRef') {
3866
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3867
- }
3868
- else if (value._bsontype === 'BSONRegExp') {
3869
- index = serializeBSONRegExp(buffer, key, value, index);
3870
- }
3871
- else if (value._bsontype === 'Int32') {
3872
- index = serializeInt32(buffer, key, value, index);
3873
- }
3874
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3875
- index = serializeMinMax(buffer, key, value, index);
3876
- }
3877
- else if (typeof value._bsontype !== 'undefined') {
3878
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3879
- }
3880
4059
  }
3881
4060
  }
3882
4061
  path.delete(object);
@@ -4128,7 +4307,7 @@ function serializeDocument(doc, options) {
4128
4307
  else if (doc != null &&
4129
4308
  typeof doc === 'object' &&
4130
4309
  typeof doc._bsontype === 'string' &&
4131
- doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
4310
+ doc[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
4132
4311
  throw new BSONVersionError();
4133
4312
  }
4134
4313
  else if (isBSONType(doc)) {