bson 6.7.0 → 6.9.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.cjs CHANGED
@@ -1,19 +1,45 @@
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 isRegExp(d) {
10
- return Object.prototype.toString.call(d) === '[object RegExp]';
33
+ const type = getPrototypeString(d);
34
+ return type === TYPES.RegExp;
11
35
  }
12
36
  function isMap(d) {
13
- return Object.prototype.toString.call(d) === '[object Map]';
37
+ const type = getPrototypeString(d);
38
+ return type === TYPES.Map;
14
39
  }
15
40
  function isDate(d) {
16
- return Object.prototype.toString.call(d) === '[object Date]';
41
+ const type = getPrototypeString(d);
42
+ return type === TYPES.Date;
17
43
  }
18
44
  function defaultInspect(x, _options) {
19
45
  return JSON.stringify(x, (k, v) => {
@@ -37,6 +63,7 @@ function getStylizeFunction(options) {
37
63
  }
38
64
 
39
65
  const BSON_MAJOR_VERSION = 6;
66
+ const BSON_VERSION_SYMBOL = Symbol.for('@@mdb.bson.version');
40
67
  const BSON_INT32_MAX = 0x7fffffff;
41
68
  const BSON_INT32_MIN = -0x80000000;
42
69
  const BSON_INT64_MAX = Math.pow(2, 63) - 1;
@@ -411,7 +438,7 @@ const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuf
411
438
  const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
412
439
 
413
440
  class BSONValue {
414
- get [Symbol.for('@@mdb.bson.version')]() {
441
+ get [BSON_VERSION_SYMBOL]() {
415
442
  return BSON_MAJOR_VERSION;
416
443
  }
417
444
  [Symbol.for('nodejs.util.inspect.custom')](depth, options, inspect) {
@@ -855,19 +882,18 @@ class Long extends BSONValue {
855
882
  get __isLong__() {
856
883
  return true;
857
884
  }
858
- constructor(low = 0, high, unsigned) {
885
+ constructor(lowOrValue = 0, highOrUnsigned, unsigned) {
859
886
  super();
860
- if (typeof low === 'bigint') {
861
- Object.assign(this, Long.fromBigInt(low, !!high));
862
- }
863
- else if (typeof low === 'string') {
864
- Object.assign(this, Long.fromString(low, !!high));
865
- }
866
- else {
867
- this.low = low | 0;
868
- this.high = high | 0;
869
- this.unsigned = !!unsigned;
870
- }
887
+ const unsignedBool = typeof highOrUnsigned === 'boolean' ? highOrUnsigned : Boolean(unsigned);
888
+ const high = typeof highOrUnsigned === 'number' ? highOrUnsigned : 0;
889
+ const res = typeof lowOrValue === 'string'
890
+ ? Long.fromString(lowOrValue, unsignedBool)
891
+ : typeof lowOrValue === 'bigint'
892
+ ? Long.fromBigInt(lowOrValue, unsignedBool)
893
+ : { low: lowOrValue | 0, high: high | 0, unsigned: unsignedBool };
894
+ this.low = res.low;
895
+ this.high = res.high;
896
+ this.unsigned = res.unsigned;
871
897
  }
872
898
  static fromBits(lowBits, highBits, unsigned) {
873
899
  return new Long(lowBits, highBits, unsigned);
@@ -919,7 +945,9 @@ class Long extends BSONValue {
919
945
  return Long.fromBits(value % TWO_PWR_32_DBL | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
920
946
  }
921
947
  static fromBigInt(value, unsigned) {
922
- return Long.fromString(value.toString(), unsigned);
948
+ const FROM_BIGINT_BIT_MASK = BigInt(0xffffffff);
949
+ const FROM_BIGINT_BIT_SHIFT = BigInt(32);
950
+ return new Long(Number(value & FROM_BIGINT_BIT_MASK), Number((value >> FROM_BIGINT_BIT_SHIFT) & FROM_BIGINT_BIT_MASK), unsigned);
923
951
  }
924
952
  static _fromString(str, unsigned, radix) {
925
953
  if (str.length === 0)
@@ -1587,7 +1615,7 @@ class Decimal128 extends BSONValue {
1587
1615
  if (typeof bytes === 'string') {
1588
1616
  this.bytes = Decimal128.fromString(bytes).bytes;
1589
1617
  }
1590
- else if (isUint8Array(bytes)) {
1618
+ else if (bytes instanceof Uint8Array || isUint8Array(bytes)) {
1591
1619
  if (bytes.byteLength !== 16) {
1592
1620
  throw new BSONError('Decimal128 must take a Buffer of 16 bytes');
1593
1621
  }
@@ -2278,7 +2306,7 @@ const NumberUtils = {
2278
2306
  return 4;
2279
2307
  },
2280
2308
  setBigInt64LE(destination, offset, value) {
2281
- const mask32bits = BigInt(4294967295);
2309
+ const mask32bits = BigInt(0xffff_ffff);
2282
2310
  let lo = Number(value & mask32bits);
2283
2311
  destination[offset] = lo;
2284
2312
  lo >>= 8;
@@ -2324,7 +2352,6 @@ const NumberUtils = {
2324
2352
  }
2325
2353
  };
2326
2354
 
2327
- const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2328
2355
  let PROCESS_UNIQUE = null;
2329
2356
  class ObjectId extends BSONValue {
2330
2357
  get _bsontype() {
@@ -2354,7 +2381,7 @@ class ObjectId extends BSONValue {
2354
2381
  this.buffer = ByteUtils.toLocalBufferType(workingId);
2355
2382
  }
2356
2383
  else if (typeof workingId === 'string') {
2357
- if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2384
+ if (ObjectId.validateHexString(workingId)) {
2358
2385
  this.buffer = ByteUtils.fromHex(workingId);
2359
2386
  }
2360
2387
  else {
@@ -2377,6 +2404,20 @@ class ObjectId extends BSONValue {
2377
2404
  this.__id = ByteUtils.toHex(value);
2378
2405
  }
2379
2406
  }
2407
+ static validateHexString(string) {
2408
+ if (string?.length !== 24)
2409
+ return false;
2410
+ for (let i = 0; i < 24; i++) {
2411
+ const char = string.charCodeAt(i);
2412
+ if ((char >= 48 && char <= 57) ||
2413
+ (char >= 97 && char <= 102) ||
2414
+ (char >= 65 && char <= 70)) {
2415
+ continue;
2416
+ }
2417
+ return false;
2418
+ }
2419
+ return true;
2420
+ }
2380
2421
  toHexString() {
2381
2422
  if (ObjectId.cacheHexString && this.__id) {
2382
2423
  return this.__id;
@@ -2489,6 +2530,8 @@ class ObjectId extends BSONValue {
2489
2530
  static isValid(id) {
2490
2531
  if (id == null)
2491
2532
  return false;
2533
+ if (typeof id === 'string')
2534
+ return ObjectId.validateHexString(id);
2492
2535
  try {
2493
2536
  new ObjectId(id);
2494
2537
  return true;
@@ -2559,7 +2602,7 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
2559
2602
  case 'object':
2560
2603
  if (value != null &&
2561
2604
  typeof value._bsontype === 'string' &&
2562
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
2605
+ value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
2563
2606
  throw new BSONVersionError();
2564
2607
  }
2565
2608
  else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
@@ -2763,6 +2806,12 @@ class Timestamp extends LongWithoutOverridesClass {
2763
2806
  get _bsontype() {
2764
2807
  return 'Timestamp';
2765
2808
  }
2809
+ get i() {
2810
+ return this.low >>> 0;
2811
+ }
2812
+ get t() {
2813
+ return this.high >>> 0;
2814
+ }
2766
2815
  constructor(low) {
2767
2816
  if (low == null) {
2768
2817
  super(0, 0, true);
@@ -2788,10 +2837,10 @@ class Timestamp extends LongWithoutOverridesClass {
2788
2837
  if (i < 0 || Number.isNaN(i)) {
2789
2838
  throw new BSONError('Timestamp constructed from { t, i } must provide a positive i');
2790
2839
  }
2791
- if (t > 4294967295) {
2840
+ if (t > 0xffff_ffff) {
2792
2841
  throw new BSONError('Timestamp constructed from { t, i } must provide t equal or less than uint32 max');
2793
2842
  }
2794
- if (i > 4294967295) {
2843
+ if (i > 0xffff_ffff) {
2795
2844
  throw new BSONError('Timestamp constructed from { t, i } must provide i equal or less than uint32 max');
2796
2845
  }
2797
2846
  super(i, t, true);
@@ -2818,7 +2867,7 @@ class Timestamp extends LongWithoutOverridesClass {
2818
2867
  return new Timestamp(Long.fromString(str, true, optRadix));
2819
2868
  }
2820
2869
  toExtendedJSON() {
2821
- return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } };
2870
+ return { $timestamp: { t: this.t, i: this.i } };
2822
2871
  }
2823
2872
  static fromExtendedJSON(doc) {
2824
2873
  const i = Long.isLong(doc.$timestamp.i)
@@ -2831,8 +2880,8 @@ class Timestamp extends LongWithoutOverridesClass {
2831
2880
  }
2832
2881
  inspect(depth, options, inspect) {
2833
2882
  inspect ??= defaultInspect;
2834
- const t = inspect(this.high >>> 0, options);
2835
- const i = inspect(this.low >>> 0, options);
2883
+ const t = inspect(this.t, options);
2884
+ const i = inspect(this.i, options);
2836
2885
  return `new Timestamp({ t: ${t}, i: ${i} })`;
2837
2886
  }
2838
2887
  }
@@ -3601,79 +3650,83 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3601
3650
  if (typeof value?.toBSON === 'function') {
3602
3651
  value = value.toBSON();
3603
3652
  }
3604
- if (typeof value === 'string') {
3605
- index = serializeString(buffer, key, value, index);
3606
- }
3607
- else if (typeof value === 'number') {
3608
- index = serializeNumber(buffer, key, value, index);
3609
- }
3610
- else if (typeof value === 'bigint') {
3611
- index = serializeBigInt(buffer, key, value, index);
3612
- }
3613
- else if (typeof value === 'boolean') {
3614
- index = serializeBoolean(buffer, key, value, index);
3615
- }
3616
- else if (value instanceof Date || isDate(value)) {
3617
- index = serializeDate(buffer, key, value, index);
3618
- }
3619
- else if (value === undefined) {
3653
+ const type = typeof value;
3654
+ if (value === undefined) {
3620
3655
  index = serializeNull(buffer, key, value, index);
3621
3656
  }
3622
3657
  else if (value === null) {
3623
3658
  index = serializeNull(buffer, key, value, index);
3624
3659
  }
3625
- else if (isUint8Array(value)) {
3626
- index = serializeBuffer(buffer, key, value, index);
3627
- }
3628
- else if (value instanceof RegExp || isRegExp(value)) {
3629
- index = serializeRegExp(buffer, key, value, index);
3630
- }
3631
- else if (typeof value === 'object' && value._bsontype == null) {
3632
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3660
+ else if (type === 'string') {
3661
+ index = serializeString(buffer, key, value, index);
3633
3662
  }
3634
- else if (typeof value === 'object' &&
3635
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3636
- throw new BSONVersionError();
3663
+ else if (type === 'number') {
3664
+ index = serializeNumber(buffer, key, value, index);
3637
3665
  }
3638
- else if (value._bsontype === 'ObjectId') {
3639
- index = serializeObjectId(buffer, key, value, index);
3666
+ else if (type === 'bigint') {
3667
+ index = serializeBigInt(buffer, key, value, index);
3640
3668
  }
3641
- else if (value._bsontype === 'Decimal128') {
3642
- index = serializeDecimal128(buffer, key, value, index);
3669
+ else if (type === 'boolean') {
3670
+ index = serializeBoolean(buffer, key, value, index);
3643
3671
  }
3644
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3645
- index = serializeLong(buffer, key, value, index);
3672
+ else if (type === 'object' && value._bsontype == null) {
3673
+ if (value instanceof Date || isDate(value)) {
3674
+ index = serializeDate(buffer, key, value, index);
3675
+ }
3676
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3677
+ index = serializeBuffer(buffer, key, value, index);
3678
+ }
3679
+ else if (value instanceof RegExp || isRegExp(value)) {
3680
+ index = serializeRegExp(buffer, key, value, index);
3681
+ }
3682
+ else {
3683
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3684
+ }
3646
3685
  }
3647
- else if (value._bsontype === 'Double') {
3648
- index = serializeDouble(buffer, key, value, index);
3686
+ else if (type === 'object') {
3687
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3688
+ throw new BSONVersionError();
3689
+ }
3690
+ else if (value._bsontype === 'ObjectId') {
3691
+ index = serializeObjectId(buffer, key, value, index);
3692
+ }
3693
+ else if (value._bsontype === 'Decimal128') {
3694
+ index = serializeDecimal128(buffer, key, value, index);
3695
+ }
3696
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3697
+ index = serializeLong(buffer, key, value, index);
3698
+ }
3699
+ else if (value._bsontype === 'Double') {
3700
+ index = serializeDouble(buffer, key, value, index);
3701
+ }
3702
+ else if (value._bsontype === 'Code') {
3703
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3704
+ }
3705
+ else if (value._bsontype === 'Binary') {
3706
+ index = serializeBinary(buffer, key, value, index);
3707
+ }
3708
+ else if (value._bsontype === 'BSONSymbol') {
3709
+ index = serializeSymbol(buffer, key, value, index);
3710
+ }
3711
+ else if (value._bsontype === 'DBRef') {
3712
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3713
+ }
3714
+ else if (value._bsontype === 'BSONRegExp') {
3715
+ index = serializeBSONRegExp(buffer, key, value, index);
3716
+ }
3717
+ else if (value._bsontype === 'Int32') {
3718
+ index = serializeInt32(buffer, key, value, index);
3719
+ }
3720
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3721
+ index = serializeMinMax(buffer, key, value, index);
3722
+ }
3723
+ else if (typeof value._bsontype !== 'undefined') {
3724
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3725
+ }
3649
3726
  }
3650
- else if (typeof value === 'function' && serializeFunctions) {
3727
+ else if (type === 'function' && serializeFunctions) {
3651
3728
  index = serializeFunction(buffer, key, value, index);
3652
3729
  }
3653
- else if (value._bsontype === 'Code') {
3654
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3655
- }
3656
- else if (value._bsontype === 'Binary') {
3657
- index = serializeBinary(buffer, key, value, index);
3658
- }
3659
- else if (value._bsontype === 'BSONSymbol') {
3660
- index = serializeSymbol(buffer, key, value, index);
3661
- }
3662
- else if (value._bsontype === 'DBRef') {
3663
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3664
- }
3665
- else if (value._bsontype === 'BSONRegExp') {
3666
- index = serializeBSONRegExp(buffer, key, value, index);
3667
- }
3668
- else if (value._bsontype === 'Int32') {
3669
- index = serializeInt32(buffer, key, value, index);
3670
- }
3671
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3672
- index = serializeMinMax(buffer, key, value, index);
3673
- }
3674
- else if (typeof value._bsontype !== 'undefined') {
3675
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3676
- }
3677
3730
  }
3678
3731
  }
3679
3732
  else if (object instanceof Map || isMap(object)) {
@@ -3703,7 +3756,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3703
3756
  }
3704
3757
  }
3705
3758
  }
3706
- if (type === 'string') {
3759
+ if (value === undefined) {
3760
+ if (ignoreUndefined === false)
3761
+ index = serializeNull(buffer, key, value, index);
3762
+ }
3763
+ else if (value === null) {
3764
+ index = serializeNull(buffer, key, value, index);
3765
+ }
3766
+ else if (type === 'string') {
3707
3767
  index = serializeString(buffer, key, value, index);
3708
3768
  }
3709
3769
  else if (type === 'number') {
@@ -3715,64 +3775,64 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3715
3775
  else if (type === 'boolean') {
3716
3776
  index = serializeBoolean(buffer, key, value, index);
3717
3777
  }
3718
- else if (value instanceof Date || isDate(value)) {
3719
- index = serializeDate(buffer, key, value, index);
3720
- }
3721
- else if (value === null || (value === undefined && ignoreUndefined === false)) {
3722
- index = serializeNull(buffer, key, value, index);
3723
- }
3724
- else if (isUint8Array(value)) {
3725
- index = serializeBuffer(buffer, key, value, index);
3726
- }
3727
- else if (value instanceof RegExp || isRegExp(value)) {
3728
- index = serializeRegExp(buffer, key, value, index);
3729
- }
3730
3778
  else if (type === 'object' && value._bsontype == null) {
3731
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3732
- }
3733
- else if (typeof value === 'object' &&
3734
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3735
- throw new BSONVersionError();
3736
- }
3737
- else if (value._bsontype === 'ObjectId') {
3738
- index = serializeObjectId(buffer, key, value, index);
3739
- }
3740
- else if (type === 'object' && value._bsontype === 'Decimal128') {
3741
- index = serializeDecimal128(buffer, key, value, index);
3742
- }
3743
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3744
- index = serializeLong(buffer, key, value, index);
3745
- }
3746
- else if (value._bsontype === 'Double') {
3747
- index = serializeDouble(buffer, key, value, index);
3779
+ if (value instanceof Date || isDate(value)) {
3780
+ index = serializeDate(buffer, key, value, index);
3781
+ }
3782
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3783
+ index = serializeBuffer(buffer, key, value, index);
3784
+ }
3785
+ else if (value instanceof RegExp || isRegExp(value)) {
3786
+ index = serializeRegExp(buffer, key, value, index);
3787
+ }
3788
+ else {
3789
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3790
+ }
3748
3791
  }
3749
- else if (value._bsontype === 'Code') {
3750
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3792
+ else if (type === 'object') {
3793
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3794
+ throw new BSONVersionError();
3795
+ }
3796
+ else if (value._bsontype === 'ObjectId') {
3797
+ index = serializeObjectId(buffer, key, value, index);
3798
+ }
3799
+ else if (value._bsontype === 'Decimal128') {
3800
+ index = serializeDecimal128(buffer, key, value, index);
3801
+ }
3802
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3803
+ index = serializeLong(buffer, key, value, index);
3804
+ }
3805
+ else if (value._bsontype === 'Double') {
3806
+ index = serializeDouble(buffer, key, value, index);
3807
+ }
3808
+ else if (value._bsontype === 'Code') {
3809
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3810
+ }
3811
+ else if (value._bsontype === 'Binary') {
3812
+ index = serializeBinary(buffer, key, value, index);
3813
+ }
3814
+ else if (value._bsontype === 'BSONSymbol') {
3815
+ index = serializeSymbol(buffer, key, value, index);
3816
+ }
3817
+ else if (value._bsontype === 'DBRef') {
3818
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3819
+ }
3820
+ else if (value._bsontype === 'BSONRegExp') {
3821
+ index = serializeBSONRegExp(buffer, key, value, index);
3822
+ }
3823
+ else if (value._bsontype === 'Int32') {
3824
+ index = serializeInt32(buffer, key, value, index);
3825
+ }
3826
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3827
+ index = serializeMinMax(buffer, key, value, index);
3828
+ }
3829
+ else if (typeof value._bsontype !== 'undefined') {
3830
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3831
+ }
3751
3832
  }
3752
- else if (typeof value === 'function' && serializeFunctions) {
3833
+ else if (type === 'function' && serializeFunctions) {
3753
3834
  index = serializeFunction(buffer, key, value, index);
3754
3835
  }
3755
- else if (value._bsontype === 'Binary') {
3756
- index = serializeBinary(buffer, key, value, index);
3757
- }
3758
- else if (value._bsontype === 'BSONSymbol') {
3759
- index = serializeSymbol(buffer, key, value, index);
3760
- }
3761
- else if (value._bsontype === 'DBRef') {
3762
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3763
- }
3764
- else if (value._bsontype === 'BSONRegExp') {
3765
- index = serializeBSONRegExp(buffer, key, value, index);
3766
- }
3767
- else if (value._bsontype === 'Int32') {
3768
- index = serializeInt32(buffer, key, value, index);
3769
- }
3770
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3771
- index = serializeMinMax(buffer, key, value, index);
3772
- }
3773
- else if (typeof value._bsontype !== 'undefined') {
3774
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3775
- }
3776
3836
  }
3777
3837
  }
3778
3838
  else {
@@ -3801,7 +3861,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3801
3861
  }
3802
3862
  }
3803
3863
  }
3804
- if (type === 'string') {
3864
+ if (value === undefined) {
3865
+ if (ignoreUndefined === false)
3866
+ index = serializeNull(buffer, key, value, index);
3867
+ }
3868
+ else if (value === null) {
3869
+ index = serializeNull(buffer, key, value, index);
3870
+ }
3871
+ else if (type === 'string') {
3805
3872
  index = serializeString(buffer, key, value, index);
3806
3873
  }
3807
3874
  else if (type === 'number') {
@@ -3813,68 +3880,64 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3813
3880
  else if (type === 'boolean') {
3814
3881
  index = serializeBoolean(buffer, key, value, index);
3815
3882
  }
3816
- else if (value instanceof Date || isDate(value)) {
3817
- index = serializeDate(buffer, key, value, index);
3818
- }
3819
- else if (value === undefined) {
3820
- if (ignoreUndefined === false)
3821
- index = serializeNull(buffer, key, value, index);
3822
- }
3823
- else if (value === null) {
3824
- index = serializeNull(buffer, key, value, index);
3825
- }
3826
- else if (isUint8Array(value)) {
3827
- index = serializeBuffer(buffer, key, value, index);
3828
- }
3829
- else if (value instanceof RegExp || isRegExp(value)) {
3830
- index = serializeRegExp(buffer, key, value, index);
3831
- }
3832
3883
  else if (type === 'object' && value._bsontype == null) {
3833
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3834
- }
3835
- else if (typeof value === 'object' &&
3836
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3837
- throw new BSONVersionError();
3838
- }
3839
- else if (value._bsontype === 'ObjectId') {
3840
- index = serializeObjectId(buffer, key, value, index);
3841
- }
3842
- else if (type === 'object' && value._bsontype === 'Decimal128') {
3843
- index = serializeDecimal128(buffer, key, value, index);
3844
- }
3845
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3846
- index = serializeLong(buffer, key, value, index);
3847
- }
3848
- else if (value._bsontype === 'Double') {
3849
- index = serializeDouble(buffer, key, value, index);
3884
+ if (value instanceof Date || isDate(value)) {
3885
+ index = serializeDate(buffer, key, value, index);
3886
+ }
3887
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3888
+ index = serializeBuffer(buffer, key, value, index);
3889
+ }
3890
+ else if (value instanceof RegExp || isRegExp(value)) {
3891
+ index = serializeRegExp(buffer, key, value, index);
3892
+ }
3893
+ else {
3894
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3895
+ }
3850
3896
  }
3851
- else if (value._bsontype === 'Code') {
3852
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3897
+ else if (type === 'object') {
3898
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3899
+ throw new BSONVersionError();
3900
+ }
3901
+ else if (value._bsontype === 'ObjectId') {
3902
+ index = serializeObjectId(buffer, key, value, index);
3903
+ }
3904
+ else if (value._bsontype === 'Decimal128') {
3905
+ index = serializeDecimal128(buffer, key, value, index);
3906
+ }
3907
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3908
+ index = serializeLong(buffer, key, value, index);
3909
+ }
3910
+ else if (value._bsontype === 'Double') {
3911
+ index = serializeDouble(buffer, key, value, index);
3912
+ }
3913
+ else if (value._bsontype === 'Code') {
3914
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3915
+ }
3916
+ else if (value._bsontype === 'Binary') {
3917
+ index = serializeBinary(buffer, key, value, index);
3918
+ }
3919
+ else if (value._bsontype === 'BSONSymbol') {
3920
+ index = serializeSymbol(buffer, key, value, index);
3921
+ }
3922
+ else if (value._bsontype === 'DBRef') {
3923
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3924
+ }
3925
+ else if (value._bsontype === 'BSONRegExp') {
3926
+ index = serializeBSONRegExp(buffer, key, value, index);
3927
+ }
3928
+ else if (value._bsontype === 'Int32') {
3929
+ index = serializeInt32(buffer, key, value, index);
3930
+ }
3931
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3932
+ index = serializeMinMax(buffer, key, value, index);
3933
+ }
3934
+ else if (typeof value._bsontype !== 'undefined') {
3935
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3936
+ }
3853
3937
  }
3854
- else if (typeof value === 'function' && serializeFunctions) {
3938
+ else if (type === 'function' && serializeFunctions) {
3855
3939
  index = serializeFunction(buffer, key, value, index);
3856
3940
  }
3857
- else if (value._bsontype === 'Binary') {
3858
- index = serializeBinary(buffer, key, value, index);
3859
- }
3860
- else if (value._bsontype === 'BSONSymbol') {
3861
- index = serializeSymbol(buffer, key, value, index);
3862
- }
3863
- else if (value._bsontype === 'DBRef') {
3864
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3865
- }
3866
- else if (value._bsontype === 'BSONRegExp') {
3867
- index = serializeBSONRegExp(buffer, key, value, index);
3868
- }
3869
- else if (value._bsontype === 'Int32') {
3870
- index = serializeInt32(buffer, key, value, index);
3871
- }
3872
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3873
- index = serializeMinMax(buffer, key, value, index);
3874
- }
3875
- else if (typeof value._bsontype !== 'undefined') {
3876
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3877
- }
3878
3941
  }
3879
3942
  }
3880
3943
  path.delete(object);
@@ -4126,7 +4189,7 @@ function serializeDocument(doc, options) {
4126
4189
  else if (doc != null &&
4127
4190
  typeof doc === 'object' &&
4128
4191
  typeof doc._bsontype === 'string' &&
4129
- doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
4192
+ doc[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
4130
4193
  throw new BSONVersionError();
4131
4194
  }
4132
4195
  else if (isBSONType(doc)) {