bson 5.0.0-alpha.1 → 5.0.0-alpha.3
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/README.md +85 -93
- package/bson.d.ts +50 -22
- package/lib/bson.bundle.js +242 -204
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +242 -204
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +241 -204
- package/lib/bson.mjs.map +1 -1
- package/package.json +4 -4
- package/src/binary.ts +11 -18
- package/src/bson.ts +2 -1
- package/src/bson_value.ts +18 -0
- package/src/code.ts +3 -6
- package/src/constants.ts +1 -3
- package/src/db_ref.ts +3 -6
- package/src/decimal128.ts +10 -13
- package/src/double.ts +9 -20
- package/src/error.ts +47 -8
- package/src/extended_json.ts +36 -10
- package/src/int_32.ts +3 -6
- package/src/long.ts +37 -14
- package/src/max_key.ts +2 -6
- package/src/min_key.ts +2 -6
- package/src/objectid.ts +9 -14
- package/src/parser/calculate_size.ts +18 -11
- package/src/parser/deserializer.ts +24 -9
- package/src/parser/serializer.ts +53 -34
- package/src/regexp.ts +5 -8
- package/src/symbol.ts +3 -7
- package/src/timestamp.ts +0 -5
- package/src/uuid_utils.ts +2 -2
package/lib/bson.bundle.js
CHANGED
|
@@ -1,20 +1,86 @@
|
|
|
1
1
|
var BSON = (function (exports) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
const BSON_MAJOR_VERSION = 5;
|
|
5
|
+
const BSON_INT32_MAX = 0x7fffffff;
|
|
6
|
+
const BSON_INT32_MIN = -0x80000000;
|
|
7
|
+
const BSON_INT64_MAX = Math.pow(2, 63) - 1;
|
|
8
|
+
const BSON_INT64_MIN = -Math.pow(2, 63);
|
|
9
|
+
const JS_INT_MAX = Math.pow(2, 53);
|
|
10
|
+
const JS_INT_MIN = -Math.pow(2, 53);
|
|
11
|
+
const BSON_DATA_NUMBER = 1;
|
|
12
|
+
const BSON_DATA_STRING = 2;
|
|
13
|
+
const BSON_DATA_OBJECT = 3;
|
|
14
|
+
const BSON_DATA_ARRAY = 4;
|
|
15
|
+
const BSON_DATA_BINARY = 5;
|
|
16
|
+
const BSON_DATA_UNDEFINED = 6;
|
|
17
|
+
const BSON_DATA_OID = 7;
|
|
18
|
+
const BSON_DATA_BOOLEAN = 8;
|
|
19
|
+
const BSON_DATA_DATE = 9;
|
|
20
|
+
const BSON_DATA_NULL = 10;
|
|
21
|
+
const BSON_DATA_REGEXP = 11;
|
|
22
|
+
const BSON_DATA_DBPOINTER = 12;
|
|
23
|
+
const BSON_DATA_CODE = 13;
|
|
24
|
+
const BSON_DATA_SYMBOL = 14;
|
|
25
|
+
const BSON_DATA_CODE_W_SCOPE = 15;
|
|
26
|
+
const BSON_DATA_INT = 16;
|
|
27
|
+
const BSON_DATA_TIMESTAMP = 17;
|
|
28
|
+
const BSON_DATA_LONG = 18;
|
|
29
|
+
const BSON_DATA_DECIMAL128 = 19;
|
|
30
|
+
const BSON_DATA_MIN_KEY = 0xff;
|
|
31
|
+
const BSON_DATA_MAX_KEY = 0x7f;
|
|
32
|
+
const BSON_BINARY_SUBTYPE_DEFAULT = 0;
|
|
33
|
+
const BSON_BINARY_SUBTYPE_UUID_NEW = 4;
|
|
34
|
+
const BSONType = Object.freeze({
|
|
35
|
+
double: 1,
|
|
36
|
+
string: 2,
|
|
37
|
+
object: 3,
|
|
38
|
+
array: 4,
|
|
39
|
+
binData: 5,
|
|
40
|
+
undefined: 6,
|
|
41
|
+
objectId: 7,
|
|
42
|
+
bool: 8,
|
|
43
|
+
date: 9,
|
|
44
|
+
null: 10,
|
|
45
|
+
regex: 11,
|
|
46
|
+
dbPointer: 12,
|
|
47
|
+
javascript: 13,
|
|
48
|
+
symbol: 14,
|
|
49
|
+
javascriptWithScope: 15,
|
|
50
|
+
int: 16,
|
|
51
|
+
timestamp: 17,
|
|
52
|
+
long: 18,
|
|
53
|
+
decimal: 19,
|
|
54
|
+
minKey: -1,
|
|
55
|
+
maxKey: 127
|
|
56
|
+
});
|
|
57
|
+
|
|
4
58
|
class BSONError extends Error {
|
|
5
|
-
|
|
6
|
-
|
|
59
|
+
get bsonError() {
|
|
60
|
+
return true;
|
|
7
61
|
}
|
|
8
62
|
get name() {
|
|
9
63
|
return 'BSONError';
|
|
10
64
|
}
|
|
11
|
-
}
|
|
12
|
-
class BSONTypeError extends TypeError {
|
|
13
65
|
constructor(message) {
|
|
14
66
|
super(message);
|
|
15
67
|
}
|
|
68
|
+
static isBSONError(value) {
|
|
69
|
+
return (value != null &&
|
|
70
|
+
typeof value === 'object' &&
|
|
71
|
+
'bsonError' in value &&
|
|
72
|
+
value.bsonError === true &&
|
|
73
|
+
'name' in value &&
|
|
74
|
+
'message' in value &&
|
|
75
|
+
'stack' in value);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
class BSONVersionError extends BSONError {
|
|
16
79
|
get name() {
|
|
17
|
-
return '
|
|
80
|
+
return 'BSONVersionError';
|
|
81
|
+
}
|
|
82
|
+
constructor() {
|
|
83
|
+
super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.0 or later`);
|
|
18
84
|
}
|
|
19
85
|
}
|
|
20
86
|
|
|
@@ -213,7 +279,7 @@ const VALIDATION_REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f
|
|
|
213
279
|
const uuidValidateString = (str) => typeof str === 'string' && VALIDATION_REGEX.test(str);
|
|
214
280
|
const uuidHexStringToBuffer = (hexString) => {
|
|
215
281
|
if (!uuidValidateString(hexString)) {
|
|
216
|
-
throw new
|
|
282
|
+
throw new BSONError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".');
|
|
217
283
|
}
|
|
218
284
|
const sanitizedHexString = hexString.replace(/-/g, '');
|
|
219
285
|
return ByteUtils.fromHex(sanitizedHexString);
|
|
@@ -237,12 +303,6 @@ function isAnyArrayBuffer(value) {
|
|
|
237
303
|
function isUint8Array(value) {
|
|
238
304
|
return Object.prototype.toString.call(value) === '[object Uint8Array]';
|
|
239
305
|
}
|
|
240
|
-
function isBigInt64Array(value) {
|
|
241
|
-
return Object.prototype.toString.call(value) === '[object BigInt64Array]';
|
|
242
|
-
}
|
|
243
|
-
function isBigUInt64Array(value) {
|
|
244
|
-
return Object.prototype.toString.call(value) === '[object BigUint64Array]';
|
|
245
|
-
}
|
|
246
306
|
function isRegExp(d) {
|
|
247
307
|
return Object.prototype.toString.call(d) === '[object RegExp]';
|
|
248
308
|
}
|
|
@@ -253,74 +313,24 @@ function isDate(d) {
|
|
|
253
313
|
return Object.prototype.toString.call(d) === '[object Date]';
|
|
254
314
|
}
|
|
255
315
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const JS_INT_MAX = Math.pow(2, 53);
|
|
262
|
-
const JS_INT_MIN = -Math.pow(2, 53);
|
|
263
|
-
const BSON_DATA_NUMBER = 1;
|
|
264
|
-
const BSON_DATA_STRING = 2;
|
|
265
|
-
const BSON_DATA_OBJECT = 3;
|
|
266
|
-
const BSON_DATA_ARRAY = 4;
|
|
267
|
-
const BSON_DATA_BINARY = 5;
|
|
268
|
-
const BSON_DATA_UNDEFINED = 6;
|
|
269
|
-
const BSON_DATA_OID = 7;
|
|
270
|
-
const BSON_DATA_BOOLEAN = 8;
|
|
271
|
-
const BSON_DATA_DATE = 9;
|
|
272
|
-
const BSON_DATA_NULL = 10;
|
|
273
|
-
const BSON_DATA_REGEXP = 11;
|
|
274
|
-
const BSON_DATA_DBPOINTER = 12;
|
|
275
|
-
const BSON_DATA_CODE = 13;
|
|
276
|
-
const BSON_DATA_SYMBOL = 14;
|
|
277
|
-
const BSON_DATA_CODE_W_SCOPE = 15;
|
|
278
|
-
const BSON_DATA_INT = 16;
|
|
279
|
-
const BSON_DATA_TIMESTAMP = 17;
|
|
280
|
-
const BSON_DATA_LONG = 18;
|
|
281
|
-
const BSON_DATA_DECIMAL128 = 19;
|
|
282
|
-
const BSON_DATA_MIN_KEY = 0xff;
|
|
283
|
-
const BSON_DATA_MAX_KEY = 0x7f;
|
|
284
|
-
const BSON_BINARY_SUBTYPE_DEFAULT = 0;
|
|
285
|
-
const BSON_BINARY_SUBTYPE_UUID_NEW = 4;
|
|
286
|
-
const BSONType = Object.freeze({
|
|
287
|
-
double: 1,
|
|
288
|
-
string: 2,
|
|
289
|
-
object: 3,
|
|
290
|
-
array: 4,
|
|
291
|
-
binData: 5,
|
|
292
|
-
undefined: 6,
|
|
293
|
-
objectId: 7,
|
|
294
|
-
bool: 8,
|
|
295
|
-
date: 9,
|
|
296
|
-
null: 10,
|
|
297
|
-
regex: 11,
|
|
298
|
-
dbPointer: 12,
|
|
299
|
-
javascript: 13,
|
|
300
|
-
symbol: 14,
|
|
301
|
-
javascriptWithScope: 15,
|
|
302
|
-
int: 16,
|
|
303
|
-
timestamp: 17,
|
|
304
|
-
long: 18,
|
|
305
|
-
decimal: 19,
|
|
306
|
-
minKey: -1,
|
|
307
|
-
maxKey: 127
|
|
308
|
-
});
|
|
316
|
+
class BSONValue {
|
|
317
|
+
get [Symbol.for('@@mdb.bson.version')]() {
|
|
318
|
+
return BSON_MAJOR_VERSION;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
309
321
|
|
|
310
|
-
class Binary {
|
|
322
|
+
class Binary extends BSONValue {
|
|
311
323
|
get _bsontype() {
|
|
312
324
|
return 'Binary';
|
|
313
325
|
}
|
|
314
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
315
|
-
return BSON_MAJOR_VERSION;
|
|
316
|
-
}
|
|
317
326
|
constructor(buffer, subType) {
|
|
327
|
+
super();
|
|
318
328
|
if (!(buffer == null) &&
|
|
319
329
|
!(typeof buffer === 'string') &&
|
|
320
330
|
!ArrayBuffer.isView(buffer) &&
|
|
321
331
|
!(buffer instanceof ArrayBuffer) &&
|
|
322
332
|
!Array.isArray(buffer)) {
|
|
323
|
-
throw new
|
|
333
|
+
throw new BSONError('Binary can only be constructed from string, Buffer, TypedArray, or Array<number>');
|
|
324
334
|
}
|
|
325
335
|
this.sub_type = subType ?? Binary.BSON_BINARY_SUBTYPE_DEFAULT;
|
|
326
336
|
if (buffer == null) {
|
|
@@ -342,10 +352,10 @@ class Binary {
|
|
|
342
352
|
}
|
|
343
353
|
put(byteValue) {
|
|
344
354
|
if (typeof byteValue === 'string' && byteValue.length !== 1) {
|
|
345
|
-
throw new
|
|
355
|
+
throw new BSONError('only accepts single character String');
|
|
346
356
|
}
|
|
347
357
|
else if (typeof byteValue !== 'number' && byteValue.length !== 1)
|
|
348
|
-
throw new
|
|
358
|
+
throw new BSONError('only accepts single character Uint8Array or Array');
|
|
349
359
|
let decodedByte;
|
|
350
360
|
if (typeof byteValue === 'string') {
|
|
351
361
|
decodedByte = byteValue.charCodeAt(0);
|
|
@@ -357,7 +367,7 @@ class Binary {
|
|
|
357
367
|
decodedByte = byteValue[0];
|
|
358
368
|
}
|
|
359
369
|
if (decodedByte < 0 || decodedByte > 255) {
|
|
360
|
-
throw new
|
|
370
|
+
throw new BSONError('only accepts number in a valid unsigned byte range 0-255');
|
|
361
371
|
}
|
|
362
372
|
if (this.buffer.byteLength > this.position) {
|
|
363
373
|
this.buffer[this.position++] = decodedByte;
|
|
@@ -461,7 +471,7 @@ class Binary {
|
|
|
461
471
|
data = uuidHexStringToBuffer(doc.$uuid);
|
|
462
472
|
}
|
|
463
473
|
if (!data) {
|
|
464
|
-
throw new
|
|
474
|
+
throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`);
|
|
465
475
|
}
|
|
466
476
|
return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new Binary(data, type);
|
|
467
477
|
}
|
|
@@ -485,9 +495,6 @@ Binary.SUBTYPE_COLUMN = 7;
|
|
|
485
495
|
Binary.SUBTYPE_USER_DEFINED = 128;
|
|
486
496
|
const UUID_BYTE_LENGTH = 16;
|
|
487
497
|
class UUID extends Binary {
|
|
488
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
489
|
-
return BSON_MAJOR_VERSION;
|
|
490
|
-
}
|
|
491
498
|
constructor(input) {
|
|
492
499
|
let bytes;
|
|
493
500
|
let hexStr;
|
|
@@ -505,7 +512,7 @@ class UUID extends Binary {
|
|
|
505
512
|
bytes = uuidHexStringToBuffer(input);
|
|
506
513
|
}
|
|
507
514
|
else {
|
|
508
|
-
throw new
|
|
515
|
+
throw new BSONError('Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).');
|
|
509
516
|
}
|
|
510
517
|
super(bytes, BSON_BINARY_SUBTYPE_UUID_NEW);
|
|
511
518
|
this.__id = hexStr;
|
|
@@ -592,14 +599,12 @@ class UUID extends Binary {
|
|
|
592
599
|
}
|
|
593
600
|
}
|
|
594
601
|
|
|
595
|
-
class Code {
|
|
602
|
+
class Code extends BSONValue {
|
|
596
603
|
get _bsontype() {
|
|
597
604
|
return 'Code';
|
|
598
605
|
}
|
|
599
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
600
|
-
return BSON_MAJOR_VERSION;
|
|
601
|
-
}
|
|
602
606
|
constructor(code, scope) {
|
|
607
|
+
super();
|
|
603
608
|
this.code = code.toString();
|
|
604
609
|
this.scope = scope ?? null;
|
|
605
610
|
}
|
|
@@ -636,14 +641,12 @@ function isDBRefLike(value) {
|
|
|
636
641
|
typeof value.$ref === 'string' &&
|
|
637
642
|
(!('$db' in value) || ('$db' in value && typeof value.$db === 'string')));
|
|
638
643
|
}
|
|
639
|
-
class DBRef {
|
|
644
|
+
class DBRef extends BSONValue {
|
|
640
645
|
get _bsontype() {
|
|
641
646
|
return 'DBRef';
|
|
642
647
|
}
|
|
643
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
644
|
-
return BSON_MAJOR_VERSION;
|
|
645
|
-
}
|
|
646
648
|
constructor(collection, oid, db, fields) {
|
|
649
|
+
super();
|
|
647
650
|
const parts = collection.split('.');
|
|
648
651
|
if (parts.length === 2) {
|
|
649
652
|
db = parts.shift();
|
|
@@ -712,17 +715,17 @@ const TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
|
|
|
712
715
|
const TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
|
|
713
716
|
const INT_CACHE = {};
|
|
714
717
|
const UINT_CACHE = {};
|
|
715
|
-
|
|
718
|
+
const MAX_INT64_STRING_LENGTH = 20;
|
|
719
|
+
const DECIMAL_REG_EX = /^(\+?0|(\+|-)?[1-9][0-9]*)$/;
|
|
720
|
+
class Long extends BSONValue {
|
|
716
721
|
get _bsontype() {
|
|
717
722
|
return 'Long';
|
|
718
723
|
}
|
|
719
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
720
|
-
return BSON_MAJOR_VERSION;
|
|
721
|
-
}
|
|
722
724
|
get __isLong__() {
|
|
723
725
|
return true;
|
|
724
726
|
}
|
|
725
727
|
constructor(low = 0, high, unsigned) {
|
|
728
|
+
super();
|
|
726
729
|
if (typeof low === 'bigint') {
|
|
727
730
|
Object.assign(this, Long.fromBigInt(low, !!high));
|
|
728
731
|
}
|
|
@@ -789,7 +792,7 @@ class Long {
|
|
|
789
792
|
}
|
|
790
793
|
static fromString(str, unsigned, radix) {
|
|
791
794
|
if (str.length === 0)
|
|
792
|
-
throw
|
|
795
|
+
throw new BSONError('empty string');
|
|
793
796
|
if (str === 'NaN' || str === 'Infinity' || str === '+Infinity' || str === '-Infinity')
|
|
794
797
|
return Long.ZERO;
|
|
795
798
|
if (typeof unsigned === 'number') {
|
|
@@ -800,10 +803,10 @@ class Long {
|
|
|
800
803
|
}
|
|
801
804
|
radix = radix || 10;
|
|
802
805
|
if (radix < 2 || 36 < radix)
|
|
803
|
-
throw
|
|
806
|
+
throw new BSONError('radix');
|
|
804
807
|
let p;
|
|
805
808
|
if ((p = str.indexOf('-')) > 0)
|
|
806
|
-
throw
|
|
809
|
+
throw new BSONError('interior hyphen');
|
|
807
810
|
else if (p === 0) {
|
|
808
811
|
return Long.fromString(str.substring(1), unsigned, radix).neg();
|
|
809
812
|
}
|
|
@@ -899,7 +902,7 @@ class Long {
|
|
|
899
902
|
if (!Long.isLong(divisor))
|
|
900
903
|
divisor = Long.fromValue(divisor);
|
|
901
904
|
if (divisor.isZero())
|
|
902
|
-
throw
|
|
905
|
+
throw new BSONError('division by zero');
|
|
903
906
|
if (wasm) {
|
|
904
907
|
if (!this.unsigned &&
|
|
905
908
|
this.high === -0x80000000 &&
|
|
@@ -1254,7 +1257,7 @@ class Long {
|
|
|
1254
1257
|
toString(radix) {
|
|
1255
1258
|
radix = radix || 10;
|
|
1256
1259
|
if (radix < 2 || 36 < radix)
|
|
1257
|
-
throw
|
|
1260
|
+
throw new BSONError('radix');
|
|
1258
1261
|
if (this.isZero())
|
|
1259
1262
|
return '0';
|
|
1260
1263
|
if (this.isNegative()) {
|
|
@@ -1305,8 +1308,22 @@ class Long {
|
|
|
1305
1308
|
return { $numberLong: this.toString() };
|
|
1306
1309
|
}
|
|
1307
1310
|
static fromExtendedJSON(doc, options) {
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1311
|
+
const { useBigInt64 = false, relaxed = true } = { ...options };
|
|
1312
|
+
if (doc.$numberLong.length > MAX_INT64_STRING_LENGTH) {
|
|
1313
|
+
throw new BSONError('$numberLong string is too long');
|
|
1314
|
+
}
|
|
1315
|
+
if (!DECIMAL_REG_EX.test(doc.$numberLong)) {
|
|
1316
|
+
throw new BSONError(`$numberLong string "${doc.$numberLong}" is in an invalid format`);
|
|
1317
|
+
}
|
|
1318
|
+
if (useBigInt64) {
|
|
1319
|
+
const bigIntResult = BigInt(doc.$numberLong);
|
|
1320
|
+
return BigInt.asIntN(64, bigIntResult);
|
|
1321
|
+
}
|
|
1322
|
+
const longResult = Long.fromString(doc.$numberLong);
|
|
1323
|
+
if (relaxed) {
|
|
1324
|
+
return longResult.toNumber();
|
|
1325
|
+
}
|
|
1326
|
+
return longResult;
|
|
1310
1327
|
}
|
|
1311
1328
|
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
1312
1329
|
return this.inspect();
|
|
@@ -1398,27 +1415,25 @@ function lessThan(left, right) {
|
|
|
1398
1415
|
return false;
|
|
1399
1416
|
}
|
|
1400
1417
|
function invalidErr(string, message) {
|
|
1401
|
-
throw new
|
|
1418
|
+
throw new BSONError(`"${string}" is not a valid Decimal128 string - ${message}`);
|
|
1402
1419
|
}
|
|
1403
|
-
class Decimal128 {
|
|
1420
|
+
class Decimal128 extends BSONValue {
|
|
1404
1421
|
get _bsontype() {
|
|
1405
1422
|
return 'Decimal128';
|
|
1406
1423
|
}
|
|
1407
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
1408
|
-
return BSON_MAJOR_VERSION;
|
|
1409
|
-
}
|
|
1410
1424
|
constructor(bytes) {
|
|
1425
|
+
super();
|
|
1411
1426
|
if (typeof bytes === 'string') {
|
|
1412
1427
|
this.bytes = Decimal128.fromString(bytes).bytes;
|
|
1413
1428
|
}
|
|
1414
1429
|
else if (isUint8Array(bytes)) {
|
|
1415
1430
|
if (bytes.byteLength !== 16) {
|
|
1416
|
-
throw new
|
|
1431
|
+
throw new BSONError('Decimal128 must take a Buffer of 16 bytes');
|
|
1417
1432
|
}
|
|
1418
1433
|
this.bytes = bytes;
|
|
1419
1434
|
}
|
|
1420
1435
|
else {
|
|
1421
|
-
throw new
|
|
1436
|
+
throw new BSONError('Decimal128 must take a Buffer or string');
|
|
1422
1437
|
}
|
|
1423
1438
|
}
|
|
1424
1439
|
static fromString(representation) {
|
|
@@ -1442,13 +1457,13 @@ class Decimal128 {
|
|
|
1442
1457
|
let biasedExponent = 0;
|
|
1443
1458
|
let index = 0;
|
|
1444
1459
|
if (representation.length >= 7000) {
|
|
1445
|
-
throw new
|
|
1460
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
1446
1461
|
}
|
|
1447
1462
|
const stringMatch = representation.match(PARSE_STRING_REGEXP);
|
|
1448
1463
|
const infMatch = representation.match(PARSE_INF_REGEXP);
|
|
1449
1464
|
const nanMatch = representation.match(PARSE_NAN_REGEXP);
|
|
1450
1465
|
if ((!stringMatch && !infMatch && !nanMatch) || representation.length === 0) {
|
|
1451
|
-
throw new
|
|
1466
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
1452
1467
|
}
|
|
1453
1468
|
if (stringMatch) {
|
|
1454
1469
|
const unsignedNumber = stringMatch[2];
|
|
@@ -1500,7 +1515,7 @@ class Decimal128 {
|
|
|
1500
1515
|
index = index + 1;
|
|
1501
1516
|
}
|
|
1502
1517
|
if (sawRadix && !nDigitsRead)
|
|
1503
|
-
throw new
|
|
1518
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
1504
1519
|
if (representation[index] === 'e' || representation[index] === 'E') {
|
|
1505
1520
|
const match = representation.substr(++index).match(EXPONENT_REGEX);
|
|
1506
1521
|
if (!match || !match[2])
|
|
@@ -1829,14 +1844,12 @@ class Decimal128 {
|
|
|
1829
1844
|
}
|
|
1830
1845
|
}
|
|
1831
1846
|
|
|
1832
|
-
class Double {
|
|
1847
|
+
class Double extends BSONValue {
|
|
1833
1848
|
get _bsontype() {
|
|
1834
1849
|
return 'Double';
|
|
1835
1850
|
}
|
|
1836
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
1837
|
-
return BSON_MAJOR_VERSION;
|
|
1838
|
-
}
|
|
1839
1851
|
constructor(value) {
|
|
1852
|
+
super();
|
|
1840
1853
|
if (value instanceof Number) {
|
|
1841
1854
|
value = value.valueOf();
|
|
1842
1855
|
}
|
|
@@ -1856,19 +1869,11 @@ class Double {
|
|
|
1856
1869
|
return this.value;
|
|
1857
1870
|
}
|
|
1858
1871
|
if (Object.is(Math.sign(this.value), -0)) {
|
|
1859
|
-
return { $numberDouble:
|
|
1872
|
+
return { $numberDouble: '-0.0' };
|
|
1860
1873
|
}
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
if ($numberDouble.length >= 13) {
|
|
1865
|
-
$numberDouble = this.value.toExponential(13).toUpperCase();
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
else {
|
|
1869
|
-
$numberDouble = this.value.toString();
|
|
1870
|
-
}
|
|
1871
|
-
return { $numberDouble };
|
|
1874
|
+
return {
|
|
1875
|
+
$numberDouble: Number.isInteger(this.value) ? this.value.toFixed(1) : this.value.toString()
|
|
1876
|
+
};
|
|
1872
1877
|
}
|
|
1873
1878
|
static fromExtendedJSON(doc, options) {
|
|
1874
1879
|
const doubleValue = parseFloat(doc.$numberDouble);
|
|
@@ -1883,14 +1888,12 @@ class Double {
|
|
|
1883
1888
|
}
|
|
1884
1889
|
}
|
|
1885
1890
|
|
|
1886
|
-
class Int32 {
|
|
1891
|
+
class Int32 extends BSONValue {
|
|
1887
1892
|
get _bsontype() {
|
|
1888
1893
|
return 'Int32';
|
|
1889
1894
|
}
|
|
1890
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
1891
|
-
return BSON_MAJOR_VERSION;
|
|
1892
|
-
}
|
|
1893
1895
|
constructor(value) {
|
|
1896
|
+
super();
|
|
1894
1897
|
if (value instanceof Number) {
|
|
1895
1898
|
value = value.valueOf();
|
|
1896
1899
|
}
|
|
@@ -1921,13 +1924,10 @@ class Int32 {
|
|
|
1921
1924
|
}
|
|
1922
1925
|
}
|
|
1923
1926
|
|
|
1924
|
-
class MaxKey {
|
|
1927
|
+
class MaxKey extends BSONValue {
|
|
1925
1928
|
get _bsontype() {
|
|
1926
1929
|
return 'MaxKey';
|
|
1927
1930
|
}
|
|
1928
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
1929
|
-
return BSON_MAJOR_VERSION;
|
|
1930
|
-
}
|
|
1931
1931
|
toExtendedJSON() {
|
|
1932
1932
|
return { $maxKey: 1 };
|
|
1933
1933
|
}
|
|
@@ -1942,13 +1942,10 @@ class MaxKey {
|
|
|
1942
1942
|
}
|
|
1943
1943
|
}
|
|
1944
1944
|
|
|
1945
|
-
class MinKey {
|
|
1945
|
+
class MinKey extends BSONValue {
|
|
1946
1946
|
get _bsontype() {
|
|
1947
1947
|
return 'MinKey';
|
|
1948
1948
|
}
|
|
1949
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
1950
|
-
return BSON_MAJOR_VERSION;
|
|
1951
|
-
}
|
|
1952
1949
|
toExtendedJSON() {
|
|
1953
1950
|
return { $minKey: 1 };
|
|
1954
1951
|
}
|
|
@@ -1966,18 +1963,16 @@ class MinKey {
|
|
|
1966
1963
|
const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
|
|
1967
1964
|
let PROCESS_UNIQUE = null;
|
|
1968
1965
|
const kId = Symbol('id');
|
|
1969
|
-
class ObjectId {
|
|
1966
|
+
class ObjectId extends BSONValue {
|
|
1970
1967
|
get _bsontype() {
|
|
1971
1968
|
return 'ObjectId';
|
|
1972
1969
|
}
|
|
1973
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
1974
|
-
return BSON_MAJOR_VERSION;
|
|
1975
|
-
}
|
|
1976
1970
|
constructor(inputId) {
|
|
1971
|
+
super();
|
|
1977
1972
|
let workingId;
|
|
1978
1973
|
if (typeof inputId === 'object' && inputId && 'id' in inputId) {
|
|
1979
1974
|
if (typeof inputId.id !== 'string' && !ArrayBuffer.isView(inputId.id)) {
|
|
1980
|
-
throw new
|
|
1975
|
+
throw new BSONError('Argument passed in must have an id that is of type string or Buffer');
|
|
1981
1976
|
}
|
|
1982
1977
|
if ('toHexString' in inputId && typeof inputId.toHexString === 'function') {
|
|
1983
1978
|
workingId = ByteUtils.fromHex(inputId.toHexString());
|
|
@@ -2002,18 +1997,18 @@ class ObjectId {
|
|
|
2002
1997
|
this[kId] = bytes;
|
|
2003
1998
|
}
|
|
2004
1999
|
else {
|
|
2005
|
-
throw new
|
|
2000
|
+
throw new BSONError('Argument passed in must be a string of 12 bytes');
|
|
2006
2001
|
}
|
|
2007
2002
|
}
|
|
2008
2003
|
else if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
|
|
2009
2004
|
this[kId] = ByteUtils.fromHex(workingId);
|
|
2010
2005
|
}
|
|
2011
2006
|
else {
|
|
2012
|
-
throw new
|
|
2007
|
+
throw new BSONError('Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer');
|
|
2013
2008
|
}
|
|
2014
2009
|
}
|
|
2015
2010
|
else {
|
|
2016
|
-
throw new
|
|
2011
|
+
throw new BSONError('Argument passed in does not match the accepted types');
|
|
2017
2012
|
}
|
|
2018
2013
|
if (ObjectId.cacheHexString) {
|
|
2019
2014
|
this.__id = ByteUtils.toHex(this.id);
|
|
@@ -2115,7 +2110,7 @@ class ObjectId {
|
|
|
2115
2110
|
}
|
|
2116
2111
|
static createFromHexString(hexString) {
|
|
2117
2112
|
if (typeof hexString === 'undefined' || (hexString != null && hexString.length !== 24)) {
|
|
2118
|
-
throw new
|
|
2113
|
+
throw new BSONError('Argument passed in must be a single String of 12 bytes or a string of 24 hex characters');
|
|
2119
2114
|
}
|
|
2120
2115
|
return new ObjectId(ByteUtils.fromHex(hexString));
|
|
2121
2116
|
}
|
|
@@ -2192,10 +2187,15 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2192
2187
|
case 'boolean':
|
|
2193
2188
|
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 1);
|
|
2194
2189
|
case 'object':
|
|
2195
|
-
if (value
|
|
2190
|
+
if (value != null &&
|
|
2191
|
+
typeof value._bsontype === 'string' &&
|
|
2192
|
+
value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
|
|
2193
|
+
throw new BSONVersionError();
|
|
2194
|
+
}
|
|
2195
|
+
else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
|
|
2196
2196
|
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1;
|
|
2197
2197
|
}
|
|
2198
|
-
else if (value
|
|
2198
|
+
else if (value._bsontype === 'ObjectId') {
|
|
2199
2199
|
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1);
|
|
2200
2200
|
}
|
|
2201
2201
|
else if (value instanceof Date || isDate(value)) {
|
|
@@ -2206,15 +2206,15 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2206
2206
|
isAnyArrayBuffer(value)) {
|
|
2207
2207
|
return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 4 + 1) + value.byteLength);
|
|
2208
2208
|
}
|
|
2209
|
-
else if (value
|
|
2210
|
-
value
|
|
2211
|
-
value
|
|
2209
|
+
else if (value._bsontype === 'Long' ||
|
|
2210
|
+
value._bsontype === 'Double' ||
|
|
2211
|
+
value._bsontype === 'Timestamp') {
|
|
2212
2212
|
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1);
|
|
2213
2213
|
}
|
|
2214
|
-
else if (value
|
|
2214
|
+
else if (value._bsontype === 'Decimal128') {
|
|
2215
2215
|
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (16 + 1);
|
|
2216
2216
|
}
|
|
2217
|
-
else if (value
|
|
2217
|
+
else if (value._bsontype === 'Code') {
|
|
2218
2218
|
if (value.scope != null && Object.keys(value.scope).length > 0) {
|
|
2219
2219
|
return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
|
2220
2220
|
1 +
|
|
@@ -2232,7 +2232,7 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2232
2232
|
1);
|
|
2233
2233
|
}
|
|
2234
2234
|
}
|
|
2235
|
-
else if (value
|
|
2235
|
+
else if (value._bsontype === 'Binary') {
|
|
2236
2236
|
const binary = value;
|
|
2237
2237
|
if (binary.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
|
|
2238
2238
|
return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
|
@@ -2242,14 +2242,14 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2242
2242
|
return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1));
|
|
2243
2243
|
}
|
|
2244
2244
|
}
|
|
2245
|
-
else if (value
|
|
2245
|
+
else if (value._bsontype === 'Symbol') {
|
|
2246
2246
|
return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
|
2247
2247
|
ByteUtils.utf8ByteLength(value.value) +
|
|
2248
2248
|
4 +
|
|
2249
2249
|
1 +
|
|
2250
2250
|
1);
|
|
2251
2251
|
}
|
|
2252
|
-
else if (value
|
|
2252
|
+
else if (value._bsontype === 'DBRef') {
|
|
2253
2253
|
const ordered_values = Object.assign({
|
|
2254
2254
|
$ref: value.collection,
|
|
2255
2255
|
$id: value.oid
|
|
@@ -2271,7 +2271,7 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2271
2271
|
(value.multiline ? 1 : 0) +
|
|
2272
2272
|
1);
|
|
2273
2273
|
}
|
|
2274
|
-
else if (value
|
|
2274
|
+
else if (value._bsontype === 'BSONRegExp') {
|
|
2275
2275
|
return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
|
2276
2276
|
1 +
|
|
2277
2277
|
ByteUtils.utf8ByteLength(value.pattern) +
|
|
@@ -2299,14 +2299,12 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2299
2299
|
function alphabetize(str) {
|
|
2300
2300
|
return str.split('').sort().join('');
|
|
2301
2301
|
}
|
|
2302
|
-
class BSONRegExp {
|
|
2302
|
+
class BSONRegExp extends BSONValue {
|
|
2303
2303
|
get _bsontype() {
|
|
2304
2304
|
return 'BSONRegExp';
|
|
2305
2305
|
}
|
|
2306
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
2307
|
-
return BSON_MAJOR_VERSION;
|
|
2308
|
-
}
|
|
2309
2306
|
constructor(pattern, options) {
|
|
2307
|
+
super();
|
|
2310
2308
|
this.pattern = pattern;
|
|
2311
2309
|
this.options = alphabetize(options ?? '');
|
|
2312
2310
|
if (this.pattern.indexOf('\x00') !== -1) {
|
|
@@ -2350,7 +2348,7 @@ class BSONRegExp {
|
|
|
2350
2348
|
if ('$regularExpression' in doc) {
|
|
2351
2349
|
return new BSONRegExp(doc.$regularExpression.pattern, BSONRegExp.parseOptions(doc.$regularExpression.options));
|
|
2352
2350
|
}
|
|
2353
|
-
throw new
|
|
2351
|
+
throw new BSONError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`);
|
|
2354
2352
|
}
|
|
2355
2353
|
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
2356
2354
|
return this.inspect();
|
|
@@ -2360,14 +2358,12 @@ class BSONRegExp {
|
|
|
2360
2358
|
}
|
|
2361
2359
|
}
|
|
2362
2360
|
|
|
2363
|
-
class BSONSymbol {
|
|
2361
|
+
class BSONSymbol extends BSONValue {
|
|
2364
2362
|
get _bsontype() {
|
|
2365
2363
|
return 'BSONSymbol';
|
|
2366
2364
|
}
|
|
2367
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
2368
|
-
return BSON_MAJOR_VERSION;
|
|
2369
|
-
}
|
|
2370
2365
|
constructor(value) {
|
|
2366
|
+
super();
|
|
2371
2367
|
this.value = value;
|
|
2372
2368
|
}
|
|
2373
2369
|
valueOf() {
|
|
@@ -2398,9 +2394,6 @@ class Timestamp extends LongWithoutOverridesClass {
|
|
|
2398
2394
|
get _bsontype() {
|
|
2399
2395
|
return 'Timestamp';
|
|
2400
2396
|
}
|
|
2401
|
-
get [Symbol.for('@@mdb.bson.version')]() {
|
|
2402
|
-
return BSON_MAJOR_VERSION;
|
|
2403
|
-
}
|
|
2404
2397
|
constructor(low) {
|
|
2405
2398
|
if (low == null) {
|
|
2406
2399
|
super(0, 0, true);
|
|
@@ -2542,9 +2535,16 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
2542
2535
|
const fieldsAsRaw = options['fieldsAsRaw'] == null ? null : options['fieldsAsRaw'];
|
|
2543
2536
|
const raw = options['raw'] == null ? false : options['raw'];
|
|
2544
2537
|
const bsonRegExp = typeof options['bsonRegExp'] === 'boolean' ? options['bsonRegExp'] : false;
|
|
2545
|
-
const promoteBuffers = options
|
|
2546
|
-
const promoteLongs = options
|
|
2547
|
-
const promoteValues = options
|
|
2538
|
+
const promoteBuffers = options.promoteBuffers ?? false;
|
|
2539
|
+
const promoteLongs = options.promoteLongs ?? true;
|
|
2540
|
+
const promoteValues = options.promoteValues ?? true;
|
|
2541
|
+
const useBigInt64 = options.useBigInt64 ?? false;
|
|
2542
|
+
if (useBigInt64 && !promoteValues) {
|
|
2543
|
+
throw new BSONError('Must either request bigint or Long for int64 deserialization');
|
|
2544
|
+
}
|
|
2545
|
+
if (useBigInt64 && !promoteLongs) {
|
|
2546
|
+
throw new BSONError('Must either request bigint or Long for int64 deserialization');
|
|
2547
|
+
}
|
|
2548
2548
|
const validation = options.validation == null ? { utf8: true } : options.validation;
|
|
2549
2549
|
let globalUTFValidation = true;
|
|
2550
2550
|
let validationSetting;
|
|
@@ -2709,6 +2709,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
2709
2709
|
value = null;
|
|
2710
2710
|
}
|
|
2711
2711
|
else if (elementType === BSON_DATA_LONG) {
|
|
2712
|
+
const dataview = BSONDataView.fromUint8Array(buffer.subarray(index, index + 8));
|
|
2712
2713
|
const lowBits = buffer[index++] |
|
|
2713
2714
|
(buffer[index++] << 8) |
|
|
2714
2715
|
(buffer[index++] << 16) |
|
|
@@ -2718,7 +2719,10 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
2718
2719
|
(buffer[index++] << 16) |
|
|
2719
2720
|
(buffer[index++] << 24);
|
|
2720
2721
|
const long = new Long(lowBits, highBits);
|
|
2721
|
-
if (
|
|
2722
|
+
if (useBigInt64) {
|
|
2723
|
+
value = dataview.getBigInt64(0, true);
|
|
2724
|
+
}
|
|
2725
|
+
else if (promoteLongs && promoteValues === true) {
|
|
2722
2726
|
value =
|
|
2723
2727
|
long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
|
|
2724
2728
|
? long.toNumber()
|
|
@@ -3040,6 +3044,16 @@ function serializeNumber(buffer, key, value, index) {
|
|
|
3040
3044
|
index += bytes.byteLength;
|
|
3041
3045
|
return index;
|
|
3042
3046
|
}
|
|
3047
|
+
function serializeBigInt(buffer, key, value, index) {
|
|
3048
|
+
buffer[index++] = BSON_DATA_LONG;
|
|
3049
|
+
const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
3050
|
+
index += numberOfWrittenBytes;
|
|
3051
|
+
buffer[index++] = 0;
|
|
3052
|
+
NUMBER_SPACE.setBigInt64(0, value, true);
|
|
3053
|
+
buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
|
|
3054
|
+
index += EIGHT_BYTE_VIEW_ON_NUMBER.byteLength;
|
|
3055
|
+
return index;
|
|
3056
|
+
}
|
|
3043
3057
|
function serializeNull(buffer, key, _, index) {
|
|
3044
3058
|
buffer[index++] = BSON_DATA_NULL;
|
|
3045
3059
|
const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
@@ -3079,7 +3093,7 @@ function serializeRegExp(buffer, key, value, index) {
|
|
|
3079
3093
|
index = index + numberOfWrittenBytes;
|
|
3080
3094
|
buffer[index++] = 0;
|
|
3081
3095
|
if (value.source && value.source.match(regexp) != null) {
|
|
3082
|
-
throw
|
|
3096
|
+
throw new BSONError('value ' + value.source + ' must not contain null bytes');
|
|
3083
3097
|
}
|
|
3084
3098
|
index = index + ByteUtils.encodeUTF8Into(buffer, value.source, index);
|
|
3085
3099
|
buffer[index++] = 0x00;
|
|
@@ -3098,7 +3112,7 @@ function serializeBSONRegExp(buffer, key, value, index) {
|
|
|
3098
3112
|
index = index + numberOfWrittenBytes;
|
|
3099
3113
|
buffer[index++] = 0;
|
|
3100
3114
|
if (value.pattern.match(regexp) != null) {
|
|
3101
|
-
throw
|
|
3115
|
+
throw new BSONError('pattern ' + value.pattern + ' must not contain null bytes');
|
|
3102
3116
|
}
|
|
3103
3117
|
index = index + ByteUtils.encodeUTF8Into(buffer, value.pattern, index);
|
|
3104
3118
|
buffer[index++] = 0x00;
|
|
@@ -3131,7 +3145,7 @@ function serializeObjectId(buffer, key, value, index) {
|
|
|
3131
3145
|
buffer.set(value.id.subarray(0, 12), index);
|
|
3132
3146
|
}
|
|
3133
3147
|
else {
|
|
3134
|
-
throw new
|
|
3148
|
+
throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
|
|
3135
3149
|
}
|
|
3136
3150
|
return index + 12;
|
|
3137
3151
|
}
|
|
@@ -3371,7 +3385,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3371
3385
|
index = serializeNumber(buffer, key, value, index);
|
|
3372
3386
|
}
|
|
3373
3387
|
else if (typeof value === 'bigint') {
|
|
3374
|
-
|
|
3388
|
+
index = serializeBigInt(buffer, key, value, index);
|
|
3375
3389
|
}
|
|
3376
3390
|
else if (typeof value === 'boolean') {
|
|
3377
3391
|
index = serializeBoolean(buffer, key, value, index);
|
|
@@ -3394,8 +3408,9 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3394
3408
|
else if (typeof value === 'object' && value._bsontype == null) {
|
|
3395
3409
|
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
3396
3410
|
}
|
|
3397
|
-
else if (typeof value === 'object' &&
|
|
3398
|
-
|
|
3411
|
+
else if (typeof value === 'object' &&
|
|
3412
|
+
value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
|
|
3413
|
+
throw new BSONVersionError();
|
|
3399
3414
|
}
|
|
3400
3415
|
else if (value._bsontype === 'ObjectId') {
|
|
3401
3416
|
index = serializeObjectId(buffer, key, value, index);
|
|
@@ -3434,7 +3449,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3434
3449
|
index = serializeMinMax(buffer, key, value, index);
|
|
3435
3450
|
}
|
|
3436
3451
|
else if (typeof value._bsontype !== 'undefined') {
|
|
3437
|
-
throw new
|
|
3452
|
+
throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
|
|
3438
3453
|
}
|
|
3439
3454
|
}
|
|
3440
3455
|
}
|
|
@@ -3447,18 +3462,21 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3447
3462
|
if (done)
|
|
3448
3463
|
continue;
|
|
3449
3464
|
const key = entry.value[0];
|
|
3450
|
-
|
|
3465
|
+
let value = entry.value[1];
|
|
3466
|
+
if (typeof value?.toBSON === 'function') {
|
|
3467
|
+
value = value.toBSON();
|
|
3468
|
+
}
|
|
3451
3469
|
const type = typeof value;
|
|
3452
3470
|
if (typeof key === 'string' && !ignoreKeys.has(key)) {
|
|
3453
3471
|
if (key.match(regexp) != null) {
|
|
3454
|
-
throw
|
|
3472
|
+
throw new BSONError('key ' + key + ' must not contain null bytes');
|
|
3455
3473
|
}
|
|
3456
3474
|
if (checkKeys) {
|
|
3457
3475
|
if ('$' === key[0]) {
|
|
3458
|
-
throw
|
|
3476
|
+
throw new BSONError('key ' + key + " must not start with '$'");
|
|
3459
3477
|
}
|
|
3460
3478
|
else if (~key.indexOf('.')) {
|
|
3461
|
-
throw
|
|
3479
|
+
throw new BSONError('key ' + key + " must not contain '.'");
|
|
3462
3480
|
}
|
|
3463
3481
|
}
|
|
3464
3482
|
}
|
|
@@ -3468,8 +3486,8 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3468
3486
|
else if (type === 'number') {
|
|
3469
3487
|
index = serializeNumber(buffer, key, value, index);
|
|
3470
3488
|
}
|
|
3471
|
-
else if (type === 'bigint'
|
|
3472
|
-
|
|
3489
|
+
else if (type === 'bigint') {
|
|
3490
|
+
index = serializeBigInt(buffer, key, value, index);
|
|
3473
3491
|
}
|
|
3474
3492
|
else if (type === 'boolean') {
|
|
3475
3493
|
index = serializeBoolean(buffer, key, value, index);
|
|
@@ -3489,8 +3507,9 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3489
3507
|
else if (type === 'object' && value._bsontype == null) {
|
|
3490
3508
|
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
3491
3509
|
}
|
|
3492
|
-
else if (typeof value === 'object' &&
|
|
3493
|
-
|
|
3510
|
+
else if (typeof value === 'object' &&
|
|
3511
|
+
value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
|
|
3512
|
+
throw new BSONVersionError();
|
|
3494
3513
|
}
|
|
3495
3514
|
else if (value._bsontype === 'ObjectId') {
|
|
3496
3515
|
index = serializeObjectId(buffer, key, value, index);
|
|
@@ -3529,7 +3548,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3529
3548
|
index = serializeMinMax(buffer, key, value, index);
|
|
3530
3549
|
}
|
|
3531
3550
|
else if (typeof value._bsontype !== 'undefined') {
|
|
3532
|
-
throw new
|
|
3551
|
+
throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
|
|
3533
3552
|
}
|
|
3534
3553
|
}
|
|
3535
3554
|
}
|
|
@@ -3537,7 +3556,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3537
3556
|
if (typeof object?.toBSON === 'function') {
|
|
3538
3557
|
object = object.toBSON();
|
|
3539
3558
|
if (object != null && typeof object !== 'object') {
|
|
3540
|
-
throw new
|
|
3559
|
+
throw new BSONError('toBSON function did not return an object');
|
|
3541
3560
|
}
|
|
3542
3561
|
}
|
|
3543
3562
|
for (const key of Object.keys(object)) {
|
|
@@ -3548,14 +3567,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3548
3567
|
const type = typeof value;
|
|
3549
3568
|
if (typeof key === 'string' && !ignoreKeys.has(key)) {
|
|
3550
3569
|
if (key.match(regexp) != null) {
|
|
3551
|
-
throw
|
|
3570
|
+
throw new BSONError('key ' + key + ' must not contain null bytes');
|
|
3552
3571
|
}
|
|
3553
3572
|
if (checkKeys) {
|
|
3554
3573
|
if ('$' === key[0]) {
|
|
3555
|
-
throw
|
|
3574
|
+
throw new BSONError('key ' + key + " must not start with '$'");
|
|
3556
3575
|
}
|
|
3557
3576
|
else if (~key.indexOf('.')) {
|
|
3558
|
-
throw
|
|
3577
|
+
throw new BSONError('key ' + key + " must not contain '.'");
|
|
3559
3578
|
}
|
|
3560
3579
|
}
|
|
3561
3580
|
}
|
|
@@ -3566,7 +3585,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3566
3585
|
index = serializeNumber(buffer, key, value, index);
|
|
3567
3586
|
}
|
|
3568
3587
|
else if (type === 'bigint') {
|
|
3569
|
-
|
|
3588
|
+
index = serializeBigInt(buffer, key, value, index);
|
|
3570
3589
|
}
|
|
3571
3590
|
else if (type === 'boolean') {
|
|
3572
3591
|
index = serializeBoolean(buffer, key, value, index);
|
|
@@ -3590,8 +3609,9 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3590
3609
|
else if (type === 'object' && value._bsontype == null) {
|
|
3591
3610
|
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
3592
3611
|
}
|
|
3593
|
-
else if (typeof value === 'object' &&
|
|
3594
|
-
|
|
3612
|
+
else if (typeof value === 'object' &&
|
|
3613
|
+
value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
|
|
3614
|
+
throw new BSONVersionError();
|
|
3595
3615
|
}
|
|
3596
3616
|
else if (value._bsontype === 'ObjectId') {
|
|
3597
3617
|
index = serializeObjectId(buffer, key, value, index);
|
|
@@ -3630,7 +3650,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3630
3650
|
index = serializeMinMax(buffer, key, value, index);
|
|
3631
3651
|
}
|
|
3632
3652
|
else if (typeof value._bsontype !== 'undefined') {
|
|
3633
|
-
throw new
|
|
3653
|
+
throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
|
|
3634
3654
|
}
|
|
3635
3655
|
}
|
|
3636
3656
|
}
|
|
@@ -3667,14 +3687,19 @@ const keysToCodecs = {
|
|
|
3667
3687
|
};
|
|
3668
3688
|
function deserializeValue(value, options = {}) {
|
|
3669
3689
|
if (typeof value === 'number') {
|
|
3690
|
+
const in32BitRange = value <= BSON_INT32_MAX && value >= BSON_INT32_MIN;
|
|
3691
|
+
const in64BitRange = value <= BSON_INT64_MAX && value >= BSON_INT64_MIN;
|
|
3670
3692
|
if (options.relaxed || options.legacy) {
|
|
3671
3693
|
return value;
|
|
3672
3694
|
}
|
|
3673
3695
|
if (Number.isInteger(value) && !Object.is(value, -0)) {
|
|
3674
|
-
if (
|
|
3696
|
+
if (in32BitRange) {
|
|
3675
3697
|
return new Int32(value);
|
|
3676
3698
|
}
|
|
3677
|
-
if (
|
|
3699
|
+
if (in64BitRange) {
|
|
3700
|
+
if (options.useBigInt64) {
|
|
3701
|
+
return BigInt(value);
|
|
3702
|
+
}
|
|
3678
3703
|
return Long.fromNumber(value);
|
|
3679
3704
|
}
|
|
3680
3705
|
}
|
|
@@ -3764,7 +3789,7 @@ function serializeValue(value, options) {
|
|
|
3764
3789
|
const current = props[props.length - 1];
|
|
3765
3790
|
const leadingSpace = ' '.repeat(leadingPart.length + alreadySeen.length / 2);
|
|
3766
3791
|
const dashes = '-'.repeat(circularPart.length + (alreadySeen.length + current.length) / 2 - 1);
|
|
3767
|
-
throw new
|
|
3792
|
+
throw new BSONError('Converting circular structure to EJSON:\n' +
|
|
3768
3793
|
` ${leadingPart}${alreadySeen}${circularPart}${current}\n` +
|
|
3769
3794
|
` ${leadingSpace}\\${dashes}/`);
|
|
3770
3795
|
}
|
|
@@ -3796,6 +3821,12 @@ function serializeValue(value, options) {
|
|
|
3796
3821
|
}
|
|
3797
3822
|
return { $numberDouble: Object.is(value, -0) ? '-0.0' : value.toString() };
|
|
3798
3823
|
}
|
|
3824
|
+
if (typeof value === 'bigint') {
|
|
3825
|
+
if (!options.relaxed) {
|
|
3826
|
+
return { $numberLong: BigInt.asIntN(64, value).toString() };
|
|
3827
|
+
}
|
|
3828
|
+
return Number(BigInt.asIntN(64, value));
|
|
3829
|
+
}
|
|
3799
3830
|
if (value instanceof RegExp || isRegExp(value)) {
|
|
3800
3831
|
let flags = value.flags;
|
|
3801
3832
|
if (flags === undefined) {
|
|
@@ -3857,15 +3888,15 @@ function serializeDocument(doc, options) {
|
|
|
3857
3888
|
else if (doc != null &&
|
|
3858
3889
|
typeof doc === 'object' &&
|
|
3859
3890
|
typeof doc._bsontype === 'string' &&
|
|
3860
|
-
doc[Symbol.for('@@mdb.bson.version')]
|
|
3861
|
-
throw new
|
|
3891
|
+
doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
|
|
3892
|
+
throw new BSONVersionError();
|
|
3862
3893
|
}
|
|
3863
3894
|
else if (isBSONType(doc)) {
|
|
3864
3895
|
let outDoc = doc;
|
|
3865
3896
|
if (typeof outDoc.toExtendedJSON !== 'function') {
|
|
3866
3897
|
const mapper = BSON_TYPE_MAPPINGS[doc._bsontype];
|
|
3867
3898
|
if (!mapper) {
|
|
3868
|
-
throw new
|
|
3899
|
+
throw new BSONError('Unrecognized or invalid _bsontype: ' + doc._bsontype);
|
|
3869
3900
|
}
|
|
3870
3901
|
outDoc = mapper(outDoc);
|
|
3871
3902
|
}
|
|
@@ -3882,11 +3913,16 @@ function serializeDocument(doc, options) {
|
|
|
3882
3913
|
}
|
|
3883
3914
|
}
|
|
3884
3915
|
function parse(text, options) {
|
|
3916
|
+
const ejsonOptions = {
|
|
3917
|
+
useBigInt64: options?.useBigInt64 ?? false,
|
|
3918
|
+
relaxed: options?.relaxed ?? true,
|
|
3919
|
+
legacy: options?.legacy ?? false
|
|
3920
|
+
};
|
|
3885
3921
|
return JSON.parse(text, (key, value) => {
|
|
3886
3922
|
if (key.indexOf('\x00') !== -1) {
|
|
3887
3923
|
throw new BSONError(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`);
|
|
3888
3924
|
}
|
|
3889
|
-
return deserializeValue(value,
|
|
3925
|
+
return deserializeValue(value, ejsonOptions);
|
|
3890
3926
|
});
|
|
3891
3927
|
}
|
|
3892
3928
|
function stringify(value, replacer, space, options) {
|
|
@@ -3996,8 +4032,9 @@ serializeWithBufferAndIndex: serializeWithBufferAndIndex,
|
|
|
3996
4032
|
deserialize: deserialize,
|
|
3997
4033
|
calculateObjectSize: calculateObjectSize,
|
|
3998
4034
|
deserializeStream: deserializeStream,
|
|
4035
|
+
BSONValue: BSONValue,
|
|
3999
4036
|
BSONError: BSONError,
|
|
4000
|
-
|
|
4037
|
+
BSONVersionError: BSONVersionError,
|
|
4001
4038
|
BSONType: BSONType,
|
|
4002
4039
|
EJSON: EJSON
|
|
4003
4040
|
});
|
|
@@ -4007,7 +4044,8 @@ exports.BSONError = BSONError;
|
|
|
4007
4044
|
exports.BSONRegExp = BSONRegExp;
|
|
4008
4045
|
exports.BSONSymbol = BSONSymbol;
|
|
4009
4046
|
exports.BSONType = BSONType;
|
|
4010
|
-
exports.
|
|
4047
|
+
exports.BSONValue = BSONValue;
|
|
4048
|
+
exports.BSONVersionError = BSONVersionError;
|
|
4011
4049
|
exports.Binary = Binary;
|
|
4012
4050
|
exports.Code = Code;
|
|
4013
4051
|
exports.DBRef = DBRef;
|