bson 4.7.0 → 5.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bson.d.ts +207 -259
- package/lib/bson.bundle.js +4033 -0
- package/lib/bson.bundle.js.map +1 -0
- package/lib/bson.cjs +4028 -0
- package/lib/bson.cjs.map +1 -0
- package/lib/bson.mjs +4002 -0
- package/lib/bson.mjs.map +1 -0
- package/package.json +49 -62
- package/src/binary.ts +63 -52
- package/src/bson.ts +27 -108
- package/src/code.ts +24 -14
- package/src/constants.ts +28 -0
- package/src/db_ref.ts +13 -8
- package/src/decimal128.ts +31 -25
- package/src/double.ts +7 -5
- package/src/error.ts +0 -2
- package/src/extended_json.ts +148 -148
- package/src/index.ts +19 -0
- package/src/int_32.ts +7 -5
- package/src/long.ts +16 -16
- package/src/max_key.ts +6 -6
- package/src/min_key.ts +6 -6
- package/src/objectid.ts +41 -74
- package/src/parser/calculate_size.ts +39 -63
- package/src/parser/deserializer.ts +41 -112
- package/src/parser/serializer.ts +234 -341
- package/src/parser/utils.ts +1 -99
- package/src/regexp.ts +16 -5
- package/src/symbol.ts +7 -5
- package/src/timestamp.ts +62 -27
- package/src/utils/byte_utils.ts +61 -0
- package/src/utils/node_byte_utils.ts +141 -0
- package/src/utils/web_byte_utils.ts +190 -0
- package/src/uuid_utils.ts +15 -15
- package/bower.json +0 -26
- package/dist/bson.browser.esm.js +0 -7470
- package/dist/bson.browser.esm.js.map +0 -1
- package/dist/bson.browser.umd.js +0 -7537
- package/dist/bson.browser.umd.js.map +0 -1
- package/dist/bson.bundle.js +0 -7536
- package/dist/bson.bundle.js.map +0 -1
- package/dist/bson.esm.js +0 -5436
- package/dist/bson.esm.js.map +0 -1
- package/lib/binary.js +0 -426
- package/lib/binary.js.map +0 -1
- package/lib/bson.js +0 -251
- package/lib/bson.js.map +0 -1
- package/lib/code.js +0 -46
- package/lib/code.js.map +0 -1
- package/lib/constants.js +0 -82
- package/lib/constants.js.map +0 -1
- package/lib/db_ref.js +0 -97
- package/lib/db_ref.js.map +0 -1
- package/lib/decimal128.js +0 -669
- package/lib/decimal128.js.map +0 -1
- package/lib/double.js +0 -76
- package/lib/double.js.map +0 -1
- package/lib/ensure_buffer.js +0 -25
- package/lib/ensure_buffer.js.map +0 -1
- package/lib/error.js +0 -55
- package/lib/error.js.map +0 -1
- package/lib/extended_json.js +0 -390
- package/lib/extended_json.js.map +0 -1
- package/lib/int_32.js +0 -58
- package/lib/int_32.js.map +0 -1
- package/lib/long.js +0 -900
- package/lib/long.js.map +0 -1
- package/lib/map.js +0 -123
- package/lib/map.js.map +0 -1
- package/lib/max_key.js +0 -33
- package/lib/max_key.js.map +0 -1
- package/lib/min_key.js +0 -33
- package/lib/min_key.js.map +0 -1
- package/lib/objectid.js +0 -299
- package/lib/objectid.js.map +0 -1
- package/lib/parser/calculate_size.js +0 -194
- package/lib/parser/calculate_size.js.map +0 -1
- package/lib/parser/deserializer.js +0 -665
- package/lib/parser/deserializer.js.map +0 -1
- package/lib/parser/serializer.js +0 -867
- package/lib/parser/serializer.js.map +0 -1
- package/lib/parser/utils.js +0 -115
- package/lib/parser/utils.js.map +0 -1
- package/lib/regexp.js +0 -74
- package/lib/regexp.js.map +0 -1
- package/lib/symbol.js +0 -48
- package/lib/symbol.js.map +0 -1
- package/lib/timestamp.js +0 -102
- package/lib/timestamp.js.map +0 -1
- package/lib/utils/global.js +0 -18
- package/lib/utils/global.js.map +0 -1
- package/lib/uuid_utils.js +0 -35
- package/lib/uuid_utils.js.map +0 -1
- package/lib/validate_utf8.js +0 -47
- package/lib/validate_utf8.js.map +0 -1
- package/src/ensure_buffer.ts +0 -27
- package/src/map.ts +0 -119
- package/src/utils/global.ts +0 -22
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Buffer } from 'buffer';
|
|
2
1
|
import { Binary } from '../binary';
|
|
3
2
|
import type { Document } from '../bson';
|
|
4
3
|
import { Code } from '../code';
|
|
@@ -15,20 +14,11 @@ import { ObjectId } from '../objectid';
|
|
|
15
14
|
import { BSONRegExp } from '../regexp';
|
|
16
15
|
import { BSONSymbol } from '../symbol';
|
|
17
16
|
import { Timestamp } from '../timestamp';
|
|
17
|
+
import { ByteUtils } from '../utils/byte_utils';
|
|
18
18
|
import { validateUtf8 } from '../validate_utf8';
|
|
19
19
|
|
|
20
20
|
/** @public */
|
|
21
21
|
export interface DeserializeOptions {
|
|
22
|
-
/** evaluate functions in the BSON document scoped to the object deserialized. */
|
|
23
|
-
evalFunctions?: boolean;
|
|
24
|
-
/** cache evaluated functions for reuse. */
|
|
25
|
-
cacheFunctions?: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* use a crc32 code for caching, otherwise use the string of the function.
|
|
28
|
-
* @deprecated this option to use the crc32 function never worked as intended
|
|
29
|
-
* due to the fact that the crc32 function itself was never implemented.
|
|
30
|
-
* */
|
|
31
|
-
cacheFunctionsCrc32?: boolean;
|
|
32
22
|
/** when deserializing a Long will fit it into a Number if it's smaller than 53 bits */
|
|
33
23
|
promoteLongs?: boolean;
|
|
34
24
|
/** when deserializing a Binary will return it as a node.js Buffer instance. */
|
|
@@ -67,10 +57,8 @@ export interface DeserializeOptions {
|
|
|
67
57
|
const JS_INT_MAX_LONG = Long.fromNumber(constants.JS_INT_MAX);
|
|
68
58
|
const JS_INT_MIN_LONG = Long.fromNumber(constants.JS_INT_MIN);
|
|
69
59
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
export function deserialize(
|
|
73
|
-
buffer: Buffer,
|
|
60
|
+
export function internalDeserialize(
|
|
61
|
+
buffer: Uint8Array,
|
|
74
62
|
options: DeserializeOptions,
|
|
75
63
|
isArray?: boolean
|
|
76
64
|
): Document {
|
|
@@ -115,14 +103,11 @@ export function deserialize(
|
|
|
115
103
|
const allowedDBRefKeys = /^\$ref$|^\$id$|^\$db$/;
|
|
116
104
|
|
|
117
105
|
function deserializeObject(
|
|
118
|
-
buffer:
|
|
106
|
+
buffer: Uint8Array,
|
|
119
107
|
index: number,
|
|
120
108
|
options: DeserializeOptions,
|
|
121
109
|
isArray = false
|
|
122
110
|
) {
|
|
123
|
-
const evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions'];
|
|
124
|
-
const cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions'];
|
|
125
|
-
|
|
126
111
|
const fieldsAsRaw = options['fieldsAsRaw'] == null ? null : options['fieldsAsRaw'];
|
|
127
112
|
|
|
128
113
|
// Return raw bson buffer instead of parsing it
|
|
@@ -216,7 +201,7 @@ function deserializeObject(
|
|
|
216
201
|
if (i >= buffer.byteLength) throw new BSONError('Bad BSON Document: illegal CString');
|
|
217
202
|
|
|
218
203
|
// Represents the key
|
|
219
|
-
const name = isArray ? arrayIndex++ : buffer.
|
|
204
|
+
const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer.subarray(index, i));
|
|
220
205
|
|
|
221
206
|
// shouldValidateKey is true if the key should be validated, false otherwise
|
|
222
207
|
let shouldValidateKey = true;
|
|
@@ -249,8 +234,8 @@ function deserializeObject(
|
|
|
249
234
|
value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
|
|
250
235
|
index = index + stringSize;
|
|
251
236
|
} else if (elementType === constants.BSON_DATA_OID) {
|
|
252
|
-
const oid =
|
|
253
|
-
buffer.
|
|
237
|
+
const oid = ByteUtils.allocate(12);
|
|
238
|
+
oid.set(buffer.subarray(index, index + 12));
|
|
254
239
|
value = new ObjectId(oid);
|
|
255
240
|
index = index + 12;
|
|
256
241
|
} else if (elementType === constants.BSON_DATA_INT && promoteValues === false) {
|
|
@@ -314,23 +299,16 @@ function deserializeObject(
|
|
|
314
299
|
(buffer[index + 1] << 8) |
|
|
315
300
|
(buffer[index + 2] << 16) |
|
|
316
301
|
(buffer[index + 3] << 24);
|
|
317
|
-
let arrayOptions = options;
|
|
302
|
+
let arrayOptions: DeserializeOptions = options;
|
|
318
303
|
|
|
319
304
|
// Stop index
|
|
320
305
|
const stopIndex = index + objectSize;
|
|
321
306
|
|
|
322
307
|
// All elements of array to be returned as raw bson
|
|
323
308
|
if (fieldsAsRaw && fieldsAsRaw[name]) {
|
|
324
|
-
arrayOptions = {};
|
|
325
|
-
for (const n in options) {
|
|
326
|
-
(
|
|
327
|
-
arrayOptions as {
|
|
328
|
-
[key: string]: DeserializeOptions[keyof DeserializeOptions];
|
|
329
|
-
}
|
|
330
|
-
)[n] = options[n as keyof DeserializeOptions];
|
|
331
|
-
}
|
|
332
|
-
arrayOptions['raw'] = true;
|
|
309
|
+
arrayOptions = { ...options, raw: true };
|
|
333
310
|
}
|
|
311
|
+
|
|
334
312
|
if (!globalUTFValidation) {
|
|
335
313
|
arrayOptions = { ...arrayOptions, validation: { utf8: shouldValidateKey } };
|
|
336
314
|
}
|
|
@@ -367,19 +345,13 @@ function deserializeObject(
|
|
|
367
345
|
}
|
|
368
346
|
} else if (elementType === constants.BSON_DATA_DECIMAL128) {
|
|
369
347
|
// Buffer to contain the decimal bytes
|
|
370
|
-
const bytes =
|
|
348
|
+
const bytes = ByteUtils.allocate(16);
|
|
371
349
|
// Copy the next 16 bytes into the bytes buffer
|
|
372
|
-
buffer.
|
|
350
|
+
bytes.set(buffer.subarray(index, index + 16), 0);
|
|
373
351
|
// Update index
|
|
374
352
|
index = index + 16;
|
|
375
353
|
// Assign the new Decimal128 value
|
|
376
|
-
|
|
377
|
-
// If we have an alternative mapper use that
|
|
378
|
-
if ('toObject' in decimal128 && typeof decimal128.toObject === 'function') {
|
|
379
|
-
value = decimal128.toObject();
|
|
380
|
-
} else {
|
|
381
|
-
value = decimal128;
|
|
382
|
-
}
|
|
354
|
+
value = new Decimal128(bytes);
|
|
383
355
|
} else if (elementType === constants.BSON_DATA_BINARY) {
|
|
384
356
|
let binarySize =
|
|
385
357
|
buffer[index++] |
|
|
@@ -414,7 +386,7 @@ function deserializeObject(
|
|
|
414
386
|
}
|
|
415
387
|
|
|
416
388
|
if (promoteBuffers && promoteValues) {
|
|
417
|
-
value = buffer.slice(index, index + binarySize);
|
|
389
|
+
value = ByteUtils.toLocalBufferType(buffer.slice(index, index + binarySize));
|
|
418
390
|
} else {
|
|
419
391
|
value = new Binary(buffer.slice(index, index + binarySize), subType);
|
|
420
392
|
if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW) {
|
|
@@ -422,7 +394,7 @@ function deserializeObject(
|
|
|
422
394
|
}
|
|
423
395
|
}
|
|
424
396
|
} else {
|
|
425
|
-
const _buffer =
|
|
397
|
+
const _buffer = ByteUtils.allocate(binarySize);
|
|
426
398
|
// If we have subtype 2 skip the 4 bytes for the size
|
|
427
399
|
if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
|
|
428
400
|
binarySize =
|
|
@@ -464,7 +436,7 @@ function deserializeObject(
|
|
|
464
436
|
// If are at the end of the buffer there is a problem with the document
|
|
465
437
|
if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString');
|
|
466
438
|
// Return the C string
|
|
467
|
-
const source = buffer.
|
|
439
|
+
const source = ByteUtils.toUTF8(buffer.subarray(index, i));
|
|
468
440
|
// Create the regexp
|
|
469
441
|
index = i + 1;
|
|
470
442
|
|
|
@@ -477,7 +449,7 @@ function deserializeObject(
|
|
|
477
449
|
// If are at the end of the buffer there is a problem with the document
|
|
478
450
|
if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString');
|
|
479
451
|
// Return the C string
|
|
480
|
-
const regExpOptions = buffer.
|
|
452
|
+
const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i));
|
|
481
453
|
index = i + 1;
|
|
482
454
|
|
|
483
455
|
// For each option add the corresponding one for javascript
|
|
@@ -509,7 +481,7 @@ function deserializeObject(
|
|
|
509
481
|
// If are at the end of the buffer there is a problem with the document
|
|
510
482
|
if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString');
|
|
511
483
|
// Return the C string
|
|
512
|
-
const source = buffer.
|
|
484
|
+
const source = ByteUtils.toUTF8(buffer.subarray(index, i));
|
|
513
485
|
index = i + 1;
|
|
514
486
|
|
|
515
487
|
// Get the start search index
|
|
@@ -521,7 +493,7 @@ function deserializeObject(
|
|
|
521
493
|
// If are at the end of the buffer there is a problem with the document
|
|
522
494
|
if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString');
|
|
523
495
|
// Return the C string
|
|
524
|
-
const regExpOptions = buffer.
|
|
496
|
+
const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i));
|
|
525
497
|
index = i + 1;
|
|
526
498
|
|
|
527
499
|
// Set the object
|
|
@@ -543,18 +515,21 @@ function deserializeObject(
|
|
|
543
515
|
value = promoteValues ? symbol : new BSONSymbol(symbol);
|
|
544
516
|
index = index + stringSize;
|
|
545
517
|
} else if (elementType === constants.BSON_DATA_TIMESTAMP) {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
buffer[index++]
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
518
|
+
// We intentionally **do not** use bit shifting here
|
|
519
|
+
// Bit shifting in javascript coerces numbers to **signed** int32s
|
|
520
|
+
// We need to keep i, and t unsigned
|
|
521
|
+
const i =
|
|
522
|
+
buffer[index++] +
|
|
523
|
+
buffer[index++] * (1 << 8) +
|
|
524
|
+
buffer[index++] * (1 << 16) +
|
|
525
|
+
buffer[index++] * (1 << 24);
|
|
526
|
+
const t =
|
|
527
|
+
buffer[index++] +
|
|
528
|
+
buffer[index++] * (1 << 8) +
|
|
529
|
+
buffer[index++] * (1 << 16) +
|
|
530
|
+
buffer[index++] * (1 << 24);
|
|
531
|
+
|
|
532
|
+
value = new Timestamp({ i, t });
|
|
558
533
|
} else if (elementType === constants.BSON_DATA_MIN_KEY) {
|
|
559
534
|
value = new MinKey();
|
|
560
535
|
} else if (elementType === constants.BSON_DATA_MAX_KEY) {
|
|
@@ -579,18 +554,7 @@ function deserializeObject(
|
|
|
579
554
|
shouldValidateKey
|
|
580
555
|
);
|
|
581
556
|
|
|
582
|
-
|
|
583
|
-
if (evalFunctions) {
|
|
584
|
-
// If we have cache enabled let's look for the md5 of the function in the cache
|
|
585
|
-
if (cacheFunctions) {
|
|
586
|
-
// Got to do this to avoid V8 deoptimizing the call due to finding eval
|
|
587
|
-
value = isolateEval(functionString, functionCache, object);
|
|
588
|
-
} else {
|
|
589
|
-
value = isolateEval(functionString);
|
|
590
|
-
}
|
|
591
|
-
} else {
|
|
592
|
-
value = new Code(functionString);
|
|
593
|
-
}
|
|
557
|
+
value = new Code(functionString);
|
|
594
558
|
|
|
595
559
|
// Update parse index position
|
|
596
560
|
index = index + stringSize;
|
|
@@ -653,20 +617,7 @@ function deserializeObject(
|
|
|
653
617
|
throw new BSONError('code_w_scope total size is too long, clips outer document');
|
|
654
618
|
}
|
|
655
619
|
|
|
656
|
-
|
|
657
|
-
if (evalFunctions) {
|
|
658
|
-
// If we have cache enabled let's look for the md5 of the function in the cache
|
|
659
|
-
if (cacheFunctions) {
|
|
660
|
-
// Got to do this to avoid V8 deoptimizing the call due to finding eval
|
|
661
|
-
value = isolateEval(functionString, functionCache, object);
|
|
662
|
-
} else {
|
|
663
|
-
value = isolateEval(functionString);
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
value.scope = scopeObject;
|
|
667
|
-
} else {
|
|
668
|
-
value = new Code(functionString, scopeObject);
|
|
669
|
-
}
|
|
620
|
+
value = new Code(functionString, scopeObject);
|
|
670
621
|
} else if (elementType === constants.BSON_DATA_DBPOINTER) {
|
|
671
622
|
// Get the code string size
|
|
672
623
|
const stringSize =
|
|
@@ -687,13 +638,13 @@ function deserializeObject(
|
|
|
687
638
|
throw new BSONError('Invalid UTF-8 string in BSON document');
|
|
688
639
|
}
|
|
689
640
|
}
|
|
690
|
-
const namespace = buffer.
|
|
641
|
+
const namespace = ByteUtils.toUTF8(buffer.subarray(index, index + stringSize - 1));
|
|
691
642
|
// Update parse index position
|
|
692
643
|
index = index + stringSize;
|
|
693
644
|
|
|
694
645
|
// Read the oid
|
|
695
|
-
const oidBuffer =
|
|
696
|
-
buffer.
|
|
646
|
+
const oidBuffer = ByteUtils.allocate(12);
|
|
647
|
+
oidBuffer.set(buffer.subarray(index, index + 12), 0);
|
|
697
648
|
const oid = new ObjectId(oidBuffer);
|
|
698
649
|
|
|
699
650
|
// Update the index
|
|
@@ -738,35 +689,13 @@ function deserializeObject(
|
|
|
738
689
|
return object;
|
|
739
690
|
}
|
|
740
691
|
|
|
741
|
-
/**
|
|
742
|
-
* Ensure eval is isolated, store the result in functionCache.
|
|
743
|
-
*
|
|
744
|
-
* @internal
|
|
745
|
-
*/
|
|
746
|
-
function isolateEval(
|
|
747
|
-
functionString: string,
|
|
748
|
-
functionCache?: { [hash: string]: Function },
|
|
749
|
-
object?: Document
|
|
750
|
-
) {
|
|
751
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
752
|
-
if (!functionCache) return new Function(functionString);
|
|
753
|
-
// Check for cache hit, eval if missing and return cached function
|
|
754
|
-
if (functionCache[functionString] == null) {
|
|
755
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
756
|
-
functionCache[functionString] = new Function(functionString);
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
// Set the object
|
|
760
|
-
return functionCache[functionString].bind(object);
|
|
761
|
-
}
|
|
762
|
-
|
|
763
692
|
function getValidatedString(
|
|
764
|
-
buffer:
|
|
693
|
+
buffer: Uint8Array,
|
|
765
694
|
start: number,
|
|
766
695
|
end: number,
|
|
767
696
|
shouldValidateUtf8: boolean
|
|
768
697
|
) {
|
|
769
|
-
const value = buffer.
|
|
698
|
+
const value = ByteUtils.toUTF8(buffer.subarray(start, end));
|
|
770
699
|
// if utf8 validation is on, do the check
|
|
771
700
|
if (shouldValidateUtf8) {
|
|
772
701
|
for (let i = 0; i < value.length; i++) {
|