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