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