bson 7.0.0 → 7.1.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/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "vendor"
15
15
  ],
16
16
  "types": "bson.d.ts",
17
- "version": "7.0.0",
17
+ "version": "7.1.0",
18
18
  "author": {
19
19
  "name": "The MongoDB NodeJS Team",
20
20
  "email": "dbx-node@mongodb.com"
@@ -48,7 +48,7 @@
48
48
  "magic-string": "^0.30.11",
49
49
  "mocha": "^11.7.1",
50
50
  "node-fetch": "^3.3.2",
51
- "nyc": "^15.1.0",
51
+ "nyc": "^17.1.0",
52
52
  "prettier": "^3.5.3",
53
53
  "rollup": "^4.40.1",
54
54
  "sinon": "^21.0.0",
package/src/bson.ts CHANGED
@@ -48,7 +48,9 @@ export {
48
48
  MinKey,
49
49
  MaxKey,
50
50
  BSONRegExp,
51
- Decimal128
51
+ Decimal128,
52
+ NumberUtils,
53
+ ByteUtils
52
54
  };
53
55
  export { BSONValue, bsonType, type BSONTypeTag } from './bson_value';
54
56
  export { BSONError, BSONVersionError, BSONRuntimeError, BSONOffsetError } from './error';
@@ -1,5 +1,3 @@
1
- import { ByteUtils } from '../../utils/byte_utils';
2
- import { NumberUtils } from '../../utils/number_utils';
3
1
  import { type BSONElement, parseToElements } from './parse_to_elements';
4
2
  /**
5
3
  * @experimental
@@ -11,10 +9,6 @@ export type OnDemand = {
11
9
  parseToElements: (this: void, bytes: Uint8Array, startOffset?: number) => Iterable<BSONElement>;
12
10
  // Types
13
11
  BSONElement: BSONElement;
14
-
15
- // Utils
16
- ByteUtils: ByteUtils;
17
- NumberUtils: NumberUtils;
18
12
  };
19
13
 
20
14
  /**
@@ -24,8 +18,6 @@ export type OnDemand = {
24
18
  const onDemand: OnDemand = Object.create(null);
25
19
 
26
20
  onDemand.parseToElements = parseToElements;
27
- onDemand.ByteUtils = ByteUtils;
28
- onDemand.NumberUtils = NumberUtils;
29
21
 
30
22
  Object.freeze(onDemand);
31
23
 
@@ -9,18 +9,26 @@ import { webByteUtils } from './web_byte_utils';
9
9
  * ByteUtils is configured at load time to use Node.js or Web based APIs for the internal implementations.
10
10
  */
11
11
  export type ByteUtils = {
12
+ /** Checks if the given value is a Uint8Array. */
13
+ isUint8Array: (value: unknown) => value is Uint8Array;
12
14
  /** Transforms the input to an instance of Buffer if running on node, otherwise Uint8Array */
13
15
  toLocalBufferType: (buffer: Uint8Array | ArrayBufferView | ArrayBuffer) => Uint8Array;
14
16
  /** Create empty space of size */
15
17
  allocate: (size: number) => Uint8Array;
16
18
  /** Create empty space of size, use pooled memory when available */
17
19
  allocateUnsafe: (size: number) => Uint8Array;
20
+ /** Compare 2 Uint8Arrays lexicographically */
21
+ compare: (buffer1: Uint8Array, buffer2: Uint8Array) => -1 | 0 | 1;
22
+ /** Concatenating all the Uint8Arrays in new Uint8Array. */
23
+ concat: (list: Uint8Array[]) => Uint8Array;
18
24
  /** Check if two Uint8Arrays are deep equal */
19
25
  equals: (a: Uint8Array, b: Uint8Array) => boolean;
20
- /** Check if two Uint8Arrays are deep equal */
26
+ /** Create a Uint8Array from an array of numbers */
21
27
  fromNumberArray: (array: number[]) => Uint8Array;
22
28
  /** Create a Uint8Array from a base64 string */
23
29
  fromBase64: (base64: string) => Uint8Array;
30
+ /** Create a Uint8Array from a UTF8 string */
31
+ fromUTF8: (utf8: string) => Uint8Array;
24
32
  /** Create a base64 string from bytes */
25
33
  toBase64: (buffer: Uint8Array) => string;
26
34
  /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
@@ -58,6 +66,7 @@ const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuf
58
66
  * The type annotation is important here, it asserts that each of the platform specific
59
67
  * utils implementations are compatible with the common one.
60
68
  *
61
- * @internal
69
+ * @public
70
+ * @experimental
62
71
  */
63
72
  export const ByteUtils: ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
@@ -1,6 +1,7 @@
1
1
  import { BSONError } from '../error';
2
2
  import { parseUtf8 } from '../parse_utf8';
3
3
  import { tryReadBasicLatin, tryWriteBasicLatin } from './latin';
4
+ import { isUint8Array } from '../parser/utils';
4
5
 
5
6
  type NodeJsEncoding = 'base64' | 'hex' | 'utf8' | 'binary';
6
7
  type NodeJsBuffer = ArrayBufferView &
@@ -10,6 +11,7 @@ type NodeJsBuffer = ArrayBufferView &
10
11
  toString: (this: Uint8Array, encoding: NodeJsEncoding, start?: number, end?: number) => string;
11
12
  equals: (this: Uint8Array, other: Uint8Array) => boolean;
12
13
  swap32: (this: NodeJsBuffer) => NodeJsBuffer;
14
+ compare: (this: Uint8Array, other: Uint8Array) => -1 | 0 | 1;
13
15
  };
14
16
  type NodeJsBufferConstructor = Omit<Uint8ArrayConstructor, 'from'> & {
15
17
  alloc: (size: number) => NodeJsBuffer;
@@ -21,6 +23,7 @@ type NodeJsBufferConstructor = Omit<Uint8ArrayConstructor, 'from'> & {
21
23
  from(base64: string, encoding: NodeJsEncoding): NodeJsBuffer;
22
24
  byteLength(input: string, encoding: 'utf8'): number;
23
25
  isBuffer(value: unknown): value is NodeJsBuffer;
26
+ concat(list: Uint8Array[]): NodeJsBuffer;
24
27
  };
25
28
 
26
29
  // This can be nullish, but we gate the nodejs functions on being exported whether or not this exists
@@ -51,8 +54,13 @@ const nodejsRandomBytes = (() => {
51
54
  }
52
55
  })();
53
56
 
54
- /** @internal */
57
+ /**
58
+ * @public
59
+ * @experimental
60
+ */
55
61
  export const nodeJsByteUtils = {
62
+ isUint8Array: isUint8Array,
63
+
56
64
  toLocalBufferType(potentialBuffer: Uint8Array | NodeJsBuffer | ArrayBuffer): NodeJsBuffer {
57
65
  if (Buffer.isBuffer(potentialBuffer)) {
58
66
  return potentialBuffer;
@@ -88,6 +96,14 @@ export const nodeJsByteUtils = {
88
96
  return Buffer.allocUnsafe(size);
89
97
  },
90
98
 
99
+ compare(a: Uint8Array, b: Uint8Array) {
100
+ return nodeJsByteUtils.toLocalBufferType(a).compare(b);
101
+ },
102
+
103
+ concat(list: Uint8Array[]): NodeJsBuffer {
104
+ return Buffer.concat(list);
105
+ },
106
+
91
107
  equals(a: Uint8Array, b: Uint8Array): boolean {
92
108
  return nodeJsByteUtils.toLocalBufferType(a).equals(b);
93
109
  },
@@ -100,6 +116,10 @@ export const nodeJsByteUtils = {
100
116
  return Buffer.from(base64, 'base64');
101
117
  },
102
118
 
119
+ fromUTF8(utf8: string): NodeJsBuffer {
120
+ return Buffer.from(utf8, 'utf8');
121
+ },
122
+
103
123
  toBase64(buffer: Uint8Array): string {
104
124
  return nodeJsByteUtils.toLocalBufferType(buffer).toString('base64');
105
125
  },
@@ -1,6 +1,7 @@
1
1
  import { BSONError } from '../error';
2
2
  import { tryReadBasicLatin } from './latin';
3
3
  import { parseUtf8 } from '../parse_utf8';
4
+ import { isUint8Array } from '../parser/utils';
4
5
 
5
6
  type TextDecoder = {
6
7
  readonly encoding: string;
@@ -69,8 +70,13 @@ const webRandomBytes: (byteLength: number) => Uint8Array = (() => {
69
70
 
70
71
  const HEX_DIGIT = /(\d|[a-f])/i;
71
72
 
72
- /** @internal */
73
+ /**
74
+ * @public
75
+ * @experimental
76
+ */
73
77
  export const webByteUtils = {
78
+ isUint8Array: isUint8Array,
79
+
74
80
  toLocalBufferType(
75
81
  potentialUint8array: Uint8Array | ArrayBufferViewWithTag | ArrayBuffer
76
82
  ): Uint8Array {
@@ -114,12 +120,47 @@ export const webByteUtils = {
114
120
  return webByteUtils.allocate(size);
115
121
  },
116
122
 
117
- equals(a: Uint8Array, b: Uint8Array): boolean {
118
- if (a.byteLength !== b.byteLength) {
123
+ compare(uint8Array: Uint8Array, otherUint8Array: Uint8Array): -1 | 0 | 1 {
124
+ if (uint8Array === otherUint8Array) return 0;
125
+
126
+ const len = Math.min(uint8Array.length, otherUint8Array.length);
127
+
128
+ for (let i = 0; i < len; i++) {
129
+ if (uint8Array[i] < otherUint8Array[i]) return -1;
130
+ if (uint8Array[i] > otherUint8Array[i]) return 1;
131
+ }
132
+
133
+ if (uint8Array.length < otherUint8Array.length) return -1;
134
+ if (uint8Array.length > otherUint8Array.length) return 1;
135
+
136
+ return 0;
137
+ },
138
+
139
+ concat(uint8Arrays: Uint8Array[]): Uint8Array {
140
+ if (uint8Arrays.length === 0) return webByteUtils.allocate(0);
141
+
142
+ let totalLength = 0;
143
+ for (const uint8Array of uint8Arrays) {
144
+ totalLength += uint8Array.length;
145
+ }
146
+
147
+ const result = webByteUtils.allocate(totalLength);
148
+ let offset = 0;
149
+
150
+ for (const uint8Array of uint8Arrays) {
151
+ result.set(uint8Array, offset);
152
+ offset += uint8Array.length;
153
+ }
154
+
155
+ return result;
156
+ },
157
+
158
+ equals(uint8Array: Uint8Array, otherUint8Array: Uint8Array): boolean {
159
+ if (uint8Array.byteLength !== otherUint8Array.byteLength) {
119
160
  return false;
120
161
  }
121
- for (let i = 0; i < a.byteLength; i++) {
122
- if (a[i] !== b[i]) {
162
+ for (let i = 0; i < uint8Array.byteLength; i++) {
163
+ if (uint8Array[i] !== otherUint8Array[i]) {
123
164
  return false;
124
165
  }
125
166
  }
@@ -134,6 +175,10 @@ export const webByteUtils = {
134
175
  return Uint8Array.from(atob(base64), c => c.charCodeAt(0));
135
176
  },
136
177
 
178
+ fromUTF8(utf8: string): Uint8Array {
179
+ return new TextEncoder().encode(utf8);
180
+ },
181
+
137
182
  toBase64(uint8array: Uint8Array): string {
138
183
  return btoa(webByteUtils.toISO88591(uint8array));
139
184
  },