bson 6.1.0 → 6.3.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": "6.1.0",
17
+ "version": "6.3.0",
18
18
  "author": {
19
19
  "name": "The MongoDB NodeJS Team",
20
20
  "email": "dbx-node@mongodb.com"
@@ -27,41 +27,42 @@
27
27
  },
28
28
  "devDependencies": {
29
29
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
30
- "@microsoft/api-extractor": "^7.36.4",
30
+ "@microsoft/api-extractor": "^7.38.4",
31
31
  "@octokit/core": "^4.2.4",
32
- "@rollup/plugin-node-resolve": "^15.1.0",
33
- "@rollup/plugin-typescript": "^11.1.2",
34
- "@types/chai": "^4.3.5",
35
- "@types/mocha": "^10.0.1",
36
- "@types/node": "^18.17.3",
37
- "@types/sinon": "^10.0.16",
38
- "@types/sinon-chai": "^3.2.9",
32
+ "@rollup/plugin-node-resolve": "^15.2.3",
33
+ "@rollup/plugin-typescript": "^11.1.5",
34
+ "@types/chai": "^4.3.11",
35
+ "@types/mocha": "^10.0.6",
36
+ "@types/node": "^18.19.2",
37
+ "@types/sinon": "^10.0.20",
38
+ "@types/sinon-chai": "^3.2.12",
39
39
  "@typescript-eslint/eslint-plugin": "^5.62.0",
40
40
  "@typescript-eslint/parser": "^5.62.0",
41
41
  "benchmark": "^2.1.4",
42
- "chai": "^4.3.7",
42
+ "chai": "^4.3.10",
43
43
  "chalk": "^5.3.0",
44
- "eslint": "^8.46.0",
44
+ "dbx-js-tools": "github:mongodb-js/dbx-js-tools",
45
+ "eslint": "^8.55.0",
45
46
  "eslint-config-prettier": "^8.10.0",
46
47
  "eslint-plugin-no-bigint-usage": "file:etc/eslint/no-bigint-usage",
47
48
  "eslint-plugin-prettier": "^4.2.1",
48
49
  "eslint-plugin-tsdoc": "^0.2.17",
49
- "magic-string": "^0.30.2",
50
+ "magic-string": "^0.30.5",
50
51
  "mocha": "10.2.0",
51
52
  "node-fetch": "^3.3.2",
52
53
  "nyc": "^15.1.0",
53
54
  "prettier": "^2.8.8",
54
- "rollup": "^3.27.2",
55
+ "rollup": "^3.29.4",
55
56
  "sinon": "^15.2.0",
56
57
  "sinon-chai": "^3.7.0",
57
58
  "source-map-support": "^0.5.21",
58
59
  "standard-version": "^9.5.0",
59
- "tar": "^6.1.15",
60
+ "tar": "^6.2.0",
60
61
  "ts-node": "^10.9.1",
61
62
  "tsd": "^0.28.1",
62
63
  "typescript": "^5.0.4",
63
64
  "typescript-cached-transpile": "0.0.6",
64
- "uuid": "^9.0.0"
65
+ "uuid": "^9.0.1"
65
66
  },
66
67
  "tsd": {
67
68
  "directory": "test/types",
@@ -103,7 +104,9 @@
103
104
  "check:tsd": "npm run build:dts && tsd",
104
105
  "check:web": "WEB=true mocha test/node",
105
106
  "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 ../../.",
107
+ "check:granular-bench": "npm run build:bench && node ./test/bench/etc/run_granular_benchmarks.js",
108
+ "check:spec-bench": "npm run build:bench && node ./test/bench/lib/spec/bsonBench.js",
109
+ "build:bench": "cd test/bench && npx tsc",
107
110
  "build:ts": "node ./node_modules/typescript/bin/tsc",
108
111
  "build:dts": "npm run build:ts && api-extractor run --typescript-compiler-folder node_modules/typescript --local && node etc/clean_definition_files.cjs",
109
112
  "build:bundle": "rollup -c rollup.config.mjs",
package/src/binary.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { isAnyArrayBuffer, isUint8Array } from './parser/utils';
1
+ import { type InspectFn, defaultInspect, 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';
@@ -191,8 +191,8 @@ export class Binary extends BSONValue {
191
191
  if (encoding === 'hex') return ByteUtils.toHex(this.buffer);
192
192
  if (encoding === 'base64') return ByteUtils.toBase64(this.buffer);
193
193
  if (encoding === 'utf8' || encoding === 'utf-8')
194
- return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength);
195
- return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength);
194
+ return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false);
195
+ return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false);
196
196
  }
197
197
 
198
198
  /** @internal */
@@ -263,14 +263,12 @@ export class Binary extends BSONValue {
263
263
  return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new Binary(data, type);
264
264
  }
265
265
 
266
- /** @internal */
267
- [Symbol.for('nodejs.util.inspect.custom')](): string {
268
- return this.inspect();
269
- }
270
-
271
- inspect(): string {
266
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
267
+ inspect ??= defaultInspect;
272
268
  const base64 = ByteUtils.toBase64(this.buffer.subarray(0, this.position));
273
- return `Binary.createFromBase64("${base64}", ${this.sub_type})`;
269
+ const base64Arg = inspect(base64, options);
270
+ const subTypeArg = inspect(this.sub_type, options);
271
+ return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`;
274
272
  }
275
273
  }
276
274
 
@@ -463,13 +461,10 @@ export class UUID extends Binary {
463
461
  * Converts to a string representation of this Id.
464
462
  *
465
463
  * @returns return the 36 character hex string representation.
466
- * @internal
464
+ *
467
465
  */
468
- [Symbol.for('nodejs.util.inspect.custom')](): string {
469
- return this.inspect();
470
- }
471
-
472
- inspect(): string {
473
- return `new UUID("${this.toHexString()}")`;
466
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
467
+ inspect ??= defaultInspect;
468
+ return `new UUID(${inspect(this.toHexString(), options)})`;
474
469
  }
475
470
  }
package/src/bson_value.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { BSON_MAJOR_VERSION } from './constants';
2
+ import { type InspectFn } from './parser/utils';
2
3
 
3
4
  /** @public */
4
5
  export abstract class BSONValue {
@@ -10,8 +11,20 @@ export abstract class BSONValue {
10
11
  return BSON_MAJOR_VERSION;
11
12
  }
12
13
 
13
- /** @public */
14
- public abstract inspect(): string;
14
+ [Symbol.for('nodejs.util.inspect.custom')](
15
+ depth?: number,
16
+ options?: unknown,
17
+ inspect?: InspectFn
18
+ ): string {
19
+ return this.inspect(depth, options, inspect);
20
+ }
21
+
22
+ /**
23
+ * @public
24
+ * Prints a human-readable string of BSON value information
25
+ * If invoked manually without node.js.inspect function, this will default to a modified JSON.stringify
26
+ */
27
+ public abstract inspect(depth?: number, options?: unknown, inspect?: InspectFn): string;
15
28
 
16
29
  /** @internal */
17
30
  abstract toExtendedJSON(): unknown;
package/src/code.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Document } from './bson';
2
2
  import { BSONValue } from './bson_value';
3
+ import { type InspectFn, defaultInspect } from './parser/utils';
3
4
 
4
5
  /** @public */
5
6
  export interface CodeExtended {
@@ -55,15 +56,14 @@ export class Code extends BSONValue {
55
56
  return new Code(doc.$code, doc.$scope);
56
57
  }
57
58
 
58
- /** @internal */
59
- [Symbol.for('nodejs.util.inspect.custom')](): string {
60
- return this.inspect();
61
- }
62
-
63
- inspect(): string {
64
- const codeJson = this.toJSON();
65
- return `new Code(${JSON.stringify(String(codeJson.code))}${
66
- codeJson.scope != null ? `, ${JSON.stringify(codeJson.scope)}` : ''
67
- })`;
59
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
60
+ inspect ??= defaultInspect;
61
+ let parametersString = inspect(this.code, options);
62
+ const multiLineFn = parametersString.includes('\n');
63
+ if (this.scope != null) {
64
+ parametersString += `,${multiLineFn ? '\n' : ' '}${inspect(this.scope, options)}`;
65
+ }
66
+ const endingNewline = multiLineFn && this.scope === null;
67
+ return `new Code(${multiLineFn ? '\n' : ''}${parametersString}${endingNewline ? '\n' : ''})`;
68
68
  }
69
69
  }
package/src/db_ref.ts CHANGED
@@ -2,6 +2,7 @@ import type { Document } from './bson';
2
2
  import { BSONValue } from './bson_value';
3
3
  import type { EJSONOptions } from './extended_json';
4
4
  import type { ObjectId } from './objectid';
5
+ import { type InspectFn, defaultInspect } from './parser/utils';
5
6
 
6
7
  /** @public */
7
8
  export interface DBRefLike {
@@ -111,17 +112,18 @@ export class DBRef extends BSONValue {
111
112
  return new DBRef(doc.$ref, doc.$id, doc.$db, copy);
112
113
  }
113
114
 
114
- /** @internal */
115
- [Symbol.for('nodejs.util.inspect.custom')](): string {
116
- return this.inspect();
117
- }
115
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
116
+ inspect ??= defaultInspect;
117
+
118
+ const args = [
119
+ inspect(this.namespace, options),
120
+ inspect(this.oid, options),
121
+ ...(this.db ? [inspect(this.db, options)] : []),
122
+ ...(Object.keys(this.fields).length > 0 ? [inspect(this.fields, options)] : [])
123
+ ];
124
+
125
+ args[1] = inspect === defaultInspect ? `new ObjectId(${args[1]})` : args[1];
118
126
 
119
- inspect(): string {
120
- // NOTE: if OID is an ObjectId class it will just print the oid string.
121
- const oid =
122
- this.oid === undefined || this.oid.toString === undefined ? this.oid : this.oid.toString();
123
- return `new DBRef("${this.namespace}", new ObjectId("${String(oid)}")${
124
- this.db ? `, "${this.db}"` : ''
125
- })`;
127
+ return `new DBRef(${args.join(', ')})`;
126
128
  }
127
129
  }
package/src/decimal128.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BSONValue } from './bson_value';
2
2
  import { BSONError } from './error';
3
3
  import { Long } from './long';
4
- import { isUint8Array } from './parser/utils';
4
+ import { type InspectFn, defaultInspect, isUint8Array } from './parser/utils';
5
5
  import { ByteUtils } from './utils/byte_utils';
6
6
 
7
7
  const PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/;
@@ -847,12 +847,9 @@ export class Decimal128 extends BSONValue {
847
847
  return Decimal128.fromString(doc.$numberDecimal);
848
848
  }
849
849
 
850
- /** @internal */
851
- [Symbol.for('nodejs.util.inspect.custom')](): string {
852
- return this.inspect();
853
- }
854
-
855
- inspect(): string {
856
- return `new Decimal128("${this.toString()}")`;
850
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
851
+ inspect ??= defaultInspect;
852
+ const d128string = inspect(this.toString(), options);
853
+ return `new Decimal128(${d128string})`;
857
854
  }
858
855
  }
package/src/double.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { BSONValue } from './bson_value';
2
2
  import type { EJSONOptions } from './extended_json';
3
+ import { type InspectFn, defaultInspect } from './parser/utils';
3
4
 
4
5
  /** @public */
5
6
  export interface DoubleExtended {
@@ -71,13 +72,8 @@ export class Double extends BSONValue {
71
72
  return options && options.relaxed ? doubleValue : new Double(doubleValue);
72
73
  }
73
74
 
74
- /** @internal */
75
- [Symbol.for('nodejs.util.inspect.custom')](): string {
76
- return this.inspect();
77
- }
78
-
79
- inspect(): string {
80
- const eJSON = this.toExtendedJSON() as DoubleExtended;
81
- return `new Double(${eJSON.$numberDouble})`;
75
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
76
+ inspect ??= defaultInspect;
77
+ return `new Double(${inspect(this.value, options)})`;
82
78
  }
83
79
  }
package/src/error.ts CHANGED
@@ -4,7 +4,7 @@ import { BSON_MAJOR_VERSION } from './constants';
4
4
  * @public
5
5
  * @category Error
6
6
  *
7
- * `BSONError` objects are thrown when BSON ecounters an error.
7
+ * `BSONError` objects are thrown when BSON encounters an error.
8
8
  *
9
9
  * This is the parent class for all the other errors thrown by this library.
10
10
  */
@@ -23,8 +23,8 @@ export class BSONError extends Error {
23
23
  return 'BSONError';
24
24
  }
25
25
 
26
- constructor(message: string) {
27
- super(message);
26
+ constructor(message: string, options?: { cause?: unknown }) {
27
+ super(message, options);
28
28
  }
29
29
 
30
30
  /**
@@ -60,9 +60,7 @@ export class BSONVersionError extends BSONError {
60
60
  }
61
61
 
62
62
  constructor() {
63
- super(
64
- `Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.0 or later`
65
- );
63
+ super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.x.x`);
66
64
  }
67
65
  }
68
66
 
package/src/int_32.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { BSONValue } from './bson_value';
2
2
  import type { EJSONOptions } from './extended_json';
3
+ import { type InspectFn, defaultInspect } from './parser/utils';
3
4
 
4
5
  /** @public */
5
6
  export interface Int32Extended {
@@ -59,12 +60,8 @@ export class Int32 extends BSONValue {
59
60
  return options && options.relaxed ? parseInt(doc.$numberInt, 10) : new Int32(doc.$numberInt);
60
61
  }
61
62
 
62
- /** @internal */
63
- [Symbol.for('nodejs.util.inspect.custom')](): string {
64
- return this.inspect();
65
- }
66
-
67
- inspect(): string {
68
- return `new Int32(${this.valueOf()})`;
63
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
64
+ inspect ??= defaultInspect;
65
+ return `new Int32(${inspect(this.value, options)})`;
69
66
  }
70
67
  }
package/src/long.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { BSONValue } from './bson_value';
2
2
  import { BSONError } from './error';
3
3
  import type { EJSONOptions } from './extended_json';
4
+ import { type InspectFn, defaultInspect } from './parser/utils';
4
5
  import type { Timestamp } from './timestamp';
5
6
 
6
7
  interface LongWASMHelpers {
@@ -1056,12 +1057,10 @@ export class Long extends BSONValue {
1056
1057
  return longResult;
1057
1058
  }
1058
1059
 
1059
- /** @internal */
1060
- [Symbol.for('nodejs.util.inspect.custom')](): string {
1061
- return this.inspect();
1062
- }
1063
-
1064
- inspect(): string {
1065
- return `new Long("${this.toString()}"${this.unsigned ? ', true' : ''})`;
1060
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
1061
+ inspect ??= defaultInspect;
1062
+ const longVal = inspect(this.toString(), options);
1063
+ const unsignedVal = this.unsigned ? `, ${inspect(this.unsigned, options)}` : '';
1064
+ return `new Long(${longVal}${unsignedVal})`;
1066
1065
  }
1067
1066
  }
package/src/max_key.ts CHANGED
@@ -25,11 +25,6 @@ export class MaxKey extends BSONValue {
25
25
  return new MaxKey();
26
26
  }
27
27
 
28
- /** @internal */
29
- [Symbol.for('nodejs.util.inspect.custom')](): string {
30
- return this.inspect();
31
- }
32
-
33
28
  inspect(): string {
34
29
  return 'new MaxKey()';
35
30
  }
package/src/min_key.ts CHANGED
@@ -25,11 +25,6 @@ export class MinKey extends BSONValue {
25
25
  return new MinKey();
26
26
  }
27
27
 
28
- /** @internal */
29
- [Symbol.for('nodejs.util.inspect.custom')](): string {
30
- return this.inspect();
31
- }
32
-
33
28
  inspect(): string {
34
29
  return 'new MinKey()';
35
30
  }
package/src/objectid.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { BSONValue } from './bson_value';
2
2
  import { BSONError } from './error';
3
+ import { type InspectFn, defaultInspect } from './parser/utils';
3
4
  import { BSONDataView, ByteUtils } from './utils/byte_utils';
4
5
 
5
6
  // Regular expression that checks for hex value
@@ -43,9 +44,48 @@ export class ObjectId extends BSONValue {
43
44
  private __id?: string;
44
45
 
45
46
  /**
46
- * Create an ObjectId type
47
+ * Create ObjectId from a number.
47
48
  *
48
- * @param inputId - Can be a 24 character hex string, 12 byte binary Buffer, or a number.
49
+ * @param inputId - A number.
50
+ * @deprecated Instead, use `static createFromTime()` to set a numeric value for the new ObjectId.
51
+ */
52
+ constructor(inputId: number);
53
+ /**
54
+ * Create ObjectId from a 24 character hex string.
55
+ *
56
+ * @param inputId - A 24 character hex string.
57
+ */
58
+ constructor(inputId: string);
59
+ /**
60
+ * Create ObjectId from the BSON ObjectId type.
61
+ *
62
+ * @param inputId - The BSON ObjectId type.
63
+ */
64
+ constructor(inputId: ObjectId);
65
+ /**
66
+ * Create ObjectId from the object type that has the toHexString method.
67
+ *
68
+ * @param inputId - The ObjectIdLike type.
69
+ */
70
+ constructor(inputId: ObjectIdLike);
71
+ /**
72
+ * Create ObjectId from a 12 byte binary Buffer.
73
+ *
74
+ * @param inputId - A 12 byte binary Buffer.
75
+ */
76
+ constructor(inputId: Uint8Array);
77
+ /** To generate a new ObjectId, use ObjectId() with no argument. */
78
+ constructor();
79
+ /**
80
+ * Implementation overload.
81
+ *
82
+ * @param inputId - All input types that are used in the constructor implementation.
83
+ */
84
+ constructor(inputId?: string | number | ObjectId | ObjectIdLike | Uint8Array);
85
+ /**
86
+ * Create a new ObjectId.
87
+ *
88
+ * @param inputId - An input value to create a new ObjectId from.
49
89
  */
50
90
  constructor(inputId?: string | number | ObjectId | ObjectIdLike | Uint8Array) {
51
91
  super();
@@ -64,7 +104,7 @@ export class ObjectId extends BSONValue {
64
104
  workingId = inputId;
65
105
  }
66
106
 
67
- // the following cases use workingId to construct an ObjectId
107
+ // The following cases use workingId to construct an ObjectId
68
108
  if (workingId == null || typeof workingId === 'number') {
69
109
  // The most common use case (blank id, new objectId instance)
70
110
  // Generate a new id
@@ -294,13 +334,9 @@ export class ObjectId extends BSONValue {
294
334
  * Converts to a string representation of this Id.
295
335
  *
296
336
  * @returns return the 24 character hex string representation.
297
- * @internal
298
337
  */
299
- [Symbol.for('nodejs.util.inspect.custom')](): string {
300
- return this.inspect();
301
- }
302
-
303
- inspect(): string {
304
- return `new ObjectId("${this.toHexString()}")`;
338
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
339
+ inspect ??= defaultInspect;
340
+ return `new ObjectId(${inspect(this.toHexString(), options)})`;
305
341
  }
306
342
  }
@@ -236,7 +236,7 @@ function deserializeObject(
236
236
  if (i >= buffer.byteLength) throw new BSONError('Bad BSON Document: illegal CString');
237
237
 
238
238
  // Represents the key
239
- const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i);
239
+ const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i, false);
240
240
 
241
241
  // shouldValidateKey is true if the key should be validated, false otherwise
242
242
  let shouldValidateKey = true;
@@ -266,7 +266,7 @@ function deserializeObject(
266
266
  ) {
267
267
  throw new BSONError('bad string length in bson');
268
268
  }
269
- value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
269
+ value = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
270
270
  index = index + stringSize;
271
271
  } else if (elementType === constants.BSON_DATA_OID) {
272
272
  const oid = ByteUtils.allocate(12);
@@ -476,7 +476,7 @@ function deserializeObject(
476
476
  // If are at the end of the buffer there is a problem with the document
477
477
  if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString');
478
478
  // Return the C string
479
- const source = ByteUtils.toUTF8(buffer, index, i);
479
+ const source = ByteUtils.toUTF8(buffer, index, i, false);
480
480
  // Create the regexp
481
481
  index = i + 1;
482
482
 
@@ -489,7 +489,7 @@ function deserializeObject(
489
489
  // If are at the end of the buffer there is a problem with the document
490
490
  if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString');
491
491
  // Return the C string
492
- const regExpOptions = ByteUtils.toUTF8(buffer, index, i);
492
+ const regExpOptions = ByteUtils.toUTF8(buffer, index, i, false);
493
493
  index = i + 1;
494
494
 
495
495
  // For each option add the corresponding one for javascript
@@ -521,7 +521,7 @@ function deserializeObject(
521
521
  // If are at the end of the buffer there is a problem with the document
522
522
  if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString');
523
523
  // Return the C string
524
- const source = ByteUtils.toUTF8(buffer, index, i);
524
+ const source = ByteUtils.toUTF8(buffer, index, i, false);
525
525
  index = i + 1;
526
526
 
527
527
  // Get the start search index
@@ -533,7 +533,7 @@ function deserializeObject(
533
533
  // If are at the end of the buffer there is a problem with the document
534
534
  if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString');
535
535
  // Return the C string
536
- const regExpOptions = ByteUtils.toUTF8(buffer, index, i);
536
+ const regExpOptions = ByteUtils.toUTF8(buffer, index, i, false);
537
537
  index = i + 1;
538
538
 
539
539
  // Set the object
@@ -551,7 +551,7 @@ function deserializeObject(
551
551
  ) {
552
552
  throw new BSONError('bad string length in bson');
553
553
  }
554
- const symbol = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
554
+ const symbol = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
555
555
  value = promoteValues ? symbol : new BSONSymbol(symbol);
556
556
  index = index + stringSize;
557
557
  } else if (elementType === constants.BSON_DATA_TIMESTAMP) {
@@ -587,7 +587,7 @@ function deserializeObject(
587
587
  ) {
588
588
  throw new BSONError('bad string length in bson');
589
589
  }
590
- const functionString = getValidatedString(
590
+ const functionString = ByteUtils.toUTF8(
591
591
  buffer,
592
592
  index,
593
593
  index + stringSize - 1,
@@ -626,7 +626,7 @@ function deserializeObject(
626
626
  }
627
627
 
628
628
  // Javascript function
629
- const functionString = getValidatedString(
629
+ const functionString = ByteUtils.toUTF8(
630
630
  buffer,
631
631
  index,
632
632
  index + stringSize - 1,
@@ -678,7 +678,7 @@ function deserializeObject(
678
678
  throw new BSONError('Invalid UTF-8 string in BSON document');
679
679
  }
680
680
  }
681
- const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1);
681
+ const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
682
682
  // Update parse index position
683
683
  index = index + stringSize;
684
684
 
@@ -728,24 +728,3 @@ function deserializeObject(
728
728
 
729
729
  return object;
730
730
  }
731
-
732
- function getValidatedString(
733
- buffer: Uint8Array,
734
- start: number,
735
- end: number,
736
- shouldValidateUtf8: boolean
737
- ) {
738
- const value = ByteUtils.toUTF8(buffer, start, end);
739
- // if utf8 validation is on, do the check
740
- if (shouldValidateUtf8) {
741
- for (let i = 0; i < value.length; i++) {
742
- if (value.charCodeAt(i) === 0xfffd) {
743
- if (!validateUtf8(buffer, start, end)) {
744
- throw new BSONError('Invalid UTF-8 string in BSON document');
745
- }
746
- break;
747
- }
748
- }
749
- }
750
- return value;
751
- }
@@ -27,3 +27,30 @@ export function isMap(d: unknown): d is Map<unknown, unknown> {
27
27
  export function isDate(d: unknown): d is Date {
28
28
  return Object.prototype.toString.call(d) === '[object Date]';
29
29
  }
30
+
31
+ export type InspectFn = (x: unknown, options?: unknown) => string;
32
+ export function defaultInspect(x: unknown, _options?: unknown): string {
33
+ return JSON.stringify(x, (k: string, v: unknown) => {
34
+ if (typeof v === 'bigint') {
35
+ return { $numberLong: `${v}` };
36
+ } else if (isMap(v)) {
37
+ return Object.fromEntries(v);
38
+ }
39
+ return v;
40
+ });
41
+ }
42
+
43
+ /** @internal */
44
+ type StylizeFunction = (x: string, style: string) => string;
45
+ /** @internal */
46
+ export function getStylizeFunction(options?: unknown): StylizeFunction | undefined {
47
+ const stylizeExists =
48
+ options != null &&
49
+ typeof options === 'object' &&
50
+ 'stylize' in options &&
51
+ typeof options.stylize === 'function';
52
+
53
+ if (stylizeExists) {
54
+ return options.stylize as StylizeFunction;
55
+ }
56
+ }
package/src/regexp.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { BSONValue } from './bson_value';
2
2
  import { BSONError } from './error';
3
3
  import type { EJSONOptions } from './extended_json';
4
+ import { type InspectFn, defaultInspect, getStylizeFunction } from './parser/utils';
4
5
 
5
6
  function alphabetize(str: string): string {
6
7
  return str.split('').sort().join('');
@@ -103,12 +104,11 @@ export class BSONRegExp extends BSONValue {
103
104
  throw new BSONError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`);
104
105
  }
105
106
 
106
- /** @internal */
107
- [Symbol.for('nodejs.util.inspect.custom')](): string {
108
- return this.inspect();
109
- }
110
-
111
- inspect(): string {
112
- return `new BSONRegExp(${JSON.stringify(this.pattern)}, ${JSON.stringify(this.options)})`;
107
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
108
+ const stylize = getStylizeFunction(options) ?? (v => v);
109
+ inspect ??= defaultInspect;
110
+ const pattern = stylize(inspect(this.pattern), 'regexp');
111
+ const flags = stylize(inspect(this.options), 'regexp');
112
+ return `new BSONRegExp(${pattern}, ${flags})`;
113
113
  }
114
114
  }