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.
- package/bson.d.ts +208 -267
- package/lib/bson.bundle.js +4033 -0
- package/lib/bson.bundle.js.map +1 -0
- package/lib/bson.cjs +4028 -0
- package/lib/bson.cjs.map +1 -0
- package/lib/bson.mjs +4002 -0
- package/lib/bson.mjs.map +1 -0
- package/package.json +49 -61
- package/src/binary.ts +235 -37
- package/src/bson.ts +43 -129
- package/src/code.ts +24 -14
- package/src/constants.ts +28 -0
- package/src/db_ref.ts +13 -8
- package/src/decimal128.ts +31 -25
- package/src/double.ts +7 -5
- package/src/error.ts +0 -2
- package/src/extended_json.ts +148 -148
- package/src/index.ts +19 -0
- package/src/int_32.ts +7 -5
- package/src/long.ts +16 -16
- package/src/max_key.ts +6 -6
- package/src/min_key.ts +6 -6
- package/src/objectid.ts +41 -74
- package/src/parser/calculate_size.ts +39 -63
- package/src/parser/deserializer.ts +47 -113
- package/src/parser/serializer.ts +234 -341
- package/src/parser/utils.ts +1 -99
- package/src/regexp.ts +16 -5
- package/src/symbol.ts +7 -5
- package/src/timestamp.ts +62 -27
- package/src/utils/byte_utils.ts +61 -0
- package/src/utils/node_byte_utils.ts +141 -0
- package/src/utils/web_byte_utils.ts +190 -0
- package/src/uuid_utils.ts +15 -15
- package/bower.json +0 -26
- package/dist/bson.browser.esm.js +0 -7471
- package/dist/bson.browser.esm.js.map +0 -1
- package/dist/bson.browser.umd.js +0 -7538
- package/dist/bson.browser.umd.js.map +0 -1
- package/dist/bson.bundle.js +0 -7537
- package/dist/bson.bundle.js.map +0 -1
- package/dist/bson.esm.js +0 -5437
- package/dist/bson.esm.js.map +0 -1
- package/lib/binary.js +0 -247
- package/lib/binary.js.map +0 -1
- package/lib/bson.js +0 -265
- package/lib/bson.js.map +0 -1
- package/lib/code.js +0 -46
- package/lib/code.js.map +0 -1
- package/lib/constants.js +0 -82
- package/lib/constants.js.map +0 -1
- package/lib/db_ref.js +0 -97
- package/lib/db_ref.js.map +0 -1
- package/lib/decimal128.js +0 -669
- package/lib/decimal128.js.map +0 -1
- package/lib/double.js +0 -76
- package/lib/double.js.map +0 -1
- package/lib/ensure_buffer.js +0 -25
- package/lib/ensure_buffer.js.map +0 -1
- package/lib/error.js +0 -55
- package/lib/error.js.map +0 -1
- package/lib/extended_json.js +0 -390
- package/lib/extended_json.js.map +0 -1
- package/lib/int_32.js +0 -58
- package/lib/int_32.js.map +0 -1
- package/lib/long.js +0 -900
- package/lib/long.js.map +0 -1
- package/lib/map.js +0 -123
- package/lib/map.js.map +0 -1
- package/lib/max_key.js +0 -33
- package/lib/max_key.js.map +0 -1
- package/lib/min_key.js +0 -33
- package/lib/min_key.js.map +0 -1
- package/lib/objectid.js +0 -299
- package/lib/objectid.js.map +0 -1
- package/lib/parser/calculate_size.js +0 -194
- package/lib/parser/calculate_size.js.map +0 -1
- package/lib/parser/deserializer.js +0 -659
- package/lib/parser/deserializer.js.map +0 -1
- package/lib/parser/serializer.js +0 -867
- package/lib/parser/serializer.js.map +0 -1
- package/lib/parser/utils.js +0 -115
- package/lib/parser/utils.js.map +0 -1
- package/lib/regexp.js +0 -74
- package/lib/regexp.js.map +0 -1
- package/lib/symbol.js +0 -48
- package/lib/symbol.js.map +0 -1
- package/lib/timestamp.js +0 -102
- package/lib/timestamp.js.map +0 -1
- package/lib/utils/global.js +0 -18
- package/lib/utils/global.js.map +0 -1
- package/lib/uuid.js +0 -179
- package/lib/uuid.js.map +0 -1
- package/lib/uuid_utils.js +0 -35
- package/lib/uuid_utils.js.map +0 -1
- package/lib/validate_utf8.js +0 -47
- package/lib/validate_utf8.js.map +0 -1
- package/src/ensure_buffer.ts +0 -27
- package/src/map.ts +0 -119
- package/src/utils/global.ts +0 -22
- package/src/uuid.ts +0 -209
package/src/extended_json.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Binary } from './binary';
|
|
2
2
|
import type { Document } from './bson';
|
|
3
3
|
import { Code } from './code';
|
|
4
|
+
import { BSON_INT32_MAX, BSON_INT32_MIN, BSON_INT64_MAX, BSON_INT64_MIN } from './constants';
|
|
4
5
|
import { DBRef, isDBRefLike } from './db_ref';
|
|
5
6
|
import { Decimal128 } from './decimal128';
|
|
6
7
|
import { Double } from './double';
|
|
@@ -10,13 +11,18 @@ import { Long } from './long';
|
|
|
10
11
|
import { MaxKey } from './max_key';
|
|
11
12
|
import { MinKey } from './min_key';
|
|
12
13
|
import { ObjectId } from './objectid';
|
|
13
|
-
import { isDate,
|
|
14
|
+
import { isDate, isRegExp } from './parser/utils';
|
|
14
15
|
import { BSONRegExp } from './regexp';
|
|
15
16
|
import { BSONSymbol } from './symbol';
|
|
16
17
|
import { Timestamp } from './timestamp';
|
|
17
18
|
|
|
18
19
|
/** @public */
|
|
19
|
-
export type EJSONOptions =
|
|
20
|
+
export type EJSONOptions = {
|
|
21
|
+
/** Output using the Extended JSON v1 spec */
|
|
22
|
+
legacy?: boolean;
|
|
23
|
+
/** Enable Extended JSON's `relaxed` mode, which attempts to return native JS types where possible, rather than BSON types */
|
|
24
|
+
relaxed?: boolean;
|
|
25
|
+
};
|
|
20
26
|
|
|
21
27
|
/** @internal */
|
|
22
28
|
type BSONType =
|
|
@@ -34,20 +40,15 @@ type BSONType =
|
|
|
34
40
|
| BSONSymbol
|
|
35
41
|
| Timestamp;
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
function isBSONType(value: unknown): value is BSONType {
|
|
38
44
|
return (
|
|
39
|
-
|
|
45
|
+
value != null &&
|
|
46
|
+
typeof value === 'object' &&
|
|
47
|
+
'_bsontype' in value &&
|
|
48
|
+
typeof value._bsontype === 'string'
|
|
40
49
|
);
|
|
41
50
|
}
|
|
42
51
|
|
|
43
|
-
// INT32 boundaries
|
|
44
|
-
const BSON_INT32_MAX = 0x7fffffff;
|
|
45
|
-
const BSON_INT32_MIN = -0x80000000;
|
|
46
|
-
// INT64 boundaries
|
|
47
|
-
// const BSON_INT64_MAX = 0x7fffffffffffffff; // TODO(NODE-4377): This number cannot be precisely represented in JS
|
|
48
|
-
const BSON_INT64_MAX = 0x8000000000000000;
|
|
49
|
-
const BSON_INT64_MIN = -0x8000000000000000;
|
|
50
|
-
|
|
51
52
|
// all the types where we don't need to do any special processing and can just pass the EJSON
|
|
52
53
|
//straight to type.fromExtendedJSON
|
|
53
54
|
const keysToCodecs = {
|
|
@@ -67,17 +68,21 @@ const keysToCodecs = {
|
|
|
67
68
|
} as const;
|
|
68
69
|
|
|
69
70
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
-
function deserializeValue(value: any, options:
|
|
71
|
+
function deserializeValue(value: any, options: EJSONOptions = {}) {
|
|
71
72
|
if (typeof value === 'number') {
|
|
72
73
|
if (options.relaxed || options.legacy) {
|
|
73
74
|
return value;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
if (Number.isInteger(value) && !Object.is(value, -0)) {
|
|
78
|
+
// interpret as being of the smallest BSON integer type that can represent the number exactly
|
|
79
|
+
if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) {
|
|
80
|
+
return new Int32(value);
|
|
81
|
+
}
|
|
82
|
+
if (value >= BSON_INT64_MIN && value <= BSON_INT64_MAX) {
|
|
83
|
+
// TODO(NODE-4377): EJSON js number handling diverges from BSON
|
|
84
|
+
return Long.fromNumber(value);
|
|
85
|
+
}
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
// If the number is a non-integer or out of integer range, should interpret as BSON Double.
|
|
@@ -142,7 +147,7 @@ function deserializeValue(value: any, options: EJSON.Options = {}) {
|
|
|
142
147
|
return value;
|
|
143
148
|
}
|
|
144
149
|
|
|
145
|
-
type EJSONSerializeOptions =
|
|
150
|
+
type EJSONSerializeOptions = EJSONOptions & {
|
|
146
151
|
seenObjects: { obj: unknown; propertyName: string }[];
|
|
147
152
|
};
|
|
148
153
|
|
|
@@ -216,16 +221,17 @@ function serializeValue(value: any, options: EJSONSerializeOptions): any {
|
|
|
216
221
|
}
|
|
217
222
|
|
|
218
223
|
if (typeof value === 'number' && (!options.relaxed || !isFinite(value))) {
|
|
219
|
-
|
|
220
|
-
if (Math.floor(value) === value) {
|
|
221
|
-
const int32Range = value >= BSON_INT32_MIN && value <= BSON_INT32_MAX,
|
|
222
|
-
int64Range = value >= BSON_INT64_MIN && value <= BSON_INT64_MAX;
|
|
223
|
-
|
|
224
|
+
if (Number.isInteger(value) && !Object.is(value, -0)) {
|
|
224
225
|
// interpret as being of the smallest BSON integer type that can represent the number exactly
|
|
225
|
-
if (
|
|
226
|
-
|
|
226
|
+
if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) {
|
|
227
|
+
return { $numberInt: value.toString() };
|
|
228
|
+
}
|
|
229
|
+
if (value >= BSON_INT64_MIN && value <= BSON_INT64_MAX) {
|
|
230
|
+
// TODO(NODE-4377): EJSON js number handling diverges from BSON
|
|
231
|
+
return { $numberLong: value.toString() };
|
|
232
|
+
}
|
|
227
233
|
}
|
|
228
|
-
return { $numberDouble: value.toString() };
|
|
234
|
+
return { $numberDouble: Object.is(value, -0) ? '-0.0' : value.toString() };
|
|
229
235
|
}
|
|
230
236
|
|
|
231
237
|
if (value instanceof RegExp || isRegExp(value)) {
|
|
@@ -267,10 +273,9 @@ const BSON_TYPE_MAPPINGS = {
|
|
|
267
273
|
),
|
|
268
274
|
MaxKey: () => new MaxKey(),
|
|
269
275
|
MinKey: () => new MinKey(),
|
|
270
|
-
|
|
271
|
-
ObjectId: (o: ObjectId) => new ObjectId(o), // support 4.0.0/4.0.1 before _bsontype was reverted back to ObjectID
|
|
276
|
+
ObjectId: (o: ObjectId) => new ObjectId(o),
|
|
272
277
|
BSONRegExp: (o: BSONRegExp) => new BSONRegExp(o.pattern, o.options),
|
|
273
|
-
|
|
278
|
+
BSONSymbol: (o: BSONSymbol) => new BSONSymbol(o.value),
|
|
274
279
|
Timestamp: (o: Timestamp) => Timestamp.fromBits(o.low, o.high)
|
|
275
280
|
} as const;
|
|
276
281
|
|
|
@@ -282,7 +287,7 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
|
|
|
282
287
|
if (typeof bsontype === 'undefined') {
|
|
283
288
|
// It's a regular object. Recursively serialize its property values.
|
|
284
289
|
const _doc: Document = {};
|
|
285
|
-
for (const name
|
|
290
|
+
for (const name of Object.keys(doc)) {
|
|
286
291
|
options.seenObjects.push({ propertyName: name, obj: null });
|
|
287
292
|
try {
|
|
288
293
|
const value = serializeValue(doc[name], options);
|
|
@@ -301,6 +306,13 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
|
|
|
301
306
|
}
|
|
302
307
|
}
|
|
303
308
|
return _doc;
|
|
309
|
+
} else if (
|
|
310
|
+
doc != null &&
|
|
311
|
+
typeof doc === 'object' &&
|
|
312
|
+
typeof doc._bsontype === 'string' &&
|
|
313
|
+
doc[Symbol.for('@@mdb.bson.version')] == null
|
|
314
|
+
) {
|
|
315
|
+
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
|
|
304
316
|
} else if (isBSONType(doc)) {
|
|
305
317
|
// the "document" is really just a BSON type object
|
|
306
318
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -336,127 +348,115 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
|
|
|
336
348
|
}
|
|
337
349
|
|
|
338
350
|
/**
|
|
339
|
-
*
|
|
340
|
-
*
|
|
351
|
+
* Parse an Extended JSON string, constructing the JavaScript value or object described by that
|
|
352
|
+
* string.
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```js
|
|
356
|
+
* const { EJSON } = require('bson');
|
|
357
|
+
* const text = '{ "int32": { "$numberInt": "10" } }';
|
|
358
|
+
*
|
|
359
|
+
* // prints { int32: { [String: '10'] _bsontype: 'Int32', value: '10' } }
|
|
360
|
+
* console.log(EJSON.parse(text, { relaxed: false }));
|
|
361
|
+
*
|
|
362
|
+
* // prints { int32: 10 }
|
|
363
|
+
* console.log(EJSON.parse(text));
|
|
364
|
+
* ```
|
|
341
365
|
*/
|
|
342
|
-
//
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
/** Enable Extended JSON's `relaxed` mode, which attempts to return native JS types where possible, rather than BSON types */
|
|
350
|
-
relaxed?: boolean;
|
|
351
|
-
/**
|
|
352
|
-
* Disable Extended JSON's `relaxed` mode, which attempts to return BSON types where possible, rather than native JS types
|
|
353
|
-
* @deprecated Please use the relaxed property instead
|
|
354
|
-
*/
|
|
355
|
-
strict?: boolean;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Parse an Extended JSON string, constructing the JavaScript value or object described by that
|
|
360
|
-
* string.
|
|
361
|
-
*
|
|
362
|
-
* @example
|
|
363
|
-
* ```js
|
|
364
|
-
* const { EJSON } = require('bson');
|
|
365
|
-
* const text = '{ "int32": { "$numberInt": "10" } }';
|
|
366
|
-
*
|
|
367
|
-
* // prints { int32: { [String: '10'] _bsontype: 'Int32', value: '10' } }
|
|
368
|
-
* console.log(EJSON.parse(text, { relaxed: false }));
|
|
369
|
-
*
|
|
370
|
-
* // prints { int32: 10 }
|
|
371
|
-
* console.log(EJSON.parse(text));
|
|
372
|
-
* ```
|
|
373
|
-
*/
|
|
374
|
-
export function parse(text: string, options?: EJSON.Options): SerializableTypes {
|
|
375
|
-
const finalOptions = Object.assign({}, { relaxed: true, legacy: false }, options);
|
|
376
|
-
|
|
377
|
-
// relaxed implies not strict
|
|
378
|
-
if (typeof finalOptions.relaxed === 'boolean') finalOptions.strict = !finalOptions.relaxed;
|
|
379
|
-
if (typeof finalOptions.strict === 'boolean') finalOptions.relaxed = !finalOptions.strict;
|
|
380
|
-
|
|
381
|
-
return JSON.parse(text, (key, value) => {
|
|
382
|
-
if (key.indexOf('\x00') !== -1) {
|
|
383
|
-
throw new BSONError(
|
|
384
|
-
`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
return deserializeValue(value, finalOptions);
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
export type JSONPrimitive = string | number | boolean | null;
|
|
392
|
-
export type SerializableTypes = Document | Array<JSONPrimitive | Document> | JSONPrimitive;
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Converts a BSON document to an Extended JSON string, optionally replacing values if a replacer
|
|
396
|
-
* function is specified or optionally including only the specified properties if a replacer array
|
|
397
|
-
* is specified.
|
|
398
|
-
*
|
|
399
|
-
* @param value - The value to convert to extended JSON
|
|
400
|
-
* @param replacer - A function that alters the behavior of the stringification process, or an array of String and Number objects that serve as a whitelist for selecting/filtering the properties of the value object to be included in the JSON string. If this value is null or not provided, all properties of the object are included in the resulting JSON string
|
|
401
|
-
* @param space - A String or Number object that's used to insert white space into the output JSON string for readability purposes.
|
|
402
|
-
* @param options - Optional settings
|
|
403
|
-
*
|
|
404
|
-
* @example
|
|
405
|
-
* ```js
|
|
406
|
-
* const { EJSON } = require('bson');
|
|
407
|
-
* const Int32 = require('mongodb').Int32;
|
|
408
|
-
* const doc = { int32: new Int32(10) };
|
|
409
|
-
*
|
|
410
|
-
* // prints '{"int32":{"$numberInt":"10"}}'
|
|
411
|
-
* console.log(EJSON.stringify(doc, { relaxed: false }));
|
|
412
|
-
*
|
|
413
|
-
* // prints '{"int32":10}'
|
|
414
|
-
* console.log(EJSON.stringify(doc));
|
|
415
|
-
* ```
|
|
416
|
-
*/
|
|
417
|
-
export function stringify(
|
|
418
|
-
value: SerializableTypes,
|
|
419
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
420
|
-
replacer?: (number | string)[] | ((this: any, key: string, value: any) => any) | EJSON.Options,
|
|
421
|
-
space?: string | number,
|
|
422
|
-
options?: EJSON.Options
|
|
423
|
-
): string {
|
|
424
|
-
if (space != null && typeof space === 'object') {
|
|
425
|
-
options = space;
|
|
426
|
-
space = 0;
|
|
427
|
-
}
|
|
428
|
-
if (replacer != null && typeof replacer === 'object' && !Array.isArray(replacer)) {
|
|
429
|
-
options = replacer;
|
|
430
|
-
replacer = undefined;
|
|
431
|
-
space = 0;
|
|
366
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
367
|
+
function parse(text: string, options?: EJSONOptions): any {
|
|
368
|
+
return JSON.parse(text, (key, value) => {
|
|
369
|
+
if (key.indexOf('\x00') !== -1) {
|
|
370
|
+
throw new BSONError(
|
|
371
|
+
`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`
|
|
372
|
+
);
|
|
432
373
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
374
|
+
return deserializeValue(value, { relaxed: true, legacy: false, ...options });
|
|
375
|
+
});
|
|
376
|
+
}
|
|
436
377
|
|
|
437
|
-
|
|
438
|
-
|
|
378
|
+
/**
|
|
379
|
+
* Converts a BSON document to an Extended JSON string, optionally replacing values if a replacer
|
|
380
|
+
* function is specified or optionally including only the specified properties if a replacer array
|
|
381
|
+
* is specified.
|
|
382
|
+
*
|
|
383
|
+
* @param value - The value to convert to extended JSON
|
|
384
|
+
* @param replacer - A function that alters the behavior of the stringification process, or an array of String and Number objects that serve as a whitelist for selecting/filtering the properties of the value object to be included in the JSON string. If this value is null or not provided, all properties of the object are included in the resulting JSON string
|
|
385
|
+
* @param space - A String or Number object that's used to insert white space into the output JSON string for readability purposes.
|
|
386
|
+
* @param options - Optional settings
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* ```js
|
|
390
|
+
* const { EJSON } = require('bson');
|
|
391
|
+
* const Int32 = require('mongodb').Int32;
|
|
392
|
+
* const doc = { int32: new Int32(10) };
|
|
393
|
+
*
|
|
394
|
+
* // prints '{"int32":{"$numberInt":"10"}}'
|
|
395
|
+
* console.log(EJSON.stringify(doc, { relaxed: false }));
|
|
396
|
+
*
|
|
397
|
+
* // prints '{"int32":10}'
|
|
398
|
+
* console.log(EJSON.stringify(doc));
|
|
399
|
+
* ```
|
|
400
|
+
*/
|
|
401
|
+
function stringify(
|
|
402
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
403
|
+
value: any,
|
|
404
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
405
|
+
replacer?: (number | string)[] | ((this: any, key: string, value: any) => any) | EJSONOptions,
|
|
406
|
+
space?: string | number,
|
|
407
|
+
options?: EJSONOptions
|
|
408
|
+
): string {
|
|
409
|
+
if (space != null && typeof space === 'object') {
|
|
410
|
+
options = space;
|
|
411
|
+
space = 0;
|
|
439
412
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
* @param value - The object to serialize
|
|
445
|
-
* @param options - Optional settings passed to the `stringify` function
|
|
446
|
-
*/
|
|
447
|
-
export function serialize(value: SerializableTypes, options?: EJSON.Options): Document {
|
|
448
|
-
options = options || {};
|
|
449
|
-
return JSON.parse(stringify(value, options));
|
|
413
|
+
if (replacer != null && typeof replacer === 'object' && !Array.isArray(replacer)) {
|
|
414
|
+
options = replacer;
|
|
415
|
+
replacer = undefined;
|
|
416
|
+
space = 0;
|
|
450
417
|
}
|
|
418
|
+
const serializeOptions = Object.assign({ relaxed: true, legacy: false }, options, {
|
|
419
|
+
seenObjects: [{ propertyName: '(root)', obj: null }]
|
|
420
|
+
});
|
|
451
421
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
*
|
|
455
|
-
* @param ejson - The Extended JSON object to deserialize
|
|
456
|
-
* @param options - Optional settings passed to the parse method
|
|
457
|
-
*/
|
|
458
|
-
export function deserialize(ejson: Document, options?: EJSON.Options): SerializableTypes {
|
|
459
|
-
options = options || {};
|
|
460
|
-
return parse(JSON.stringify(ejson), options);
|
|
461
|
-
}
|
|
422
|
+
const doc = serializeValue(value, serializeOptions);
|
|
423
|
+
return JSON.stringify(doc, replacer as Parameters<JSON['stringify']>[1], space);
|
|
462
424
|
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Serializes an object to an Extended JSON string, and reparse it as a JavaScript object.
|
|
428
|
+
*
|
|
429
|
+
* @param value - The object to serialize
|
|
430
|
+
* @param options - Optional settings passed to the `stringify` function
|
|
431
|
+
*/
|
|
432
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
433
|
+
function EJSONserialize(value: any, options?: EJSONOptions): Document {
|
|
434
|
+
options = options || {};
|
|
435
|
+
return JSON.parse(stringify(value, options));
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Deserializes an Extended JSON object into a plain JavaScript object with native/BSON types
|
|
440
|
+
*
|
|
441
|
+
* @param ejson - The Extended JSON object to deserialize
|
|
442
|
+
* @param options - Optional settings passed to the parse method
|
|
443
|
+
*/
|
|
444
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
445
|
+
function EJSONdeserialize(ejson: Document, options?: EJSONOptions): any {
|
|
446
|
+
options = options || {};
|
|
447
|
+
return parse(JSON.stringify(ejson), options);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** @public */
|
|
451
|
+
const EJSON: {
|
|
452
|
+
parse: typeof parse;
|
|
453
|
+
stringify: typeof stringify;
|
|
454
|
+
serialize: typeof EJSONserialize;
|
|
455
|
+
deserialize: typeof EJSONdeserialize;
|
|
456
|
+
} = Object.create(null);
|
|
457
|
+
EJSON.parse = parse;
|
|
458
|
+
EJSON.stringify = stringify;
|
|
459
|
+
EJSON.serialize = EJSONserialize;
|
|
460
|
+
EJSON.deserialize = EJSONdeserialize;
|
|
461
|
+
Object.freeze(EJSON);
|
|
462
|
+
export { EJSON };
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as BSON from './bson';
|
|
2
|
+
|
|
3
|
+
// Export all named properties from BSON to support
|
|
4
|
+
// import { ObjectId, serialize } from 'bson';
|
|
5
|
+
// const { ObjectId, serialize } = require('bson');
|
|
6
|
+
export * from './bson';
|
|
7
|
+
|
|
8
|
+
// Export BSON as a namespace to support:
|
|
9
|
+
// import { BSON } from 'bson';
|
|
10
|
+
// const { BSON } = require('bson');
|
|
11
|
+
export { BSON };
|
|
12
|
+
|
|
13
|
+
// BSON does **NOT** have a default export
|
|
14
|
+
|
|
15
|
+
// The following will crash in es module environments
|
|
16
|
+
// import BSON from 'bson';
|
|
17
|
+
|
|
18
|
+
// The following will work as expected, BSON as a namespace of all the APIs (BSON.ObjectId, BSON.serialize)
|
|
19
|
+
// const BSON = require('bson');
|
package/src/int_32.ts
CHANGED
|
@@ -11,7 +11,13 @@ export interface Int32Extended {
|
|
|
11
11
|
* @category BSONType
|
|
12
12
|
*/
|
|
13
13
|
export class Int32 {
|
|
14
|
-
_bsontype
|
|
14
|
+
get _bsontype(): 'Int32' {
|
|
15
|
+
return 'Int32';
|
|
16
|
+
}
|
|
17
|
+
/** @internal */
|
|
18
|
+
get [Symbol.for('@@mdb.bson.version')](): 5 {
|
|
19
|
+
return 5;
|
|
20
|
+
}
|
|
15
21
|
|
|
16
22
|
value!: number;
|
|
17
23
|
/**
|
|
@@ -20,8 +26,6 @@ export class Int32 {
|
|
|
20
26
|
* @param value - the number we want to represent as an int32.
|
|
21
27
|
*/
|
|
22
28
|
constructor(value: number | string) {
|
|
23
|
-
if (!(this instanceof Int32)) return new Int32(value);
|
|
24
|
-
|
|
25
29
|
if ((value as unknown) instanceof Number) {
|
|
26
30
|
value = value.valueOf();
|
|
27
31
|
}
|
|
@@ -66,5 +70,3 @@ export class Int32 {
|
|
|
66
70
|
return `new Int32(${this.valueOf()})`;
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
|
-
|
|
70
|
-
Object.defineProperty(Int32.prototype, '_bsontype', { value: 'Int32' });
|
package/src/long.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { EJSONOptions } from './extended_json';
|
|
2
|
-
import { isObjectLike } from './parser/utils';
|
|
3
2
|
import type { Timestamp } from './timestamp';
|
|
4
3
|
|
|
5
4
|
interface LongWASMHelpers {
|
|
@@ -100,10 +99,18 @@ export interface LongExtended {
|
|
|
100
99
|
* Common constant values ZERO, ONE, NEG_ONE, etc. are found as static properties on this class.
|
|
101
100
|
*/
|
|
102
101
|
export class Long {
|
|
103
|
-
_bsontype
|
|
102
|
+
get _bsontype(): 'Long' {
|
|
103
|
+
return 'Long';
|
|
104
|
+
}
|
|
105
|
+
/** @internal */
|
|
106
|
+
get [Symbol.for('@@mdb.bson.version')](): 5 {
|
|
107
|
+
return 5;
|
|
108
|
+
}
|
|
104
109
|
|
|
105
110
|
/** An indicator used to reliably determine if an object is a Long or not. */
|
|
106
|
-
__isLong__
|
|
111
|
+
get __isLong__(): boolean {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
107
114
|
|
|
108
115
|
/**
|
|
109
116
|
* The high 32 bits as a signed value.
|
|
@@ -134,8 +141,6 @@ export class Long {
|
|
|
134
141
|
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
135
142
|
*/
|
|
136
143
|
constructor(low: number | bigint | string = 0, high?: number | boolean, unsigned?: boolean) {
|
|
137
|
-
if (!(this instanceof Long)) return new Long(low, high, unsigned);
|
|
138
|
-
|
|
139
144
|
if (typeof low === 'bigint') {
|
|
140
145
|
Object.assign(this, Long.fromBigInt(low, !!high));
|
|
141
146
|
} else if (typeof low === 'string') {
|
|
@@ -145,13 +150,6 @@ export class Long {
|
|
|
145
150
|
this.high = (high as number) | 0;
|
|
146
151
|
this.unsigned = !!unsigned;
|
|
147
152
|
}
|
|
148
|
-
|
|
149
|
-
Object.defineProperty(this, '__isLong__', {
|
|
150
|
-
value: true,
|
|
151
|
-
configurable: false,
|
|
152
|
-
writable: false,
|
|
153
|
-
enumerable: false
|
|
154
|
-
});
|
|
155
153
|
}
|
|
156
154
|
|
|
157
155
|
static TWO_PWR_24 = Long.fromInt(TWO_PWR_24_DBL);
|
|
@@ -332,7 +330,12 @@ export class Long {
|
|
|
332
330
|
* Tests if the specified object is a Long.
|
|
333
331
|
*/
|
|
334
332
|
static isLong(value: unknown): value is Long {
|
|
335
|
-
return
|
|
333
|
+
return (
|
|
334
|
+
value != null &&
|
|
335
|
+
typeof value === 'object' &&
|
|
336
|
+
'__isLong__' in value &&
|
|
337
|
+
value.__isLong__ === true
|
|
338
|
+
);
|
|
336
339
|
}
|
|
337
340
|
|
|
338
341
|
/**
|
|
@@ -1035,6 +1038,3 @@ export class Long {
|
|
|
1035
1038
|
return `new Long("${this.toString()}"${this.unsigned ? ', true' : ''})`;
|
|
1036
1039
|
}
|
|
1037
1040
|
}
|
|
1038
|
-
|
|
1039
|
-
Object.defineProperty(Long.prototype, '__isLong__', { value: true });
|
|
1040
|
-
Object.defineProperty(Long.prototype, '_bsontype', { value: 'Long' });
|
package/src/max_key.ts
CHANGED
|
@@ -9,10 +9,12 @@ export interface MaxKeyExtended {
|
|
|
9
9
|
* @category BSONType
|
|
10
10
|
*/
|
|
11
11
|
export class MaxKey {
|
|
12
|
-
_bsontype
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
get _bsontype(): 'MaxKey' {
|
|
13
|
+
return 'MaxKey';
|
|
14
|
+
}
|
|
15
|
+
/** @internal */
|
|
16
|
+
get [Symbol.for('@@mdb.bson.version')](): 5 {
|
|
17
|
+
return 5;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
/** @internal */
|
|
@@ -34,5 +36,3 @@ export class MaxKey {
|
|
|
34
36
|
return 'new MaxKey()';
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
|
|
38
|
-
Object.defineProperty(MaxKey.prototype, '_bsontype', { value: 'MaxKey' });
|
package/src/min_key.ts
CHANGED
|
@@ -9,10 +9,12 @@ export interface MinKeyExtended {
|
|
|
9
9
|
* @category BSONType
|
|
10
10
|
*/
|
|
11
11
|
export class MinKey {
|
|
12
|
-
_bsontype
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
get _bsontype(): 'MinKey' {
|
|
13
|
+
return 'MinKey';
|
|
14
|
+
}
|
|
15
|
+
/** @internal */
|
|
16
|
+
get [Symbol.for('@@mdb.bson.version')](): 5 {
|
|
17
|
+
return 5;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
/** @internal */
|
|
@@ -34,5 +36,3 @@ export class MinKey {
|
|
|
34
36
|
return 'new MinKey()';
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
|
|
38
|
-
Object.defineProperty(MinKey.prototype, '_bsontype', { value: 'MinKey' });
|