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