bson 7.1.1 → 7.3.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/README.md +8 -2
- package/bson.d.ts +156 -10
- package/lib/bson.bundle.js +479 -453
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +479 -453
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +479 -453
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.node.mjs +479 -453
- package/lib/bson.node.mjs.map +1 -1
- package/lib/bson.rn.cjs +480 -456
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +1 -1
- package/src/binary.ts +2 -2
- package/src/bson.ts +6 -3
- package/src/extended_json.ts +63 -22
- package/src/objectid.ts +24 -10
- package/src/parser/calculate_size.ts +75 -68
- package/src/parser/deserializer.ts +227 -61
- package/src/parser/serializer.ts +272 -478
- package/src/timestamp.ts +157 -4
- package/src/utils/byte_utils.ts +8 -0
- package/src/utils/node_byte_utils.ts +12 -0
- package/src/utils/web_byte_utils.ts +43 -0
package/lib/bson.rn.cjs
CHANGED
|
@@ -269,6 +269,11 @@ const nodeJsByteUtils = {
|
|
|
269
269
|
concat(list) {
|
|
270
270
|
return Buffer.concat(list);
|
|
271
271
|
},
|
|
272
|
+
copy(source, target, targetStart, sourceStart, sourceEnd) {
|
|
273
|
+
return nodeJsByteUtils
|
|
274
|
+
.toLocalBufferType(source)
|
|
275
|
+
.copy(target, targetStart ?? 0, sourceStart ?? 0, sourceEnd ?? source.length);
|
|
276
|
+
},
|
|
272
277
|
equals(a, b) {
|
|
273
278
|
return nodeJsByteUtils.toLocalBufferType(a).equals(b);
|
|
274
279
|
},
|
|
@@ -413,6 +418,27 @@ const webByteUtils = {
|
|
|
413
418
|
}
|
|
414
419
|
return result;
|
|
415
420
|
},
|
|
421
|
+
copy(source, target, targetStart, sourceStart, sourceEnd) {
|
|
422
|
+
if (sourceEnd !== undefined && sourceEnd < 0) {
|
|
423
|
+
throw new RangeError(`The value of "sourceEnd" is out of range. It must be >= 0. Received ${sourceEnd}`);
|
|
424
|
+
}
|
|
425
|
+
sourceEnd = sourceEnd ?? source.length;
|
|
426
|
+
if (sourceStart !== undefined && (sourceStart < 0 || sourceStart > sourceEnd)) {
|
|
427
|
+
throw new RangeError(`The value of "sourceStart" is out of range. It must be >= 0 and <= ${sourceEnd}. Received ${sourceStart}`);
|
|
428
|
+
}
|
|
429
|
+
sourceStart = sourceStart ?? 0;
|
|
430
|
+
if (targetStart !== undefined && targetStart < 0) {
|
|
431
|
+
throw new RangeError(`The value of "targetStart" is out of range. It must be >= 0. Received ${targetStart}`);
|
|
432
|
+
}
|
|
433
|
+
targetStart = targetStart ?? 0;
|
|
434
|
+
const srcSlice = source.subarray(sourceStart, sourceEnd);
|
|
435
|
+
const maxLen = Math.min(srcSlice.length, target.length - targetStart);
|
|
436
|
+
if (maxLen <= 0) {
|
|
437
|
+
return 0;
|
|
438
|
+
}
|
|
439
|
+
target.set(srcSlice.subarray(0, maxLen), targetStart);
|
|
440
|
+
return maxLen;
|
|
441
|
+
},
|
|
416
442
|
equals(uint8Array, otherUint8Array) {
|
|
417
443
|
if (uint8Array.byteLength !== otherUint8Array.byteLength) {
|
|
418
444
|
return false;
|
|
@@ -680,7 +706,7 @@ class Binary extends BSONValue {
|
|
|
680
706
|
!Array.isArray(buffer)) {
|
|
681
707
|
throw new BSONError('Binary can only be constructed from Uint8Array or number[]');
|
|
682
708
|
}
|
|
683
|
-
this.sub_type = subType ?? Binary.BSON_BINARY_SUBTYPE_DEFAULT;
|
|
709
|
+
this.sub_type = (subType ?? Binary.BSON_BINARY_SUBTYPE_DEFAULT) & 0xff;
|
|
684
710
|
if (buffer == null) {
|
|
685
711
|
this.buffer = ByteUtils.allocate(Binary.BUFFER_SIZE);
|
|
686
712
|
this.position = 0;
|
|
@@ -786,7 +812,7 @@ class Binary extends BSONValue {
|
|
|
786
812
|
if (this.sub_type === Binary.SUBTYPE_UUID) {
|
|
787
813
|
return new UUID(this.buffer.subarray(0, this.position));
|
|
788
814
|
}
|
|
789
|
-
throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only
|
|
815
|
+
throw new BSONError(`Binary sub_type "${this.sub_type}" (${typeof this.sub_type}) is not supported for converting to UUID. Only 0x${Binary.SUBTYPE_UUID.toString(16).padStart(2, '0')} is currently supported.`);
|
|
790
816
|
}
|
|
791
817
|
static createFromHexString(hex, subType) {
|
|
792
818
|
return new Binary(ByteUtils.fromHex(hex), subType);
|
|
@@ -2575,13 +2601,24 @@ class MinKey extends BSONValue {
|
|
|
2575
2601
|
}
|
|
2576
2602
|
}
|
|
2577
2603
|
|
|
2578
|
-
let PROCESS_UNIQUE = null;
|
|
2579
2604
|
const __idCache = new WeakMap();
|
|
2580
2605
|
class ObjectId extends BSONValue {
|
|
2581
2606
|
get _bsontype() {
|
|
2582
2607
|
return 'ObjectId';
|
|
2583
2608
|
}
|
|
2584
|
-
static index =
|
|
2609
|
+
static index = 0;
|
|
2610
|
+
static PROCESS_UNIQUE = null;
|
|
2611
|
+
static resetState = () => {
|
|
2612
|
+
this.index = Math.floor(Math.random() * 0x1000000);
|
|
2613
|
+
this.PROCESS_UNIQUE = ByteUtils.randomBytes(5);
|
|
2614
|
+
};
|
|
2615
|
+
static {
|
|
2616
|
+
this.resetState();
|
|
2617
|
+
const { startupSnapshot } = globalThis?.process?.getBuiltinModule('v8') ?? {};
|
|
2618
|
+
if (startupSnapshot?.isBuildingSnapshot()) {
|
|
2619
|
+
startupSnapshot?.addDeserializeCallback(this.resetState);
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2585
2622
|
static cacheHexString;
|
|
2586
2623
|
buffer;
|
|
2587
2624
|
constructor(inputId) {
|
|
@@ -2658,7 +2695,7 @@ class ObjectId extends BSONValue {
|
|
|
2658
2695
|
return hexString;
|
|
2659
2696
|
}
|
|
2660
2697
|
static getInc() {
|
|
2661
|
-
return (ObjectId.index = (ObjectId.index + 1) %
|
|
2698
|
+
return (ObjectId.index = (ObjectId.index + 1) % 0x1000000);
|
|
2662
2699
|
}
|
|
2663
2700
|
static generate(time) {
|
|
2664
2701
|
if ('number' !== typeof time) {
|
|
@@ -2667,9 +2704,7 @@ class ObjectId extends BSONValue {
|
|
|
2667
2704
|
const inc = ObjectId.getInc();
|
|
2668
2705
|
const buffer = ByteUtils.allocateUnsafe(12);
|
|
2669
2706
|
NumberUtils.setInt32BE(buffer, 0, time);
|
|
2670
|
-
|
|
2671
|
-
PROCESS_UNIQUE = ByteUtils.randomBytes(5);
|
|
2672
|
-
}
|
|
2707
|
+
const PROCESS_UNIQUE = this.PROCESS_UNIQUE;
|
|
2673
2708
|
buffer[4] = PROCESS_UNIQUE[0];
|
|
2674
2709
|
buffer[5] = PROCESS_UNIQUE[1];
|
|
2675
2710
|
buffer[6] = PROCESS_UNIQUE[2];
|
|
@@ -2787,23 +2822,33 @@ class ObjectId extends BSONValue {
|
|
|
2787
2822
|
}
|
|
2788
2823
|
|
|
2789
2824
|
function internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined) {
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2825
|
+
const objectStack = [
|
|
2826
|
+
{ obj: object, ignoreUndefined: ignoreUndefined ?? false }
|
|
2827
|
+
];
|
|
2828
|
+
let total = 0;
|
|
2829
|
+
while (objectStack.length > 0) {
|
|
2830
|
+
const { obj, ignoreUndefined: frameIgnoreUndefined } = objectStack.pop();
|
|
2831
|
+
total += 5;
|
|
2832
|
+
const isObjArray = Array.isArray(obj);
|
|
2833
|
+
let target = obj;
|
|
2834
|
+
if (!isObjArray && typeof obj?.toBSON === 'function') {
|
|
2835
|
+
target = obj.toBSON();
|
|
2836
|
+
}
|
|
2837
|
+
if (isObjArray) {
|
|
2838
|
+
const array = target;
|
|
2839
|
+
for (let i = 0; i < array.length; i++) {
|
|
2840
|
+
total += calculateElementSize(i.toString(), array[i], serializeFunctions, true, frameIgnoreUndefined, objectStack);
|
|
2841
|
+
}
|
|
2799
2842
|
}
|
|
2800
|
-
|
|
2801
|
-
|
|
2843
|
+
else {
|
|
2844
|
+
for (const key of Object.keys(target)) {
|
|
2845
|
+
total += calculateElementSize(key, target[key], serializeFunctions, false, frameIgnoreUndefined, objectStack);
|
|
2846
|
+
}
|
|
2802
2847
|
}
|
|
2803
2848
|
}
|
|
2804
|
-
return
|
|
2849
|
+
return total;
|
|
2805
2850
|
}
|
|
2806
|
-
function
|
|
2851
|
+
function calculateElementSize(name, value, serializeFunctions = false, isArray = false, ignoreUndefined = false, objectStack) {
|
|
2807
2852
|
if (typeof value?.toBSON === 'function') {
|
|
2808
2853
|
value = value.toBSON();
|
|
2809
2854
|
}
|
|
@@ -2815,21 +2860,21 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2815
2860
|
value >= JS_INT_MIN &&
|
|
2816
2861
|
value <= JS_INT_MAX) {
|
|
2817
2862
|
if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) {
|
|
2818
|
-
return
|
|
2863
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (4 + 1);
|
|
2819
2864
|
}
|
|
2820
2865
|
else {
|
|
2821
|
-
return
|
|
2866
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (8 + 1);
|
|
2822
2867
|
}
|
|
2823
2868
|
}
|
|
2824
2869
|
else {
|
|
2825
|
-
return
|
|
2870
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (8 + 1);
|
|
2826
2871
|
}
|
|
2827
2872
|
case 'undefined':
|
|
2828
2873
|
if (isArray || !ignoreUndefined)
|
|
2829
|
-
return
|
|
2874
|
+
return ByteUtils.utf8ByteLength(name) + 1 + 1;
|
|
2830
2875
|
return 0;
|
|
2831
2876
|
case 'boolean':
|
|
2832
|
-
return
|
|
2877
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (1 + 1);
|
|
2833
2878
|
case 'object':
|
|
2834
2879
|
if (value != null &&
|
|
2835
2880
|
typeof value._bsontype === 'string' &&
|
|
@@ -2837,39 +2882,41 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2837
2882
|
throw new BSONVersionError();
|
|
2838
2883
|
}
|
|
2839
2884
|
else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
|
|
2840
|
-
return
|
|
2885
|
+
return ByteUtils.utf8ByteLength(name) + 1 + 1;
|
|
2841
2886
|
}
|
|
2842
2887
|
else if (value._bsontype === 'ObjectId') {
|
|
2843
|
-
return
|
|
2888
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (12 + 1);
|
|
2844
2889
|
}
|
|
2845
2890
|
else if (value instanceof Date || isDate(value)) {
|
|
2846
|
-
return
|
|
2891
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (8 + 1);
|
|
2847
2892
|
}
|
|
2848
2893
|
else if (ArrayBuffer.isView(value) ||
|
|
2849
2894
|
value instanceof ArrayBuffer ||
|
|
2850
2895
|
isAnyArrayBuffer(value)) {
|
|
2851
|
-
return
|
|
2896
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (1 + 4 + 1) + value.byteLength;
|
|
2852
2897
|
}
|
|
2853
2898
|
else if (value._bsontype === 'Long' ||
|
|
2854
2899
|
value._bsontype === 'Double' ||
|
|
2855
2900
|
value._bsontype === 'Timestamp') {
|
|
2856
|
-
return
|
|
2901
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (8 + 1);
|
|
2857
2902
|
}
|
|
2858
2903
|
else if (value._bsontype === 'Decimal128') {
|
|
2859
|
-
return
|
|
2904
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (16 + 1);
|
|
2860
2905
|
}
|
|
2861
2906
|
else if (value._bsontype === 'Code') {
|
|
2862
2907
|
if (value.scope != null && Object.keys(value.scope).length > 0) {
|
|
2863
|
-
|
|
2908
|
+
objectStack.push({ obj: value.scope, ignoreUndefined });
|
|
2909
|
+
return (ByteUtils.utf8ByteLength(name) +
|
|
2910
|
+
1 +
|
|
2864
2911
|
1 +
|
|
2865
2912
|
4 +
|
|
2866
2913
|
4 +
|
|
2867
2914
|
ByteUtils.utf8ByteLength(value.code.toString()) +
|
|
2868
|
-
1
|
|
2869
|
-
internalCalculateObjectSize(value.scope, serializeFunctions, ignoreUndefined));
|
|
2915
|
+
1);
|
|
2870
2916
|
}
|
|
2871
2917
|
else {
|
|
2872
|
-
return (
|
|
2918
|
+
return (ByteUtils.utf8ByteLength(name) +
|
|
2919
|
+
1 +
|
|
2873
2920
|
1 +
|
|
2874
2921
|
4 +
|
|
2875
2922
|
ByteUtils.utf8ByteLength(value.code.toString()) +
|
|
@@ -2879,19 +2926,14 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2879
2926
|
else if (value._bsontype === 'Binary') {
|
|
2880
2927
|
const binary = value;
|
|
2881
2928
|
if (binary.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
|
|
2882
|
-
return (
|
|
2883
|
-
(binary.position + 1 + 4 + 1 + 4));
|
|
2929
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (binary.position + 1 + 4 + 1 + 4);
|
|
2884
2930
|
}
|
|
2885
2931
|
else {
|
|
2886
|
-
return
|
|
2932
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (binary.position + 1 + 4 + 1);
|
|
2887
2933
|
}
|
|
2888
2934
|
}
|
|
2889
2935
|
else if (value._bsontype === 'Symbol') {
|
|
2890
|
-
return ((name
|
|
2891
|
-
ByteUtils.utf8ByteLength(value.value) +
|
|
2892
|
-
4 +
|
|
2893
|
-
1 +
|
|
2894
|
-
1);
|
|
2936
|
+
return (ByteUtils.utf8ByteLength(name) + 1 + ByteUtils.utf8ByteLength(value.value) + 4 + 1 + 1);
|
|
2895
2937
|
}
|
|
2896
2938
|
else if (value._bsontype === 'DBRef') {
|
|
2897
2939
|
const ordered_values = Object.assign({
|
|
@@ -2901,12 +2943,12 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2901
2943
|
if (value.db != null) {
|
|
2902
2944
|
ordered_values['$db'] = value.db;
|
|
2903
2945
|
}
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
internalCalculateObjectSize(ordered_values, serializeFunctions, ignoreUndefined));
|
|
2946
|
+
objectStack.push({ obj: ordered_values, ignoreUndefined: true });
|
|
2947
|
+
return ByteUtils.utf8ByteLength(name) + 1 + 1;
|
|
2907
2948
|
}
|
|
2908
2949
|
else if (value instanceof RegExp || isRegExp(value)) {
|
|
2909
|
-
return (
|
|
2950
|
+
return (ByteUtils.utf8ByteLength(name) +
|
|
2951
|
+
1 +
|
|
2910
2952
|
1 +
|
|
2911
2953
|
ByteUtils.utf8ByteLength(value.source) +
|
|
2912
2954
|
1 +
|
|
@@ -2916,7 +2958,8 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2916
2958
|
1);
|
|
2917
2959
|
}
|
|
2918
2960
|
else if (value._bsontype === 'BSONRegExp') {
|
|
2919
|
-
return (
|
|
2961
|
+
return (ByteUtils.utf8ByteLength(name) +
|
|
2962
|
+
1 +
|
|
2920
2963
|
1 +
|
|
2921
2964
|
ByteUtils.utf8ByteLength(value.pattern) +
|
|
2922
2965
|
1 +
|
|
@@ -2924,13 +2967,13 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2924
2967
|
1);
|
|
2925
2968
|
}
|
|
2926
2969
|
else {
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
1);
|
|
2970
|
+
objectStack.push({ obj: value, ignoreUndefined });
|
|
2971
|
+
return ByteUtils.utf8ByteLength(name) + 1 + 1;
|
|
2930
2972
|
}
|
|
2931
2973
|
case 'function':
|
|
2932
2974
|
if (serializeFunctions) {
|
|
2933
|
-
return (
|
|
2975
|
+
return (ByteUtils.utf8ByteLength(name) +
|
|
2976
|
+
1 +
|
|
2934
2977
|
1 +
|
|
2935
2978
|
4 +
|
|
2936
2979
|
ByteUtils.utf8ByteLength(value.toString()) +
|
|
@@ -2938,13 +2981,12 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
|
|
|
2938
2981
|
}
|
|
2939
2982
|
return 0;
|
|
2940
2983
|
case 'bigint':
|
|
2941
|
-
return
|
|
2984
|
+
return ByteUtils.utf8ByteLength(name) + 1 + (8 + 1);
|
|
2942
2985
|
case 'symbol':
|
|
2943
2986
|
return 0;
|
|
2944
2987
|
default:
|
|
2945
2988
|
throw new BSONError(`Unrecognized JS type: ${typeof value}`);
|
|
2946
2989
|
}
|
|
2947
|
-
return 0;
|
|
2948
2990
|
}
|
|
2949
2991
|
|
|
2950
2992
|
function alphabetize(str) {
|
|
@@ -3155,7 +3197,28 @@ function internalDeserialize(buffer, options, isArray) {
|
|
|
3155
3197
|
return deserializeObject(buffer, index, options, isArray);
|
|
3156
3198
|
}
|
|
3157
3199
|
const allowedDBRefKeys = /^\$ref$|^\$id$|^\$db$/;
|
|
3200
|
+
function assignValue(dest, name, value) {
|
|
3201
|
+
if (name === '__proto__') {
|
|
3202
|
+
Object.defineProperty(dest, name, {
|
|
3203
|
+
value,
|
|
3204
|
+
writable: true,
|
|
3205
|
+
enumerable: true,
|
|
3206
|
+
configurable: true
|
|
3207
|
+
});
|
|
3208
|
+
}
|
|
3209
|
+
else {
|
|
3210
|
+
dest[name] = value;
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
function toPotentialDbRef(doc) {
|
|
3214
|
+
if (isDBRefLike(doc)) {
|
|
3215
|
+
const { $ref, $id, $db, ...fields } = doc;
|
|
3216
|
+
return new DBRef($ref, $id, $db, fields);
|
|
3217
|
+
}
|
|
3218
|
+
return doc;
|
|
3219
|
+
}
|
|
3158
3220
|
function deserializeObject(buffer, index, options, isArray = false) {
|
|
3221
|
+
options = { ...options };
|
|
3159
3222
|
const fieldsAsRaw = options['fieldsAsRaw'] == null ? null : options['fieldsAsRaw'];
|
|
3160
3223
|
const raw = options['raw'] == null ? false : options['raw'];
|
|
3161
3224
|
const bsonRegExp = typeof options['bsonRegExp'] === 'boolean' ? options['bsonRegExp'] : false;
|
|
@@ -3206,32 +3269,87 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
3206
3269
|
index += 4;
|
|
3207
3270
|
if (size < 5 || size > buffer.length)
|
|
3208
3271
|
throw new BSONError('corrupt bson message');
|
|
3209
|
-
const
|
|
3272
|
+
const rootObject = isArray ? [] : {};
|
|
3210
3273
|
let arrayIndex = 0;
|
|
3211
|
-
const done = false;
|
|
3212
3274
|
let isPossibleDBRef = isArray ? false : null;
|
|
3213
|
-
|
|
3275
|
+
let currentFrame = null;
|
|
3276
|
+
let currentDest = rootObject;
|
|
3277
|
+
let currentIsArray = isArray;
|
|
3278
|
+
while (true) {
|
|
3214
3279
|
const elementType = buffer[index++];
|
|
3215
|
-
if (elementType === 0)
|
|
3216
|
-
|
|
3280
|
+
if (elementType === 0) {
|
|
3281
|
+
if (currentFrame) {
|
|
3282
|
+
if (index === currentFrame.lastIndex) {
|
|
3283
|
+
const completedFrame = currentFrame;
|
|
3284
|
+
currentFrame = completedFrame.prev;
|
|
3285
|
+
if (currentFrame === null) {
|
|
3286
|
+
currentDest = rootObject;
|
|
3287
|
+
currentIsArray = isArray;
|
|
3288
|
+
}
|
|
3289
|
+
else {
|
|
3290
|
+
currentDest = currentFrame.holdingDocument;
|
|
3291
|
+
currentIsArray = currentFrame.isArray;
|
|
3292
|
+
}
|
|
3293
|
+
let result = completedFrame.holdingDocument;
|
|
3294
|
+
switch (completedFrame.elementType) {
|
|
3295
|
+
case BSON_DATA_OBJECT:
|
|
3296
|
+
if (completedFrame.isPossibleDBRef) {
|
|
3297
|
+
result = toPotentialDbRef(result);
|
|
3298
|
+
}
|
|
3299
|
+
break;
|
|
3300
|
+
case BSON_DATA_ARRAY:
|
|
3301
|
+
break;
|
|
3302
|
+
case BSON_DATA_CODE_W_SCOPE:
|
|
3303
|
+
result = new Code(completedFrame.functionString, completedFrame.holdingDocument);
|
|
3304
|
+
break;
|
|
3305
|
+
default:
|
|
3306
|
+
throw new BSONError('Unexpected element type in frame stack');
|
|
3307
|
+
}
|
|
3308
|
+
assignValue(currentDest, completedFrame.propertyName, result);
|
|
3309
|
+
continue;
|
|
3310
|
+
}
|
|
3311
|
+
else {
|
|
3312
|
+
if (currentFrame.elementType === BSON_DATA_ARRAY) {
|
|
3313
|
+
throw new BSONError('corrupted array bson');
|
|
3314
|
+
}
|
|
3315
|
+
throw new BSONError('Bad BSON Document: object not properly terminated');
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
else {
|
|
3319
|
+
break;
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3217
3322
|
let i = index;
|
|
3218
3323
|
while (buffer[i] !== 0x00 && i < buffer.length) {
|
|
3219
3324
|
i++;
|
|
3220
3325
|
}
|
|
3221
3326
|
if (i >= buffer.byteLength)
|
|
3222
3327
|
throw new BSONError('Bad BSON Document: illegal CString');
|
|
3223
|
-
const name =
|
|
3224
|
-
|
|
3225
|
-
|
|
3328
|
+
const name = currentIsArray
|
|
3329
|
+
? currentFrame !== null
|
|
3330
|
+
? currentFrame.arrayIndex++
|
|
3331
|
+
: arrayIndex++
|
|
3332
|
+
: ByteUtils.toUTF8(buffer, index, i, false);
|
|
3333
|
+
let shouldValidateKey;
|
|
3334
|
+
if (currentFrame !== null) {
|
|
3335
|
+
shouldValidateKey = currentFrame.validationSetting;
|
|
3336
|
+
}
|
|
3337
|
+
else if (globalUTFValidation || utf8KeysSet?.has(name)) {
|
|
3226
3338
|
shouldValidateKey = validationSetting;
|
|
3227
3339
|
}
|
|
3228
3340
|
else {
|
|
3229
3341
|
shouldValidateKey = !validationSetting;
|
|
3230
3342
|
}
|
|
3231
|
-
if (
|
|
3343
|
+
if (currentFrame !== null) {
|
|
3344
|
+
if (currentFrame.isPossibleDBRef !== false && typeof name === 'string' && name[0] === '$') {
|
|
3345
|
+
currentFrame.isPossibleDBRef = allowedDBRefKeys.test(name);
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
else if (isPossibleDBRef !== false && name[0] === '$') {
|
|
3232
3349
|
isPossibleDBRef = allowedDBRefKeys.test(name);
|
|
3233
3350
|
}
|
|
3234
3351
|
let value;
|
|
3352
|
+
let isDeferredValue = false;
|
|
3235
3353
|
index = i + 1;
|
|
3236
3354
|
if (elementType === BSON_DATA_STRING) {
|
|
3237
3355
|
const stringSize = NumberUtils.getInt32LE(buffer, index);
|
|
@@ -3277,39 +3395,58 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
3277
3395
|
value = buffer[index++] === 1;
|
|
3278
3396
|
}
|
|
3279
3397
|
else if (elementType === BSON_DATA_OBJECT) {
|
|
3280
|
-
const _index = index;
|
|
3281
3398
|
const objectSize = NumberUtils.getInt32LE(buffer, index);
|
|
3282
|
-
if (objectSize
|
|
3399
|
+
if (objectSize < 5 || objectSize > buffer.length - index)
|
|
3283
3400
|
throw new BSONError('bad embedded document length in bson');
|
|
3284
|
-
if (raw) {
|
|
3401
|
+
if (raw || (currentFrame?.raw ?? false)) {
|
|
3285
3402
|
value = buffer.subarray(index, index + objectSize);
|
|
3403
|
+
index = index + objectSize;
|
|
3286
3404
|
}
|
|
3287
3405
|
else {
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3406
|
+
isDeferredValue = true;
|
|
3407
|
+
const objectFrame = {
|
|
3408
|
+
holdingDocument: {},
|
|
3409
|
+
elementType: BSON_DATA_OBJECT,
|
|
3410
|
+
propertyName: name,
|
|
3411
|
+
functionString: null,
|
|
3412
|
+
lastIndex: index + objectSize,
|
|
3413
|
+
isArray: false,
|
|
3414
|
+
arrayIndex: 0,
|
|
3415
|
+
raw: false,
|
|
3416
|
+
isPossibleDBRef: null,
|
|
3417
|
+
validationSetting: shouldValidateKey,
|
|
3418
|
+
prev: currentFrame
|
|
3419
|
+
};
|
|
3420
|
+
currentFrame = objectFrame;
|
|
3421
|
+
currentDest = objectFrame.holdingDocument;
|
|
3422
|
+
currentIsArray = false;
|
|
3423
|
+
index = index + 4;
|
|
3293
3424
|
}
|
|
3294
|
-
index = index + objectSize;
|
|
3295
3425
|
}
|
|
3296
3426
|
else if (elementType === BSON_DATA_ARRAY) {
|
|
3297
|
-
const _index = index;
|
|
3298
3427
|
const objectSize = NumberUtils.getInt32LE(buffer, index);
|
|
3299
|
-
|
|
3428
|
+
if (objectSize < 5 || objectSize > buffer.length - index)
|
|
3429
|
+
throw new BSONError('bad embedded array length in bson');
|
|
3300
3430
|
const stopIndex = index + objectSize;
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3431
|
+
const arrayRaw = !!(fieldsAsRaw && fieldsAsRaw[name]) || (currentFrame?.raw ?? false);
|
|
3432
|
+
isDeferredValue = true;
|
|
3433
|
+
const arrayFrame = {
|
|
3434
|
+
holdingDocument: [],
|
|
3435
|
+
elementType: BSON_DATA_ARRAY,
|
|
3436
|
+
propertyName: name,
|
|
3437
|
+
functionString: null,
|
|
3438
|
+
lastIndex: stopIndex,
|
|
3439
|
+
isArray: true,
|
|
3440
|
+
arrayIndex: 0,
|
|
3441
|
+
raw: arrayRaw,
|
|
3442
|
+
isPossibleDBRef: false,
|
|
3443
|
+
validationSetting: shouldValidateKey,
|
|
3444
|
+
prev: currentFrame
|
|
3445
|
+
};
|
|
3446
|
+
currentFrame = arrayFrame;
|
|
3447
|
+
currentDest = arrayFrame.holdingDocument;
|
|
3448
|
+
currentIsArray = true;
|
|
3449
|
+
index = index + 4;
|
|
3313
3450
|
}
|
|
3314
3451
|
else if (elementType === BSON_DATA_UNDEFINED) {
|
|
3315
3452
|
value = undefined;
|
|
@@ -3481,15 +3618,32 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
3481
3618
|
index = index + stringSize;
|
|
3482
3619
|
const _index = index;
|
|
3483
3620
|
const objectSize = NumberUtils.getInt32LE(buffer, index);
|
|
3484
|
-
|
|
3485
|
-
|
|
3621
|
+
if (objectSize < 5 || objectSize > buffer.length - index)
|
|
3622
|
+
throw new BSONError('bad scope document size in code_w_scope');
|
|
3486
3623
|
if (totalSize < 4 + 4 + objectSize + stringSize) {
|
|
3487
3624
|
throw new BSONError('code_w_scope total size is too short, truncating scope');
|
|
3488
3625
|
}
|
|
3489
3626
|
if (totalSize > 4 + 4 + objectSize + stringSize) {
|
|
3490
3627
|
throw new BSONError('code_w_scope total size is too long, clips outer document');
|
|
3491
3628
|
}
|
|
3492
|
-
|
|
3629
|
+
isDeferredValue = true;
|
|
3630
|
+
const scopeFrame = {
|
|
3631
|
+
holdingDocument: {},
|
|
3632
|
+
elementType: BSON_DATA_CODE_W_SCOPE,
|
|
3633
|
+
propertyName: name,
|
|
3634
|
+
functionString: functionString,
|
|
3635
|
+
lastIndex: _index + objectSize,
|
|
3636
|
+
isArray: false,
|
|
3637
|
+
arrayIndex: 0,
|
|
3638
|
+
raw: false,
|
|
3639
|
+
isPossibleDBRef: null,
|
|
3640
|
+
validationSetting: shouldValidateKey,
|
|
3641
|
+
prev: currentFrame
|
|
3642
|
+
};
|
|
3643
|
+
currentFrame = scopeFrame;
|
|
3644
|
+
currentDest = scopeFrame.holdingDocument;
|
|
3645
|
+
currentIsArray = false;
|
|
3646
|
+
index = index + 4;
|
|
3493
3647
|
}
|
|
3494
3648
|
else if (elementType === BSON_DATA_DBPOINTER) {
|
|
3495
3649
|
const stringSize = NumberUtils.getInt32LE(buffer, index);
|
|
@@ -3510,18 +3664,14 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
3510
3664
|
else {
|
|
3511
3665
|
throw new BSONError(`Detected unknown BSON type ${elementType.toString(16)} for fieldname "${name}"`);
|
|
3512
3666
|
}
|
|
3513
|
-
if (
|
|
3514
|
-
|
|
3515
|
-
value,
|
|
3516
|
-
writable: true,
|
|
3517
|
-
enumerable: true,
|
|
3518
|
-
configurable: true
|
|
3519
|
-
});
|
|
3520
|
-
}
|
|
3521
|
-
else {
|
|
3522
|
-
object[name] = value;
|
|
3667
|
+
if (!isDeferredValue) {
|
|
3668
|
+
assignValue(currentDest, name, value);
|
|
3523
3669
|
}
|
|
3524
3670
|
}
|
|
3671
|
+
if (currentFrame !== null) {
|
|
3672
|
+
throw new BSONError('corrupted bson, more objects expected based on the current document size');
|
|
3673
|
+
}
|
|
3674
|
+
const object = rootObject;
|
|
3525
3675
|
if (size !== index - startIndex) {
|
|
3526
3676
|
if (isArray)
|
|
3527
3677
|
throw new BSONError('corrupt array bson');
|
|
@@ -3529,14 +3679,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
3529
3679
|
}
|
|
3530
3680
|
if (!isPossibleDBRef)
|
|
3531
3681
|
return object;
|
|
3532
|
-
|
|
3533
|
-
const copy = Object.assign({}, object);
|
|
3534
|
-
delete copy.$ref;
|
|
3535
|
-
delete copy.$id;
|
|
3536
|
-
delete copy.$db;
|
|
3537
|
-
return new DBRef(object.$ref, object.$id, object.$db, copy);
|
|
3538
|
-
}
|
|
3539
|
-
return object;
|
|
3682
|
+
return toPotentialDbRef(object);
|
|
3540
3683
|
}
|
|
3541
3684
|
|
|
3542
3685
|
const regexp = /\x00/;
|
|
@@ -3645,7 +3788,7 @@ function serializeMinMax(buffer, key, value, index) {
|
|
|
3645
3788
|
if (value === null) {
|
|
3646
3789
|
buffer[index++] = BSON_DATA_NULL;
|
|
3647
3790
|
}
|
|
3648
|
-
else if (value
|
|
3791
|
+
else if (value[bsonType] === 'MinKey') {
|
|
3649
3792
|
buffer[index++] = BSON_DATA_MIN_KEY;
|
|
3650
3793
|
}
|
|
3651
3794
|
else {
|
|
@@ -3682,19 +3825,6 @@ function serializeBuffer(buffer, key, value, index) {
|
|
|
3682
3825
|
index = index + size;
|
|
3683
3826
|
return index;
|
|
3684
3827
|
}
|
|
3685
|
-
function serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path) {
|
|
3686
|
-
if (path.has(value)) {
|
|
3687
|
-
throw new BSONError('Cannot convert circular structure to BSON');
|
|
3688
|
-
}
|
|
3689
|
-
path.add(value);
|
|
3690
|
-
buffer[index++] = Array.isArray(value) ? BSON_DATA_ARRAY : BSON_DATA_OBJECT;
|
|
3691
|
-
const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
3692
|
-
index = index + numberOfWrittenBytes;
|
|
3693
|
-
buffer[index++] = 0;
|
|
3694
|
-
const endIndex = serializeInto(buffer, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
|
|
3695
|
-
path.delete(value);
|
|
3696
|
-
return endIndex;
|
|
3697
|
-
}
|
|
3698
3828
|
function serializeDecimal128(buffer, key, value, index) {
|
|
3699
3829
|
buffer[index++] = BSON_DATA_DECIMAL128;
|
|
3700
3830
|
const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
@@ -3706,7 +3836,7 @@ function serializeDecimal128(buffer, key, value, index) {
|
|
|
3706
3836
|
}
|
|
3707
3837
|
function serializeLong(buffer, key, value, index) {
|
|
3708
3838
|
buffer[index++] =
|
|
3709
|
-
value
|
|
3839
|
+
value[bsonType] === 'Long' ? BSON_DATA_LONG : BSON_DATA_TIMESTAMP;
|
|
3710
3840
|
const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
3711
3841
|
index = index + numberOfWrittenBytes;
|
|
3712
3842
|
buffer[index++] = 0;
|
|
@@ -3745,38 +3875,6 @@ function serializeFunction(buffer, key, value, index) {
|
|
|
3745
3875
|
buffer[index++] = 0;
|
|
3746
3876
|
return index;
|
|
3747
3877
|
}
|
|
3748
|
-
function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0, serializeFunctions = false, ignoreUndefined = true, path) {
|
|
3749
|
-
if (value.scope && typeof value.scope === 'object') {
|
|
3750
|
-
buffer[index++] = BSON_DATA_CODE_W_SCOPE;
|
|
3751
|
-
const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
3752
|
-
index = index + numberOfWrittenBytes;
|
|
3753
|
-
buffer[index++] = 0;
|
|
3754
|
-
let startIndex = index;
|
|
3755
|
-
const functionString = value.code;
|
|
3756
|
-
index = index + 4;
|
|
3757
|
-
const codeSize = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
|
|
3758
|
-
NumberUtils.setInt32LE(buffer, index, codeSize);
|
|
3759
|
-
buffer[index + 4 + codeSize - 1] = 0;
|
|
3760
|
-
index = index + codeSize + 4;
|
|
3761
|
-
const endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
|
|
3762
|
-
index = endIndex - 1;
|
|
3763
|
-
const totalSize = endIndex - startIndex;
|
|
3764
|
-
startIndex += NumberUtils.setInt32LE(buffer, startIndex, totalSize);
|
|
3765
|
-
buffer[index++] = 0;
|
|
3766
|
-
}
|
|
3767
|
-
else {
|
|
3768
|
-
buffer[index++] = BSON_DATA_CODE;
|
|
3769
|
-
const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
3770
|
-
index = index + numberOfWrittenBytes;
|
|
3771
|
-
buffer[index++] = 0;
|
|
3772
|
-
const functionString = value.code.toString();
|
|
3773
|
-
const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
|
|
3774
|
-
NumberUtils.setInt32LE(buffer, index, size);
|
|
3775
|
-
index = index + 4 + size - 1;
|
|
3776
|
-
buffer[index++] = 0;
|
|
3777
|
-
}
|
|
3778
|
-
return index;
|
|
3779
|
-
}
|
|
3780
3878
|
function serializeBinary(buffer, key, value, index) {
|
|
3781
3879
|
buffer[index++] = BSON_DATA_BINARY;
|
|
3782
3880
|
const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
@@ -3816,26 +3914,59 @@ function serializeSymbol(buffer, key, value, index) {
|
|
|
3816
3914
|
buffer[index++] = 0;
|
|
3817
3915
|
return index;
|
|
3818
3916
|
}
|
|
3819
|
-
function
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3917
|
+
function makeFrame(sourceObject, objectSizeIndex, codeSizeIndex, prev, checkKeys, ignoreUndefined) {
|
|
3918
|
+
if (Array.isArray(sourceObject)) {
|
|
3919
|
+
return {
|
|
3920
|
+
sourceObject,
|
|
3921
|
+
isArray: true,
|
|
3922
|
+
objectSizeIndex,
|
|
3923
|
+
codeSizeIndex,
|
|
3924
|
+
iterTarget: sourceObject,
|
|
3925
|
+
keys: null,
|
|
3926
|
+
keyIndex: 0,
|
|
3927
|
+
mapIterator: null,
|
|
3928
|
+
prev,
|
|
3929
|
+
checkKeys,
|
|
3930
|
+
ignoreUndefined
|
|
3931
|
+
};
|
|
3932
|
+
}
|
|
3933
|
+
if (sourceObject instanceof Map || isMap(sourceObject)) {
|
|
3934
|
+
return {
|
|
3935
|
+
sourceObject,
|
|
3936
|
+
isArray: false,
|
|
3937
|
+
objectSizeIndex,
|
|
3938
|
+
codeSizeIndex,
|
|
3939
|
+
iterTarget: sourceObject,
|
|
3940
|
+
keys: null,
|
|
3941
|
+
keyIndex: 0,
|
|
3942
|
+
mapIterator: sourceObject.entries(),
|
|
3943
|
+
prev,
|
|
3944
|
+
checkKeys,
|
|
3945
|
+
ignoreUndefined
|
|
3946
|
+
};
|
|
3947
|
+
}
|
|
3948
|
+
let target = sourceObject;
|
|
3949
|
+
if (typeof target?.toBSON === 'function') {
|
|
3950
|
+
target = target.toBSON();
|
|
3951
|
+
if (target != null && typeof target !== 'object') {
|
|
3952
|
+
throw new BSONError('toBSON function did not return an object');
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
return {
|
|
3956
|
+
sourceObject,
|
|
3957
|
+
isArray: false,
|
|
3958
|
+
objectSizeIndex,
|
|
3959
|
+
codeSizeIndex,
|
|
3960
|
+
iterTarget: target,
|
|
3961
|
+
keys: Object.keys(target),
|
|
3962
|
+
keyIndex: 0,
|
|
3963
|
+
mapIterator: null,
|
|
3964
|
+
prev,
|
|
3965
|
+
checkKeys,
|
|
3966
|
+
ignoreUndefined
|
|
3828
3967
|
};
|
|
3829
|
-
if (value.db != null) {
|
|
3830
|
-
output.$db = value.db;
|
|
3831
|
-
}
|
|
3832
|
-
output = Object.assign(output, value.fields);
|
|
3833
|
-
const endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions, true, path);
|
|
3834
|
-
const size = endIndex - startIndex;
|
|
3835
|
-
startIndex += NumberUtils.setInt32LE(buffer, index, size);
|
|
3836
|
-
return endIndex;
|
|
3837
3968
|
}
|
|
3838
|
-
function serializeInto(buffer, object, checkKeys, startingIndex,
|
|
3969
|
+
function serializeInto(buffer, object, checkKeys, startingIndex, serializeFunctions, ignoreUndefined, path) {
|
|
3839
3970
|
if (path == null) {
|
|
3840
3971
|
if (object == null) {
|
|
3841
3972
|
buffer[0] = 0x05;
|
|
@@ -3863,308 +3994,200 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
|
|
|
3863
3994
|
path = new Set();
|
|
3864
3995
|
}
|
|
3865
3996
|
path.add(object);
|
|
3997
|
+
let currentFrame = makeFrame(object, startingIndex, null, null, checkKeys, ignoreUndefined);
|
|
3866
3998
|
let index = startingIndex + 4;
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
else if (value === null) {
|
|
3879
|
-
index = serializeNull(buffer, key, value, index);
|
|
3880
|
-
}
|
|
3881
|
-
else if (type === 'string') {
|
|
3882
|
-
index = serializeString(buffer, key, value, index);
|
|
3883
|
-
}
|
|
3884
|
-
else if (type === 'number') {
|
|
3885
|
-
index = serializeNumber(buffer, key, value, index);
|
|
3886
|
-
}
|
|
3887
|
-
else if (type === 'bigint') {
|
|
3888
|
-
index = serializeBigInt(buffer, key, value, index);
|
|
3889
|
-
}
|
|
3890
|
-
else if (type === 'boolean') {
|
|
3891
|
-
index = serializeBoolean(buffer, key, value, index);
|
|
3892
|
-
}
|
|
3893
|
-
else if (type === 'object' && value._bsontype == null) {
|
|
3894
|
-
if (value instanceof Date || isDate(value)) {
|
|
3895
|
-
index = serializeDate(buffer, key, value, index);
|
|
3896
|
-
}
|
|
3897
|
-
else if (value instanceof Uint8Array || isUint8Array(value)) {
|
|
3898
|
-
index = serializeBuffer(buffer, key, value, index);
|
|
3899
|
-
}
|
|
3900
|
-
else if (value instanceof RegExp || isRegExp(value)) {
|
|
3901
|
-
index = serializeRegExp(buffer, key, value, index);
|
|
3902
|
-
}
|
|
3903
|
-
else {
|
|
3904
|
-
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
3999
|
+
while (currentFrame !== null) {
|
|
4000
|
+
const frame = currentFrame;
|
|
4001
|
+
let key;
|
|
4002
|
+
let value;
|
|
4003
|
+
if (frame.mapIterator !== null) {
|
|
4004
|
+
const next = frame.mapIterator.next();
|
|
4005
|
+
if (next.done) {
|
|
4006
|
+
buffer[index++] = 0x00;
|
|
4007
|
+
NumberUtils.setInt32LE(buffer, frame.objectSizeIndex, index - frame.objectSizeIndex);
|
|
4008
|
+
if (frame.codeSizeIndex !== null) {
|
|
4009
|
+
NumberUtils.setInt32LE(buffer, frame.codeSizeIndex, index - frame.codeSizeIndex);
|
|
3905
4010
|
}
|
|
4011
|
+
path.delete(frame.sourceObject);
|
|
4012
|
+
currentFrame = frame.prev;
|
|
4013
|
+
continue;
|
|
3906
4014
|
}
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
}
|
|
3917
|
-
else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
|
|
3918
|
-
index = serializeLong(buffer, key, value, index);
|
|
3919
|
-
}
|
|
3920
|
-
else if (value._bsontype === 'Double') {
|
|
3921
|
-
index = serializeDouble(buffer, key, value, index);
|
|
3922
|
-
}
|
|
3923
|
-
else if (value._bsontype === 'Code') {
|
|
3924
|
-
index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
3925
|
-
}
|
|
3926
|
-
else if (value._bsontype === 'Binary') {
|
|
3927
|
-
index = serializeBinary(buffer, key, value, index);
|
|
3928
|
-
}
|
|
3929
|
-
else if (value._bsontype === 'BSONSymbol') {
|
|
3930
|
-
index = serializeSymbol(buffer, key, value, index);
|
|
3931
|
-
}
|
|
3932
|
-
else if (value._bsontype === 'DBRef') {
|
|
3933
|
-
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
|
|
3934
|
-
}
|
|
3935
|
-
else if (value._bsontype === 'BSONRegExp') {
|
|
3936
|
-
index = serializeBSONRegExp(buffer, key, value, index);
|
|
3937
|
-
}
|
|
3938
|
-
else if (value._bsontype === 'Int32') {
|
|
3939
|
-
index = serializeInt32(buffer, key, value, index);
|
|
3940
|
-
}
|
|
3941
|
-
else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
|
|
3942
|
-
index = serializeMinMax(buffer, key, value, index);
|
|
3943
|
-
}
|
|
3944
|
-
else if (typeof value._bsontype !== 'undefined') {
|
|
3945
|
-
throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
|
|
4015
|
+
key = next.value[0];
|
|
4016
|
+
value = next.value[1];
|
|
4017
|
+
}
|
|
4018
|
+
else if (frame.keys !== null) {
|
|
4019
|
+
if (frame.keyIndex >= frame.keys.length) {
|
|
4020
|
+
buffer[index++] = 0x00;
|
|
4021
|
+
NumberUtils.setInt32LE(buffer, frame.objectSizeIndex, index - frame.objectSizeIndex);
|
|
4022
|
+
if (frame.codeSizeIndex !== null) {
|
|
4023
|
+
NumberUtils.setInt32LE(buffer, frame.codeSizeIndex, index - frame.codeSizeIndex);
|
|
3946
4024
|
}
|
|
4025
|
+
path.delete(frame.sourceObject);
|
|
4026
|
+
currentFrame = frame.prev;
|
|
4027
|
+
continue;
|
|
3947
4028
|
}
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
}
|
|
4029
|
+
key = frame.keys[frame.keyIndex++];
|
|
4030
|
+
value = frame.iterTarget[key];
|
|
3951
4031
|
}
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
4032
|
+
else {
|
|
4033
|
+
const arr = frame.iterTarget;
|
|
4034
|
+
if (frame.keyIndex >= arr.length) {
|
|
4035
|
+
buffer[index++] = 0x00;
|
|
4036
|
+
NumberUtils.setInt32LE(buffer, frame.objectSizeIndex, index - frame.objectSizeIndex);
|
|
4037
|
+
if (frame.codeSizeIndex !== null) {
|
|
4038
|
+
NumberUtils.setInt32LE(buffer, frame.codeSizeIndex, index - frame.codeSizeIndex);
|
|
4039
|
+
}
|
|
4040
|
+
path.delete(frame.sourceObject);
|
|
4041
|
+
currentFrame = frame.prev;
|
|
3960
4042
|
continue;
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
4043
|
+
}
|
|
4044
|
+
const i = frame.keyIndex++;
|
|
4045
|
+
key = String(i);
|
|
4046
|
+
value = arr[i];
|
|
4047
|
+
}
|
|
4048
|
+
if (typeof value?.toBSON === 'function') {
|
|
4049
|
+
value = value.toBSON();
|
|
4050
|
+
}
|
|
4051
|
+
if (!frame.isArray && typeof key === 'string' && !(key[0] === '$' && ignoreKeys.has(key))) {
|
|
4052
|
+
if (regexp.test(key)) {
|
|
4053
|
+
throw new BSONError('key ' + key + ' must not contain null bytes');
|
|
4054
|
+
}
|
|
4055
|
+
if (frame.checkKeys) {
|
|
4056
|
+
if ('$' === key[0]) {
|
|
4057
|
+
throw new BSONError('key ' + key + " must not start with '$'");
|
|
3970
4058
|
}
|
|
3971
|
-
if (
|
|
3972
|
-
|
|
3973
|
-
throw new BSONError('key ' + key + " must not start with '$'");
|
|
3974
|
-
}
|
|
3975
|
-
else if (key.includes('.')) {
|
|
3976
|
-
throw new BSONError('key ' + key + " must not contain '.'");
|
|
3977
|
-
}
|
|
4059
|
+
else if (key.includes('.')) {
|
|
4060
|
+
throw new BSONError('key ' + key + " must not contain '.'");
|
|
3978
4061
|
}
|
|
3979
4062
|
}
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
else if (value === null) {
|
|
4063
|
+
}
|
|
4064
|
+
const type = typeof value;
|
|
4065
|
+
if (value === undefined) {
|
|
4066
|
+
if (frame.isArray || frame.ignoreUndefined === false) {
|
|
3985
4067
|
index = serializeNull(buffer, key, value, index);
|
|
3986
4068
|
}
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
4069
|
+
}
|
|
4070
|
+
else if (value === null) {
|
|
4071
|
+
index = serializeNull(buffer, key, value, index);
|
|
4072
|
+
}
|
|
4073
|
+
else if (type === 'string') {
|
|
4074
|
+
index = serializeString(buffer, key, value, index);
|
|
4075
|
+
}
|
|
4076
|
+
else if (type === 'number') {
|
|
4077
|
+
index = serializeNumber(buffer, key, value, index);
|
|
4078
|
+
}
|
|
4079
|
+
else if (type === 'bigint') {
|
|
4080
|
+
index = serializeBigInt(buffer, key, value, index);
|
|
4081
|
+
}
|
|
4082
|
+
else if (type === 'boolean') {
|
|
4083
|
+
index = serializeBoolean(buffer, key, value, index);
|
|
4084
|
+
}
|
|
4085
|
+
else if (type === 'object' && value._bsontype == null) {
|
|
4086
|
+
if (value instanceof Date || isDate(value)) {
|
|
4087
|
+
index = serializeDate(buffer, key, value, index);
|
|
3995
4088
|
}
|
|
3996
|
-
else if (
|
|
3997
|
-
index =
|
|
4089
|
+
else if (value instanceof Uint8Array || isUint8Array(value)) {
|
|
4090
|
+
index = serializeBuffer(buffer, key, value, index);
|
|
3998
4091
|
}
|
|
3999
|
-
else if (
|
|
4000
|
-
|
|
4001
|
-
index = serializeDate(buffer, key, value, index);
|
|
4002
|
-
}
|
|
4003
|
-
else if (value instanceof Uint8Array || isUint8Array(value)) {
|
|
4004
|
-
index = serializeBuffer(buffer, key, value, index);
|
|
4005
|
-
}
|
|
4006
|
-
else if (value instanceof RegExp || isRegExp(value)) {
|
|
4007
|
-
index = serializeRegExp(buffer, key, value, index);
|
|
4008
|
-
}
|
|
4009
|
-
else {
|
|
4010
|
-
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
4011
|
-
}
|
|
4092
|
+
else if (value instanceof RegExp || isRegExp(value)) {
|
|
4093
|
+
index = serializeRegExp(buffer, key, value, index);
|
|
4012
4094
|
}
|
|
4013
|
-
else
|
|
4014
|
-
if (value
|
|
4015
|
-
throw new
|
|
4016
|
-
}
|
|
4017
|
-
else if (value._bsontype === 'ObjectId') {
|
|
4018
|
-
index = serializeObjectId(buffer, key, value, index);
|
|
4019
|
-
}
|
|
4020
|
-
else if (value._bsontype === 'Decimal128') {
|
|
4021
|
-
index = serializeDecimal128(buffer, key, value, index);
|
|
4022
|
-
}
|
|
4023
|
-
else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
|
|
4024
|
-
index = serializeLong(buffer, key, value, index);
|
|
4025
|
-
}
|
|
4026
|
-
else if (value._bsontype === 'Double') {
|
|
4027
|
-
index = serializeDouble(buffer, key, value, index);
|
|
4028
|
-
}
|
|
4029
|
-
else if (value._bsontype === 'Code') {
|
|
4030
|
-
index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
4031
|
-
}
|
|
4032
|
-
else if (value._bsontype === 'Binary') {
|
|
4033
|
-
index = serializeBinary(buffer, key, value, index);
|
|
4034
|
-
}
|
|
4035
|
-
else if (value._bsontype === 'BSONSymbol') {
|
|
4036
|
-
index = serializeSymbol(buffer, key, value, index);
|
|
4037
|
-
}
|
|
4038
|
-
else if (value._bsontype === 'DBRef') {
|
|
4039
|
-
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
|
|
4040
|
-
}
|
|
4041
|
-
else if (value._bsontype === 'BSONRegExp') {
|
|
4042
|
-
index = serializeBSONRegExp(buffer, key, value, index);
|
|
4043
|
-
}
|
|
4044
|
-
else if (value._bsontype === 'Int32') {
|
|
4045
|
-
index = serializeInt32(buffer, key, value, index);
|
|
4046
|
-
}
|
|
4047
|
-
else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
|
|
4048
|
-
index = serializeMinMax(buffer, key, value, index);
|
|
4049
|
-
}
|
|
4050
|
-
else if (typeof value._bsontype !== 'undefined') {
|
|
4051
|
-
throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
|
|
4095
|
+
else {
|
|
4096
|
+
if (path.has(value)) {
|
|
4097
|
+
throw new BSONError('Cannot convert circular structure to BSON');
|
|
4052
4098
|
}
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
index
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
object = object.toBSON();
|
|
4062
|
-
if (object != null && typeof object !== 'object') {
|
|
4063
|
-
throw new BSONError('toBSON function did not return an object');
|
|
4099
|
+
const nestedIsArray = Array.isArray(value);
|
|
4100
|
+
buffer[index++] = nestedIsArray ? BSON_DATA_ARRAY : BSON_DATA_OBJECT;
|
|
4101
|
+
index += ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
4102
|
+
buffer[index++] = 0x00;
|
|
4103
|
+
const nestedStartIndex = index;
|
|
4104
|
+
path.add(value);
|
|
4105
|
+
currentFrame = makeFrame(value, nestedStartIndex, null, frame, frame.checkKeys, frame.ignoreUndefined);
|
|
4106
|
+
index += 4;
|
|
4064
4107
|
}
|
|
4065
4108
|
}
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
value = value.toBSON();
|
|
4109
|
+
else if (type === 'object') {
|
|
4110
|
+
if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
|
|
4111
|
+
throw new BSONVersionError();
|
|
4070
4112
|
}
|
|
4071
|
-
const
|
|
4072
|
-
if (
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4113
|
+
const tag = value[bsonType];
|
|
4114
|
+
if (tag === 'ObjectId') {
|
|
4115
|
+
index = serializeObjectId(buffer, key, value, index);
|
|
4116
|
+
}
|
|
4117
|
+
else if (tag === 'Decimal128') {
|
|
4118
|
+
index = serializeDecimal128(buffer, key, value, index);
|
|
4119
|
+
}
|
|
4120
|
+
else if (tag === 'Long' || tag === 'Timestamp') {
|
|
4121
|
+
index = serializeLong(buffer, key, value, index);
|
|
4122
|
+
}
|
|
4123
|
+
else if (tag === 'Double') {
|
|
4124
|
+
index = serializeDouble(buffer, key, value, index);
|
|
4125
|
+
}
|
|
4126
|
+
else if (tag === 'Code') {
|
|
4127
|
+
const codeValue = value;
|
|
4128
|
+
if (codeValue.scope && typeof codeValue.scope === 'object') {
|
|
4129
|
+
buffer[index++] = BSON_DATA_CODE_W_SCOPE;
|
|
4130
|
+
index += ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
4131
|
+
buffer[index++] = 0x00;
|
|
4132
|
+
const codeTotalSizeIndex = index;
|
|
4133
|
+
index += 4;
|
|
4134
|
+
const functionString = codeValue.code;
|
|
4135
|
+
const codeSize = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
|
|
4136
|
+
NumberUtils.setInt32LE(buffer, index, codeSize);
|
|
4137
|
+
buffer[index + 4 + codeSize - 1] = 0;
|
|
4138
|
+
index = index + codeSize + 4;
|
|
4139
|
+
const scope = codeValue.scope;
|
|
4140
|
+
if (path.has(scope)) {
|
|
4141
|
+
throw new BSONError('Cannot convert circular structure to BSON');
|
|
4082
4142
|
}
|
|
4143
|
+
path.add(scope);
|
|
4144
|
+
currentFrame = makeFrame(scope, index, codeTotalSizeIndex, frame, frame.checkKeys, frame.ignoreUndefined);
|
|
4145
|
+
index += 4;
|
|
4146
|
+
}
|
|
4147
|
+
else {
|
|
4148
|
+
buffer[index++] = BSON_DATA_CODE;
|
|
4149
|
+
index += ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
4150
|
+
buffer[index++] = 0x00;
|
|
4151
|
+
const functionString = codeValue.code.toString();
|
|
4152
|
+
const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
|
|
4153
|
+
NumberUtils.setInt32LE(buffer, index, size);
|
|
4154
|
+
index = index + 4 + size - 1;
|
|
4155
|
+
buffer[index++] = 0;
|
|
4083
4156
|
}
|
|
4084
4157
|
}
|
|
4085
|
-
if (
|
|
4086
|
-
|
|
4087
|
-
index = serializeNull(buffer, key, value, index);
|
|
4088
|
-
}
|
|
4089
|
-
else if (value === null) {
|
|
4090
|
-
index = serializeNull(buffer, key, value, index);
|
|
4091
|
-
}
|
|
4092
|
-
else if (type === 'string') {
|
|
4093
|
-
index = serializeString(buffer, key, value, index);
|
|
4158
|
+
else if (tag === 'Binary') {
|
|
4159
|
+
index = serializeBinary(buffer, key, value, index);
|
|
4094
4160
|
}
|
|
4095
|
-
else if (
|
|
4096
|
-
index =
|
|
4161
|
+
else if (tag === 'BSONSymbol') {
|
|
4162
|
+
index = serializeSymbol(buffer, key, value, index);
|
|
4097
4163
|
}
|
|
4098
|
-
else if (
|
|
4099
|
-
|
|
4164
|
+
else if (tag === 'DBRef') {
|
|
4165
|
+
const dbref = value;
|
|
4166
|
+
const orderedValues = Object.assign({ $ref: dbref.collection, $id: dbref.oid }, dbref.db != null ? { $db: dbref.db } : null, dbref.fields);
|
|
4167
|
+
buffer[index++] = BSON_DATA_OBJECT;
|
|
4168
|
+
index += ByteUtils.encodeUTF8Into(buffer, key, index);
|
|
4169
|
+
buffer[index++] = 0x00;
|
|
4170
|
+
path.add(orderedValues);
|
|
4171
|
+
currentFrame = makeFrame(orderedValues, index, null, frame, false, true);
|
|
4172
|
+
index += 4;
|
|
4100
4173
|
}
|
|
4101
|
-
else if (
|
|
4102
|
-
index =
|
|
4174
|
+
else if (tag === 'BSONRegExp') {
|
|
4175
|
+
index = serializeBSONRegExp(buffer, key, value, index);
|
|
4103
4176
|
}
|
|
4104
|
-
else if (
|
|
4105
|
-
|
|
4106
|
-
index = serializeDate(buffer, key, value, index);
|
|
4107
|
-
}
|
|
4108
|
-
else if (value instanceof Uint8Array || isUint8Array(value)) {
|
|
4109
|
-
index = serializeBuffer(buffer, key, value, index);
|
|
4110
|
-
}
|
|
4111
|
-
else if (value instanceof RegExp || isRegExp(value)) {
|
|
4112
|
-
index = serializeRegExp(buffer, key, value, index);
|
|
4113
|
-
}
|
|
4114
|
-
else {
|
|
4115
|
-
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
4116
|
-
}
|
|
4177
|
+
else if (tag === 'Int32') {
|
|
4178
|
+
index = serializeInt32(buffer, key, value, index);
|
|
4117
4179
|
}
|
|
4118
|
-
else if (
|
|
4119
|
-
|
|
4120
|
-
throw new BSONVersionError();
|
|
4121
|
-
}
|
|
4122
|
-
else if (value._bsontype === 'ObjectId') {
|
|
4123
|
-
index = serializeObjectId(buffer, key, value, index);
|
|
4124
|
-
}
|
|
4125
|
-
else if (value._bsontype === 'Decimal128') {
|
|
4126
|
-
index = serializeDecimal128(buffer, key, value, index);
|
|
4127
|
-
}
|
|
4128
|
-
else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
|
|
4129
|
-
index = serializeLong(buffer, key, value, index);
|
|
4130
|
-
}
|
|
4131
|
-
else if (value._bsontype === 'Double') {
|
|
4132
|
-
index = serializeDouble(buffer, key, value, index);
|
|
4133
|
-
}
|
|
4134
|
-
else if (value._bsontype === 'Code') {
|
|
4135
|
-
index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
|
|
4136
|
-
}
|
|
4137
|
-
else if (value._bsontype === 'Binary') {
|
|
4138
|
-
index = serializeBinary(buffer, key, value, index);
|
|
4139
|
-
}
|
|
4140
|
-
else if (value._bsontype === 'BSONSymbol') {
|
|
4141
|
-
index = serializeSymbol(buffer, key, value, index);
|
|
4142
|
-
}
|
|
4143
|
-
else if (value._bsontype === 'DBRef') {
|
|
4144
|
-
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
|
|
4145
|
-
}
|
|
4146
|
-
else if (value._bsontype === 'BSONRegExp') {
|
|
4147
|
-
index = serializeBSONRegExp(buffer, key, value, index);
|
|
4148
|
-
}
|
|
4149
|
-
else if (value._bsontype === 'Int32') {
|
|
4150
|
-
index = serializeInt32(buffer, key, value, index);
|
|
4151
|
-
}
|
|
4152
|
-
else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
|
|
4153
|
-
index = serializeMinMax(buffer, key, value, index);
|
|
4154
|
-
}
|
|
4155
|
-
else if (typeof value._bsontype !== 'undefined') {
|
|
4156
|
-
throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
|
|
4157
|
-
}
|
|
4180
|
+
else if (tag === 'MinKey' || tag === 'MaxKey') {
|
|
4181
|
+
index = serializeMinMax(buffer, key, value, index);
|
|
4158
4182
|
}
|
|
4159
|
-
else if (
|
|
4160
|
-
|
|
4183
|
+
else if (typeof value._bsontype !== 'undefined') {
|
|
4184
|
+
throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
|
|
4161
4185
|
}
|
|
4162
4186
|
}
|
|
4187
|
+
else if (type === 'function' && serializeFunctions) {
|
|
4188
|
+
index = serializeFunction(buffer, key, value, index);
|
|
4189
|
+
}
|
|
4163
4190
|
}
|
|
4164
|
-
path.delete(object);
|
|
4165
|
-
buffer[index++] = 0x00;
|
|
4166
|
-
const size = index - startingIndex;
|
|
4167
|
-
startingIndex += NumberUtils.setInt32LE(buffer, startingIndex, size);
|
|
4168
4191
|
return index;
|
|
4169
4192
|
}
|
|
4170
4193
|
|
|
@@ -4320,7 +4343,7 @@ function serializeValue(value, options) {
|
|
|
4320
4343
|
if (Array.isArray(value))
|
|
4321
4344
|
return serializeArray(value, options);
|
|
4322
4345
|
if (value === undefined)
|
|
4323
|
-
return null;
|
|
4346
|
+
return options.ignoreUndefined ? undefined : null;
|
|
4324
4347
|
if (value instanceof Date || isDate(value)) {
|
|
4325
4348
|
const dateNum = value.getTime(), inRange = dateNum > -1 && dateNum < 253402318800000;
|
|
4326
4349
|
if (options.legacy) {
|
|
@@ -4447,21 +4470,22 @@ function parse(text, options) {
|
|
|
4447
4470
|
return deserializeValue(value, ejsonOptions);
|
|
4448
4471
|
});
|
|
4449
4472
|
}
|
|
4450
|
-
function stringify(value,
|
|
4451
|
-
if (
|
|
4452
|
-
options =
|
|
4453
|
-
|
|
4473
|
+
function stringify(value, replacerOrOptions, spaceOrOptions, options) {
|
|
4474
|
+
if (spaceOrOptions != null && typeof spaceOrOptions === 'object') {
|
|
4475
|
+
options = spaceOrOptions;
|
|
4476
|
+
spaceOrOptions = undefined;
|
|
4454
4477
|
}
|
|
4455
|
-
if (
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4478
|
+
if (replacerOrOptions != null &&
|
|
4479
|
+
typeof replacerOrOptions === 'object' &&
|
|
4480
|
+
!Array.isArray(replacerOrOptions)) {
|
|
4481
|
+
options = replacerOrOptions;
|
|
4482
|
+
replacerOrOptions = undefined;
|
|
4459
4483
|
}
|
|
4460
4484
|
const serializeOptions = Object.assign({ relaxed: true, legacy: false }, options, {
|
|
4461
4485
|
seenObjects: [{ propertyName: '(root)', obj: null }]
|
|
4462
4486
|
});
|
|
4463
4487
|
const doc = serializeValue(value, serializeOptions);
|
|
4464
|
-
return JSON.stringify(doc,
|
|
4488
|
+
return JSON.stringify(doc, replacerOrOptions, spaceOrOptions);
|
|
4465
4489
|
}
|
|
4466
4490
|
function EJSONserialize(value, options) {
|
|
4467
4491
|
options = options || {};
|
|
@@ -4623,7 +4647,7 @@ function serialize(object, options = {}) {
|
|
|
4623
4647
|
if (buffer.length < minInternalBufferSize) {
|
|
4624
4648
|
buffer = ByteUtils.allocate(minInternalBufferSize);
|
|
4625
4649
|
}
|
|
4626
|
-
const serializationIndex = serializeInto(buffer, object, checkKeys, 0,
|
|
4650
|
+
const serializationIndex = serializeInto(buffer, object, checkKeys, 0, serializeFunctions, ignoreUndefined, null);
|
|
4627
4651
|
const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
|
|
4628
4652
|
finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
|
|
4629
4653
|
return finishedBuffer;
|
|
@@ -4633,7 +4657,7 @@ function serializeWithBufferAndIndex(object, finalBuffer, options = {}) {
|
|
|
4633
4657
|
const serializeFunctions = typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
|
|
4634
4658
|
const ignoreUndefined = typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true;
|
|
4635
4659
|
const startIndex = typeof options.index === 'number' ? options.index : 0;
|
|
4636
|
-
const serializationIndex = serializeInto(buffer, object, checkKeys, 0,
|
|
4660
|
+
const serializationIndex = serializeInto(buffer, object, checkKeys, 0, serializeFunctions, ignoreUndefined, null);
|
|
4637
4661
|
finalBuffer.set(buffer.subarray(0, serializationIndex), startIndex);
|
|
4638
4662
|
return startIndex + serializationIndex - 1;
|
|
4639
4663
|
}
|