bson 5.0.0-alpha.0 → 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 +119 -96
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +119 -96
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +120 -96
- package/lib/bson.mjs.map +1 -1
- package/package.json +4 -4
- package/src/binary.ts +12 -12
- package/src/bson.ts +1 -1
- package/src/code.ts +3 -2
- package/src/constants.ts +5 -0
- package/src/db_ref.ts +3 -2
- package/src/decimal128.ts +10 -9
- package/src/double.ts +9 -16
- package/src/error.ts +33 -9
- package/src/extended_json.ts +11 -5
- package/src/int_32.ts +3 -2
- package/src/long.ts +9 -7
- package/src/max_key.ts +4 -2
- package/src/min_key.ts +4 -2
- package/src/objectid.ts +9 -10
- package/src/parser/calculate_size.ts +12 -1
- package/src/parser/deserializer.ts +24 -9
- package/src/parser/serializer.ts +53 -34
- package/src/regexp.ts +5 -4
- package/src/symbol.ts +4 -2
- package/src/timestamp.ts +3 -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,8 +1,8 @@
|
|
|
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
|
|
5
|
-
import { BSON_BINARY_SUBTYPE_UUID_NEW } from './constants';
|
|
4
|
+
import { BSONError } from './error';
|
|
5
|
+
import { BSON_BINARY_SUBTYPE_UUID_NEW, BSON_MAJOR_VERSION } from './constants';
|
|
6
6
|
import { ByteUtils } from './utils/byte_utils';
|
|
7
7
|
|
|
8
8
|
/** @public */
|
|
@@ -32,8 +32,8 @@ export class Binary {
|
|
|
32
32
|
return 'Binary';
|
|
33
33
|
}
|
|
34
34
|
/** @internal */
|
|
35
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
36
|
-
return
|
|
35
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
36
|
+
return BSON_MAJOR_VERSION;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -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
|
}
|
|
@@ -310,8 +310,8 @@ const UUID_BYTE_LENGTH = 16;
|
|
|
310
310
|
*/
|
|
311
311
|
export class UUID extends Binary {
|
|
312
312
|
/** @internal */
|
|
313
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
314
|
-
return
|
|
313
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
314
|
+
return BSON_MAJOR_VERSION;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
static cacheHexString: boolean;
|
|
@@ -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/code.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Document } from './bson';
|
|
2
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
3
|
|
|
3
4
|
/** @public */
|
|
4
5
|
export interface CodeExtended {
|
|
@@ -16,8 +17,8 @@ export class Code {
|
|
|
16
17
|
return 'Code';
|
|
17
18
|
}
|
|
18
19
|
/** @internal */
|
|
19
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
20
|
-
return
|
|
20
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
21
|
+
return BSON_MAJOR_VERSION;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
code: string;
|
package/src/constants.ts
CHANGED
package/src/db_ref.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Document } from './bson';
|
|
2
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
3
|
import type { EJSONOptions } from './extended_json';
|
|
3
4
|
import type { ObjectId } from './objectid';
|
|
4
5
|
|
|
@@ -33,8 +34,8 @@ export class DBRef {
|
|
|
33
34
|
return 'DBRef';
|
|
34
35
|
}
|
|
35
36
|
/** @internal */
|
|
36
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
37
|
-
return
|
|
37
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
38
|
+
return BSON_MAJOR_VERSION;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
collection!: string;
|
package/src/decimal128.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
|
+
import { BSONError } from './error';
|
|
2
3
|
import { Long } from './long';
|
|
3
4
|
import { isUint8Array } from './parser/utils';
|
|
4
5
|
import { ByteUtils } from './utils/byte_utils';
|
|
@@ -113,7 +114,7 @@ function lessThan(left: Long, right: Long): boolean {
|
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
function invalidErr(string: string, message: string) {
|
|
116
|
-
throw new
|
|
117
|
+
throw new BSONError(`"${string}" is not a valid Decimal128 string - ${message}`);
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
/** @public */
|
|
@@ -131,8 +132,8 @@ export class Decimal128 {
|
|
|
131
132
|
return 'Decimal128';
|
|
132
133
|
}
|
|
133
134
|
/** @internal */
|
|
134
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
135
|
-
return
|
|
135
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
136
|
+
return BSON_MAJOR_VERSION;
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
readonly bytes!: Uint8Array;
|
|
@@ -146,11 +147,11 @@ export class Decimal128 {
|
|
|
146
147
|
this.bytes = Decimal128.fromString(bytes).bytes;
|
|
147
148
|
} else if (isUint8Array(bytes)) {
|
|
148
149
|
if (bytes.byteLength !== 16) {
|
|
149
|
-
throw new
|
|
150
|
+
throw new BSONError('Decimal128 must take a Buffer of 16 bytes');
|
|
150
151
|
}
|
|
151
152
|
this.bytes = bytes;
|
|
152
153
|
} else {
|
|
153
|
-
throw new
|
|
154
|
+
throw new BSONError('Decimal128 must take a Buffer or string');
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
|
|
@@ -205,7 +206,7 @@ export class Decimal128 {
|
|
|
205
206
|
// TODO: implementing a custom parsing for this, or refactoring the regex would yield
|
|
206
207
|
// further gains.
|
|
207
208
|
if (representation.length >= 7000) {
|
|
208
|
-
throw new
|
|
209
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
209
210
|
}
|
|
210
211
|
|
|
211
212
|
// Results
|
|
@@ -215,7 +216,7 @@ export class Decimal128 {
|
|
|
215
216
|
|
|
216
217
|
// Validate the string
|
|
217
218
|
if ((!stringMatch && !infMatch && !nanMatch) || representation.length === 0) {
|
|
218
|
-
throw new
|
|
219
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
if (stringMatch) {
|
|
@@ -287,7 +288,7 @@ export class Decimal128 {
|
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
if (sawRadix && !nDigitsRead)
|
|
290
|
-
throw new
|
|
291
|
+
throw new BSONError('' + representation + ' not a valid Decimal128 string');
|
|
291
292
|
|
|
292
293
|
// Read exponent if exists
|
|
293
294
|
if (representation[index] === 'e' || representation[index] === 'E') {
|
package/src/double.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
1
2
|
import type { EJSONOptions } from './extended_json';
|
|
2
3
|
|
|
3
4
|
/** @public */
|
|
@@ -15,8 +16,8 @@ export class Double {
|
|
|
15
16
|
return 'Double';
|
|
16
17
|
}
|
|
17
18
|
/** @internal */
|
|
18
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
19
|
-
return
|
|
19
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
20
|
+
return BSON_MAJOR_VERSION;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
value!: number;
|
|
@@ -56,23 +57,15 @@ export class Double {
|
|
|
56
57
|
return this.value;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
// NOTE: JavaScript has +0 and -0, apparently to model limit calculations. If a user
|
|
60
|
-
// explicitly provided `-0` then we need to ensure the sign makes it into the output
|
|
61
60
|
if (Object.is(Math.sign(this.value), -0)) {
|
|
62
|
-
|
|
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' };
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if ($numberDouble.length >= 13) {
|
|
69
|
-
$numberDouble = this.value.toExponential(13).toUpperCase();
|
|
70
|
-
}
|
|
71
|
-
} else {
|
|
72
|
-
$numberDouble = this.value.toString();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return { $numberDouble };
|
|
66
|
+
return {
|
|
67
|
+
$numberDouble: Number.isInteger(this.value) ? this.value.toFixed(1) : this.value.toString()
|
|
68
|
+
};
|
|
76
69
|
}
|
|
77
70
|
|
|
78
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/int_32.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
1
2
|
import type { EJSONOptions } from './extended_json';
|
|
2
3
|
|
|
3
4
|
/** @public */
|
|
@@ -15,8 +16,8 @@ export class Int32 {
|
|
|
15
16
|
return 'Int32';
|
|
16
17
|
}
|
|
17
18
|
/** @internal */
|
|
18
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
19
|
-
return
|
|
19
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
20
|
+
return BSON_MAJOR_VERSION;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
value!: number;
|
package/src/long.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
|
+
import { BSONError } from './error';
|
|
1
3
|
import type { EJSONOptions } from './extended_json';
|
|
2
4
|
import type { Timestamp } from './timestamp';
|
|
3
5
|
|
|
@@ -103,8 +105,8 @@ export class Long {
|
|
|
103
105
|
return 'Long';
|
|
104
106
|
}
|
|
105
107
|
/** @internal */
|
|
106
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
107
|
-
return
|
|
108
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
109
|
+
return BSON_MAJOR_VERSION;
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
/** An indicator used to reliably determine if an object is a Long or not. */
|
|
@@ -249,7 +251,7 @@ export class Long {
|
|
|
249
251
|
* @returns The corresponding Long value
|
|
250
252
|
*/
|
|
251
253
|
static fromString(str: string, unsigned?: boolean, radix?: number): Long {
|
|
252
|
-
if (str.length === 0) throw
|
|
254
|
+
if (str.length === 0) throw new BSONError('empty string');
|
|
253
255
|
if (str === 'NaN' || str === 'Infinity' || str === '+Infinity' || str === '-Infinity')
|
|
254
256
|
return Long.ZERO;
|
|
255
257
|
if (typeof unsigned === 'number') {
|
|
@@ -259,10 +261,10 @@ export class Long {
|
|
|
259
261
|
unsigned = !!unsigned;
|
|
260
262
|
}
|
|
261
263
|
radix = radix || 10;
|
|
262
|
-
if (radix < 2 || 36 < radix) throw
|
|
264
|
+
if (radix < 2 || 36 < radix) throw new BSONError('radix');
|
|
263
265
|
|
|
264
266
|
let p;
|
|
265
|
-
if ((p = str.indexOf('-')) > 0) throw
|
|
267
|
+
if ((p = str.indexOf('-')) > 0) throw new BSONError('interior hyphen');
|
|
266
268
|
else if (p === 0) {
|
|
267
269
|
return Long.fromString(str.substring(1), unsigned, radix).neg();
|
|
268
270
|
}
|
|
@@ -430,7 +432,7 @@ export class Long {
|
|
|
430
432
|
*/
|
|
431
433
|
divide(divisor: string | number | Long | Timestamp): Long {
|
|
432
434
|
if (!Long.isLong(divisor)) divisor = Long.fromValue(divisor);
|
|
433
|
-
if (divisor.isZero()) throw
|
|
435
|
+
if (divisor.isZero()) throw new BSONError('division by zero');
|
|
434
436
|
|
|
435
437
|
// use wasm support if present
|
|
436
438
|
if (wasm) {
|
|
@@ -958,7 +960,7 @@ export class Long {
|
|
|
958
960
|
*/
|
|
959
961
|
toString(radix?: number): string {
|
|
960
962
|
radix = radix || 10;
|
|
961
|
-
if (radix < 2 || 36 < radix) throw
|
|
963
|
+
if (radix < 2 || 36 < radix) throw new BSONError('radix');
|
|
962
964
|
if (this.isZero()) return '0';
|
|
963
965
|
if (this.isNegative()) {
|
|
964
966
|
// Unsigned Longs are never negative
|
package/src/max_key.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
|
+
|
|
1
3
|
/** @public */
|
|
2
4
|
export interface MaxKeyExtended {
|
|
3
5
|
$maxKey: 1;
|
|
@@ -13,8 +15,8 @@ export class MaxKey {
|
|
|
13
15
|
return 'MaxKey';
|
|
14
16
|
}
|
|
15
17
|
/** @internal */
|
|
16
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
17
|
-
return
|
|
18
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
19
|
+
return BSON_MAJOR_VERSION;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/** @internal */
|
package/src/min_key.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
|
+
|
|
1
3
|
/** @public */
|
|
2
4
|
export interface MinKeyExtended {
|
|
3
5
|
$minKey: 1;
|
|
@@ -13,8 +15,8 @@ export class MinKey {
|
|
|
13
15
|
return 'MinKey';
|
|
14
16
|
}
|
|
15
17
|
/** @internal */
|
|
16
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
17
|
-
return
|
|
18
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
19
|
+
return BSON_MAJOR_VERSION;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/** @internal */
|
package/src/objectid.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BSON_MAJOR_VERSION } from './constants';
|
|
2
|
+
import { BSONError } from './error';
|
|
2
3
|
import { isUint8Array } from './parser/utils';
|
|
3
4
|
import { BSONDataView, ByteUtils } from './utils/byte_utils';
|
|
4
5
|
|
|
@@ -32,8 +33,8 @@ export class ObjectId {
|
|
|
32
33
|
return 'ObjectId';
|
|
33
34
|
}
|
|
34
35
|
/** @internal */
|
|
35
|
-
get [Symbol.for('@@mdb.bson.version')]():
|
|
36
|
-
return
|
|
36
|
+
get [Symbol.for('@@mdb.bson.version')](): BSON_MAJOR_VERSION {
|
|
37
|
+
return BSON_MAJOR_VERSION;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/** @internal */
|
|
@@ -56,9 +57,7 @@ export class ObjectId {
|
|
|
56
57
|
let workingId;
|
|
57
58
|
if (typeof inputId === 'object' && inputId && 'id' in inputId) {
|
|
58
59
|
if (typeof inputId.id !== 'string' && !ArrayBuffer.isView(inputId.id)) {
|
|
59
|
-
throw new
|
|
60
|
-
'Argument passed in must have an id that is of type string or Buffer'
|
|
61
|
-
);
|
|
60
|
+
throw new BSONError('Argument passed in must have an id that is of type string or Buffer');
|
|
62
61
|
}
|
|
63
62
|
if ('toHexString' in inputId && typeof inputId.toHexString === 'function') {
|
|
64
63
|
workingId = ByteUtils.fromHex(inputId.toHexString());
|
|
@@ -84,17 +83,17 @@ export class ObjectId {
|
|
|
84
83
|
if (bytes.byteLength === 12) {
|
|
85
84
|
this[kId] = bytes;
|
|
86
85
|
} else {
|
|
87
|
-
throw new
|
|
86
|
+
throw new BSONError('Argument passed in must be a string of 12 bytes');
|
|
88
87
|
}
|
|
89
88
|
} else if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
|
|
90
89
|
this[kId] = ByteUtils.fromHex(workingId);
|
|
91
90
|
} else {
|
|
92
|
-
throw new
|
|
91
|
+
throw new BSONError(
|
|
93
92
|
'Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer'
|
|
94
93
|
);
|
|
95
94
|
}
|
|
96
95
|
} else {
|
|
97
|
-
throw new
|
|
96
|
+
throw new BSONError('Argument passed in does not match the accepted types');
|
|
98
97
|
}
|
|
99
98
|
// If we are caching the hex string
|
|
100
99
|
if (ObjectId.cacheHexString) {
|
|
@@ -270,7 +269,7 @@ export class ObjectId {
|
|
|
270
269
|
static createFromHexString(hexString: string): ObjectId {
|
|
271
270
|
// Throw an error if it's not a valid setup
|
|
272
271
|
if (typeof hexString === 'undefined' || (hexString != null && hexString.length !== 24)) {
|
|
273
|
-
throw new
|
|
272
|
+
throw new BSONError(
|
|
274
273
|
'Argument passed in must be a single String of 12 bytes or a string of 24 hex characters'
|
|
275
274
|
);
|
|
276
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()
|