bson 4.6.3 → 4.7.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/bower.json +1 -1
- package/bson.d.ts +9 -9
- package/dist/bson.browser.esm.js +352 -400
- package/dist/bson.browser.esm.js.map +1 -1
- package/dist/bson.browser.umd.js +355 -403
- package/dist/bson.browser.umd.js.map +1 -1
- package/dist/bson.bundle.js +355 -403
- package/dist/bson.bundle.js.map +1 -1
- package/dist/bson.esm.js +349 -400
- package/dist/bson.esm.js.map +1 -1
- package/lib/binary.js +196 -10
- package/lib/binary.js.map +1 -1
- package/lib/bson.js +8 -9
- package/lib/bson.js.map +1 -1
- package/lib/code.js +1 -1
- package/lib/code.js.map +1 -1
- package/lib/db_ref.js +2 -2
- package/lib/db_ref.js.map +1 -1
- package/lib/decimal128.js +13 -13
- package/lib/decimal128.js.map +1 -1
- package/lib/double.js +2 -2
- package/lib/double.js.map +1 -1
- package/lib/ensure_buffer.js +1 -1
- package/lib/ensure_buffer.js.map +1 -1
- package/lib/extended_json.js +24 -12
- package/lib/extended_json.js.map +1 -1
- package/lib/int_32.js +1 -1
- package/lib/int_32.js.map +1 -1
- package/lib/long.js +3 -3
- package/lib/long.js.map +1 -1
- package/lib/map.js +1 -1
- package/lib/map.js.map +1 -1
- package/lib/objectid.js +9 -8
- package/lib/objectid.js.map +1 -1
- package/lib/parser/calculate_size.js +10 -9
- package/lib/parser/calculate_size.js.map +1 -1
- package/lib/parser/deserializer.js +20 -11
- package/lib/parser/deserializer.js.map +1 -1
- package/lib/parser/serializer.js +25 -22
- package/lib/parser/serializer.js.map +1 -1
- package/lib/parser/utils.js +23 -19
- package/lib/parser/utils.js.map +1 -1
- package/lib/regexp.js +4 -4
- package/lib/regexp.js.map +1 -1
- package/lib/symbol.js +1 -1
- package/lib/symbol.js.map +1 -1
- package/lib/timestamp.js +3 -3
- package/lib/timestamp.js.map +1 -1
- package/lib/utils/global.js +1 -1
- package/lib/utils/global.js.map +1 -1
- package/lib/uuid_utils.js +1 -1
- package/lib/uuid_utils.js.map +1 -1
- package/package.json +17 -24
- package/src/binary.ts +197 -3
- package/src/bson.ts +18 -23
- package/src/code.ts +1 -1
- package/src/db_ref.ts +1 -1
- package/src/decimal128.ts +3 -3
- package/src/extended_json.ts +13 -2
- package/src/long.ts +32 -7
- package/src/objectid.ts +3 -2
- package/src/parser/calculate_size.ts +4 -3
- package/src/parser/deserializer.ts +12 -4
- package/src/parser/serializer.ts +14 -7
- package/src/parser/utils.ts +24 -20
- package/src/timestamp.ts +1 -1
- package/src/utils/global.ts +1 -1
- package/bson-ts34.d.ts +0 -1133
- package/lib/float_parser.js +0 -137
- package/lib/float_parser.js.map +0 -1
- package/lib/uuid.js +0 -179
- package/lib/uuid.js.map +0 -1
- package/src/float_parser.ts +0 -152
- package/src/uuid.ts +0 -209
package/src/binary.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
2
|
import { ensureBuffer } from './ensure_buffer';
|
|
3
|
-
import { uuidHexStringToBuffer } from './uuid_utils';
|
|
4
|
-
import {
|
|
3
|
+
import { bufferToUuidHexString, uuidHexStringToBuffer, uuidValidateString } from './uuid_utils';
|
|
4
|
+
import { isUint8Array, randomBytes } from './parser/utils';
|
|
5
5
|
import type { EJSONOptions } from './extended_json';
|
|
6
6
|
import { BSONError, BSONTypeError } from './error';
|
|
7
|
+
import { BSON_BINARY_SUBTYPE_UUID_NEW } from './constants';
|
|
7
8
|
|
|
8
9
|
/** @public */
|
|
9
10
|
export type BinarySequence = Uint8Array | Buffer | number[];
|
|
@@ -62,6 +63,13 @@ export class Binary {
|
|
|
62
63
|
position!: number;
|
|
63
64
|
|
|
64
65
|
/**
|
|
66
|
+
* Create a new Binary instance.
|
|
67
|
+
*
|
|
68
|
+
* This constructor can accept a string as its first argument. In this case,
|
|
69
|
+
* this string will be encoded using ISO-8859-1, **not** using UTF-8.
|
|
70
|
+
* This is almost certainly not what you want. Use `new Binary(Buffer.from(string))`
|
|
71
|
+
* instead to convert the string to a Buffer using UTF-8 first.
|
|
72
|
+
*
|
|
65
73
|
* @param buffer - a buffer object containing the binary data.
|
|
66
74
|
* @param subType - the option binary type.
|
|
67
75
|
*/
|
|
@@ -270,7 +278,7 @@ export class Binary {
|
|
|
270
278
|
if (!data) {
|
|
271
279
|
throw new BSONTypeError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`);
|
|
272
280
|
}
|
|
273
|
-
return new Binary(data, type);
|
|
281
|
+
return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new Binary(data, type);
|
|
274
282
|
}
|
|
275
283
|
|
|
276
284
|
/** @internal */
|
|
@@ -285,3 +293,189 @@ export class Binary {
|
|
|
285
293
|
}
|
|
286
294
|
|
|
287
295
|
Object.defineProperty(Binary.prototype, '_bsontype', { value: 'Binary' });
|
|
296
|
+
|
|
297
|
+
/** @public */
|
|
298
|
+
export type UUIDExtended = {
|
|
299
|
+
$uuid: string;
|
|
300
|
+
};
|
|
301
|
+
const UUID_BYTE_LENGTH = 16;
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* A class representation of the BSON UUID type.
|
|
305
|
+
* @public
|
|
306
|
+
*/
|
|
307
|
+
export class UUID extends Binary {
|
|
308
|
+
static cacheHexString: boolean;
|
|
309
|
+
|
|
310
|
+
/** UUID hexString cache @internal */
|
|
311
|
+
private __id?: string;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Create an UUID type
|
|
315
|
+
*
|
|
316
|
+
* @param input - Can be a 32 or 36 character hex string (dashes excluded/included) or a 16 byte binary Buffer.
|
|
317
|
+
*/
|
|
318
|
+
constructor(input?: string | Buffer | UUID) {
|
|
319
|
+
let bytes;
|
|
320
|
+
let hexStr;
|
|
321
|
+
if (input == null) {
|
|
322
|
+
bytes = UUID.generate();
|
|
323
|
+
} else if (input instanceof UUID) {
|
|
324
|
+
bytes = Buffer.from(input.buffer);
|
|
325
|
+
hexStr = input.__id;
|
|
326
|
+
} else if (ArrayBuffer.isView(input) && input.byteLength === UUID_BYTE_LENGTH) {
|
|
327
|
+
bytes = ensureBuffer(input);
|
|
328
|
+
} else if (typeof input === 'string') {
|
|
329
|
+
bytes = uuidHexStringToBuffer(input);
|
|
330
|
+
} else {
|
|
331
|
+
throw new BSONTypeError(
|
|
332
|
+
'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).'
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
super(bytes, BSON_BINARY_SUBTYPE_UUID_NEW);
|
|
336
|
+
this.__id = hexStr;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* The UUID bytes
|
|
341
|
+
* @readonly
|
|
342
|
+
*/
|
|
343
|
+
get id(): Buffer {
|
|
344
|
+
return this.buffer;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
set id(value: Buffer) {
|
|
348
|
+
this.buffer = value;
|
|
349
|
+
|
|
350
|
+
if (UUID.cacheHexString) {
|
|
351
|
+
this.__id = bufferToUuidHexString(value);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Returns the UUID id as a 32 or 36 character hex string representation, excluding/including dashes (defaults to 36 character dash separated)
|
|
357
|
+
* @param includeDashes - should the string exclude dash-separators.
|
|
358
|
+
* */
|
|
359
|
+
toHexString(includeDashes = true): string {
|
|
360
|
+
if (UUID.cacheHexString && this.__id) {
|
|
361
|
+
return this.__id;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const uuidHexString = bufferToUuidHexString(this.id, includeDashes);
|
|
365
|
+
|
|
366
|
+
if (UUID.cacheHexString) {
|
|
367
|
+
this.__id = uuidHexString;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return uuidHexString;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Converts the id into a 36 character (dashes included) hex string, unless a encoding is specified.
|
|
375
|
+
*/
|
|
376
|
+
toString(encoding?: string): string {
|
|
377
|
+
return encoding ? this.id.toString(encoding) : this.toHexString();
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Converts the id into its JSON string representation.
|
|
382
|
+
* A 36 character (dashes included) hex string in the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
383
|
+
*/
|
|
384
|
+
toJSON(): string {
|
|
385
|
+
return this.toHexString();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Compares the equality of this UUID with `otherID`.
|
|
390
|
+
*
|
|
391
|
+
* @param otherId - UUID instance to compare against.
|
|
392
|
+
*/
|
|
393
|
+
equals(otherId: string | Buffer | UUID): boolean {
|
|
394
|
+
if (!otherId) {
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (otherId instanceof UUID) {
|
|
399
|
+
return otherId.id.equals(this.id);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
return new UUID(otherId).id.equals(this.id);
|
|
404
|
+
} catch {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Creates a Binary instance from the current UUID.
|
|
411
|
+
*/
|
|
412
|
+
toBinary(): Binary {
|
|
413
|
+
return new Binary(this.id, Binary.SUBTYPE_UUID);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Generates a populated buffer containing a v4 uuid
|
|
418
|
+
*/
|
|
419
|
+
static generate(): Buffer {
|
|
420
|
+
const bytes = randomBytes(UUID_BYTE_LENGTH);
|
|
421
|
+
|
|
422
|
+
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
|
423
|
+
// Kindly borrowed from https://github.com/uuidjs/uuid/blob/master/src/v4.js
|
|
424
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
425
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
426
|
+
|
|
427
|
+
return Buffer.from(bytes);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Checks if a value is a valid bson UUID
|
|
432
|
+
* @param input - UUID, string or Buffer to validate.
|
|
433
|
+
*/
|
|
434
|
+
static isValid(input: string | Buffer | UUID): boolean {
|
|
435
|
+
if (!input) {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (input instanceof UUID) {
|
|
440
|
+
return true;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (typeof input === 'string') {
|
|
444
|
+
return uuidValidateString(input);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (isUint8Array(input)) {
|
|
448
|
+
// check for length & uuid version (https://tools.ietf.org/html/rfc4122#section-4.1.3)
|
|
449
|
+
if (input.length !== UUID_BYTE_LENGTH) {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return (input[6] & 0xf0) === 0x40 && (input[8] & 0x80) === 0x80;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Creates an UUID from a hex string representation of an UUID.
|
|
461
|
+
* @param hexString - 32 or 36 character hex string (dashes excluded/included).
|
|
462
|
+
*/
|
|
463
|
+
static createFromHexString(hexString: string): UUID {
|
|
464
|
+
const buffer = uuidHexStringToBuffer(hexString);
|
|
465
|
+
return new UUID(buffer);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Converts to a string representation of this Id.
|
|
470
|
+
*
|
|
471
|
+
* @returns return the 36 character hex string representation.
|
|
472
|
+
* @internal
|
|
473
|
+
*/
|
|
474
|
+
[Symbol.for('nodejs.util.inspect.custom')](): string {
|
|
475
|
+
return this.inspect();
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
inspect(): string {
|
|
479
|
+
return `new UUID("${this.toHexString()}")`;
|
|
480
|
+
}
|
|
481
|
+
}
|
package/src/bson.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
|
-
import { Binary } from './binary';
|
|
2
|
+
import { Binary, UUID } from './binary';
|
|
3
3
|
import { Code } from './code';
|
|
4
4
|
import { DBRef } from './db_ref';
|
|
5
5
|
import { Decimal128 } from './decimal128';
|
|
@@ -20,9 +20,8 @@ import { serializeInto as internalSerialize, SerializeOptions } from './parser/s
|
|
|
20
20
|
import { BSONRegExp } from './regexp';
|
|
21
21
|
import { BSONSymbol } from './symbol';
|
|
22
22
|
import { Timestamp } from './timestamp';
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
export { CodeExtended } from './code';
|
|
23
|
+
export type { UUIDExtended, BinaryExtended, BinaryExtendedLegacy, BinarySequence } from './binary';
|
|
24
|
+
export type { CodeExtended } from './code';
|
|
26
25
|
export {
|
|
27
26
|
BSON_BINARY_SUBTYPE_BYTE_ARRAY,
|
|
28
27
|
BSON_BINARY_SUBTYPE_DEFAULT,
|
|
@@ -59,25 +58,21 @@ export {
|
|
|
59
58
|
BSON_INT64_MAX,
|
|
60
59
|
BSON_INT64_MIN
|
|
61
60
|
} from './constants';
|
|
62
|
-
export { DBRefLike } from './db_ref';
|
|
63
|
-
export { Decimal128Extended } from './decimal128';
|
|
64
|
-
export { DoubleExtended } from './double';
|
|
65
|
-
export {
|
|
66
|
-
export {
|
|
67
|
-
export {
|
|
68
|
-
export {
|
|
69
|
-
export {
|
|
70
|
-
export {
|
|
71
|
-
export {
|
|
72
|
-
export {
|
|
73
|
-
export {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
TimestampOverrides
|
|
78
|
-
} from './timestamp';
|
|
79
|
-
export { UUIDExtended } from './uuid';
|
|
80
|
-
export { SerializeOptions, DeserializeOptions };
|
|
61
|
+
export type { DBRefLike } from './db_ref';
|
|
62
|
+
export type { Decimal128Extended } from './decimal128';
|
|
63
|
+
export type { DoubleExtended } from './double';
|
|
64
|
+
export type { EJSONOptions } from './extended_json';
|
|
65
|
+
export { EJSON } from './extended_json';
|
|
66
|
+
export type { Int32Extended } from './int_32';
|
|
67
|
+
export type { LongExtended } from './long';
|
|
68
|
+
export type { MaxKeyExtended } from './max_key';
|
|
69
|
+
export type { MinKeyExtended } from './min_key';
|
|
70
|
+
export type { ObjectIdExtended, ObjectIdLike } from './objectid';
|
|
71
|
+
export type { BSONRegExpExtended, BSONRegExpExtendedLegacy } from './regexp';
|
|
72
|
+
export type { BSONSymbolExtended } from './symbol';
|
|
73
|
+
export type { LongWithoutOverrides, TimestampExtended, TimestampOverrides } from './timestamp';
|
|
74
|
+
export { LongWithoutOverridesClass } from './timestamp';
|
|
75
|
+
export type { SerializeOptions, DeserializeOptions };
|
|
81
76
|
export {
|
|
82
77
|
Code,
|
|
83
78
|
Map,
|
package/src/code.ts
CHANGED
package/src/db_ref.ts
CHANGED
|
@@ -115,7 +115,7 @@ export class DBRef {
|
|
|
115
115
|
// NOTE: if OID is an ObjectId class it will just print the oid string.
|
|
116
116
|
const oid =
|
|
117
117
|
this.oid === undefined || this.oid.toString === undefined ? this.oid : this.oid.toString();
|
|
118
|
-
return `new DBRef("${this.namespace}", new ObjectId("${oid}")${
|
|
118
|
+
return `new DBRef("${this.namespace}", new ObjectId("${String(oid)}")${
|
|
119
119
|
this.db ? `, "${this.db}"` : ''
|
|
120
120
|
})`;
|
|
121
121
|
}
|
package/src/decimal128.ts
CHANGED
|
@@ -690,8 +690,8 @@ export class Decimal128 {
|
|
|
690
690
|
// representation should be treated as 0/-0" spec cases in decimal128-1.json)
|
|
691
691
|
if (significand_digits > 34) {
|
|
692
692
|
string.push(`${0}`);
|
|
693
|
-
if (exponent > 0) string.push(
|
|
694
|
-
else if (exponent < 0) string.push(
|
|
693
|
+
if (exponent > 0) string.push(`E+${exponent}`);
|
|
694
|
+
else if (exponent < 0) string.push(`E${exponent}`);
|
|
695
695
|
return string.join('');
|
|
696
696
|
}
|
|
697
697
|
|
|
@@ -709,7 +709,7 @@ export class Decimal128 {
|
|
|
709
709
|
// Exponent
|
|
710
710
|
string.push('E');
|
|
711
711
|
if (scientific_exponent > 0) {
|
|
712
|
-
string.push(
|
|
712
|
+
string.push(`+${scientific_exponent}`);
|
|
713
713
|
} else {
|
|
714
714
|
string.push(`${scientific_exponent}`);
|
|
715
715
|
}
|
package/src/extended_json.ts
CHANGED
|
@@ -44,7 +44,8 @@ export function isBSONType(value: unknown): value is BSONType {
|
|
|
44
44
|
const BSON_INT32_MAX = 0x7fffffff;
|
|
45
45
|
const BSON_INT32_MIN = -0x80000000;
|
|
46
46
|
// INT64 boundaries
|
|
47
|
-
const BSON_INT64_MAX = 0x7fffffffffffffff;
|
|
47
|
+
// const BSON_INT64_MAX = 0x7fffffffffffffff; // TODO(NODE-4377): This number cannot be precisely represented in JS
|
|
48
|
+
const BSON_INT64_MAX = 0x8000000000000000;
|
|
48
49
|
const BSON_INT64_MIN = -0x8000000000000000;
|
|
49
50
|
|
|
50
51
|
// all the types where we don't need to do any special processing and can just pass the EJSON
|
|
@@ -284,7 +285,17 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
|
|
|
284
285
|
for (const name in doc) {
|
|
285
286
|
options.seenObjects.push({ propertyName: name, obj: null });
|
|
286
287
|
try {
|
|
287
|
-
|
|
288
|
+
const value = serializeValue(doc[name], options);
|
|
289
|
+
if (name === '__proto__') {
|
|
290
|
+
Object.defineProperty(_doc, name, {
|
|
291
|
+
value,
|
|
292
|
+
writable: true,
|
|
293
|
+
enumerable: true,
|
|
294
|
+
configurable: true
|
|
295
|
+
});
|
|
296
|
+
} else {
|
|
297
|
+
_doc[name] = value;
|
|
298
|
+
}
|
|
288
299
|
} finally {
|
|
289
300
|
options.seenObjects.pop();
|
|
290
301
|
}
|
package/src/long.ts
CHANGED
|
@@ -4,12 +4,37 @@ import type { Timestamp } from './timestamp';
|
|
|
4
4
|
|
|
5
5
|
interface LongWASMHelpers {
|
|
6
6
|
/** Gets the high bits of the last operation performed */
|
|
7
|
-
get_high(): number;
|
|
8
|
-
div_u(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
get_high(this: void): number;
|
|
8
|
+
div_u(
|
|
9
|
+
this: void,
|
|
10
|
+
lowBits: number,
|
|
11
|
+
highBits: number,
|
|
12
|
+
lowBitsDivisor: number,
|
|
13
|
+
highBitsDivisor: number
|
|
14
|
+
): number;
|
|
15
|
+
div_s(
|
|
16
|
+
this: void,
|
|
17
|
+
lowBits: number,
|
|
18
|
+
highBits: number,
|
|
19
|
+
lowBitsDivisor: number,
|
|
20
|
+
highBitsDivisor: number
|
|
21
|
+
): number;
|
|
22
|
+
rem_u(
|
|
23
|
+
this: void,
|
|
24
|
+
lowBits: number,
|
|
25
|
+
highBits: number,
|
|
26
|
+
lowBitsDivisor: number,
|
|
27
|
+
highBitsDivisor: number
|
|
28
|
+
): number;
|
|
29
|
+
rem_s(
|
|
30
|
+
this: void,
|
|
31
|
+
lowBits: number,
|
|
32
|
+
highBits: number,
|
|
33
|
+
lowBitsDivisor: number,
|
|
34
|
+
highBitsDivisor: number
|
|
35
|
+
): number;
|
|
12
36
|
mul(
|
|
37
|
+
this: void,
|
|
13
38
|
lowBits: number,
|
|
14
39
|
highBits: number,
|
|
15
40
|
lowBitsMultiplier: number,
|
|
@@ -306,8 +331,7 @@ export class Long {
|
|
|
306
331
|
/**
|
|
307
332
|
* Tests if the specified object is a Long.
|
|
308
333
|
*/
|
|
309
|
-
|
|
310
|
-
static isLong(value: any): value is Long {
|
|
334
|
+
static isLong(value: unknown): value is Long {
|
|
311
335
|
return isObjectLike(value) && value['__isLong__'] === true;
|
|
312
336
|
}
|
|
313
337
|
|
|
@@ -471,6 +495,7 @@ export class Long {
|
|
|
471
495
|
// into the result, and subtract it from the remainder. It is critical that
|
|
472
496
|
// the approximate value is less than or equal to the real value so that the
|
|
473
497
|
// remainder never becomes negative.
|
|
498
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
474
499
|
rem = this;
|
|
475
500
|
while (rem.gte(divisor)) {
|
|
476
501
|
// Approximate the result of division. This may be a little greater or
|
package/src/objectid.ts
CHANGED
|
@@ -37,7 +37,7 @@ export class ObjectId {
|
|
|
37
37
|
static cacheHexString: boolean;
|
|
38
38
|
|
|
39
39
|
/** ObjectId Bytes @internal */
|
|
40
|
-
private [kId]
|
|
40
|
+
private [kId]!: Buffer;
|
|
41
41
|
/** ObjectId hexString cache @internal */
|
|
42
42
|
private __id?: string;
|
|
43
43
|
|
|
@@ -72,7 +72,8 @@ export class ObjectId {
|
|
|
72
72
|
// Generate a new id
|
|
73
73
|
this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
|
|
74
74
|
} else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
|
|
75
|
-
|
|
75
|
+
// If intstanceof matches we can escape calling ensure buffer in Node.js environments
|
|
76
|
+
this[kId] = workingId instanceof Buffer ? workingId : ensureBuffer(workingId);
|
|
76
77
|
} else if (typeof workingId === 'string') {
|
|
77
78
|
if (workingId.length === 12) {
|
|
78
79
|
const bytes = Buffer.from(workingId);
|
|
@@ -121,15 +121,16 @@ function calculateElement(
|
|
|
121
121
|
);
|
|
122
122
|
}
|
|
123
123
|
} else if (value['_bsontype'] === 'Binary') {
|
|
124
|
+
const binary: Binary = value;
|
|
124
125
|
// Check what kind of subtype we have
|
|
125
|
-
if (
|
|
126
|
+
if (binary.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
|
|
126
127
|
return (
|
|
127
128
|
(name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) +
|
|
128
|
-
(
|
|
129
|
+
(binary.position + 1 + 4 + 1 + 4)
|
|
129
130
|
);
|
|
130
131
|
} else {
|
|
131
132
|
return (
|
|
132
|
-
(name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (
|
|
133
|
+
(name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (binary.position + 1 + 4 + 1)
|
|
133
134
|
);
|
|
134
135
|
}
|
|
135
136
|
} else if (value['_bsontype'] === 'Symbol') {
|
|
@@ -197,6 +197,7 @@ function deserializeObject(
|
|
|
197
197
|
let isPossibleDBRef = isArray ? false : null;
|
|
198
198
|
|
|
199
199
|
// While we have more left data left keep parsing
|
|
200
|
+
const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
200
201
|
while (!done) {
|
|
201
202
|
// Read the type
|
|
202
203
|
const elementType = buffer[index++];
|
|
@@ -263,10 +264,10 @@ function deserializeObject(
|
|
|
263
264
|
(buffer[index++] << 16) |
|
|
264
265
|
(buffer[index++] << 24);
|
|
265
266
|
} else if (elementType === constants.BSON_DATA_NUMBER && promoteValues === false) {
|
|
266
|
-
value = new Double(
|
|
267
|
+
value = new Double(dataview.getFloat64(index, true));
|
|
267
268
|
index = index + 8;
|
|
268
269
|
} else if (elementType === constants.BSON_DATA_NUMBER) {
|
|
269
|
-
value =
|
|
270
|
+
value = dataview.getFloat64(index, true);
|
|
270
271
|
index = index + 8;
|
|
271
272
|
} else if (elementType === constants.BSON_DATA_DATE) {
|
|
272
273
|
const lowBits =
|
|
@@ -416,6 +417,9 @@ function deserializeObject(
|
|
|
416
417
|
value = buffer.slice(index, index + binarySize);
|
|
417
418
|
} else {
|
|
418
419
|
value = new Binary(buffer.slice(index, index + binarySize), subType);
|
|
420
|
+
if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW) {
|
|
421
|
+
value = value.toUUID();
|
|
422
|
+
}
|
|
419
423
|
}
|
|
420
424
|
} else {
|
|
421
425
|
const _buffer = Buffer.alloc(binarySize);
|
|
@@ -441,8 +445,10 @@ function deserializeObject(
|
|
|
441
445
|
|
|
442
446
|
if (promoteBuffers && promoteValues) {
|
|
443
447
|
value = _buffer;
|
|
448
|
+
} else if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW) {
|
|
449
|
+
value = new Binary(buffer.slice(index, index + binarySize), subType).toUUID();
|
|
444
450
|
} else {
|
|
445
|
-
value = new Binary(
|
|
451
|
+
value = new Binary(buffer.slice(index, index + binarySize), subType);
|
|
446
452
|
}
|
|
447
453
|
}
|
|
448
454
|
|
|
@@ -697,7 +703,7 @@ function deserializeObject(
|
|
|
697
703
|
value = new DBRef(namespace, oid);
|
|
698
704
|
} else {
|
|
699
705
|
throw new BSONError(
|
|
700
|
-
|
|
706
|
+
`Detected unknown BSON type ${elementType.toString(16)} for fieldname "${name}"`
|
|
701
707
|
);
|
|
702
708
|
}
|
|
703
709
|
if (name === '__proto__') {
|
|
@@ -742,9 +748,11 @@ function isolateEval(
|
|
|
742
748
|
functionCache?: { [hash: string]: Function },
|
|
743
749
|
object?: Document
|
|
744
750
|
) {
|
|
751
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
745
752
|
if (!functionCache) return new Function(functionString);
|
|
746
753
|
// Check for cache hit, eval if missing and return cached function
|
|
747
754
|
if (functionCache[functionString] == null) {
|
|
755
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
748
756
|
functionCache[functionString] = new Function(functionString);
|
|
749
757
|
}
|
|
750
758
|
|
package/src/parser/serializer.ts
CHANGED
|
@@ -9,7 +9,6 @@ import type { Double } from '../double';
|
|
|
9
9
|
import { ensureBuffer } from '../ensure_buffer';
|
|
10
10
|
import { BSONError, BSONTypeError } from '../error';
|
|
11
11
|
import { isBSONType } from '../extended_json';
|
|
12
|
-
import { writeIEEE754 } from '../float_parser';
|
|
13
12
|
import type { Int32 } from '../int_32';
|
|
14
13
|
import { Long } from '../long';
|
|
15
14
|
import { Map } from '../map';
|
|
@@ -79,6 +78,12 @@ function serializeString(
|
|
|
79
78
|
return index;
|
|
80
79
|
}
|
|
81
80
|
|
|
81
|
+
const SPACE_FOR_FLOAT64 = new Uint8Array(8);
|
|
82
|
+
const DV_FOR_FLOAT64 = new DataView(
|
|
83
|
+
SPACE_FOR_FLOAT64.buffer,
|
|
84
|
+
SPACE_FOR_FLOAT64.byteOffset,
|
|
85
|
+
SPACE_FOR_FLOAT64.byteLength
|
|
86
|
+
);
|
|
82
87
|
function serializeNumber(
|
|
83
88
|
buffer: Buffer,
|
|
84
89
|
key: string,
|
|
@@ -119,7 +124,8 @@ function serializeNumber(
|
|
|
119
124
|
index = index + numberOfWrittenBytes;
|
|
120
125
|
buffer[index++] = 0;
|
|
121
126
|
// Write float
|
|
122
|
-
|
|
127
|
+
DV_FOR_FLOAT64.setFloat64(0, value, true);
|
|
128
|
+
buffer.set(SPACE_FOR_FLOAT64, index);
|
|
123
129
|
// Adjust index
|
|
124
130
|
index = index + 8;
|
|
125
131
|
}
|
|
@@ -487,7 +493,8 @@ function serializeDouble(
|
|
|
487
493
|
buffer[index++] = 0;
|
|
488
494
|
|
|
489
495
|
// Write float
|
|
490
|
-
|
|
496
|
+
DV_FOR_FLOAT64.setFloat64(0, value.value, true);
|
|
497
|
+
buffer.set(SPACE_FOR_FLOAT64, index);
|
|
491
498
|
|
|
492
499
|
// Adjust index
|
|
493
500
|
index = index + 8;
|
|
@@ -763,7 +770,7 @@ export function serializeInto(
|
|
|
763
770
|
if (Array.isArray(object)) {
|
|
764
771
|
// Get object keys
|
|
765
772
|
for (let i = 0; i < object.length; i++) {
|
|
766
|
-
const key =
|
|
773
|
+
const key = `${i}`;
|
|
767
774
|
let value = object[i];
|
|
768
775
|
|
|
769
776
|
// Is there an override value
|
|
@@ -841,7 +848,7 @@ export function serializeInto(
|
|
|
841
848
|
} else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
|
|
842
849
|
index = serializeMinMax(buffer, key, value, index, true);
|
|
843
850
|
} else if (typeof value['_bsontype'] !== 'undefined') {
|
|
844
|
-
throw new BSONTypeError(
|
|
851
|
+
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value['_bsontype'])}`);
|
|
845
852
|
}
|
|
846
853
|
}
|
|
847
854
|
} else if (object instanceof Map || isMap(object)) {
|
|
@@ -942,7 +949,7 @@ export function serializeInto(
|
|
|
942
949
|
} else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
|
|
943
950
|
index = serializeMinMax(buffer, key, value, index);
|
|
944
951
|
} else if (typeof value['_bsontype'] !== 'undefined') {
|
|
945
|
-
throw new BSONTypeError(
|
|
952
|
+
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value['_bsontype'])}`);
|
|
946
953
|
}
|
|
947
954
|
}
|
|
948
955
|
} else {
|
|
@@ -1047,7 +1054,7 @@ export function serializeInto(
|
|
|
1047
1054
|
} else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
|
|
1048
1055
|
index = serializeMinMax(buffer, key, value, index);
|
|
1049
1056
|
} else if (typeof value['_bsontype'] !== 'undefined') {
|
|
1050
|
-
throw new BSONTypeError(
|
|
1057
|
+
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value['_bsontype'])}`);
|
|
1051
1058
|
}
|
|
1052
1059
|
}
|
|
1053
1060
|
}
|
package/src/parser/utils.ts
CHANGED
|
@@ -33,33 +33,37 @@ declare let window: any;
|
|
|
33
33
|
declare let require: Function;
|
|
34
34
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
35
|
declare let global: any;
|
|
36
|
-
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
declare let process: any; // Used by @rollup/plugin-replace
|
|
37
38
|
|
|
38
39
|
const detectRandomBytes = (): RandomBytesFunction => {
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
if (process.browser) {
|
|
41
|
+
if (typeof window !== 'undefined') {
|
|
42
|
+
// browser crypto implementation(s)
|
|
43
|
+
const target = window.crypto || window.msCrypto; // allow for IE11
|
|
44
|
+
if (target && target.getRandomValues) {
|
|
45
|
+
return size => target.getRandomValues(Buffer.alloc(size));
|
|
46
|
+
}
|
|
44
47
|
}
|
|
45
|
-
}
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
if (typeof global !== 'undefined' && global.crypto && global.crypto.getRandomValues) {
|
|
50
|
+
// allow for RN packages such as https://www.npmjs.com/package/react-native-get-random-values to populate global
|
|
51
|
+
return size => global.crypto.getRandomValues(Buffer.alloc(size));
|
|
52
|
+
}
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
return insecureRandomBytes;
|
|
55
|
+
} else {
|
|
56
|
+
let requiredRandomBytes: RandomBytesFunction | null | undefined;
|
|
57
|
+
try {
|
|
58
|
+
requiredRandomBytes = require('crypto').randomBytes;
|
|
59
|
+
} catch (e) {
|
|
60
|
+
// keep the fallback
|
|
61
|
+
}
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
// NOTE: in transpiled cases the above require might return null/undefined
|
|
61
64
|
|
|
62
|
-
|
|
65
|
+
return requiredRandomBytes || insecureRandomBytes;
|
|
66
|
+
}
|
|
63
67
|
};
|
|
64
68
|
|
|
65
69
|
export const randomBytes = detectRandomBytes();
|
package/src/timestamp.ts
CHANGED
|
@@ -44,7 +44,7 @@ export class Timestamp extends LongWithoutOverridesClass {
|
|
|
44
44
|
constructor(low: number, high: number);
|
|
45
45
|
constructor(low: number | Long | { t: number; i: number }, high?: number) {
|
|
46
46
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
47
|
-
|
|
47
|
+
// @ts-expect-error
|
|
48
48
|
if (!(this instanceof Timestamp)) return new Timestamp(low, high);
|
|
49
49
|
|
|
50
50
|
if (Long.isLong(low)) {
|