bson 5.0.0-alpha.1 → 5.0.0-alpha.2
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 +20 -11
- package/lib/bson.bundle.js +101 -79
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +101 -79
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +102 -79
- package/lib/bson.mjs.map +1 -1
- package/package.json +4 -4
- package/src/binary.ts +7 -7
- package/src/bson.ts +1 -1
- package/src/decimal128.ts +7 -7
- package/src/double.ts +6 -14
- package/src/error.ts +33 -9
- package/src/extended_json.ts +11 -5
- package/src/long.ts +6 -5
- package/src/objectid.ts +6 -8
- package/src/parser/calculate_size.ts +12 -1
- package/src/parser/deserializer.ts +24 -9
- package/src/parser/serializer.ts +50 -31
- package/src/regexp.ts +2 -2
- package/src/uuid_utils.ts +2 -2
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"etc/prepare.js"
|
|
14
14
|
],
|
|
15
15
|
"types": "bson.d.ts",
|
|
16
|
-
"version": "5.0.0-alpha.
|
|
16
|
+
"version": "5.0.0-alpha.2",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "The MongoDB NodeJS Team",
|
|
19
19
|
"email": "dbx-node@mongodb.com"
|
|
@@ -75,11 +75,11 @@
|
|
|
75
75
|
},
|
|
76
76
|
"main": "./lib/bson.cjs",
|
|
77
77
|
"module": "./lib/bson.mjs",
|
|
78
|
-
"browser": "./lib/bson.mjs",
|
|
79
78
|
"exports": {
|
|
80
|
-
"browser": "./lib/bson.mjs",
|
|
81
79
|
"import": "./lib/bson.mjs",
|
|
82
|
-
"require": "./lib/bson.cjs"
|
|
80
|
+
"require": "./lib/bson.cjs",
|
|
81
|
+
"react-native": "./lib/bson.cjs",
|
|
82
|
+
"browser": "./lib/bson.mjs"
|
|
83
83
|
},
|
|
84
84
|
"engines": {
|
|
85
85
|
"node": ">=14.20.1"
|
package/src/binary.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { bufferToUuidHexString, uuidHexStringToBuffer, uuidValidateString } from './uuid_utils';
|
|
2
2
|
import { isUint8Array } from './parser/utils';
|
|
3
3
|
import type { EJSONOptions } from './extended_json';
|
|
4
|
-
import { BSONError
|
|
4
|
+
import { BSONError } from './error';
|
|
5
5
|
import { BSON_BINARY_SUBTYPE_UUID_NEW, BSON_MAJOR_VERSION } from './constants';
|
|
6
6
|
import { ByteUtils } from './utils/byte_utils';
|
|
7
7
|
|
|
@@ -86,7 +86,7 @@ export class Binary {
|
|
|
86
86
|
!(buffer instanceof ArrayBuffer) &&
|
|
87
87
|
!Array.isArray(buffer)
|
|
88
88
|
) {
|
|
89
|
-
throw new
|
|
89
|
+
throw new BSONError(
|
|
90
90
|
'Binary can only be constructed from string, Buffer, TypedArray, or Array<number>'
|
|
91
91
|
);
|
|
92
92
|
}
|
|
@@ -121,9 +121,9 @@ export class Binary {
|
|
|
121
121
|
put(byteValue: string | number | Uint8Array | number[]): void {
|
|
122
122
|
// If it's a string and a has more than one character throw an error
|
|
123
123
|
if (typeof byteValue === 'string' && byteValue.length !== 1) {
|
|
124
|
-
throw new
|
|
124
|
+
throw new BSONError('only accepts single character String');
|
|
125
125
|
} else if (typeof byteValue !== 'number' && byteValue.length !== 1)
|
|
126
|
-
throw new
|
|
126
|
+
throw new BSONError('only accepts single character Uint8Array or Array');
|
|
127
127
|
|
|
128
128
|
// Decode the byte value once
|
|
129
129
|
let decodedByte: number;
|
|
@@ -136,7 +136,7 @@ export class Binary {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
if (decodedByte < 0 || decodedByte > 255) {
|
|
139
|
-
throw new
|
|
139
|
+
throw new BSONError('only accepts number in a valid unsigned byte range 0-255');
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
if (this.buffer.byteLength > this.position) {
|
|
@@ -283,7 +283,7 @@ export class Binary {
|
|
|
283
283
|
data = uuidHexStringToBuffer(doc.$uuid);
|
|
284
284
|
}
|
|
285
285
|
if (!data) {
|
|
286
|
-
throw new
|
|
286
|
+
throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`);
|
|
287
287
|
}
|
|
288
288
|
return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new Binary(data, type);
|
|
289
289
|
}
|
|
@@ -337,7 +337,7 @@ export class UUID extends Binary {
|
|
|
337
337
|
} else if (typeof input === 'string') {
|
|
338
338
|
bytes = uuidHexStringToBuffer(input);
|
|
339
339
|
} else {
|
|
340
|
-
throw new
|
|
340
|
+
throw new BSONError(
|
|
341
341
|
'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).'
|
|
342
342
|
);
|
|
343
343
|
}
|
package/src/bson.ts
CHANGED
package/src/decimal128.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
|
-
import {
|
|
2
|
+
import { BSONError } from './error';
|
|
3
3
|
import { Long } from './long';
|
|
4
4
|
import { isUint8Array } from './parser/utils';
|
|
5
5
|
import { ByteUtils } from './utils/byte_utils';
|
|
@@ -114,7 +114,7 @@ function lessThan(left: Long, right: Long): boolean {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
function invalidErr(string: string, message: string) {
|
|
117
|
-
throw new
|
|
117
|
+
throw new BSONError(`"${string}" is not a valid Decimal128 string - ${message}`);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/** @public */
|
|
@@ -147,11 +147,11 @@ export class Decimal128 {
|
|
|
147
147
|
this.bytes = Decimal128.fromString(bytes).bytes;
|
|
148
148
|
} else if (isUint8Array(bytes)) {
|
|
149
149
|
if (bytes.byteLength !== 16) {
|
|
150
|
-
throw new
|
|
150
|
+
throw new BSONError('Decimal128 must take a Buffer of 16 bytes');
|
|
151
151
|
}
|
|
152
152
|
this.bytes = bytes;
|
|
153
153
|
} else {
|
|
154
|
-
throw new
|
|
154
|
+
throw new BSONError('Decimal128 must take a Buffer or string');
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -206,7 +206,7 @@ export class Decimal128 {
|
|
|
206
206
|
// TODO: implementing a custom parsing for this, or refactoring the regex would yield
|
|
207
207
|
// further gains.
|
|
208
208
|
if (representation.length >= 7000) {
|
|
209
|
-
throw new
|
|
209
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
// Results
|
|
@@ -216,7 +216,7 @@ export class Decimal128 {
|
|
|
216
216
|
|
|
217
217
|
// Validate the string
|
|
218
218
|
if ((!stringMatch && !infMatch && !nanMatch) || representation.length === 0) {
|
|
219
|
-
throw new
|
|
219
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
if (stringMatch) {
|
|
@@ -288,7 +288,7 @@ export class Decimal128 {
|
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
if (sawRadix && !nDigitsRead)
|
|
291
|
-
throw new
|
|
291
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
292
292
|
|
|
293
293
|
// Read exponent if exists
|
|
294
294
|
if (representation[index] === 'e' || representation[index] === 'E') {
|
package/src/double.ts
CHANGED
|
@@ -57,23 +57,15 @@ export class Double {
|
|
|
57
57
|
return this.value;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
// NOTE: JavaScript has +0 and -0, apparently to model limit calculations. If a user
|
|
61
|
-
// explicitly provided `-0` then we need to ensure the sign makes it into the output
|
|
62
60
|
if (Object.is(Math.sign(this.value), -0)) {
|
|
63
|
-
|
|
61
|
+
// NOTE: JavaScript has +0 and -0, apparently to model limit calculations. If a user
|
|
62
|
+
// explicitly provided `-0` then we need to ensure the sign makes it into the output
|
|
63
|
+
return { $numberDouble: '-0.0' };
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if ($numberDouble.length >= 13) {
|
|
70
|
-
$numberDouble = this.value.toExponential(13).toUpperCase();
|
|
71
|
-
}
|
|
72
|
-
} else {
|
|
73
|
-
$numberDouble = this.value.toString();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return { $numberDouble };
|
|
66
|
+
return {
|
|
67
|
+
$numberDouble: Number.isInteger(this.value) ? this.value.toFixed(1) : this.value.toString()
|
|
68
|
+
};
|
|
77
69
|
}
|
|
78
70
|
|
|
79
71
|
/** @internal */
|
package/src/error.ts
CHANGED
|
@@ -1,21 +1,45 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* @public
|
|
3
|
+
* `BSONError` objects are thrown when runtime errors occur.
|
|
4
|
+
*/
|
|
2
5
|
export class BSONError extends Error {
|
|
3
|
-
|
|
4
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @internal
|
|
8
|
+
* The underlying algorithm for isBSONError may change to improve how strict it is
|
|
9
|
+
* about determining if an input is a BSONError. But it must remain backwards compatible
|
|
10
|
+
* with previous minors & patches of the current major version.
|
|
11
|
+
*/
|
|
12
|
+
protected get bsonError(): true {
|
|
13
|
+
return true;
|
|
5
14
|
}
|
|
6
15
|
|
|
7
|
-
get name(): string {
|
|
16
|
+
override get name(): string {
|
|
8
17
|
return 'BSONError';
|
|
9
18
|
}
|
|
10
|
-
}
|
|
11
19
|
|
|
12
|
-
/** @public */
|
|
13
|
-
export class BSONTypeError extends TypeError {
|
|
14
20
|
constructor(message: string) {
|
|
15
21
|
super(message);
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
/**
|
|
25
|
+
* @public
|
|
26
|
+
*
|
|
27
|
+
* All errors thrown from the BSON library inherit from `BSONError`.
|
|
28
|
+
* This method can assist with determining if an error originates from the BSON library
|
|
29
|
+
* even if it does not pass an `instanceof` check against this class' constructor.
|
|
30
|
+
*
|
|
31
|
+
* @param value - any javascript value that needs type checking
|
|
32
|
+
*/
|
|
33
|
+
public static isBSONError(value: unknown): value is BSONError {
|
|
34
|
+
return (
|
|
35
|
+
value != null &&
|
|
36
|
+
typeof value === 'object' &&
|
|
37
|
+
'bsonError' in value &&
|
|
38
|
+
value.bsonError === true &&
|
|
39
|
+
// Do not access the following properties, just check existence
|
|
40
|
+
'name' in value &&
|
|
41
|
+
'message' in value &&
|
|
42
|
+
'stack' in value
|
|
43
|
+
);
|
|
20
44
|
}
|
|
21
45
|
}
|
package/src/extended_json.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { Binary } from './binary';
|
|
2
2
|
import type { Document } from './bson';
|
|
3
3
|
import { Code } from './code';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
BSON_INT32_MAX,
|
|
6
|
+
BSON_INT32_MIN,
|
|
7
|
+
BSON_INT64_MAX,
|
|
8
|
+
BSON_INT64_MIN,
|
|
9
|
+
BSON_MAJOR_VERSION
|
|
10
|
+
} from './constants';
|
|
5
11
|
import { DBRef, isDBRefLike } from './db_ref';
|
|
6
12
|
import { Decimal128 } from './decimal128';
|
|
7
13
|
import { Double } from './double';
|
|
8
|
-
import { BSONError
|
|
14
|
+
import { BSONError } from './error';
|
|
9
15
|
import { Int32 } from './int_32';
|
|
10
16
|
import { Long } from './long';
|
|
11
17
|
import { MaxKey } from './max_key';
|
|
@@ -192,7 +198,7 @@ function serializeValue(value: any, options: EJSONSerializeOptions): any {
|
|
|
192
198
|
circularPart.length + (alreadySeen.length + current.length) / 2 - 1
|
|
193
199
|
);
|
|
194
200
|
|
|
195
|
-
throw new
|
|
201
|
+
throw new BSONError(
|
|
196
202
|
'Converting circular structure to EJSON:\n' +
|
|
197
203
|
` ${leadingPart}${alreadySeen}${circularPart}${current}\n` +
|
|
198
204
|
` ${leadingSpace}\\${dashes}/`
|
|
@@ -310,7 +316,7 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
|
|
|
310
316
|
doc != null &&
|
|
311
317
|
typeof doc === 'object' &&
|
|
312
318
|
typeof doc._bsontype === 'string' &&
|
|
313
|
-
doc[Symbol.for('@@mdb.bson.version')]
|
|
319
|
+
doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION
|
|
314
320
|
) {
|
|
315
321
|
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
|
|
316
322
|
} else if (isBSONType(doc)) {
|
|
@@ -324,7 +330,7 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
|
|
|
324
330
|
// Copy the object into this library's version of that type.
|
|
325
331
|
const mapper = BSON_TYPE_MAPPINGS[doc._bsontype];
|
|
326
332
|
if (!mapper) {
|
|
327
|
-
throw new
|
|
333
|
+
throw new BSONError('Unrecognized or invalid _bsontype: ' + doc._bsontype);
|
|
328
334
|
}
|
|
329
335
|
outDoc = mapper(outDoc);
|
|
330
336
|
}
|
package/src/long.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
|
+
import { BSONError } from './error';
|
|
2
3
|
import type { EJSONOptions } from './extended_json';
|
|
3
4
|
import type { Timestamp } from './timestamp';
|
|
4
5
|
|
|
@@ -250,7 +251,7 @@ export class Long {
|
|
|
250
251
|
* @returns The corresponding Long value
|
|
251
252
|
*/
|
|
252
253
|
static fromString(str: string, unsigned?: boolean, radix?: number): Long {
|
|
253
|
-
if (str.length === 0) throw
|
|
254
|
+
if (str.length === 0) throw new BSONError('empty string');
|
|
254
255
|
if (str === 'NaN' || str === 'Infinity' || str === '+Infinity' || str === '-Infinity')
|
|
255
256
|
return Long.ZERO;
|
|
256
257
|
if (typeof unsigned === 'number') {
|
|
@@ -260,10 +261,10 @@ export class Long {
|
|
|
260
261
|
unsigned = !!unsigned;
|
|
261
262
|
}
|
|
262
263
|
radix = radix || 10;
|
|
263
|
-
if (radix < 2 || 36 < radix) throw
|
|
264
|
+
if (radix < 2 || 36 < radix) throw new BSONError('radix');
|
|
264
265
|
|
|
265
266
|
let p;
|
|
266
|
-
if ((p = str.indexOf('-')) > 0) throw
|
|
267
|
+
if ((p = str.indexOf('-')) > 0) throw new BSONError('interior hyphen');
|
|
267
268
|
else if (p === 0) {
|
|
268
269
|
return Long.fromString(str.substring(1), unsigned, radix).neg();
|
|
269
270
|
}
|
|
@@ -431,7 +432,7 @@ export class Long {
|
|
|
431
432
|
*/
|
|
432
433
|
divide(divisor: string | number | Long | Timestamp): Long {
|
|
433
434
|
if (!Long.isLong(divisor)) divisor = Long.fromValue(divisor);
|
|
434
|
-
if (divisor.isZero()) throw
|
|
435
|
+
if (divisor.isZero()) throw new BSONError('division by zero');
|
|
435
436
|
|
|
436
437
|
// use wasm support if present
|
|
437
438
|
if (wasm) {
|
|
@@ -959,7 +960,7 @@ export class Long {
|
|
|
959
960
|
*/
|
|
960
961
|
toString(radix?: number): string {
|
|
961
962
|
radix = radix || 10;
|
|
962
|
-
if (radix < 2 || 36 < radix) throw
|
|
963
|
+
if (radix < 2 || 36 < radix) throw new BSONError('radix');
|
|
963
964
|
if (this.isZero()) return '0';
|
|
964
965
|
if (this.isNegative()) {
|
|
965
966
|
// Unsigned Longs are never negative
|
package/src/objectid.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
|
-
import {
|
|
2
|
+
import { BSONError } from './error';
|
|
3
3
|
import { isUint8Array } from './parser/utils';
|
|
4
4
|
import { BSONDataView, ByteUtils } from './utils/byte_utils';
|
|
5
5
|
|
|
@@ -57,9 +57,7 @@ export class ObjectId {
|
|
|
57
57
|
let workingId;
|
|
58
58
|
if (typeof inputId === 'object' && inputId && 'id' in inputId) {
|
|
59
59
|
if (typeof inputId.id !== 'string' && !ArrayBuffer.isView(inputId.id)) {
|
|
60
|
-
throw new
|
|
61
|
-
'Argument passed in must have an id that is of type string or Buffer'
|
|
62
|
-
);
|
|
60
|
+
throw new BSONError('Argument passed in must have an id that is of type string or Buffer');
|
|
63
61
|
}
|
|
64
62
|
if ('toHexString' in inputId && typeof inputId.toHexString === 'function') {
|
|
65
63
|
workingId = ByteUtils.fromHex(inputId.toHexString());
|
|
@@ -85,17 +83,17 @@ export class ObjectId {
|
|
|
85
83
|
if (bytes.byteLength === 12) {
|
|
86
84
|
this[kId] = bytes;
|
|
87
85
|
} else {
|
|
88
|
-
throw new
|
|
86
|
+
throw new BSONError('Argument passed in must be a string of 12 bytes');
|
|
89
87
|
}
|
|
90
88
|
} else if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
|
|
91
89
|
this[kId] = ByteUtils.fromHex(workingId);
|
|
92
90
|
} else {
|
|
93
|
-
throw new
|
|
91
|
+
throw new BSONError(
|
|
94
92
|
'Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer'
|
|
95
93
|
);
|
|
96
94
|
}
|
|
97
95
|
} else {
|
|
98
|
-
throw new
|
|
96
|
+
throw new BSONError('Argument passed in does not match the accepted types');
|
|
99
97
|
}
|
|
100
98
|
// If we are caching the hex string
|
|
101
99
|
if (ObjectId.cacheHexString) {
|
|
@@ -271,7 +269,7 @@ export class ObjectId {
|
|
|
271
269
|
static createFromHexString(hexString: string): ObjectId {
|
|
272
270
|
// Throw an error if it's not a valid setup
|
|
273
271
|
if (typeof hexString === 'undefined' || (hexString != null && hexString.length !== 24)) {
|
|
274
|
-
throw new
|
|
272
|
+
throw new BSONError(
|
|
275
273
|
'Argument passed in must be a single String of 12 bytes or a string of 24 hex characters'
|
|
276
274
|
);
|
|
277
275
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Binary } from '../binary';
|
|
2
2
|
import type { Document } from '../bson';
|
|
3
|
+
import { BSONError } from '../error';
|
|
3
4
|
import * as constants from '../constants';
|
|
4
5
|
import { ByteUtils } from '../utils/byte_utils';
|
|
5
6
|
import { isAnyArrayBuffer, isDate, isRegExp } from './utils';
|
|
@@ -77,7 +78,17 @@ function calculateElement(
|
|
|
77
78
|
case 'boolean':
|
|
78
79
|
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 1);
|
|
79
80
|
case 'object':
|
|
80
|
-
if (
|
|
81
|
+
if (
|
|
82
|
+
value != null &&
|
|
83
|
+
typeof value._bsontype === 'string' &&
|
|
84
|
+
value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION
|
|
85
|
+
) {
|
|
86
|
+
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
|
|
87
|
+
} else if (
|
|
88
|
+
value == null ||
|
|
89
|
+
value['_bsontype'] === 'MinKey' ||
|
|
90
|
+
value['_bsontype'] === 'MaxKey'
|
|
91
|
+
) {
|
|
81
92
|
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1;
|
|
82
93
|
} else if (value['_bsontype'] === 'ObjectId') {
|
|
83
94
|
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1);
|
|
@@ -14,12 +14,14 @@ import { ObjectId } from '../objectid';
|
|
|
14
14
|
import { BSONRegExp } from '../regexp';
|
|
15
15
|
import { BSONSymbol } from '../symbol';
|
|
16
16
|
import { Timestamp } from '../timestamp';
|
|
17
|
-
import { ByteUtils } from '../utils/byte_utils';
|
|
17
|
+
import { BSONDataView, ByteUtils } from '../utils/byte_utils';
|
|
18
18
|
import { validateUtf8 } from '../validate_utf8';
|
|
19
19
|
|
|
20
20
|
/** @public */
|
|
21
21
|
export interface DeserializeOptions {
|
|
22
|
-
/** when deserializing a Long will
|
|
22
|
+
/** when deserializing a Long will return as a BigInt. */
|
|
23
|
+
useBigInt64?: boolean;
|
|
24
|
+
/** when deserializing a Long will fit it into a Number if it's smaller than 53 bits. */
|
|
23
25
|
promoteLongs?: boolean;
|
|
24
26
|
/** when deserializing a Binary will return it as a node.js Buffer instance. */
|
|
25
27
|
promoteBuffers?: boolean;
|
|
@@ -29,7 +31,7 @@ export interface DeserializeOptions {
|
|
|
29
31
|
fieldsAsRaw?: Document;
|
|
30
32
|
/** return BSON regular expressions as BSONRegExp instances. */
|
|
31
33
|
bsonRegExp?: boolean;
|
|
32
|
-
/** allows the buffer to be larger than the parsed BSON object */
|
|
34
|
+
/** allows the buffer to be larger than the parsed BSON object. */
|
|
33
35
|
allowObjectSmallerThanBufferSize?: boolean;
|
|
34
36
|
/** Offset into buffer to begin reading document from */
|
|
35
37
|
index?: number;
|
|
@@ -96,7 +98,7 @@ export function internalDeserialize(
|
|
|
96
98
|
);
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
// Start
|
|
101
|
+
// Start deserialization
|
|
100
102
|
return deserializeObject(buffer, index, options, isArray);
|
|
101
103
|
}
|
|
102
104
|
|
|
@@ -117,9 +119,18 @@ function deserializeObject(
|
|
|
117
119
|
const bsonRegExp = typeof options['bsonRegExp'] === 'boolean' ? options['bsonRegExp'] : false;
|
|
118
120
|
|
|
119
121
|
// Controls the promotion of values vs wrapper classes
|
|
120
|
-
const promoteBuffers = options
|
|
121
|
-
const promoteLongs = options
|
|
122
|
-
const promoteValues = options
|
|
122
|
+
const promoteBuffers = options.promoteBuffers ?? false;
|
|
123
|
+
const promoteLongs = options.promoteLongs ?? true;
|
|
124
|
+
const promoteValues = options.promoteValues ?? true;
|
|
125
|
+
const useBigInt64 = options.useBigInt64 ?? false;
|
|
126
|
+
|
|
127
|
+
if (useBigInt64 && !promoteValues) {
|
|
128
|
+
throw new BSONError('Must either request bigint or Long for int64 deserialization');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (useBigInt64 && !promoteLongs) {
|
|
132
|
+
throw new BSONError('Must either request bigint or Long for int64 deserialization');
|
|
133
|
+
}
|
|
123
134
|
|
|
124
135
|
// Ensures default validation option if none given
|
|
125
136
|
const validation = options.validation == null ? { utf8: true } : options.validation;
|
|
@@ -323,6 +334,8 @@ function deserializeObject(
|
|
|
323
334
|
value = null;
|
|
324
335
|
} else if (elementType === constants.BSON_DATA_LONG) {
|
|
325
336
|
// Unpack the low and high bits
|
|
337
|
+
const dataview = BSONDataView.fromUint8Array(buffer.subarray(index, index + 8));
|
|
338
|
+
|
|
326
339
|
const lowBits =
|
|
327
340
|
buffer[index++] |
|
|
328
341
|
(buffer[index++] << 8) |
|
|
@@ -334,8 +347,10 @@ function deserializeObject(
|
|
|
334
347
|
(buffer[index++] << 16) |
|
|
335
348
|
(buffer[index++] << 24);
|
|
336
349
|
const long = new Long(lowBits, highBits);
|
|
337
|
-
|
|
338
|
-
|
|
350
|
+
if (useBigInt64) {
|
|
351
|
+
value = dataview.getBigInt64(0, true);
|
|
352
|
+
} else if (promoteLongs && promoteValues === true) {
|
|
353
|
+
// Promote the long if possible
|
|
339
354
|
value =
|
|
340
355
|
long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
|
|
341
356
|
? long.toNumber()
|