bson 4.6.5 → 5.0.0-alpha.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.
Files changed (101) hide show
  1. package/bson.d.ts +208 -267
  2. package/lib/bson.bundle.js +4033 -0
  3. package/lib/bson.bundle.js.map +1 -0
  4. package/lib/bson.cjs +4028 -0
  5. package/lib/bson.cjs.map +1 -0
  6. package/lib/bson.mjs +4002 -0
  7. package/lib/bson.mjs.map +1 -0
  8. package/package.json +49 -61
  9. package/src/binary.ts +235 -37
  10. package/src/bson.ts +43 -129
  11. package/src/code.ts +24 -14
  12. package/src/constants.ts +28 -0
  13. package/src/db_ref.ts +13 -8
  14. package/src/decimal128.ts +31 -25
  15. package/src/double.ts +7 -5
  16. package/src/error.ts +0 -2
  17. package/src/extended_json.ts +148 -148
  18. package/src/index.ts +19 -0
  19. package/src/int_32.ts +7 -5
  20. package/src/long.ts +16 -16
  21. package/src/max_key.ts +6 -6
  22. package/src/min_key.ts +6 -6
  23. package/src/objectid.ts +41 -74
  24. package/src/parser/calculate_size.ts +39 -63
  25. package/src/parser/deserializer.ts +47 -113
  26. package/src/parser/serializer.ts +234 -341
  27. package/src/parser/utils.ts +1 -99
  28. package/src/regexp.ts +16 -5
  29. package/src/symbol.ts +7 -5
  30. package/src/timestamp.ts +62 -27
  31. package/src/utils/byte_utils.ts +61 -0
  32. package/src/utils/node_byte_utils.ts +141 -0
  33. package/src/utils/web_byte_utils.ts +190 -0
  34. package/src/uuid_utils.ts +15 -15
  35. package/bower.json +0 -26
  36. package/dist/bson.browser.esm.js +0 -7471
  37. package/dist/bson.browser.esm.js.map +0 -1
  38. package/dist/bson.browser.umd.js +0 -7538
  39. package/dist/bson.browser.umd.js.map +0 -1
  40. package/dist/bson.bundle.js +0 -7537
  41. package/dist/bson.bundle.js.map +0 -1
  42. package/dist/bson.esm.js +0 -5437
  43. package/dist/bson.esm.js.map +0 -1
  44. package/lib/binary.js +0 -247
  45. package/lib/binary.js.map +0 -1
  46. package/lib/bson.js +0 -265
  47. package/lib/bson.js.map +0 -1
  48. package/lib/code.js +0 -46
  49. package/lib/code.js.map +0 -1
  50. package/lib/constants.js +0 -82
  51. package/lib/constants.js.map +0 -1
  52. package/lib/db_ref.js +0 -97
  53. package/lib/db_ref.js.map +0 -1
  54. package/lib/decimal128.js +0 -669
  55. package/lib/decimal128.js.map +0 -1
  56. package/lib/double.js +0 -76
  57. package/lib/double.js.map +0 -1
  58. package/lib/ensure_buffer.js +0 -25
  59. package/lib/ensure_buffer.js.map +0 -1
  60. package/lib/error.js +0 -55
  61. package/lib/error.js.map +0 -1
  62. package/lib/extended_json.js +0 -390
  63. package/lib/extended_json.js.map +0 -1
  64. package/lib/int_32.js +0 -58
  65. package/lib/int_32.js.map +0 -1
  66. package/lib/long.js +0 -900
  67. package/lib/long.js.map +0 -1
  68. package/lib/map.js +0 -123
  69. package/lib/map.js.map +0 -1
  70. package/lib/max_key.js +0 -33
  71. package/lib/max_key.js.map +0 -1
  72. package/lib/min_key.js +0 -33
  73. package/lib/min_key.js.map +0 -1
  74. package/lib/objectid.js +0 -299
  75. package/lib/objectid.js.map +0 -1
  76. package/lib/parser/calculate_size.js +0 -194
  77. package/lib/parser/calculate_size.js.map +0 -1
  78. package/lib/parser/deserializer.js +0 -659
  79. package/lib/parser/deserializer.js.map +0 -1
  80. package/lib/parser/serializer.js +0 -867
  81. package/lib/parser/serializer.js.map +0 -1
  82. package/lib/parser/utils.js +0 -115
  83. package/lib/parser/utils.js.map +0 -1
  84. package/lib/regexp.js +0 -74
  85. package/lib/regexp.js.map +0 -1
  86. package/lib/symbol.js +0 -48
  87. package/lib/symbol.js.map +0 -1
  88. package/lib/timestamp.js +0 -102
  89. package/lib/timestamp.js.map +0 -1
  90. package/lib/utils/global.js +0 -18
  91. package/lib/utils/global.js.map +0 -1
  92. package/lib/uuid.js +0 -179
  93. package/lib/uuid.js.map +0 -1
  94. package/lib/uuid_utils.js +0 -35
  95. package/lib/uuid_utils.js.map +0 -1
  96. package/lib/validate_utf8.js +0 -47
  97. package/lib/validate_utf8.js.map +0 -1
  98. package/src/ensure_buffer.ts +0 -27
  99. package/src/map.ts +0 -119
  100. package/src/utils/global.ts +0 -22
  101. package/src/uuid.ts +0 -209
@@ -1,73 +1,3 @@
1
- import { Buffer } from 'buffer';
2
- import { getGlobal } from '../utils/global';
3
-
4
- type RandomBytesFunction = (size: number) => Uint8Array;
5
-
6
- /**
7
- * Normalizes our expected stringified form of a function across versions of node
8
- * @param fn - The function to stringify
9
- */
10
- export function normalizedFunctionString(fn: Function): string {
11
- return fn.toString().replace('function(', 'function (');
12
- }
13
-
14
- function isReactNative() {
15
- const g = getGlobal<{ navigator?: { product?: string } }>();
16
- return typeof g.navigator === 'object' && g.navigator.product === 'ReactNative';
17
- }
18
-
19
- const insecureRandomBytes: RandomBytesFunction = function insecureRandomBytes(size: number) {
20
- const insecureWarning = isReactNative()
21
- ? 'BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.'
22
- : 'BSON: No cryptographic implementation for random bytes present, falling back to a less secure implementation.';
23
- console.warn(insecureWarning);
24
-
25
- const result = Buffer.alloc(size);
26
- for (let i = 0; i < size; ++i) result[i] = Math.floor(Math.random() * 256);
27
- return result;
28
- };
29
-
30
- /* We do not want to have to include DOM types just for this check */
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
- declare let window: any;
33
- declare let require: Function;
34
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
- declare let global: any;
36
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
- declare let process: any; // Used by @rollup/plugin-replace
38
-
39
- const detectRandomBytes = (): RandomBytesFunction => {
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
- }
47
- }
48
-
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
- }
53
-
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
- }
62
-
63
- // NOTE: in transpiled cases the above require might return null/undefined
64
-
65
- return requiredRandomBytes || insecureRandomBytes;
66
- }
67
- };
68
-
69
- export const randomBytes = detectRandomBytes();
70
-
71
1
  export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer {
72
2
  return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes(
73
3
  Object.prototype.toString.call(value)
@@ -94,34 +24,6 @@ export function isMap(d: unknown): d is Map<unknown, unknown> {
94
24
  return Object.prototype.toString.call(d) === '[object Map]';
95
25
  }
96
26
 
97
- /** Call to check if your environment has `Buffer` */
98
- export function haveBuffer(): boolean {
99
- return typeof global !== 'undefined' && typeof global.Buffer !== 'undefined';
100
- }
101
-
102
- // To ensure that 0.4 of node works correctly
103
27
  export function isDate(d: unknown): d is Date {
104
- return isObjectLike(d) && Object.prototype.toString.call(d) === '[object Date]';
105
- }
106
-
107
- /**
108
- * @internal
109
- * this is to solve the `'someKey' in x` problem where x is unknown.
110
- * https://github.com/typescript-eslint/typescript-eslint/issues/1071#issuecomment-541955753
111
- */
112
- export function isObjectLike(candidate: unknown): candidate is Record<string, unknown> {
113
- return typeof candidate === 'object' && candidate !== null;
114
- }
115
-
116
- declare let console: { warn(...message: unknown[]): void };
117
- export function deprecate<T extends Function>(fn: T, message: string): T {
118
- let warned = false;
119
- function deprecated(this: unknown, ...args: unknown[]) {
120
- if (!warned) {
121
- console.warn(message);
122
- warned = true;
123
- }
124
- return fn.apply(this, args);
125
- }
126
- return deprecated as unknown as T;
28
+ return Object.prototype.toString.call(d) === '[object Date]';
127
29
  }
package/src/regexp.ts CHANGED
@@ -25,7 +25,13 @@ export interface BSONRegExpExtended {
25
25
  * @category BSONType
26
26
  */
27
27
  export class BSONRegExp {
28
- _bsontype!: 'BSONRegExp';
28
+ get _bsontype(): 'BSONRegExp' {
29
+ return 'BSONRegExp';
30
+ }
31
+ /** @internal */
32
+ get [Symbol.for('@@mdb.bson.version')](): 5 {
33
+ return 5;
34
+ }
29
35
 
30
36
  pattern!: string;
31
37
  options!: string;
@@ -34,8 +40,6 @@ export class BSONRegExp {
34
40
  * @param options - The regular expression options
35
41
  */
36
42
  constructor(pattern: string, options?: string) {
37
- if (!(this instanceof BSONRegExp)) return new BSONRegExp(pattern, options);
38
-
39
43
  this.pattern = pattern;
40
44
  this.options = alphabetize(options ?? '');
41
45
 
@@ -100,6 +104,13 @@ export class BSONRegExp {
100
104
  }
101
105
  throw new BSONTypeError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`);
102
106
  }
103
- }
104
107
 
105
- Object.defineProperty(BSONRegExp.prototype, '_bsontype', { value: 'BSONRegExp' });
108
+ /** @internal */
109
+ [Symbol.for('nodejs.util.inspect.custom')](): string {
110
+ return this.inspect();
111
+ }
112
+
113
+ inspect(): string {
114
+ return `new BSONRegExp(${JSON.stringify(this.pattern)}, ${JSON.stringify(this.options)})`;
115
+ }
116
+ }
package/src/symbol.ts CHANGED
@@ -9,15 +9,19 @@ export interface BSONSymbolExtended {
9
9
  * @category BSONType
10
10
  */
11
11
  export class BSONSymbol {
12
- _bsontype!: 'Symbol';
12
+ get _bsontype(): 'BSONSymbol' {
13
+ return 'BSONSymbol';
14
+ }
15
+ /** @internal */
16
+ get [Symbol.for('@@mdb.bson.version')](): 5 {
17
+ return 5;
18
+ }
13
19
 
14
20
  value!: string;
15
21
  /**
16
22
  * @param value - the string representing the symbol.
17
23
  */
18
24
  constructor(value: string) {
19
- if (!(this instanceof BSONSymbol)) return new BSONSymbol(value);
20
-
21
25
  this.value = value;
22
26
  }
23
27
 
@@ -54,5 +58,3 @@ export class BSONSymbol {
54
58
  return this.inspect();
55
59
  }
56
60
  }
57
-
58
- Object.defineProperty(BSONSymbol.prototype, '_bsontype', { value: 'Symbol' });
package/src/timestamp.ts CHANGED
@@ -1,10 +1,15 @@
1
+ import { BSONError } from './error';
2
+ import type { Int32 } from './int_32';
1
3
  import { Long } from './long';
2
- import { isObjectLike } from './parser/utils';
3
4
 
4
5
  /** @public */
5
6
  export type TimestampOverrides = '_bsontype' | 'toExtendedJSON' | 'fromExtendedJSON' | 'inspect';
6
7
  /** @public */
7
- export type LongWithoutOverrides = new (low: unknown, high?: number, unsigned?: boolean) => {
8
+ export type LongWithoutOverrides = new (
9
+ low: unknown,
10
+ high?: number | boolean,
11
+ unsigned?: boolean
12
+ ) => {
8
13
  [P in Exclude<keyof Long, TimestampOverrides>]: Long[P];
9
14
  };
10
15
  /** @public */
@@ -24,42 +29,65 @@ export interface TimestampExtended {
24
29
  * @category BSONType
25
30
  * */
26
31
  export class Timestamp extends LongWithoutOverridesClass {
27
- _bsontype!: 'Timestamp';
32
+ get _bsontype(): 'Timestamp' {
33
+ return 'Timestamp';
34
+ }
35
+ /** @internal */
36
+ get [Symbol.for('@@mdb.bson.version')](): 5 {
37
+ return 5;
38
+ }
28
39
 
29
40
  static readonly MAX_VALUE = Long.MAX_UNSIGNED_VALUE;
30
41
 
31
42
  /**
32
- * @param low - A 64-bit Long representing the Timestamp.
43
+ * @param int - A 64-bit bigint representing the Timestamp.
44
+ */
45
+ constructor(int: bigint);
46
+ /**
47
+ * @param long - A 64-bit Long representing the Timestamp.
33
48
  */
34
49
  constructor(long: Long);
35
50
  /**
36
51
  * @param value - A pair of two values indicating timestamp and increment.
37
52
  */
38
53
  constructor(value: { t: number; i: number });
39
- /**
40
- * @param low - the low (signed) 32 bits of the Timestamp.
41
- * @param high - the high (signed) 32 bits of the Timestamp.
42
- * @deprecated Please use `Timestamp({ t: high, i: low })` or `Timestamp(Long(low, high))` instead.
43
- */
44
- constructor(low: number, high: number);
45
- constructor(low: number | Long | { t: number; i: number }, high?: number) {
46
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
47
- // @ts-expect-error
48
- if (!(this instanceof Timestamp)) return new Timestamp(low, high);
49
-
50
- if (Long.isLong(low)) {
54
+ constructor(low?: bigint | Long | { t: number | Int32; i: number | Int32 }) {
55
+ if (low == null) {
56
+ super(0, 0, true);
57
+ } else if (typeof low === 'bigint') {
58
+ super(low, true);
59
+ } else if (Long.isLong(low)) {
51
60
  super(low.low, low.high, true);
52
- } else if (isObjectLike(low) && typeof low.t !== 'undefined' && typeof low.i !== 'undefined') {
53
- super(low.i, low.t, true);
61
+ } else if (typeof low === 'object' && 't' in low && 'i' in low) {
62
+ if (typeof low.t !== 'number' && (typeof low.t !== 'object' || low.t._bsontype !== 'Int32')) {
63
+ throw new BSONError('Timestamp constructed from { t, i } must provide t as a number');
64
+ }
65
+ if (typeof low.i !== 'number' && (typeof low.i !== 'object' || low.i._bsontype !== 'Int32')) {
66
+ throw new BSONError('Timestamp constructed from { t, i } must provide i as a number');
67
+ }
68
+ if (low.t < 0) {
69
+ throw new BSONError('Timestamp constructed from { t, i } must provide a positive t');
70
+ }
71
+ if (low.i < 0) {
72
+ throw new BSONError('Timestamp constructed from { t, i } must provide a positive i');
73
+ }
74
+ if (low.t > 0xffff_ffff) {
75
+ throw new BSONError(
76
+ 'Timestamp constructed from { t, i } must provide t equal or less than uint32 max'
77
+ );
78
+ }
79
+ if (low.i > 0xffff_ffff) {
80
+ throw new BSONError(
81
+ 'Timestamp constructed from { t, i } must provide i equal or less than uint32 max'
82
+ );
83
+ }
84
+
85
+ super(low.i.valueOf(), low.t.valueOf(), true);
54
86
  } else {
55
- super(low, high, true);
87
+ throw new BSONError(
88
+ 'A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }'
89
+ );
56
90
  }
57
- Object.defineProperty(this, '_bsontype', {
58
- value: 'Timestamp',
59
- writable: false,
60
- configurable: false,
61
- enumerable: false
62
- });
63
91
  }
64
92
 
65
93
  toJSON(): { $timestamp: string } {
@@ -85,7 +113,7 @@ export class Timestamp extends LongWithoutOverridesClass {
85
113
  * @param highBits - the high 32-bits.
86
114
  */
87
115
  static fromBits(lowBits: number, highBits: number): Timestamp {
88
- return new Timestamp(lowBits, highBits);
116
+ return new Timestamp({ i: lowBits, t: highBits });
89
117
  }
90
118
 
91
119
  /**
@@ -105,7 +133,14 @@ export class Timestamp extends LongWithoutOverridesClass {
105
133
 
106
134
  /** @internal */
107
135
  static fromExtendedJSON(doc: TimestampExtended): Timestamp {
108
- return new Timestamp(doc.$timestamp);
136
+ // The Long check is necessary because extended JSON has different behavior given the size of the input number
137
+ const i = Long.isLong(doc.$timestamp.i)
138
+ ? doc.$timestamp.i.getLowBitsUnsigned() // Need to fetch the least significant 32 bits
139
+ : doc.$timestamp.i;
140
+ const t = Long.isLong(doc.$timestamp.t)
141
+ ? doc.$timestamp.t.getLowBitsUnsigned() // Need to fetch the least significant 32 bits
142
+ : doc.$timestamp.t;
143
+ return new Timestamp({ t, i });
109
144
  }
110
145
 
111
146
  /** @internal */
@@ -0,0 +1,61 @@
1
+ import { nodeJsByteUtils } from './node_byte_utils';
2
+ import { webByteUtils } from './web_byte_utils';
3
+
4
+ /** @internal */
5
+ export type ByteUtils = {
6
+ /** Transforms the input to an instance of Buffer if running on node, otherwise Uint8Array */
7
+ toLocalBufferType(buffer: Uint8Array | ArrayBufferView | ArrayBuffer): Uint8Array;
8
+ /** Create empty space of size */
9
+ allocate: (size: number) => Uint8Array;
10
+ /** Check if two Uint8Arrays are deep equal */
11
+ equals: (a: Uint8Array, b: Uint8Array) => boolean;
12
+ /** Check if two Uint8Arrays are deep equal */
13
+ fromNumberArray: (array: number[]) => Uint8Array;
14
+ /** Create a Uint8Array from a base64 string */
15
+ fromBase64: (base64: string) => Uint8Array;
16
+ /** Create a base64 string from bytes */
17
+ toBase64: (buffer: Uint8Array) => string;
18
+ /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
19
+ fromISO88591: (codePoints: string) => Uint8Array;
20
+ /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
21
+ toISO88591: (buffer: Uint8Array) => string;
22
+ /** Create a Uint8Array from a hex string */
23
+ fromHex: (hex: string) => Uint8Array;
24
+ /** Create a hex string from bytes */
25
+ toHex: (buffer: Uint8Array) => string;
26
+ /** Create a Uint8Array containing utf8 code units from a string */
27
+ fromUTF8: (text: string) => Uint8Array;
28
+ /** Create a string from utf8 code units */
29
+ toUTF8: (buffer: Uint8Array) => string;
30
+ /** Get the utf8 code unit count from a string if it were to be transformed to utf8 */
31
+ utf8ByteLength: (input: string) => number;
32
+ /** Encode UTF8 bytes generated from `source` string into `destination` at byteOffset. Returns the number of bytes encoded. */
33
+ encodeUTF8Into(destination: Uint8Array, source: string, byteOffset: number): number;
34
+ /** Generate a Uint8Array filled with random bytes with byteLength */
35
+ randomBytes(byteLength: number): Uint8Array;
36
+ };
37
+
38
+ declare const Buffer: { new (): unknown; prototype?: { _isBuffer?: boolean } } | undefined;
39
+
40
+ /**
41
+ * Check that a global Buffer exists that is a function and
42
+ * does not have a '_isBuffer' property defined on the prototype
43
+ * (this is to prevent using the npm buffer)
44
+ */
45
+ const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
46
+
47
+ /**
48
+ * This is the only ByteUtils that should be used across the rest of the BSON library.
49
+ *
50
+ * The type annotation is important here, it asserts that each of the platform specific
51
+ * utils implementations are compatible with the common one.
52
+ *
53
+ * @internal
54
+ */
55
+ export const ByteUtils: ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
56
+
57
+ export class BSONDataView extends DataView {
58
+ static fromUint8Array(input: Uint8Array) {
59
+ return new DataView(input.buffer, input.byteOffset, input.byteLength);
60
+ }
61
+ }
@@ -0,0 +1,141 @@
1
+ import { BSONError } from '../error';
2
+
3
+ type NodeJsEncoding = 'base64' | 'hex' | 'utf8' | 'binary';
4
+ type NodeJsBuffer = ArrayBufferView &
5
+ Uint8Array & {
6
+ write(string: string, offset: number, length: undefined, encoding: 'utf8'): number;
7
+ copy(target: Uint8Array, targetStart: number, sourceStart: number, sourceEnd: number): number;
8
+ toString: (this: Uint8Array, encoding: NodeJsEncoding) => string;
9
+ equals: (this: Uint8Array, other: Uint8Array) => boolean;
10
+ };
11
+ type NodeJsBufferConstructor = Omit<Uint8ArrayConstructor, 'from'> & {
12
+ alloc: (size: number) => NodeJsBuffer;
13
+ from(array: number[]): NodeJsBuffer;
14
+ from(array: Uint8Array): NodeJsBuffer;
15
+ from(array: ArrayBuffer): NodeJsBuffer;
16
+ from(array: ArrayBuffer, byteOffset: number, byteLength: number): NodeJsBuffer;
17
+ from(base64: string, encoding: NodeJsEncoding): NodeJsBuffer;
18
+ byteLength(input: string, encoding: 'utf8'): number;
19
+ isBuffer(value: unknown): value is NodeJsBuffer;
20
+ };
21
+
22
+ // This can be nullish, but we gate the nodejs functions on being exported whether or not this exists
23
+ // Node.js global
24
+ declare const Buffer: NodeJsBufferConstructor;
25
+ declare const require: (mod: 'node:crypto') => { randomBytes: (byteLength: number) => Uint8Array };
26
+
27
+ /** @internal */
28
+ export function nodejsMathRandomBytes(byteLength: number) {
29
+ return nodeJsByteUtils.fromNumberArray(
30
+ Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256))
31
+ );
32
+ }
33
+
34
+ /**
35
+ * @internal
36
+ * WARNING: REQUIRE WILL BE REWRITTEN
37
+ *
38
+ * This code is carefully used by require_rewriter.mjs any modifications must be reflected in the plugin.
39
+ *
40
+ * @remarks
41
+ * "crypto" is the only dependency BSON needs. This presents a problem for creating a bundle of the BSON library
42
+ * in an es module format that can be used both on the browser and in Node.js. In Node.js when BSON is imported as
43
+ * an es module, there will be no global require function defined, making the code below fallback to the much less desireable math.random bytes.
44
+ * In order to make our es module bundle work as expected on Node.js we need to change this `require()` to a dynamic import, and the dynamic
45
+ * import must be top-level awaited since es modules are async. So we rely on a custom rollup plugin to seek out the following lines of code
46
+ * and replace `require` with `await import` and the IIFE line (`nodejsRandomBytes = (() => { ... })()`) with `nodejsRandomBytes = await (async () => { ... })()`
47
+ * when generating an es module bundle.
48
+ */
49
+ const nodejsRandomBytes: (byteLength: number) => Uint8Array = (() => {
50
+ try {
51
+ return require('node:crypto').randomBytes;
52
+ } catch {
53
+ return nodejsMathRandomBytes;
54
+ }
55
+ })();
56
+
57
+ /** @internal */
58
+ export const nodeJsByteUtils = {
59
+ toLocalBufferType(potentialBuffer: Uint8Array | NodeJsBuffer | ArrayBuffer): NodeJsBuffer {
60
+ if (Buffer.isBuffer(potentialBuffer)) {
61
+ return potentialBuffer;
62
+ }
63
+
64
+ if (ArrayBuffer.isView(potentialBuffer)) {
65
+ return Buffer.from(
66
+ potentialBuffer.buffer,
67
+ potentialBuffer.byteOffset,
68
+ potentialBuffer.byteLength
69
+ );
70
+ }
71
+
72
+ const stringTag =
73
+ potentialBuffer?.[Symbol.toStringTag] ?? Object.prototype.toString.call(potentialBuffer);
74
+ if (
75
+ stringTag === 'ArrayBuffer' ||
76
+ stringTag === 'SharedArrayBuffer' ||
77
+ stringTag === '[object ArrayBuffer]' ||
78
+ stringTag === '[object SharedArrayBuffer]'
79
+ ) {
80
+ return Buffer.from(potentialBuffer);
81
+ }
82
+
83
+ throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`);
84
+ },
85
+
86
+ allocate(size: number): NodeJsBuffer {
87
+ return Buffer.alloc(size);
88
+ },
89
+
90
+ equals(a: Uint8Array, b: Uint8Array): boolean {
91
+ return nodeJsByteUtils.toLocalBufferType(a).equals(b);
92
+ },
93
+
94
+ fromNumberArray(array: number[]): NodeJsBuffer {
95
+ return Buffer.from(array);
96
+ },
97
+
98
+ fromBase64(base64: string): NodeJsBuffer {
99
+ return Buffer.from(base64, 'base64');
100
+ },
101
+
102
+ toBase64(buffer: Uint8Array): string {
103
+ return nodeJsByteUtils.toLocalBufferType(buffer).toString('base64');
104
+ },
105
+
106
+ /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
107
+ fromISO88591(codePoints: string): NodeJsBuffer {
108
+ return Buffer.from(codePoints, 'binary');
109
+ },
110
+
111
+ /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
112
+ toISO88591(buffer: Uint8Array): string {
113
+ return nodeJsByteUtils.toLocalBufferType(buffer).toString('binary');
114
+ },
115
+
116
+ fromHex(hex: string): NodeJsBuffer {
117
+ return Buffer.from(hex, 'hex');
118
+ },
119
+
120
+ toHex(buffer: Uint8Array): string {
121
+ return nodeJsByteUtils.toLocalBufferType(buffer).toString('hex');
122
+ },
123
+
124
+ fromUTF8(text: string): NodeJsBuffer {
125
+ return Buffer.from(text, 'utf8');
126
+ },
127
+
128
+ toUTF8(buffer: Uint8Array): string {
129
+ return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8');
130
+ },
131
+
132
+ utf8ByteLength(input: string): number {
133
+ return Buffer.byteLength(input, 'utf8');
134
+ },
135
+
136
+ encodeUTF8Into(buffer: Uint8Array, source: string, byteOffset: number): number {
137
+ return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
138
+ },
139
+
140
+ randomBytes: nodejsRandomBytes
141
+ };