bson 5.4.0 → 6.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.
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "vendor"
15
15
  ],
16
16
  "types": "bson.d.ts",
17
- "version": "5.4.0",
17
+ "version": "6.0.0-alpha.0",
18
18
  "author": {
19
19
  "name": "The MongoDB NodeJS Team",
20
20
  "email": "dbx-node@mongodb.com"
@@ -27,41 +27,41 @@
27
27
  },
28
28
  "devDependencies": {
29
29
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
30
- "@microsoft/api-extractor": "^7.35.1",
30
+ "@microsoft/api-extractor": "^7.36.4",
31
31
  "@octokit/core": "^4.2.4",
32
- "@rollup/plugin-node-resolve": "^15.0.2",
33
- "@rollup/plugin-typescript": "^11.1.0",
32
+ "@rollup/plugin-node-resolve": "^15.1.0",
33
+ "@rollup/plugin-typescript": "^11.1.2",
34
34
  "@types/chai": "^4.3.5",
35
35
  "@types/mocha": "^10.0.1",
36
- "@types/node": "^18.16.3",
37
- "@types/sinon": "^10.0.14",
36
+ "@types/node": "^18.17.3",
37
+ "@types/sinon": "^10.0.16",
38
38
  "@types/sinon-chai": "^3.2.9",
39
- "@typescript-eslint/eslint-plugin": "^5.59.2",
40
- "@typescript-eslint/parser": "^5.59.2",
39
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
40
+ "@typescript-eslint/parser": "^5.62.0",
41
41
  "benchmark": "^2.1.4",
42
42
  "chai": "^4.3.7",
43
- "chalk": "^5.2.0",
44
- "eslint": "^8.39.0",
45
- "eslint-config-prettier": "^8.8.0",
46
- "eslint-plugin-no-bigint-usage": "file:./etc/eslint/no-bigint-usage",
43
+ "chalk": "^5.3.0",
44
+ "eslint": "^8.46.0",
45
+ "eslint-config-prettier": "^8.10.0",
46
+ "eslint-plugin-no-bigint-usage": "file:etc/eslint/no-bigint-usage",
47
47
  "eslint-plugin-prettier": "^4.2.1",
48
48
  "eslint-plugin-tsdoc": "^0.2.17",
49
- "magic-string": "^0.30.0",
49
+ "magic-string": "^0.30.2",
50
50
  "mocha": "10.2.0",
51
- "node-fetch": "^3.3.1",
51
+ "node-fetch": "^3.3.2",
52
52
  "nyc": "^15.1.0",
53
53
  "prettier": "^2.8.8",
54
- "rollup": "^3.21.4",
55
- "sinon": "^15.0.4",
54
+ "rollup": "^3.27.2",
55
+ "sinon": "^15.2.0",
56
56
  "sinon-chai": "^3.7.0",
57
57
  "source-map-support": "^0.5.21",
58
58
  "standard-version": "^9.5.0",
59
+ "tar": "^6.1.15",
59
60
  "ts-node": "^10.9.1",
60
61
  "tsd": "^0.28.1",
61
62
  "typescript": "^5.0.4",
62
63
  "typescript-cached-transpile": "0.0.6",
63
- "uuid": "^9.0.0",
64
- "v8-profiler-next": "^1.9.0"
64
+ "uuid": "^9.0.0"
65
65
  },
66
66
  "tsd": {
67
67
  "directory": "test/types",
@@ -94,7 +94,7 @@
94
94
  "require": "./lib/bson.cjs"
95
95
  },
96
96
  "engines": {
97
- "node": ">=14.20.1"
97
+ "node": ">=16.20.1"
98
98
  },
99
99
  "scripts": {
100
100
  "pretest": "npm run build",
@@ -103,6 +103,7 @@
103
103
  "check:tsd": "npm run build:dts && tsd",
104
104
  "check:web": "WEB=true mocha test/node",
105
105
  "check:web-no-bigint": "WEB=true NO_BIGINT=true mocha test/node",
106
+ "check:bench": "cd test/bench && npx tsc && node ./lib/index.js && mv benchmarks.json ../../.",
106
107
  "build:ts": "node ./node_modules/typescript/bin/tsc",
107
108
  "build:dts": "npm run build:ts && api-extractor run --typescript-compiler-folder node_modules/typescript --local && node etc/clean_definition_files.cjs",
108
109
  "build:bundle": "rollup -c rollup.config.mjs",
package/src/binary.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { isUint8Array } from './parser/utils';
1
+ import { isAnyArrayBuffer, isUint8Array } from './parser/utils';
2
2
  import type { EJSONOptions } from './extended_json';
3
3
  import { BSONError } from './error';
4
4
  import { BSON_BINARY_SUBTYPE_UUID_NEW } from './constants';
@@ -65,27 +65,19 @@ export class Binary extends BSONValue {
65
65
 
66
66
  /**
67
67
  * Create a new Binary instance.
68
- *
69
- * This constructor can accept a string as its first argument. In this case,
70
- * this string will be encoded using ISO-8859-1, **not** using UTF-8.
71
- * This is almost certainly not what you want. Use `new Binary(Buffer.from(string))`
72
- * instead to convert the string to a Buffer using UTF-8 first.
73
- *
74
68
  * @param buffer - a buffer object containing the binary data.
75
69
  * @param subType - the option binary type.
76
70
  */
77
- constructor(buffer?: string | BinarySequence, subType?: number) {
71
+ constructor(buffer?: BinarySequence, subType?: number) {
78
72
  super();
79
73
  if (
80
74
  !(buffer == null) &&
81
- !(typeof buffer === 'string') &&
75
+ typeof buffer === 'string' &&
82
76
  !ArrayBuffer.isView(buffer) &&
83
- !(buffer instanceof ArrayBuffer) &&
77
+ !isAnyArrayBuffer(buffer) &&
84
78
  !Array.isArray(buffer)
85
79
  ) {
86
- throw new BSONError(
87
- 'Binary can only be constructed from string, Buffer, TypedArray, or Array<number>'
88
- );
80
+ throw new BSONError('Binary can only be constructed from Uint8Array or number[]');
89
81
  }
90
82
 
91
83
  this.sub_type = subType ?? Binary.BSON_BINARY_SUBTYPE_DEFAULT;
@@ -95,17 +87,9 @@ export class Binary extends BSONValue {
95
87
  this.buffer = ByteUtils.allocate(Binary.BUFFER_SIZE);
96
88
  this.position = 0;
97
89
  } else {
98
- if (typeof buffer === 'string') {
99
- // string
100
- this.buffer = ByteUtils.fromISO88591(buffer);
101
- } else if (Array.isArray(buffer)) {
102
- // number[]
103
- this.buffer = ByteUtils.fromNumberArray(buffer);
104
- } else {
105
- // Buffer | TypedArray | ArrayBuffer
106
- this.buffer = ByteUtils.toLocalBufferType(buffer);
107
- }
108
-
90
+ this.buffer = Array.isArray(buffer)
91
+ ? ByteUtils.fromNumberArray(buffer)
92
+ : ByteUtils.toLocalBufferType(buffer);
109
93
  this.position = this.buffer.byteLength;
110
94
  }
111
95
  }
@@ -147,12 +131,12 @@ export class Binary extends BSONValue {
147
131
  }
148
132
 
149
133
  /**
150
- * Writes a buffer or string to the binary.
134
+ * Writes a buffer to the binary.
151
135
  *
152
136
  * @param sequence - a string or buffer to be written to the Binary BSON object.
153
137
  * @param offset - specify the binary of where to write the content.
154
138
  */
155
- write(sequence: string | BinarySequence, offset: number): void {
139
+ write(sequence: BinarySequence, offset: number): void {
156
140
  offset = typeof offset === 'number' ? offset : this.position;
157
141
 
158
142
  // If the buffer is to small let's extend the buffer
@@ -169,10 +153,7 @@ export class Binary extends BSONValue {
169
153
  this.position =
170
154
  offset + sequence.byteLength > this.position ? offset + sequence.length : this.position;
171
155
  } else if (typeof sequence === 'string') {
172
- const bytes = ByteUtils.fromISO88591(sequence);
173
- this.buffer.set(bytes, offset);
174
- this.position =
175
- offset + sequence.length > this.position ? offset + sequence.length : this.position;
156
+ throw new BSONError('input cannot be string');
176
157
  }
177
158
  }
178
159
 
@@ -189,26 +170,12 @@ export class Binary extends BSONValue {
189
170
  return this.buffer.slice(position, position + length);
190
171
  }
191
172
 
192
- /**
193
- * Returns the value of this binary as a string.
194
- * @param asRaw - Will skip converting to a string
195
- * @remarks
196
- * This is handy when calling this function conditionally for some key value pairs and not others
197
- */
198
- value(asRaw?: boolean): string | BinarySequence {
199
- asRaw = !!asRaw;
200
-
173
+ /** returns a view of the binary value as a Uint8Array */
174
+ value(): Uint8Array {
201
175
  // Optimize to serialize for the situation where the data == size of buffer
202
- if (asRaw && this.buffer.length === this.position) {
203
- return this.buffer;
204
- }
205
-
206
- // If it's a node.js buffer object
207
- if (asRaw) {
208
- return this.buffer.slice(0, this.position);
209
- }
210
- // TODO(NODE-4361): remove binary string support, value(true) should be the default / only option here.
211
- return ByteUtils.toISO88591(this.buffer.subarray(0, this.position));
176
+ return this.buffer.length === this.position
177
+ ? this.buffer
178
+ : this.buffer.subarray(0, this.position);
212
179
  }
213
180
 
214
181
  /** the length of the binary sequence */
@@ -321,8 +288,6 @@ const UUID_WITH_DASHES = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A
321
288
  * @public
322
289
  */
323
290
  export class UUID extends Binary {
324
- /** @deprecated Hex string is no longer cached, this control will be removed in a future major release */
325
- static cacheHexString = false;
326
291
  /**
327
292
  * Create a UUID type
328
293
  *
package/src/constants.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /** @internal */
2
- export const BSON_MAJOR_VERSION = 5 as const;
2
+ export const BSON_MAJOR_VERSION = 6 as const;
3
3
 
4
4
  /** @internal */
5
5
  export const BSON_INT32_MAX = 0x7fffffff;
package/src/objectid.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { BSONValue } from './bson_value';
2
2
  import { BSONError } from './error';
3
- import { isUint8Array } from './parser/utils';
4
3
  import { BSONDataView, ByteUtils } from './utils/byte_utils';
5
4
 
6
5
  // Regular expression that checks for hex value
@@ -74,19 +73,11 @@ export class ObjectId extends BSONValue {
74
73
  // If intstanceof matches we can escape calling ensure buffer in Node.js environments
75
74
  this[kId] = ByteUtils.toLocalBufferType(workingId);
76
75
  } else if (typeof workingId === 'string') {
77
- if (workingId.length === 12) {
78
- // TODO(NODE-4361): Remove string of length 12 support
79
- const bytes = ByteUtils.fromUTF8(workingId);
80
- if (bytes.byteLength === 12) {
81
- this[kId] = bytes;
82
- } else {
83
- throw new BSONError('Argument passed in must be a string of 12 bytes');
84
- }
85
- } else if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
76
+ if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
86
77
  this[kId] = ByteUtils.fromHex(workingId);
87
78
  } else {
88
79
  throw new BSONError(
89
- 'Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer'
80
+ 'input must be a 24 character hex string, 12 byte Uint8Array, or an integer'
90
81
  );
91
82
  }
92
83
  } else {
@@ -113,7 +104,7 @@ export class ObjectId extends BSONValue {
113
104
  }
114
105
  }
115
106
 
116
- /** Returns the ObjectId id as a 24 character hex string representation */
107
+ /** Returns the ObjectId id as a 24 lowercase character hex string representation */
117
108
  toHexString(): string {
118
109
  if (ObjectId.cacheHexString && this.__id) {
119
110
  return this.__id;
@@ -188,44 +179,37 @@ export class ObjectId extends BSONValue {
188
179
  return this.toHexString();
189
180
  }
190
181
 
182
+ /** @internal */
183
+ private static is(variable: unknown): variable is ObjectId {
184
+ return (
185
+ variable != null &&
186
+ typeof variable === 'object' &&
187
+ '_bsontype' in variable &&
188
+ variable._bsontype === 'ObjectId'
189
+ );
190
+ }
191
+
191
192
  /**
192
193
  * Compares the equality of this ObjectId with `otherID`.
193
194
  *
194
195
  * @param otherId - ObjectId instance to compare against.
195
196
  */
196
- equals(otherId: string | ObjectId | ObjectIdLike): boolean {
197
+ equals(otherId: string | ObjectId | ObjectIdLike | undefined | null): boolean {
197
198
  if (otherId === undefined || otherId === null) {
198
199
  return false;
199
200
  }
200
201
 
201
- if (otherId instanceof ObjectId) {
202
+ if (ObjectId.is(otherId)) {
202
203
  return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]);
203
204
  }
204
205
 
205
- if (
206
- typeof otherId === 'string' &&
207
- ObjectId.isValid(otherId) &&
208
- otherId.length === 12 &&
209
- isUint8Array(this.id)
210
- ) {
211
- return ByteUtils.equals(this.id, ByteUtils.fromISO88591(otherId));
212
- }
213
-
214
- if (typeof otherId === 'string' && ObjectId.isValid(otherId) && otherId.length === 24) {
206
+ if (typeof otherId === 'string') {
215
207
  return otherId.toLowerCase() === this.toHexString();
216
208
  }
217
209
 
218
- if (typeof otherId === 'string' && ObjectId.isValid(otherId) && otherId.length === 12) {
219
- return ByteUtils.equals(ByteUtils.fromUTF8(otherId), this.id);
220
- }
221
-
222
- if (
223
- typeof otherId === 'object' &&
224
- 'toHexString' in otherId &&
225
- typeof otherId.toHexString === 'function'
226
- ) {
210
+ if (typeof otherId === 'object' && typeof otherId.toHexString === 'function') {
227
211
  const otherIdString = otherId.toHexString();
228
- const thisIdString = this.toHexString().toLowerCase();
212
+ const thisIdString = this.toHexString();
229
213
  return typeof otherIdString === 'string' && otherIdString.toLowerCase() === thisIdString;
230
214
  }
231
215
 
@@ -281,9 +265,8 @@ export class ObjectId extends BSONValue {
281
265
  }
282
266
 
283
267
  /**
284
- * Checks if a value is a valid bson ObjectId
285
- *
286
- * @param id - ObjectId instance to validate.
268
+ * Checks if a value can be used to create a valid bson ObjectId
269
+ * @param id - any JS value
287
270
  */
288
271
  static isValid(id: string | number | ObjectId | ObjectIdLike | Uint8Array): boolean {
289
272
  if (id == null) return false;
@@ -21,7 +21,7 @@ export type ByteUtils = {
21
21
  toISO88591: (buffer: Uint8Array) => string;
22
22
  /** Create a Uint8Array from a hex string */
23
23
  fromHex: (hex: string) => Uint8Array;
24
- /** Create a hex string from bytes */
24
+ /** Create a lowercase hex string from bytes */
25
25
  toHex: (buffer: Uint8Array) => string;
26
26
  /** Create a Uint8Array containing utf8 code units from a string */
27
27
  fromUTF8: (text: string) => Uint8Array;