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