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