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.
package/lib/bson.rn.cjs CHANGED
@@ -1,25 +1,53 @@
1
1
  'use strict';
2
2
 
3
+ const map = new WeakMap();
4
+ const TYPES = {
5
+ ArrayBuffer: '[object ArrayBuffer]',
6
+ SharedArrayBuffer: '[object SharedArrayBuffer]',
7
+ Uint8Array: '[object Uint8Array]',
8
+ BigInt64Array: '[object BigInt64Array]',
9
+ BigUint64Array: '[object BigUint64Array]',
10
+ RegExp: '[object RegExp]',
11
+ Map: '[object Map]',
12
+ Date: '[object Date]'
13
+ };
14
+ function getPrototypeString(value) {
15
+ let str = map.get(value);
16
+ if (!str) {
17
+ str = Object.prototype.toString.call(value);
18
+ if (value !== null && typeof value === 'object') {
19
+ map.set(value, str);
20
+ }
21
+ }
22
+ return str;
23
+ }
3
24
  function isAnyArrayBuffer(value) {
4
- return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes(Object.prototype.toString.call(value));
25
+ const type = getPrototypeString(value);
26
+ return type === TYPES.ArrayBuffer || type === TYPES.SharedArrayBuffer;
5
27
  }
6
28
  function isUint8Array(value) {
7
- return Object.prototype.toString.call(value) === '[object Uint8Array]';
29
+ const type = getPrototypeString(value);
30
+ return type === TYPES.Uint8Array;
8
31
  }
9
32
  function isBigInt64Array(value) {
10
- return Object.prototype.toString.call(value) === '[object BigInt64Array]';
33
+ const type = getPrototypeString(value);
34
+ return type === TYPES.BigInt64Array;
11
35
  }
12
36
  function isBigUInt64Array(value) {
13
- return Object.prototype.toString.call(value) === '[object BigUint64Array]';
37
+ const type = getPrototypeString(value);
38
+ return type === TYPES.BigUint64Array;
14
39
  }
15
40
  function isRegExp(d) {
16
- return Object.prototype.toString.call(d) === '[object RegExp]';
41
+ const type = getPrototypeString(d);
42
+ return type === TYPES.RegExp;
17
43
  }
18
44
  function isMap(d) {
19
- return Object.prototype.toString.call(d) === '[object Map]';
45
+ const type = getPrototypeString(d);
46
+ return type === TYPES.Map;
20
47
  }
21
48
  function isDate(d) {
22
- return Object.prototype.toString.call(d) === '[object Date]';
49
+ const type = getPrototypeString(d);
50
+ return type === TYPES.Date;
23
51
  }
24
52
  function defaultInspect(x, _options) {
25
53
  return JSON.stringify(x, (k, v) => {
@@ -43,6 +71,7 @@ function getStylizeFunction(options) {
43
71
  }
44
72
 
45
73
  const BSON_MAJOR_VERSION = 6;
74
+ const BSON_VERSION_SYMBOL = Symbol.for('@@mdb.bson.version');
46
75
  const BSON_INT32_MAX = 0x7fffffff;
47
76
  const BSON_INT32_MIN = -0x80000000;
48
77
  const BSON_INT64_MAX = Math.pow(2, 63) - 1;
@@ -244,7 +273,7 @@ const nodeJsByteUtils = {
244
273
  stringTag === '[object SharedArrayBuffer]') {
245
274
  return Buffer.from(potentialBuffer);
246
275
  }
247
- throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`);
276
+ throw new BSONError(`Cannot create Buffer from the passed potentialBuffer.`);
248
277
  },
249
278
  allocate(size) {
250
279
  return Buffer.alloc(size);
@@ -302,7 +331,10 @@ const nodeJsByteUtils = {
302
331
  }
303
332
  return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
304
333
  },
305
- randomBytes: nodejsRandomBytes
334
+ randomBytes: nodejsRandomBytes,
335
+ swap32(buffer) {
336
+ return nodeJsByteUtils.toLocalBufferType(buffer).swap32();
337
+ }
306
338
  };
307
339
 
308
340
  const { TextEncoder } = require('../vendor/text-encoding');
@@ -349,7 +381,7 @@ const webByteUtils = {
349
381
  stringTag === '[object SharedArrayBuffer]') {
350
382
  return new Uint8Array(potentialUint8array);
351
383
  }
352
- throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`);
384
+ throw new BSONError(`Cannot make a Uint8Array from passed potentialBuffer.`);
353
385
  },
354
386
  allocate(size) {
355
387
  if (typeof size !== 'number') {
@@ -421,14 +453,30 @@ const webByteUtils = {
421
453
  uint8array.set(bytes, byteOffset);
422
454
  return bytes.byteLength;
423
455
  },
424
- randomBytes: webRandomBytes
456
+ randomBytes: webRandomBytes,
457
+ swap32(buffer) {
458
+ if (buffer.length % 4 !== 0) {
459
+ throw new RangeError('Buffer size must be a multiple of 32-bits');
460
+ }
461
+ for (let i = 0; i < buffer.length; i += 4) {
462
+ const byte0 = buffer[i];
463
+ const byte1 = buffer[i + 1];
464
+ const byte2 = buffer[i + 2];
465
+ const byte3 = buffer[i + 3];
466
+ buffer[i] = byte3;
467
+ buffer[i + 1] = byte2;
468
+ buffer[i + 2] = byte1;
469
+ buffer[i + 3] = byte0;
470
+ }
471
+ return buffer;
472
+ }
425
473
  };
426
474
 
427
475
  const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
428
476
  const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
429
477
 
430
478
  class BSONValue {
431
- get [Symbol.for('@@mdb.bson.version')]() {
479
+ get [BSON_VERSION_SYMBOL]() {
432
480
  return BSON_MAJOR_VERSION;
433
481
  }
434
482
  [Symbol.for('nodejs.util.inspect.custom')](depth, options, inspect) {
@@ -436,6 +484,134 @@ class BSONValue {
436
484
  }
437
485
  }
438
486
 
487
+ const FLOAT = new Float64Array(1);
488
+ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
489
+ FLOAT[0] = -1;
490
+ const isBigEndian = FLOAT_BYTES[7] === 0;
491
+ const NumberUtils = {
492
+ isBigEndian,
493
+ getNonnegativeInt32LE(source, offset) {
494
+ if (source[offset + 3] > 127) {
495
+ throw new RangeError(`Size cannot be negative at offset: ${offset}`);
496
+ }
497
+ return (source[offset] |
498
+ (source[offset + 1] << 8) |
499
+ (source[offset + 2] << 16) |
500
+ (source[offset + 3] << 24));
501
+ },
502
+ getInt32LE(source, offset) {
503
+ return (source[offset] |
504
+ (source[offset + 1] << 8) |
505
+ (source[offset + 2] << 16) |
506
+ (source[offset + 3] << 24));
507
+ },
508
+ getUint32LE(source, offset) {
509
+ return (source[offset] +
510
+ source[offset + 1] * 256 +
511
+ source[offset + 2] * 65536 +
512
+ source[offset + 3] * 16777216);
513
+ },
514
+ getUint32BE(source, offset) {
515
+ return (source[offset + 3] +
516
+ source[offset + 2] * 256 +
517
+ source[offset + 1] * 65536 +
518
+ source[offset] * 16777216);
519
+ },
520
+ getBigInt64LE(source, offset) {
521
+ const lo = NumberUtils.getUint32LE(source, offset);
522
+ const hi = NumberUtils.getUint32LE(source, offset + 4);
523
+ return (BigInt(hi) << BigInt(32)) + BigInt(lo);
524
+ },
525
+ getFloat64LE: isBigEndian
526
+ ? (source, offset) => {
527
+ FLOAT_BYTES[7] = source[offset];
528
+ FLOAT_BYTES[6] = source[offset + 1];
529
+ FLOAT_BYTES[5] = source[offset + 2];
530
+ FLOAT_BYTES[4] = source[offset + 3];
531
+ FLOAT_BYTES[3] = source[offset + 4];
532
+ FLOAT_BYTES[2] = source[offset + 5];
533
+ FLOAT_BYTES[1] = source[offset + 6];
534
+ FLOAT_BYTES[0] = source[offset + 7];
535
+ return FLOAT[0];
536
+ }
537
+ : (source, offset) => {
538
+ FLOAT_BYTES[0] = source[offset];
539
+ FLOAT_BYTES[1] = source[offset + 1];
540
+ FLOAT_BYTES[2] = source[offset + 2];
541
+ FLOAT_BYTES[3] = source[offset + 3];
542
+ FLOAT_BYTES[4] = source[offset + 4];
543
+ FLOAT_BYTES[5] = source[offset + 5];
544
+ FLOAT_BYTES[6] = source[offset + 6];
545
+ FLOAT_BYTES[7] = source[offset + 7];
546
+ return FLOAT[0];
547
+ },
548
+ setInt32BE(destination, offset, value) {
549
+ destination[offset + 3] = value;
550
+ value >>>= 8;
551
+ destination[offset + 2] = value;
552
+ value >>>= 8;
553
+ destination[offset + 1] = value;
554
+ value >>>= 8;
555
+ destination[offset] = value;
556
+ return 4;
557
+ },
558
+ setInt32LE(destination, offset, value) {
559
+ destination[offset] = value;
560
+ value >>>= 8;
561
+ destination[offset + 1] = value;
562
+ value >>>= 8;
563
+ destination[offset + 2] = value;
564
+ value >>>= 8;
565
+ destination[offset + 3] = value;
566
+ return 4;
567
+ },
568
+ setBigInt64LE(destination, offset, value) {
569
+ const mask32bits = BigInt(0xffff_ffff);
570
+ let lo = Number(value & mask32bits);
571
+ destination[offset] = lo;
572
+ lo >>= 8;
573
+ destination[offset + 1] = lo;
574
+ lo >>= 8;
575
+ destination[offset + 2] = lo;
576
+ lo >>= 8;
577
+ destination[offset + 3] = lo;
578
+ let hi = Number((value >> BigInt(32)) & mask32bits);
579
+ destination[offset + 4] = hi;
580
+ hi >>= 8;
581
+ destination[offset + 5] = hi;
582
+ hi >>= 8;
583
+ destination[offset + 6] = hi;
584
+ hi >>= 8;
585
+ destination[offset + 7] = hi;
586
+ return 8;
587
+ },
588
+ setFloat64LE: isBigEndian
589
+ ? (destination, offset, value) => {
590
+ FLOAT[0] = value;
591
+ destination[offset] = FLOAT_BYTES[7];
592
+ destination[offset + 1] = FLOAT_BYTES[6];
593
+ destination[offset + 2] = FLOAT_BYTES[5];
594
+ destination[offset + 3] = FLOAT_BYTES[4];
595
+ destination[offset + 4] = FLOAT_BYTES[3];
596
+ destination[offset + 5] = FLOAT_BYTES[2];
597
+ destination[offset + 6] = FLOAT_BYTES[1];
598
+ destination[offset + 7] = FLOAT_BYTES[0];
599
+ return 8;
600
+ }
601
+ : (destination, offset, value) => {
602
+ FLOAT[0] = value;
603
+ destination[offset] = FLOAT_BYTES[0];
604
+ destination[offset + 1] = FLOAT_BYTES[1];
605
+ destination[offset + 2] = FLOAT_BYTES[2];
606
+ destination[offset + 3] = FLOAT_BYTES[3];
607
+ destination[offset + 4] = FLOAT_BYTES[4];
608
+ destination[offset + 5] = FLOAT_BYTES[5];
609
+ destination[offset + 6] = FLOAT_BYTES[6];
610
+ destination[offset + 7] = FLOAT_BYTES[7];
611
+ return 8;
612
+ }
613
+ };
614
+
439
615
  class Binary extends BSONValue {
440
616
  get _bsontype() {
441
617
  return 'Binary';
@@ -508,7 +684,8 @@ class Binary extends BSONValue {
508
684
  }
509
685
  read(position, length) {
510
686
  length = length && length > 0 ? length : this.position;
511
- return this.buffer.slice(position, position + length);
687
+ const end = position + length;
688
+ return this.buffer.subarray(position, end > this.position ? this.position : end);
512
689
  }
513
690
  value() {
514
691
  return this.buffer.length === this.position
@@ -532,6 +709,9 @@ class Binary extends BSONValue {
532
709
  }
533
710
  toExtendedJSON(options) {
534
711
  options = options || {};
712
+ if (this.sub_type === Binary.SUBTYPE_VECTOR) {
713
+ validateBinaryVector(this);
714
+ }
535
715
  const base64String = ByteUtils.toBase64(this.buffer);
536
716
  const subType = Number(this.sub_type).toString(16);
537
717
  if (options.legacy) {
@@ -549,7 +729,7 @@ class Binary extends BSONValue {
549
729
  }
550
730
  toUUID() {
551
731
  if (this.sub_type === Binary.SUBTYPE_UUID) {
552
- return new UUID(this.buffer.slice(0, this.position));
732
+ return new UUID(this.buffer.subarray(0, this.position));
553
733
  }
554
734
  throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${Binary.SUBTYPE_UUID}" is currently supported.`);
555
735
  }
@@ -591,6 +771,99 @@ class Binary extends BSONValue {
591
771
  const subTypeArg = inspect(this.sub_type, options);
592
772
  return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`;
593
773
  }
774
+ toInt8Array() {
775
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
776
+ throw new BSONError('Binary sub_type is not Vector');
777
+ }
778
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.Int8) {
779
+ throw new BSONError('Binary datatype field is not Int8');
780
+ }
781
+ return new Int8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
782
+ }
783
+ toFloat32Array() {
784
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
785
+ throw new BSONError('Binary sub_type is not Vector');
786
+ }
787
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.Float32) {
788
+ throw new BSONError('Binary datatype field is not Float32');
789
+ }
790
+ const floatBytes = new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
791
+ if (NumberUtils.isBigEndian)
792
+ ByteUtils.swap32(floatBytes);
793
+ return new Float32Array(floatBytes.buffer);
794
+ }
795
+ toPackedBits() {
796
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
797
+ throw new BSONError('Binary sub_type is not Vector');
798
+ }
799
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {
800
+ throw new BSONError('Binary datatype field is not packed bit');
801
+ }
802
+ return new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
803
+ }
804
+ toBits() {
805
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
806
+ throw new BSONError('Binary sub_type is not Vector');
807
+ }
808
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {
809
+ throw new BSONError('Binary datatype field is not packed bit');
810
+ }
811
+ const byteCount = this.length() - 2;
812
+ const bitCount = byteCount * 8 - this.buffer[1];
813
+ const bits = new Int8Array(bitCount);
814
+ for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {
815
+ const byteOffset = (bitOffset / 8) | 0;
816
+ const byte = this.buffer[byteOffset + 2];
817
+ const shift = 7 - (bitOffset % 8);
818
+ const bit = (byte >> shift) & 1;
819
+ bits[bitOffset] = bit;
820
+ }
821
+ return bits;
822
+ }
823
+ static fromInt8Array(array) {
824
+ const buffer = ByteUtils.allocate(array.byteLength + 2);
825
+ buffer[0] = Binary.VECTOR_TYPE.Int8;
826
+ buffer[1] = 0;
827
+ const intBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
828
+ buffer.set(intBytes, 2);
829
+ return new this(buffer, this.SUBTYPE_VECTOR);
830
+ }
831
+ static fromFloat32Array(array) {
832
+ const binaryBytes = ByteUtils.allocate(array.byteLength + 2);
833
+ binaryBytes[0] = Binary.VECTOR_TYPE.Float32;
834
+ binaryBytes[1] = 0;
835
+ const floatBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
836
+ binaryBytes.set(floatBytes, 2);
837
+ if (NumberUtils.isBigEndian)
838
+ ByteUtils.swap32(new Uint8Array(binaryBytes.buffer, 2));
839
+ return new this(binaryBytes, this.SUBTYPE_VECTOR);
840
+ }
841
+ static fromPackedBits(array, padding = 0) {
842
+ const buffer = ByteUtils.allocate(array.byteLength + 2);
843
+ buffer[0] = Binary.VECTOR_TYPE.PackedBit;
844
+ buffer[1] = padding;
845
+ buffer.set(array, 2);
846
+ return new this(buffer, this.SUBTYPE_VECTOR);
847
+ }
848
+ static fromBits(bits) {
849
+ const byteLength = (bits.length + 7) >>> 3;
850
+ const bytes = new Uint8Array(byteLength + 2);
851
+ bytes[0] = Binary.VECTOR_TYPE.PackedBit;
852
+ const remainder = bits.length % 8;
853
+ bytes[1] = remainder === 0 ? 0 : 8 - remainder;
854
+ for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {
855
+ const byteOffset = bitOffset >>> 3;
856
+ const bit = bits[bitOffset];
857
+ if (bit !== 0 && bit !== 1) {
858
+ throw new BSONError(`Invalid bit value at ${bitOffset}: must be 0 or 1, found ${bits[bitOffset]}`);
859
+ }
860
+ if (bit === 0)
861
+ continue;
862
+ const shift = 7 - (bitOffset % 8);
863
+ bytes[byteOffset + 2] |= bit << shift;
864
+ }
865
+ return new this(bytes, Binary.SUBTYPE_VECTOR);
866
+ }
594
867
  }
595
868
  Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0;
596
869
  Binary.BUFFER_SIZE = 256;
@@ -603,7 +876,30 @@ Binary.SUBTYPE_MD5 = 5;
603
876
  Binary.SUBTYPE_ENCRYPTED = 6;
604
877
  Binary.SUBTYPE_COLUMN = 7;
605
878
  Binary.SUBTYPE_SENSITIVE = 8;
879
+ Binary.SUBTYPE_VECTOR = 9;
606
880
  Binary.SUBTYPE_USER_DEFINED = 128;
881
+ Binary.VECTOR_TYPE = Object.freeze({
882
+ Int8: 0x03,
883
+ Float32: 0x27,
884
+ PackedBit: 0x10
885
+ });
886
+ function validateBinaryVector(vector) {
887
+ if (vector.sub_type !== Binary.SUBTYPE_VECTOR)
888
+ return;
889
+ const size = vector.position;
890
+ const datatype = vector.buffer[0];
891
+ const padding = vector.buffer[1];
892
+ if ((datatype === Binary.VECTOR_TYPE.Float32 || datatype === Binary.VECTOR_TYPE.Int8) &&
893
+ padding !== 0) {
894
+ throw new BSONError('Invalid Vector: padding must be zero for int8 and float32 vectors');
895
+ }
896
+ if (datatype === Binary.VECTOR_TYPE.PackedBit && padding !== 0 && size === 2) {
897
+ throw new BSONError('Invalid Vector: padding must be zero for packed bit vectors that are empty');
898
+ }
899
+ if (datatype === Binary.VECTOR_TYPE.PackedBit && padding > 7) {
900
+ throw new BSONError(`Invalid Vector: padding must be a value between 0 and 7. found: ${padding}`);
901
+ }
902
+ }
607
903
  const UUID_BYTE_LENGTH = 16;
608
904
  const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;
609
905
  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;
@@ -1605,7 +1901,7 @@ class Decimal128 extends BSONValue {
1605
1901
  if (typeof bytes === 'string') {
1606
1902
  this.bytes = Decimal128.fromString(bytes).bytes;
1607
1903
  }
1608
- else if (isUint8Array(bytes)) {
1904
+ else if (bytes instanceof Uint8Array || isUint8Array(bytes)) {
1609
1905
  if (bytes.byteLength !== 16) {
1610
1906
  throw new BSONError('Decimal128 must take a Buffer of 16 bytes');
1611
1907
  }
@@ -2215,134 +2511,6 @@ class MinKey extends BSONValue {
2215
2511
  }
2216
2512
  }
2217
2513
 
2218
- const FLOAT = new Float64Array(1);
2219
- const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
2220
- FLOAT[0] = -1;
2221
- const isBigEndian = FLOAT_BYTES[7] === 0;
2222
- const NumberUtils = {
2223
- getNonnegativeInt32LE(source, offset) {
2224
- if (source[offset + 3] > 127) {
2225
- throw new RangeError(`Size cannot be negative at offset: ${offset}`);
2226
- }
2227
- return (source[offset] |
2228
- (source[offset + 1] << 8) |
2229
- (source[offset + 2] << 16) |
2230
- (source[offset + 3] << 24));
2231
- },
2232
- getInt32LE(source, offset) {
2233
- return (source[offset] |
2234
- (source[offset + 1] << 8) |
2235
- (source[offset + 2] << 16) |
2236
- (source[offset + 3] << 24));
2237
- },
2238
- getUint32LE(source, offset) {
2239
- return (source[offset] +
2240
- source[offset + 1] * 256 +
2241
- source[offset + 2] * 65536 +
2242
- source[offset + 3] * 16777216);
2243
- },
2244
- getUint32BE(source, offset) {
2245
- return (source[offset + 3] +
2246
- source[offset + 2] * 256 +
2247
- source[offset + 1] * 65536 +
2248
- source[offset] * 16777216);
2249
- },
2250
- getBigInt64LE(source, offset) {
2251
- const lo = NumberUtils.getUint32LE(source, offset);
2252
- const hi = NumberUtils.getUint32LE(source, offset + 4);
2253
- return (BigInt(hi) << BigInt(32)) + BigInt(lo);
2254
- },
2255
- getFloat64LE: isBigEndian
2256
- ? (source, offset) => {
2257
- FLOAT_BYTES[7] = source[offset];
2258
- FLOAT_BYTES[6] = source[offset + 1];
2259
- FLOAT_BYTES[5] = source[offset + 2];
2260
- FLOAT_BYTES[4] = source[offset + 3];
2261
- FLOAT_BYTES[3] = source[offset + 4];
2262
- FLOAT_BYTES[2] = source[offset + 5];
2263
- FLOAT_BYTES[1] = source[offset + 6];
2264
- FLOAT_BYTES[0] = source[offset + 7];
2265
- return FLOAT[0];
2266
- }
2267
- : (source, offset) => {
2268
- FLOAT_BYTES[0] = source[offset];
2269
- FLOAT_BYTES[1] = source[offset + 1];
2270
- FLOAT_BYTES[2] = source[offset + 2];
2271
- FLOAT_BYTES[3] = source[offset + 3];
2272
- FLOAT_BYTES[4] = source[offset + 4];
2273
- FLOAT_BYTES[5] = source[offset + 5];
2274
- FLOAT_BYTES[6] = source[offset + 6];
2275
- FLOAT_BYTES[7] = source[offset + 7];
2276
- return FLOAT[0];
2277
- },
2278
- setInt32BE(destination, offset, value) {
2279
- destination[offset + 3] = value;
2280
- value >>>= 8;
2281
- destination[offset + 2] = value;
2282
- value >>>= 8;
2283
- destination[offset + 1] = value;
2284
- value >>>= 8;
2285
- destination[offset] = value;
2286
- return 4;
2287
- },
2288
- setInt32LE(destination, offset, value) {
2289
- destination[offset] = value;
2290
- value >>>= 8;
2291
- destination[offset + 1] = value;
2292
- value >>>= 8;
2293
- destination[offset + 2] = value;
2294
- value >>>= 8;
2295
- destination[offset + 3] = value;
2296
- return 4;
2297
- },
2298
- setBigInt64LE(destination, offset, value) {
2299
- const mask32bits = BigInt(4294967295);
2300
- let lo = Number(value & mask32bits);
2301
- destination[offset] = lo;
2302
- lo >>= 8;
2303
- destination[offset + 1] = lo;
2304
- lo >>= 8;
2305
- destination[offset + 2] = lo;
2306
- lo >>= 8;
2307
- destination[offset + 3] = lo;
2308
- let hi = Number((value >> BigInt(32)) & mask32bits);
2309
- destination[offset + 4] = hi;
2310
- hi >>= 8;
2311
- destination[offset + 5] = hi;
2312
- hi >>= 8;
2313
- destination[offset + 6] = hi;
2314
- hi >>= 8;
2315
- destination[offset + 7] = hi;
2316
- return 8;
2317
- },
2318
- setFloat64LE: isBigEndian
2319
- ? (destination, offset, value) => {
2320
- FLOAT[0] = value;
2321
- destination[offset] = FLOAT_BYTES[7];
2322
- destination[offset + 1] = FLOAT_BYTES[6];
2323
- destination[offset + 2] = FLOAT_BYTES[5];
2324
- destination[offset + 3] = FLOAT_BYTES[4];
2325
- destination[offset + 4] = FLOAT_BYTES[3];
2326
- destination[offset + 5] = FLOAT_BYTES[2];
2327
- destination[offset + 6] = FLOAT_BYTES[1];
2328
- destination[offset + 7] = FLOAT_BYTES[0];
2329
- return 8;
2330
- }
2331
- : (destination, offset, value) => {
2332
- FLOAT[0] = value;
2333
- destination[offset] = FLOAT_BYTES[0];
2334
- destination[offset + 1] = FLOAT_BYTES[1];
2335
- destination[offset + 2] = FLOAT_BYTES[2];
2336
- destination[offset + 3] = FLOAT_BYTES[3];
2337
- destination[offset + 4] = FLOAT_BYTES[4];
2338
- destination[offset + 5] = FLOAT_BYTES[5];
2339
- destination[offset + 6] = FLOAT_BYTES[6];
2340
- destination[offset + 7] = FLOAT_BYTES[7];
2341
- return 8;
2342
- }
2343
- };
2344
-
2345
- const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2346
2514
  let PROCESS_UNIQUE = null;
2347
2515
  class ObjectId extends BSONValue {
2348
2516
  get _bsontype() {
@@ -2372,7 +2540,7 @@ class ObjectId extends BSONValue {
2372
2540
  this.buffer = ByteUtils.toLocalBufferType(workingId);
2373
2541
  }
2374
2542
  else if (typeof workingId === 'string') {
2375
- if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2543
+ if (ObjectId.validateHexString(workingId)) {
2376
2544
  this.buffer = ByteUtils.fromHex(workingId);
2377
2545
  }
2378
2546
  else {
@@ -2395,6 +2563,20 @@ class ObjectId extends BSONValue {
2395
2563
  this.__id = ByteUtils.toHex(value);
2396
2564
  }
2397
2565
  }
2566
+ static validateHexString(string) {
2567
+ if (string?.length !== 24)
2568
+ return false;
2569
+ for (let i = 0; i < 24; i++) {
2570
+ const char = string.charCodeAt(i);
2571
+ if ((char >= 48 && char <= 57) ||
2572
+ (char >= 97 && char <= 102) ||
2573
+ (char >= 65 && char <= 70)) {
2574
+ continue;
2575
+ }
2576
+ return false;
2577
+ }
2578
+ return true;
2579
+ }
2398
2580
  toHexString() {
2399
2581
  if (ObjectId.cacheHexString && this.__id) {
2400
2582
  return this.__id;
@@ -2507,6 +2689,8 @@ class ObjectId extends BSONValue {
2507
2689
  static isValid(id) {
2508
2690
  if (id == null)
2509
2691
  return false;
2692
+ if (typeof id === 'string')
2693
+ return ObjectId.validateHexString(id);
2510
2694
  try {
2511
2695
  new ObjectId(id);
2512
2696
  return true;
@@ -2577,7 +2761,7 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
2577
2761
  case 'object':
2578
2762
  if (value != null &&
2579
2763
  typeof value._bsontype === 'string' &&
2580
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
2764
+ value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
2581
2765
  throw new BSONVersionError();
2582
2766
  }
2583
2767
  else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
@@ -2781,6 +2965,12 @@ class Timestamp extends LongWithoutOverridesClass {
2781
2965
  get _bsontype() {
2782
2966
  return 'Timestamp';
2783
2967
  }
2968
+ get i() {
2969
+ return this.low >>> 0;
2970
+ }
2971
+ get t() {
2972
+ return this.high >>> 0;
2973
+ }
2784
2974
  constructor(low) {
2785
2975
  if (low == null) {
2786
2976
  super(0, 0, true);
@@ -2806,10 +2996,10 @@ class Timestamp extends LongWithoutOverridesClass {
2806
2996
  if (i < 0 || Number.isNaN(i)) {
2807
2997
  throw new BSONError('Timestamp constructed from { t, i } must provide a positive i');
2808
2998
  }
2809
- if (t > 4294967295) {
2999
+ if (t > 0xffff_ffff) {
2810
3000
  throw new BSONError('Timestamp constructed from { t, i } must provide t equal or less than uint32 max');
2811
3001
  }
2812
- if (i > 4294967295) {
3002
+ if (i > 0xffff_ffff) {
2813
3003
  throw new BSONError('Timestamp constructed from { t, i } must provide i equal or less than uint32 max');
2814
3004
  }
2815
3005
  super(i, t, true);
@@ -2836,7 +3026,7 @@ class Timestamp extends LongWithoutOverridesClass {
2836
3026
  return new Timestamp(Long.fromString(str, true, optRadix));
2837
3027
  }
2838
3028
  toExtendedJSON() {
2839
- return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } };
3029
+ return { $timestamp: { t: this.t, i: this.i } };
2840
3030
  }
2841
3031
  static fromExtendedJSON(doc) {
2842
3032
  const i = Long.isLong(doc.$timestamp.i)
@@ -2849,8 +3039,8 @@ class Timestamp extends LongWithoutOverridesClass {
2849
3039
  }
2850
3040
  inspect(depth, options, inspect) {
2851
3041
  inspect ??= defaultInspect;
2852
- const t = inspect(this.high >>> 0, options);
2853
- const i = inspect(this.low >>> 0, options);
3042
+ const t = inspect(this.t, options);
3043
+ const i = inspect(this.i, options);
2854
3044
  return `new Timestamp({ t: ${t}, i: ${i} })`;
2855
3045
  }
2856
3046
  }
@@ -3007,7 +3197,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3007
3197
  if (objectSize <= 0 || objectSize > buffer.length - index)
3008
3198
  throw new BSONError('bad embedded document length in bson');
3009
3199
  if (raw) {
3010
- value = buffer.slice(index, index + objectSize);
3200
+ value = buffer.subarray(index, index + objectSize);
3011
3201
  }
3012
3202
  else {
3013
3203
  let objectOptions = options;
@@ -3079,49 +3269,23 @@ function deserializeObject(buffer, index, options, isArray = false) {
3079
3269
  throw new BSONError('Negative binary type element size found');
3080
3270
  if (binarySize > buffer.byteLength)
3081
3271
  throw new BSONError('Binary type size larger than document size');
3082
- if (buffer['slice'] != null) {
3083
- if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3084
- binarySize = NumberUtils.getInt32LE(buffer, index);
3085
- index += 4;
3086
- if (binarySize < 0)
3087
- throw new BSONError('Negative binary type element size found for subtype 0x02');
3088
- if (binarySize > totalBinarySize - 4)
3089
- throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3090
- if (binarySize < totalBinarySize - 4)
3091
- throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3092
- }
3093
- if (promoteBuffers && promoteValues) {
3094
- value = ByteUtils.toLocalBufferType(buffer.slice(index, index + binarySize));
3095
- }
3096
- else {
3097
- value = new Binary(buffer.slice(index, index + binarySize), subType);
3098
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3099
- value = value.toUUID();
3100
- }
3101
- }
3272
+ if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3273
+ binarySize = NumberUtils.getInt32LE(buffer, index);
3274
+ index += 4;
3275
+ if (binarySize < 0)
3276
+ throw new BSONError('Negative binary type element size found for subtype 0x02');
3277
+ if (binarySize > totalBinarySize - 4)
3278
+ throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3279
+ if (binarySize < totalBinarySize - 4)
3280
+ throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3281
+ }
3282
+ if (promoteBuffers && promoteValues) {
3283
+ value = ByteUtils.toLocalBufferType(buffer.subarray(index, index + binarySize));
3102
3284
  }
3103
3285
  else {
3104
- if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3105
- binarySize = NumberUtils.getInt32LE(buffer, index);
3106
- index += 4;
3107
- if (binarySize < 0)
3108
- throw new BSONError('Negative binary type element size found for subtype 0x02');
3109
- if (binarySize > totalBinarySize - 4)
3110
- throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3111
- if (binarySize < totalBinarySize - 4)
3112
- throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3113
- }
3114
- if (promoteBuffers && promoteValues) {
3115
- value = ByteUtils.allocateUnsafe(binarySize);
3116
- for (i = 0; i < binarySize; i++) {
3117
- value[i] = buffer[index + i];
3118
- }
3119
- }
3120
- else {
3121
- value = new Binary(buffer.slice(index, index + binarySize), subType);
3122
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3123
- value = value.toUUID();
3124
- }
3286
+ value = new Binary(buffer.subarray(index, index + binarySize), subType);
3287
+ if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3288
+ value = value.toUUID();
3125
3289
  }
3126
3290
  }
3127
3291
  index = index + binarySize;
@@ -3543,6 +3707,9 @@ function serializeBinary(buffer, key, value, index) {
3543
3707
  size = size - 4;
3544
3708
  index += NumberUtils.setInt32LE(buffer, index, size);
3545
3709
  }
3710
+ if (value.sub_type === Binary.SUBTYPE_VECTOR) {
3711
+ validateBinaryVector(value);
3712
+ }
3546
3713
  if (size <= 16) {
3547
3714
  for (let i = 0; i < size; i++)
3548
3715
  buffer[index + i] = data[i];
@@ -3619,79 +3786,83 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3619
3786
  if (typeof value?.toBSON === 'function') {
3620
3787
  value = value.toBSON();
3621
3788
  }
3622
- if (typeof value === 'string') {
3623
- index = serializeString(buffer, key, value, index);
3624
- }
3625
- else if (typeof value === 'number') {
3626
- index = serializeNumber(buffer, key, value, index);
3627
- }
3628
- else if (typeof value === 'bigint') {
3629
- index = serializeBigInt(buffer, key, value, index);
3630
- }
3631
- else if (typeof value === 'boolean') {
3632
- index = serializeBoolean(buffer, key, value, index);
3633
- }
3634
- else if (value instanceof Date || isDate(value)) {
3635
- index = serializeDate(buffer, key, value, index);
3636
- }
3637
- else if (value === undefined) {
3789
+ const type = typeof value;
3790
+ if (value === undefined) {
3638
3791
  index = serializeNull(buffer, key, value, index);
3639
3792
  }
3640
3793
  else if (value === null) {
3641
3794
  index = serializeNull(buffer, key, value, index);
3642
3795
  }
3643
- else if (isUint8Array(value)) {
3644
- index = serializeBuffer(buffer, key, value, index);
3645
- }
3646
- else if (value instanceof RegExp || isRegExp(value)) {
3647
- index = serializeRegExp(buffer, key, value, index);
3648
- }
3649
- else if (typeof value === 'object' && value._bsontype == null) {
3650
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3796
+ else if (type === 'string') {
3797
+ index = serializeString(buffer, key, value, index);
3651
3798
  }
3652
- else if (typeof value === 'object' &&
3653
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3654
- throw new BSONVersionError();
3799
+ else if (type === 'number') {
3800
+ index = serializeNumber(buffer, key, value, index);
3655
3801
  }
3656
- else if (value._bsontype === 'ObjectId') {
3657
- index = serializeObjectId(buffer, key, value, index);
3802
+ else if (type === 'bigint') {
3803
+ index = serializeBigInt(buffer, key, value, index);
3658
3804
  }
3659
- else if (value._bsontype === 'Decimal128') {
3660
- index = serializeDecimal128(buffer, key, value, index);
3805
+ else if (type === 'boolean') {
3806
+ index = serializeBoolean(buffer, key, value, index);
3661
3807
  }
3662
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3663
- index = serializeLong(buffer, key, value, index);
3808
+ else if (type === 'object' && value._bsontype == null) {
3809
+ if (value instanceof Date || isDate(value)) {
3810
+ index = serializeDate(buffer, key, value, index);
3811
+ }
3812
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3813
+ index = serializeBuffer(buffer, key, value, index);
3814
+ }
3815
+ else if (value instanceof RegExp || isRegExp(value)) {
3816
+ index = serializeRegExp(buffer, key, value, index);
3817
+ }
3818
+ else {
3819
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3820
+ }
3664
3821
  }
3665
- else if (value._bsontype === 'Double') {
3666
- index = serializeDouble(buffer, key, value, index);
3822
+ else if (type === 'object') {
3823
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3824
+ throw new BSONVersionError();
3825
+ }
3826
+ else if (value._bsontype === 'ObjectId') {
3827
+ index = serializeObjectId(buffer, key, value, index);
3828
+ }
3829
+ else if (value._bsontype === 'Decimal128') {
3830
+ index = serializeDecimal128(buffer, key, value, index);
3831
+ }
3832
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3833
+ index = serializeLong(buffer, key, value, index);
3834
+ }
3835
+ else if (value._bsontype === 'Double') {
3836
+ index = serializeDouble(buffer, key, value, index);
3837
+ }
3838
+ else if (value._bsontype === 'Code') {
3839
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3840
+ }
3841
+ else if (value._bsontype === 'Binary') {
3842
+ index = serializeBinary(buffer, key, value, index);
3843
+ }
3844
+ else if (value._bsontype === 'BSONSymbol') {
3845
+ index = serializeSymbol(buffer, key, value, index);
3846
+ }
3847
+ else if (value._bsontype === 'DBRef') {
3848
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3849
+ }
3850
+ else if (value._bsontype === 'BSONRegExp') {
3851
+ index = serializeBSONRegExp(buffer, key, value, index);
3852
+ }
3853
+ else if (value._bsontype === 'Int32') {
3854
+ index = serializeInt32(buffer, key, value, index);
3855
+ }
3856
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3857
+ index = serializeMinMax(buffer, key, value, index);
3858
+ }
3859
+ else if (typeof value._bsontype !== 'undefined') {
3860
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3861
+ }
3667
3862
  }
3668
- else if (typeof value === 'function' && serializeFunctions) {
3863
+ else if (type === 'function' && serializeFunctions) {
3669
3864
  index = serializeFunction(buffer, key, value, index);
3670
3865
  }
3671
- else if (value._bsontype === 'Code') {
3672
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3673
- }
3674
- else if (value._bsontype === 'Binary') {
3675
- index = serializeBinary(buffer, key, value, index);
3676
- }
3677
- else if (value._bsontype === 'BSONSymbol') {
3678
- index = serializeSymbol(buffer, key, value, index);
3679
- }
3680
- else if (value._bsontype === 'DBRef') {
3681
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3682
- }
3683
- else if (value._bsontype === 'BSONRegExp') {
3684
- index = serializeBSONRegExp(buffer, key, value, index);
3685
- }
3686
- else if (value._bsontype === 'Int32') {
3687
- index = serializeInt32(buffer, key, value, index);
3688
- }
3689
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3690
- index = serializeMinMax(buffer, key, value, index);
3691
- }
3692
- else if (typeof value._bsontype !== 'undefined') {
3693
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3694
- }
3695
3866
  }
3696
3867
  }
3697
3868
  else if (object instanceof Map || isMap(object)) {
@@ -3721,7 +3892,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3721
3892
  }
3722
3893
  }
3723
3894
  }
3724
- if (type === 'string') {
3895
+ if (value === undefined) {
3896
+ if (ignoreUndefined === false)
3897
+ index = serializeNull(buffer, key, value, index);
3898
+ }
3899
+ else if (value === null) {
3900
+ index = serializeNull(buffer, key, value, index);
3901
+ }
3902
+ else if (type === 'string') {
3725
3903
  index = serializeString(buffer, key, value, index);
3726
3904
  }
3727
3905
  else if (type === 'number') {
@@ -3733,64 +3911,64 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3733
3911
  else if (type === 'boolean') {
3734
3912
  index = serializeBoolean(buffer, key, value, index);
3735
3913
  }
3736
- else if (value instanceof Date || isDate(value)) {
3737
- index = serializeDate(buffer, key, value, index);
3738
- }
3739
- else if (value === null || (value === undefined && ignoreUndefined === false)) {
3740
- index = serializeNull(buffer, key, value, index);
3741
- }
3742
- else if (isUint8Array(value)) {
3743
- index = serializeBuffer(buffer, key, value, index);
3744
- }
3745
- else if (value instanceof RegExp || isRegExp(value)) {
3746
- index = serializeRegExp(buffer, key, value, index);
3747
- }
3748
3914
  else if (type === 'object' && value._bsontype == null) {
3749
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3750
- }
3751
- else if (typeof value === 'object' &&
3752
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3753
- throw new BSONVersionError();
3754
- }
3755
- else if (value._bsontype === 'ObjectId') {
3756
- index = serializeObjectId(buffer, key, value, index);
3757
- }
3758
- else if (type === 'object' && value._bsontype === 'Decimal128') {
3759
- index = serializeDecimal128(buffer, key, value, index);
3760
- }
3761
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3762
- index = serializeLong(buffer, key, value, index);
3763
- }
3764
- else if (value._bsontype === 'Double') {
3765
- index = serializeDouble(buffer, key, value, index);
3915
+ if (value instanceof Date || isDate(value)) {
3916
+ index = serializeDate(buffer, key, value, index);
3917
+ }
3918
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3919
+ index = serializeBuffer(buffer, key, value, index);
3920
+ }
3921
+ else if (value instanceof RegExp || isRegExp(value)) {
3922
+ index = serializeRegExp(buffer, key, value, index);
3923
+ }
3924
+ else {
3925
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3926
+ }
3766
3927
  }
3767
- else if (value._bsontype === 'Code') {
3768
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3928
+ else if (type === 'object') {
3929
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3930
+ throw new BSONVersionError();
3931
+ }
3932
+ else if (value._bsontype === 'ObjectId') {
3933
+ index = serializeObjectId(buffer, key, value, index);
3934
+ }
3935
+ else if (value._bsontype === 'Decimal128') {
3936
+ index = serializeDecimal128(buffer, key, value, index);
3937
+ }
3938
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3939
+ index = serializeLong(buffer, key, value, index);
3940
+ }
3941
+ else if (value._bsontype === 'Double') {
3942
+ index = serializeDouble(buffer, key, value, index);
3943
+ }
3944
+ else if (value._bsontype === 'Code') {
3945
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3946
+ }
3947
+ else if (value._bsontype === 'Binary') {
3948
+ index = serializeBinary(buffer, key, value, index);
3949
+ }
3950
+ else if (value._bsontype === 'BSONSymbol') {
3951
+ index = serializeSymbol(buffer, key, value, index);
3952
+ }
3953
+ else if (value._bsontype === 'DBRef') {
3954
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3955
+ }
3956
+ else if (value._bsontype === 'BSONRegExp') {
3957
+ index = serializeBSONRegExp(buffer, key, value, index);
3958
+ }
3959
+ else if (value._bsontype === 'Int32') {
3960
+ index = serializeInt32(buffer, key, value, index);
3961
+ }
3962
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3963
+ index = serializeMinMax(buffer, key, value, index);
3964
+ }
3965
+ else if (typeof value._bsontype !== 'undefined') {
3966
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3967
+ }
3769
3968
  }
3770
- else if (typeof value === 'function' && serializeFunctions) {
3969
+ else if (type === 'function' && serializeFunctions) {
3771
3970
  index = serializeFunction(buffer, key, value, index);
3772
3971
  }
3773
- else if (value._bsontype === 'Binary') {
3774
- index = serializeBinary(buffer, key, value, index);
3775
- }
3776
- else if (value._bsontype === 'BSONSymbol') {
3777
- index = serializeSymbol(buffer, key, value, index);
3778
- }
3779
- else if (value._bsontype === 'DBRef') {
3780
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3781
- }
3782
- else if (value._bsontype === 'BSONRegExp') {
3783
- index = serializeBSONRegExp(buffer, key, value, index);
3784
- }
3785
- else if (value._bsontype === 'Int32') {
3786
- index = serializeInt32(buffer, key, value, index);
3787
- }
3788
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3789
- index = serializeMinMax(buffer, key, value, index);
3790
- }
3791
- else if (typeof value._bsontype !== 'undefined') {
3792
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3793
- }
3794
3972
  }
3795
3973
  }
3796
3974
  else {
@@ -3819,7 +3997,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3819
3997
  }
3820
3998
  }
3821
3999
  }
3822
- if (type === 'string') {
4000
+ if (value === undefined) {
4001
+ if (ignoreUndefined === false)
4002
+ index = serializeNull(buffer, key, value, index);
4003
+ }
4004
+ else if (value === null) {
4005
+ index = serializeNull(buffer, key, value, index);
4006
+ }
4007
+ else if (type === 'string') {
3823
4008
  index = serializeString(buffer, key, value, index);
3824
4009
  }
3825
4010
  else if (type === 'number') {
@@ -3831,68 +4016,64 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3831
4016
  else if (type === 'boolean') {
3832
4017
  index = serializeBoolean(buffer, key, value, index);
3833
4018
  }
3834
- else if (value instanceof Date || isDate(value)) {
3835
- index = serializeDate(buffer, key, value, index);
3836
- }
3837
- else if (value === undefined) {
3838
- if (ignoreUndefined === false)
3839
- index = serializeNull(buffer, key, value, index);
3840
- }
3841
- else if (value === null) {
3842
- index = serializeNull(buffer, key, value, index);
3843
- }
3844
- else if (isUint8Array(value)) {
3845
- index = serializeBuffer(buffer, key, value, index);
3846
- }
3847
- else if (value instanceof RegExp || isRegExp(value)) {
3848
- index = serializeRegExp(buffer, key, value, index);
3849
- }
3850
4019
  else if (type === 'object' && value._bsontype == null) {
3851
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3852
- }
3853
- else if (typeof value === 'object' &&
3854
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3855
- throw new BSONVersionError();
3856
- }
3857
- else if (value._bsontype === 'ObjectId') {
3858
- index = serializeObjectId(buffer, key, value, index);
3859
- }
3860
- else if (type === 'object' && value._bsontype === 'Decimal128') {
3861
- index = serializeDecimal128(buffer, key, value, index);
3862
- }
3863
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3864
- index = serializeLong(buffer, key, value, index);
3865
- }
3866
- else if (value._bsontype === 'Double') {
3867
- index = serializeDouble(buffer, key, value, index);
4020
+ if (value instanceof Date || isDate(value)) {
4021
+ index = serializeDate(buffer, key, value, index);
4022
+ }
4023
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
4024
+ index = serializeBuffer(buffer, key, value, index);
4025
+ }
4026
+ else if (value instanceof RegExp || isRegExp(value)) {
4027
+ index = serializeRegExp(buffer, key, value, index);
4028
+ }
4029
+ else {
4030
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4031
+ }
3868
4032
  }
3869
- else if (value._bsontype === 'Code') {
3870
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4033
+ else if (type === 'object') {
4034
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
4035
+ throw new BSONVersionError();
4036
+ }
4037
+ else if (value._bsontype === 'ObjectId') {
4038
+ index = serializeObjectId(buffer, key, value, index);
4039
+ }
4040
+ else if (value._bsontype === 'Decimal128') {
4041
+ index = serializeDecimal128(buffer, key, value, index);
4042
+ }
4043
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
4044
+ index = serializeLong(buffer, key, value, index);
4045
+ }
4046
+ else if (value._bsontype === 'Double') {
4047
+ index = serializeDouble(buffer, key, value, index);
4048
+ }
4049
+ else if (value._bsontype === 'Code') {
4050
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4051
+ }
4052
+ else if (value._bsontype === 'Binary') {
4053
+ index = serializeBinary(buffer, key, value, index);
4054
+ }
4055
+ else if (value._bsontype === 'BSONSymbol') {
4056
+ index = serializeSymbol(buffer, key, value, index);
4057
+ }
4058
+ else if (value._bsontype === 'DBRef') {
4059
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
4060
+ }
4061
+ else if (value._bsontype === 'BSONRegExp') {
4062
+ index = serializeBSONRegExp(buffer, key, value, index);
4063
+ }
4064
+ else if (value._bsontype === 'Int32') {
4065
+ index = serializeInt32(buffer, key, value, index);
4066
+ }
4067
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
4068
+ index = serializeMinMax(buffer, key, value, index);
4069
+ }
4070
+ else if (typeof value._bsontype !== 'undefined') {
4071
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
4072
+ }
3871
4073
  }
3872
- else if (typeof value === 'function' && serializeFunctions) {
4074
+ else if (type === 'function' && serializeFunctions) {
3873
4075
  index = serializeFunction(buffer, key, value, index);
3874
4076
  }
3875
- else if (value._bsontype === 'Binary') {
3876
- index = serializeBinary(buffer, key, value, index);
3877
- }
3878
- else if (value._bsontype === 'BSONSymbol') {
3879
- index = serializeSymbol(buffer, key, value, index);
3880
- }
3881
- else if (value._bsontype === 'DBRef') {
3882
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3883
- }
3884
- else if (value._bsontype === 'BSONRegExp') {
3885
- index = serializeBSONRegExp(buffer, key, value, index);
3886
- }
3887
- else if (value._bsontype === 'Int32') {
3888
- index = serializeInt32(buffer, key, value, index);
3889
- }
3890
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3891
- index = serializeMinMax(buffer, key, value, index);
3892
- }
3893
- else if (typeof value._bsontype !== 'undefined') {
3894
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3895
- }
3896
4077
  }
3897
4078
  }
3898
4079
  path.delete(object);
@@ -4144,7 +4325,7 @@ function serializeDocument(doc, options) {
4144
4325
  else if (doc != null &&
4145
4326
  typeof doc === 'object' &&
4146
4327
  typeof doc._bsontype === 'string' &&
4147
- doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
4328
+ doc[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
4148
4329
  throw new BSONVersionError();
4149
4330
  }
4150
4331
  else if (isBSONType(doc)) {