bson 5.2.0 → 5.4.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/lib/bson.cjs CHANGED
@@ -1,5 +1,21 @@
1
1
  'use strict';
2
2
 
3
+ function isAnyArrayBuffer(value) {
4
+ return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes(Object.prototype.toString.call(value));
5
+ }
6
+ function isUint8Array(value) {
7
+ return Object.prototype.toString.call(value) === '[object Uint8Array]';
8
+ }
9
+ function isRegExp(d) {
10
+ return Object.prototype.toString.call(d) === '[object RegExp]';
11
+ }
12
+ function isMap(d) {
13
+ return Object.prototype.toString.call(d) === '[object Map]';
14
+ }
15
+ function isDate(d) {
16
+ return Object.prototype.toString.call(d) === '[object Date]';
17
+ }
18
+
3
19
  const BSON_MAJOR_VERSION = 5;
4
20
  const BSON_INT32_MAX = 0x7fffffff;
5
21
  const BSON_INT32_MIN = -0x80000000;
@@ -149,8 +165,8 @@ const nodeJsByteUtils = {
149
165
  fromUTF8(text) {
150
166
  return Buffer.from(text, 'utf8');
151
167
  },
152
- toUTF8(buffer) {
153
- return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8');
168
+ toUTF8(buffer, start, end) {
169
+ return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8', start, end);
154
170
  },
155
171
  utf8ByteLength(input) {
156
172
  return Buffer.byteLength(input, 'utf8');
@@ -260,8 +276,8 @@ const webByteUtils = {
260
276
  fromUTF8(text) {
261
277
  return new TextEncoder().encode(text);
262
278
  },
263
- toUTF8(uint8array) {
264
- return new TextDecoder('utf8', { fatal: false }).decode(uint8array);
279
+ toUTF8(uint8array, start, end) {
280
+ return new TextDecoder('utf8', { fatal: false }).decode(uint8array.slice(start, end));
265
281
  },
266
282
  utf8ByteLength(input) {
267
283
  return webByteUtils.fromUTF8(input).byteLength;
@@ -282,44 +298,6 @@ class BSONDataView extends DataView {
282
298
  }
283
299
  }
284
300
 
285
- const VALIDATION_REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15})$/i;
286
- const uuidValidateString = (str) => typeof str === 'string' && VALIDATION_REGEX.test(str);
287
- const uuidHexStringToBuffer = (hexString) => {
288
- if (!uuidValidateString(hexString)) {
289
- throw new BSONError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".');
290
- }
291
- const sanitizedHexString = hexString.replace(/-/g, '');
292
- return ByteUtils.fromHex(sanitizedHexString);
293
- };
294
- function bufferToUuidHexString(buffer, includeDashes = true) {
295
- if (includeDashes) {
296
- return [
297
- ByteUtils.toHex(buffer.subarray(0, 4)),
298
- ByteUtils.toHex(buffer.subarray(4, 6)),
299
- ByteUtils.toHex(buffer.subarray(6, 8)),
300
- ByteUtils.toHex(buffer.subarray(8, 10)),
301
- ByteUtils.toHex(buffer.subarray(10, 16))
302
- ].join('-');
303
- }
304
- return ByteUtils.toHex(buffer);
305
- }
306
-
307
- function isAnyArrayBuffer(value) {
308
- return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes(Object.prototype.toString.call(value));
309
- }
310
- function isUint8Array(value) {
311
- return Object.prototype.toString.call(value) === '[object Uint8Array]';
312
- }
313
- function isRegExp(d) {
314
- return Object.prototype.toString.call(d) === '[object RegExp]';
315
- }
316
- function isMap(d) {
317
- return Object.prototype.toString.call(d) === '[object Map]';
318
- }
319
- function isDate(d) {
320
- return Object.prototype.toString.call(d) === '[object Date]';
321
- }
322
-
323
301
  class BSONValue {
324
302
  get [Symbol.for('@@mdb.bson.version')]() {
325
303
  return BSON_MAJOR_VERSION;
@@ -431,8 +409,8 @@ class Binary extends BSONValue {
431
409
  if (encoding === 'base64')
432
410
  return ByteUtils.toBase64(this.buffer);
433
411
  if (encoding === 'utf8' || encoding === 'utf-8')
434
- return ByteUtils.toUTF8(this.buffer);
435
- return ByteUtils.toUTF8(this.buffer);
412
+ return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength);
413
+ return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength);
436
414
  }
437
415
  toExtendedJSON(options) {
438
416
  options = options || {};
@@ -481,7 +459,7 @@ class Binary extends BSONValue {
481
459
  }
482
460
  else if ('$uuid' in doc) {
483
461
  type = 4;
484
- data = uuidHexStringToBuffer(doc.$uuid);
462
+ data = UUID.bytesFromString(doc.$uuid);
485
463
  }
486
464
  if (!data) {
487
465
  throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`);
@@ -508,47 +486,45 @@ Binary.SUBTYPE_ENCRYPTED = 6;
508
486
  Binary.SUBTYPE_COLUMN = 7;
509
487
  Binary.SUBTYPE_USER_DEFINED = 128;
510
488
  const UUID_BYTE_LENGTH = 16;
489
+ const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;
490
+ const UUID_WITH_DASHES = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i;
511
491
  class UUID extends Binary {
512
492
  constructor(input) {
513
493
  let bytes;
514
- let hexStr;
515
494
  if (input == null) {
516
495
  bytes = UUID.generate();
517
496
  }
518
497
  else if (input instanceof UUID) {
519
498
  bytes = ByteUtils.toLocalBufferType(new Uint8Array(input.buffer));
520
- hexStr = input.__id;
521
499
  }
522
500
  else if (ArrayBuffer.isView(input) && input.byteLength === UUID_BYTE_LENGTH) {
523
501
  bytes = ByteUtils.toLocalBufferType(input);
524
502
  }
525
503
  else if (typeof input === 'string') {
526
- bytes = uuidHexStringToBuffer(input);
504
+ bytes = UUID.bytesFromString(input);
527
505
  }
528
506
  else {
529
507
  throw new BSONError('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).');
530
508
  }
531
509
  super(bytes, BSON_BINARY_SUBTYPE_UUID_NEW);
532
- this.__id = hexStr;
533
510
  }
534
511
  get id() {
535
512
  return this.buffer;
536
513
  }
537
514
  set id(value) {
538
515
  this.buffer = value;
539
- if (UUID.cacheHexString) {
540
- this.__id = bufferToUuidHexString(value);
541
- }
542
516
  }
543
517
  toHexString(includeDashes = true) {
544
- if (UUID.cacheHexString && this.__id) {
545
- return this.__id;
546
- }
547
- const uuidHexString = bufferToUuidHexString(this.id, includeDashes);
548
- if (UUID.cacheHexString) {
549
- this.__id = uuidHexString;
518
+ if (includeDashes) {
519
+ return [
520
+ ByteUtils.toHex(this.buffer.subarray(0, 4)),
521
+ ByteUtils.toHex(this.buffer.subarray(4, 6)),
522
+ ByteUtils.toHex(this.buffer.subarray(6, 8)),
523
+ ByteUtils.toHex(this.buffer.subarray(8, 10)),
524
+ ByteUtils.toHex(this.buffer.subarray(10, 16))
525
+ ].join('-');
550
526
  }
551
- return uuidHexString;
527
+ return ByteUtils.toHex(this.buffer);
552
528
  }
553
529
  toString(encoding) {
554
530
  if (encoding === 'hex')
@@ -587,27 +563,32 @@ class UUID extends Binary {
587
563
  if (!input) {
588
564
  return false;
589
565
  }
590
- if (input instanceof UUID) {
591
- return true;
592
- }
593
566
  if (typeof input === 'string') {
594
- return uuidValidateString(input);
567
+ return UUID.isValidUUIDString(input);
595
568
  }
596
569
  if (isUint8Array(input)) {
597
- if (input.byteLength !== UUID_BYTE_LENGTH) {
598
- return false;
599
- }
600
- return (input[6] & 0xf0) === 0x40 && (input[8] & 0x80) === 0x80;
570
+ return input.byteLength === UUID_BYTE_LENGTH;
601
571
  }
602
- return false;
572
+ return (input._bsontype === 'Binary' &&
573
+ input.sub_type === this.SUBTYPE_UUID &&
574
+ input.buffer.byteLength === 16);
603
575
  }
604
576
  static createFromHexString(hexString) {
605
- const buffer = uuidHexStringToBuffer(hexString);
577
+ const buffer = UUID.bytesFromString(hexString);
606
578
  return new UUID(buffer);
607
579
  }
608
580
  static createFromBase64(base64) {
609
581
  return new UUID(ByteUtils.fromBase64(base64));
610
582
  }
583
+ static bytesFromString(representation) {
584
+ if (!UUID.isValidUUIDString(representation)) {
585
+ throw new BSONError('UUID string representation must be 32 hex digits or canonical hyphenated representation');
586
+ }
587
+ return ByteUtils.fromHex(representation.replace(/-/g, ''));
588
+ }
589
+ static isValidUUIDString(representation) {
590
+ return UUID_WITHOUT_DASHES.test(representation) || UUID_WITH_DASHES.test(representation);
591
+ }
611
592
  [Symbol.for('nodejs.util.inspect.custom')]() {
612
593
  return this.inspect();
613
594
  }
@@ -615,6 +596,7 @@ class UUID extends Binary {
615
596
  return `new UUID("${this.toHexString()}")`;
616
597
  }
617
598
  }
599
+ UUID.cacheHexString = false;
618
600
 
619
601
  class Code extends BSONValue {
620
602
  get _bsontype() {
@@ -2434,19 +2416,21 @@ class Timestamp extends LongWithoutOverridesClass {
2434
2416
  if (typeof low.i !== 'number' && (typeof low.i !== 'object' || low.i._bsontype !== 'Int32')) {
2435
2417
  throw new BSONError('Timestamp constructed from { t, i } must provide i as a number');
2436
2418
  }
2437
- if (low.t < 0) {
2419
+ const t = Number(low.t);
2420
+ const i = Number(low.i);
2421
+ if (t < 0 || Number.isNaN(t)) {
2438
2422
  throw new BSONError('Timestamp constructed from { t, i } must provide a positive t');
2439
2423
  }
2440
- if (low.i < 0) {
2424
+ if (i < 0 || Number.isNaN(i)) {
2441
2425
  throw new BSONError('Timestamp constructed from { t, i } must provide a positive i');
2442
2426
  }
2443
- if (low.t > 4294967295) {
2427
+ if (t > 4294967295) {
2444
2428
  throw new BSONError('Timestamp constructed from { t, i } must provide t equal or less than uint32 max');
2445
2429
  }
2446
- if (low.i > 4294967295) {
2430
+ if (i > 4294967295) {
2447
2431
  throw new BSONError('Timestamp constructed from { t, i } must provide i equal or less than uint32 max');
2448
2432
  }
2449
- super(low.i.valueOf(), low.t.valueOf(), true);
2433
+ super(i, t, true);
2450
2434
  }
2451
2435
  else {
2452
2436
  throw new BSONError('A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }');
@@ -2618,7 +2602,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2618
2602
  }
2619
2603
  if (i >= buffer.byteLength)
2620
2604
  throw new BSONError('Bad BSON Document: illegal CString');
2621
- const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer.subarray(index, i));
2605
+ const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i);
2622
2606
  let shouldValidateKey = true;
2623
2607
  if (globalUTFValidation || utf8KeysSet.has(name)) {
2624
2608
  shouldValidateKey = validationSetting;
@@ -2791,7 +2775,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2791
2775
  }
2792
2776
  else {
2793
2777
  value = new Binary(buffer.slice(index, index + binarySize), subType);
2794
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW) {
2778
+ if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
2795
2779
  value = value.toUUID();
2796
2780
  }
2797
2781
  }
@@ -2817,11 +2801,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2817
2801
  if (promoteBuffers && promoteValues) {
2818
2802
  value = _buffer;
2819
2803
  }
2820
- else if (subType === BSON_BINARY_SUBTYPE_UUID_NEW) {
2821
- value = new Binary(buffer.slice(index, index + binarySize), subType).toUUID();
2822
- }
2823
2804
  else {
2824
2805
  value = new Binary(buffer.slice(index, index + binarySize), subType);
2806
+ if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
2807
+ value = value.toUUID();
2808
+ }
2825
2809
  }
2826
2810
  }
2827
2811
  index = index + binarySize;
@@ -2833,7 +2817,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2833
2817
  }
2834
2818
  if (i >= buffer.length)
2835
2819
  throw new BSONError('Bad BSON Document: illegal CString');
2836
- const source = ByteUtils.toUTF8(buffer.subarray(index, i));
2820
+ const source = ByteUtils.toUTF8(buffer, index, i);
2837
2821
  index = i + 1;
2838
2822
  i = index;
2839
2823
  while (buffer[i] !== 0x00 && i < buffer.length) {
@@ -2841,7 +2825,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2841
2825
  }
2842
2826
  if (i >= buffer.length)
2843
2827
  throw new BSONError('Bad BSON Document: illegal CString');
2844
- const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i));
2828
+ const regExpOptions = ByteUtils.toUTF8(buffer, index, i);
2845
2829
  index = i + 1;
2846
2830
  const optionsArray = new Array(regExpOptions.length);
2847
2831
  for (i = 0; i < regExpOptions.length; i++) {
@@ -2866,7 +2850,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2866
2850
  }
2867
2851
  if (i >= buffer.length)
2868
2852
  throw new BSONError('Bad BSON Document: illegal CString');
2869
- const source = ByteUtils.toUTF8(buffer.subarray(index, i));
2853
+ const source = ByteUtils.toUTF8(buffer, index, i);
2870
2854
  index = i + 1;
2871
2855
  i = index;
2872
2856
  while (buffer[i] !== 0x00 && i < buffer.length) {
@@ -2874,7 +2858,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2874
2858
  }
2875
2859
  if (i >= buffer.length)
2876
2860
  throw new BSONError('Bad BSON Document: illegal CString');
2877
- const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i));
2861
+ const regExpOptions = ByteUtils.toUTF8(buffer, index, i);
2878
2862
  index = i + 1;
2879
2863
  value = new BSONRegExp(source, regExpOptions);
2880
2864
  }
@@ -2971,7 +2955,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2971
2955
  throw new BSONError('Invalid UTF-8 string in BSON document');
2972
2956
  }
2973
2957
  }
2974
- const namespace = ByteUtils.toUTF8(buffer.subarray(index, index + stringSize - 1));
2958
+ const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1);
2975
2959
  index = index + stringSize;
2976
2960
  const oidBuffer = ByteUtils.allocate(12);
2977
2961
  oidBuffer.set(buffer.subarray(index, index + 12), 0);
@@ -3011,7 +2995,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3011
2995
  return object;
3012
2996
  }
3013
2997
  function getValidatedString(buffer, start, end, shouldValidateUtf8) {
3014
- const value = ByteUtils.toUTF8(buffer.subarray(start, end));
2998
+ const value = ByteUtils.toUTF8(buffer, start, end);
3015
2999
  if (shouldValidateUtf8) {
3016
3000
  for (let i = 0; i < value.length; i++) {
3017
3001
  if (value.charCodeAt(i) === 0xfffd) {
@@ -4053,32 +4037,32 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
4053
4037
 
4054
4038
  var bson = /*#__PURE__*/Object.freeze({
4055
4039
  __proto__: null,
4056
- Code: Code,
4040
+ BSONError: BSONError,
4041
+ BSONRegExp: BSONRegExp,
4042
+ BSONRuntimeError: BSONRuntimeError,
4057
4043
  BSONSymbol: BSONSymbol,
4058
- DBRef: DBRef,
4044
+ BSONType: BSONType,
4045
+ BSONValue: BSONValue,
4046
+ BSONVersionError: BSONVersionError,
4059
4047
  Binary: Binary,
4060
- ObjectId: ObjectId,
4061
- UUID: UUID,
4062
- Long: Long,
4063
- Timestamp: Timestamp,
4048
+ Code: Code,
4049
+ DBRef: DBRef,
4050
+ Decimal128: Decimal128,
4064
4051
  Double: Double,
4052
+ EJSON: EJSON,
4065
4053
  Int32: Int32,
4066
- MinKey: MinKey,
4054
+ Long: Long,
4067
4055
  MaxKey: MaxKey,
4068
- BSONRegExp: BSONRegExp,
4069
- Decimal128: Decimal128,
4070
- setInternalBufferSize: setInternalBufferSize,
4071
- serialize: serialize,
4072
- serializeWithBufferAndIndex: serializeWithBufferAndIndex,
4073
- deserialize: deserialize,
4056
+ MinKey: MinKey,
4057
+ ObjectId: ObjectId,
4058
+ Timestamp: Timestamp,
4059
+ UUID: UUID,
4074
4060
  calculateObjectSize: calculateObjectSize,
4061
+ deserialize: deserialize,
4075
4062
  deserializeStream: deserializeStream,
4076
- BSONValue: BSONValue,
4077
- BSONError: BSONError,
4078
- BSONVersionError: BSONVersionError,
4079
- BSONRuntimeError: BSONRuntimeError,
4080
- BSONType: BSONType,
4081
- EJSON: EJSON
4063
+ serialize: serialize,
4064
+ serializeWithBufferAndIndex: serializeWithBufferAndIndex,
4065
+ setInternalBufferSize: setInternalBufferSize
4082
4066
  });
4083
4067
 
4084
4068
  exports.BSON = bson;