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