bson 6.0.0 → 6.2.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.0.0",
17
+ "version": "6.2.0",
18
18
  "author": {
19
19
  "name": "The MongoDB NodeJS Team",
20
20
  "email": "dbx-node@mongodb.com"
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';
@@ -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+)?$/;
@@ -158,6 +158,32 @@ export class Decimal128 extends BSONValue {
158
158
  * @param representation - a numeric string representation.
159
159
  */
160
160
  static fromString(representation: string): Decimal128 {
161
+ return Decimal128._fromString(representation, { allowRounding: false });
162
+ }
163
+
164
+ /**
165
+ * Create a Decimal128 instance from a string representation, allowing for rounding to 34
166
+ * significant digits
167
+ *
168
+ * @example Example of a number that will be rounded
169
+ * ```ts
170
+ * > let d = Decimal128.fromString('37.499999999999999196428571428571375')
171
+ * Uncaught:
172
+ * BSONError: "37.499999999999999196428571428571375" is not a valid Decimal128 string - inexact rounding
173
+ * at invalidErr (/home/wajames/js-bson/lib/bson.cjs:1402:11)
174
+ * at Decimal128.fromStringInternal (/home/wajames/js-bson/lib/bson.cjs:1633:25)
175
+ * at Decimal128.fromString (/home/wajames/js-bson/lib/bson.cjs:1424:27)
176
+ *
177
+ * > d = Decimal128.fromStringWithRounding('37.499999999999999196428571428571375')
178
+ * new Decimal128("37.49999999999999919642857142857138")
179
+ * ```
180
+ * @param representation - a numeric string representation.
181
+ */
182
+ static fromStringWithRounding(representation: string): Decimal128 {
183
+ return Decimal128._fromString(representation, { allowRounding: true });
184
+ }
185
+
186
+ private static _fromString(representation: string, options: { allowRounding: boolean }) {
161
187
  // Parse state tracking
162
188
  let isNegative = false;
163
189
  let sawSign = false;
@@ -351,59 +377,147 @@ export class Decimal128 extends BSONValue {
351
377
  exponent = exponent - 1;
352
378
  }
353
379
 
354
- while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
355
- // Shift last digit. can only do this if < significant digits than # stored.
356
- if (lastDigit === 0) {
357
- if (significantDigits === 0) {
380
+ if (options.allowRounding) {
381
+ while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
382
+ // Shift last digit. can only do this if < significant digits than # stored.
383
+ if (lastDigit === 0 && significantDigits < nDigitsStored) {
358
384
  exponent = EXPONENT_MIN;
385
+ significantDigits = 0;
359
386
  break;
360
387
  }
361
388
 
362
- invalidErr(representation, 'exponent underflow');
389
+ if (nDigitsStored < nDigits) {
390
+ // adjust to match digits not stored
391
+ nDigits = nDigits - 1;
392
+ } else {
393
+ // adjust to round
394
+ lastDigit = lastDigit - 1;
395
+ }
396
+
397
+ if (exponent < EXPONENT_MAX) {
398
+ exponent = exponent + 1;
399
+ } else {
400
+ // Check if we have a zero then just hard clamp, otherwise fail
401
+ const digitsString = digits.join('');
402
+ if (digitsString.match(/^0+$/)) {
403
+ exponent = EXPONENT_MAX;
404
+ break;
405
+ }
406
+ invalidErr(representation, 'overflow');
407
+ }
363
408
  }
364
409
 
365
- if (nDigitsStored < nDigits) {
366
- if (
367
- representation[nDigits - 1 + Number(sawSign) + Number(sawRadix)] !== '0' &&
368
- significantDigits !== 0
369
- ) {
370
- invalidErr(representation, 'inexact rounding');
410
+ // Round
411
+ // We've normalized the exponent, but might still need to round.
412
+ if (lastDigit + 1 < significantDigits) {
413
+ let endOfString = nDigitsRead;
414
+
415
+ // If we have seen a radix point, 'string' is 1 longer than we have
416
+ // documented with ndigits_read, so inc the position of the first nonzero
417
+ // digit and the position that digits are read to.
418
+ if (sawRadix) {
419
+ firstNonZero = firstNonZero + 1;
420
+ endOfString = endOfString + 1;
371
421
  }
372
- // adjust to match digits not stored
373
- nDigits = nDigits - 1;
374
- } else {
375
- if (digits[lastDigit] !== 0) {
376
- invalidErr(representation, 'inexact rounding');
422
+ // if negative, we need to increment again to account for - sign at start.
423
+ if (sawSign) {
424
+ firstNonZero = firstNonZero + 1;
425
+ endOfString = endOfString + 1;
377
426
  }
378
- // adjust to round
379
- lastDigit = lastDigit - 1;
380
- }
381
427
 
382
- if (exponent < EXPONENT_MAX) {
383
- exponent = exponent + 1;
384
- } else {
385
- invalidErr(representation, 'overflow');
386
- }
387
- }
428
+ const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
429
+ let roundBit = 0;
430
+
431
+ if (roundDigit >= 5) {
432
+ roundBit = 1;
433
+ if (roundDigit === 5) {
434
+ roundBit = digits[lastDigit] % 2 === 1 ? 1 : 0;
435
+ for (let i = firstNonZero + lastDigit + 2; i < endOfString; i++) {
436
+ if (parseInt(representation[i], 10)) {
437
+ roundBit = 1;
438
+ break;
439
+ }
440
+ }
441
+ }
442
+ }
388
443
 
389
- // Round
390
- // We've normalized the exponent, but might still need to round.
391
- if (lastDigit + 1 < significantDigits) {
392
- // If we have seen a radix point, 'string' is 1 longer than we have
393
- // documented with ndigits_read, so inc the position of the first nonzero
394
- // digit and the position that digits are read to.
395
- if (sawRadix) {
396
- firstNonZero = firstNonZero + 1;
444
+ if (roundBit) {
445
+ let dIdx = lastDigit;
446
+
447
+ for (; dIdx >= 0; dIdx--) {
448
+ if (++digits[dIdx] > 9) {
449
+ digits[dIdx] = 0;
450
+
451
+ // overflowed most significant digit
452
+ if (dIdx === 0) {
453
+ if (exponent < EXPONENT_MAX) {
454
+ exponent = exponent + 1;
455
+ digits[dIdx] = 1;
456
+ } else {
457
+ return new Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER);
458
+ }
459
+ }
460
+ } else {
461
+ break;
462
+ }
463
+ }
464
+ }
397
465
  }
398
- // if saw sign, we need to increment again to account for - or + sign at start.
399
- if (sawSign) {
400
- firstNonZero = firstNonZero + 1;
466
+ } else {
467
+ while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
468
+ // Shift last digit. can only do this if < significant digits than # stored.
469
+ if (lastDigit === 0) {
470
+ if (significantDigits === 0) {
471
+ exponent = EXPONENT_MIN;
472
+ break;
473
+ }
474
+
475
+ invalidErr(representation, 'exponent underflow');
476
+ }
477
+
478
+ if (nDigitsStored < nDigits) {
479
+ if (
480
+ representation[nDigits - 1 + Number(sawSign) + Number(sawRadix)] !== '0' &&
481
+ significantDigits !== 0
482
+ ) {
483
+ invalidErr(representation, 'inexact rounding');
484
+ }
485
+ // adjust to match digits not stored
486
+ nDigits = nDigits - 1;
487
+ } else {
488
+ if (digits[lastDigit] !== 0) {
489
+ invalidErr(representation, 'inexact rounding');
490
+ }
491
+ // adjust to round
492
+ lastDigit = lastDigit - 1;
493
+ }
494
+
495
+ if (exponent < EXPONENT_MAX) {
496
+ exponent = exponent + 1;
497
+ } else {
498
+ invalidErr(representation, 'overflow');
499
+ }
401
500
  }
402
501
 
403
- const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
502
+ // Round
503
+ // We've normalized the exponent, but might still need to round.
504
+ if (lastDigit + 1 < significantDigits) {
505
+ // If we have seen a radix point, 'string' is 1 longer than we have
506
+ // documented with ndigits_read, so inc the position of the first nonzero
507
+ // digit and the position that digits are read to.
508
+ if (sawRadix) {
509
+ firstNonZero = firstNonZero + 1;
510
+ }
511
+ // if saw sign, we need to increment again to account for - or + sign at start.
512
+ if (sawSign) {
513
+ firstNonZero = firstNonZero + 1;
514
+ }
515
+
516
+ const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
404
517
 
405
- if (roundDigit !== 0) {
406
- invalidErr(representation, 'inexact rounding');
518
+ if (roundDigit !== 0) {
519
+ invalidErr(representation, 'inexact rounding');
520
+ }
407
521
  }
408
522
  }
409
523
 
@@ -507,7 +621,6 @@ export class Decimal128 extends BSONValue {
507
621
  // Return the new Decimal128
508
622
  return new Decimal128(buffer);
509
623
  }
510
-
511
624
  /** Create a string representation of the raw Decimal128 value */
512
625
  toString(): string {
513
626
  // Note: bits in this routine are referred to starting at 0,
@@ -734,12 +847,9 @@ export class Decimal128 extends BSONValue {
734
847
  return Decimal128.fromString(doc.$numberDecimal);
735
848
  }
736
849
 
737
- /** @internal */
738
- [Symbol.for('nodejs.util.inspect.custom')](): string {
739
- return this.inspect();
740
- }
741
-
742
- inspect(): string {
743
- 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})`;
744
854
  }
745
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
@@ -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
@@ -294,13 +295,9 @@ export class ObjectId extends BSONValue {
294
295
  * Converts to a string representation of this Id.
295
296
  *
296
297
  * @returns return the 24 character hex string representation.
297
- * @internal
298
298
  */
299
- [Symbol.for('nodejs.util.inspect.custom')](): string {
300
- return this.inspect();
301
- }
302
-
303
- inspect(): string {
304
- return `new ObjectId("${this.toHexString()}")`;
299
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
300
+ inspect ??= defaultInspect;
301
+ return `new ObjectId(${inspect(this.toHexString(), options)})`;
305
302
  }
306
303
  }
@@ -257,14 +257,18 @@ function serializeObjectId(buffer: Uint8Array, key: string, value: ObjectId, ind
257
257
  buffer[index++] = 0;
258
258
 
259
259
  // Write the objectId into the shared buffer
260
- if (isUint8Array(value.id)) {
261
- buffer.set(value.id.subarray(0, 12), index);
260
+ const idValue = value.id;
261
+
262
+ if (isUint8Array(idValue)) {
263
+ for (let i = 0; i < 12; i++) {
264
+ buffer[index++] = idValue[i];
265
+ }
262
266
  } else {
263
267
  throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
264
268
  }
265
269
 
266
270
  // Adjust index
267
- return index + 12;
271
+ return index;
268
272
  }
269
273
 
270
274
  function serializeBuffer(buffer: Uint8Array, key: string, value: Uint8Array, index: number) {
@@ -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
  }
package/src/symbol.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { BSONValue } from './bson_value';
2
+ import { type InspectFn, defaultInspect } from './parser/utils';
2
3
 
3
4
  /** @public */
4
5
  export interface BSONSymbolExtended {
@@ -33,10 +34,6 @@ export class BSONSymbol extends BSONValue {
33
34
  return this.value;
34
35
  }
35
36
 
36
- inspect(): string {
37
- return `new BSONSymbol(${JSON.stringify(this.value)})`;
38
- }
39
-
40
37
  toJSON(): string {
41
38
  return this.value;
42
39
  }
@@ -51,8 +48,8 @@ export class BSONSymbol extends BSONValue {
51
48
  return new BSONSymbol(doc.$symbol);
52
49
  }
53
50
 
54
- /** @internal */
55
- [Symbol.for('nodejs.util.inspect.custom')](): string {
56
- return this.inspect();
51
+ inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
52
+ inspect ??= defaultInspect;
53
+ return `new BSONSymbol(${inspect(this.value, options)})`;
57
54
  }
58
55
  }