bson 7.1.0 → 7.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/bson.d.ts +30 -6
- package/lib/bson.bundle.js +29 -1
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +29 -1
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +29 -1
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.node.mjs +29 -1
- package/lib/bson.node.mjs.map +1 -1
- package/lib/bson.rn.cjs +29 -1
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +1 -1
- package/src/bson.ts +6 -1
- package/src/extended_json.ts +33 -13
- package/src/parser/on_demand/index.ts +8 -0
- package/src/utils/byte_utils.ts +8 -0
- package/src/utils/node_byte_utils.ts +12 -0
- package/src/utils/web_byte_utils.ts +43 -0
package/package.json
CHANGED
package/src/bson.ts
CHANGED
|
@@ -22,7 +22,12 @@ export type { CodeExtended } from './code';
|
|
|
22
22
|
export type { DBRefLike } from './db_ref';
|
|
23
23
|
export type { Decimal128Extended } from './decimal128';
|
|
24
24
|
export type { DoubleExtended } from './double';
|
|
25
|
-
export type {
|
|
25
|
+
export type {
|
|
26
|
+
EJSONOptions,
|
|
27
|
+
EJSONOptionsBase,
|
|
28
|
+
EJSONSerializeOptions,
|
|
29
|
+
EJSONParseOptions
|
|
30
|
+
} from './extended_json';
|
|
26
31
|
export type { Int32Extended } from './int_32';
|
|
27
32
|
export type { LongExtended } from './long';
|
|
28
33
|
export type { MaxKeyExtended } from './max_key';
|
package/src/extended_json.ts
CHANGED
|
@@ -24,7 +24,7 @@ import { BSONSymbol } from './symbol';
|
|
|
24
24
|
import { Timestamp } from './timestamp';
|
|
25
25
|
|
|
26
26
|
/** @public */
|
|
27
|
-
export type
|
|
27
|
+
export type EJSONOptionsBase = {
|
|
28
28
|
/**
|
|
29
29
|
* Output using the Extended JSON v1 spec
|
|
30
30
|
* @defaultValue `false`
|
|
@@ -32,8 +32,22 @@ export type EJSONOptions = {
|
|
|
32
32
|
legacy?: boolean;
|
|
33
33
|
/**
|
|
34
34
|
* Enable Extended JSON's `relaxed` mode, which attempts to return native JS types where possible, rather than BSON types
|
|
35
|
-
* @defaultValue `false`
|
|
35
|
+
* @defaultValue `false`
|
|
36
|
+
*/
|
|
36
37
|
relaxed?: boolean;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** @public */
|
|
41
|
+
export type EJSONSerializeOptions = EJSONOptionsBase & {
|
|
42
|
+
/**
|
|
43
|
+
* Omits undefined values from the output instead of converting them to null
|
|
44
|
+
* @defaultValue `false`
|
|
45
|
+
*/
|
|
46
|
+
ignoreUndefined?: boolean;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** @public */
|
|
50
|
+
export type EJSONParseOptions = EJSONOptionsBase & {
|
|
37
51
|
/**
|
|
38
52
|
* Enable native bigint support
|
|
39
53
|
* @defaultValue `false`
|
|
@@ -41,6 +55,9 @@ export type EJSONOptions = {
|
|
|
41
55
|
useBigInt64?: boolean;
|
|
42
56
|
};
|
|
43
57
|
|
|
58
|
+
/** @public */
|
|
59
|
+
export type EJSONOptions = EJSONSerializeOptions & EJSONParseOptions;
|
|
60
|
+
|
|
44
61
|
/** @internal */
|
|
45
62
|
type BSONType =
|
|
46
63
|
| Binary
|
|
@@ -174,12 +191,12 @@ function deserializeValue(value: any, options: EJSONOptions = {}) {
|
|
|
174
191
|
return value;
|
|
175
192
|
}
|
|
176
193
|
|
|
177
|
-
type
|
|
194
|
+
type EJSONSerializeInternalOptions = EJSONSerializeOptions & {
|
|
178
195
|
seenObjects: { obj: unknown; propertyName: string }[];
|
|
179
196
|
};
|
|
180
197
|
|
|
181
198
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
182
|
-
function serializeArray(array: any[], options:
|
|
199
|
+
function serializeArray(array: any[], options: EJSONSerializeInternalOptions): any[] {
|
|
183
200
|
return array.map((v: unknown, index: number) => {
|
|
184
201
|
options.seenObjects.push({ propertyName: `index ${index}`, obj: null });
|
|
185
202
|
try {
|
|
@@ -197,7 +214,7 @@ function getISOString(date: Date) {
|
|
|
197
214
|
}
|
|
198
215
|
|
|
199
216
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
200
|
-
function serializeValue(value: any, options:
|
|
217
|
+
function serializeValue(value: any, options: EJSONSerializeInternalOptions): any {
|
|
201
218
|
if (value instanceof Map || isMap(value)) {
|
|
202
219
|
const obj: Record<string, unknown> = Object.create(null);
|
|
203
220
|
for (const [k, v] of value) {
|
|
@@ -242,7 +259,7 @@ function serializeValue(value: any, options: EJSONSerializeOptions): any {
|
|
|
242
259
|
|
|
243
260
|
if (Array.isArray(value)) return serializeArray(value, options);
|
|
244
261
|
|
|
245
|
-
if (value === undefined) return null;
|
|
262
|
+
if (value === undefined) return options.ignoreUndefined ? undefined : null;
|
|
246
263
|
|
|
247
264
|
if (value instanceof Date || isDate(value)) {
|
|
248
265
|
const dateNum = value.getTime(),
|
|
@@ -326,7 +343,7 @@ const BSON_TYPE_MAPPINGS = {
|
|
|
326
343
|
} as const;
|
|
327
344
|
|
|
328
345
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
329
|
-
function serializeDocument(doc: any, options:
|
|
346
|
+
function serializeDocument(doc: any, options: EJSONSerializeInternalOptions) {
|
|
330
347
|
if (doc == null || typeof doc !== 'object') throw new BSONError('not an object instance');
|
|
331
348
|
|
|
332
349
|
const bsontype: BSONType['_bsontype'] = doc._bsontype;
|
|
@@ -410,7 +427,7 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
|
|
|
410
427
|
* ```
|
|
411
428
|
*/
|
|
412
429
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
413
|
-
function parse(text: string, options?:
|
|
430
|
+
function parse(text: string, options?: EJSONParseOptions): any {
|
|
414
431
|
const ejsonOptions = {
|
|
415
432
|
useBigInt64: options?.useBigInt64 ?? false,
|
|
416
433
|
relaxed: options?.relaxed ?? true,
|
|
@@ -452,10 +469,13 @@ function parse(text: string, options?: EJSONOptions): any {
|
|
|
452
469
|
function stringify(
|
|
453
470
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
454
471
|
value: any,
|
|
455
|
-
|
|
456
|
-
|
|
472
|
+
replacer?:
|
|
473
|
+
| (number | string)[]
|
|
474
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
475
|
+
| ((this: any, key: string, value: any) => any)
|
|
476
|
+
| EJSONSerializeOptions,
|
|
457
477
|
space?: string | number,
|
|
458
|
-
options?:
|
|
478
|
+
options?: EJSONSerializeOptions
|
|
459
479
|
): string {
|
|
460
480
|
if (space != null && typeof space === 'object') {
|
|
461
481
|
options = space;
|
|
@@ -481,7 +501,7 @@ function stringify(
|
|
|
481
501
|
* @param options - Optional settings passed to the `stringify` function
|
|
482
502
|
*/
|
|
483
503
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
484
|
-
function EJSONserialize(value: any, options?:
|
|
504
|
+
function EJSONserialize(value: any, options?: EJSONSerializeOptions): Document {
|
|
485
505
|
options = options || {};
|
|
486
506
|
return JSON.parse(stringify(value, options));
|
|
487
507
|
}
|
|
@@ -493,7 +513,7 @@ function EJSONserialize(value: any, options?: EJSONOptions): Document {
|
|
|
493
513
|
* @param options - Optional settings passed to the parse method
|
|
494
514
|
*/
|
|
495
515
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
496
|
-
function EJSONdeserialize(ejson: Document, options?:
|
|
516
|
+
function EJSONdeserialize(ejson: Document, options?: EJSONParseOptions): any {
|
|
497
517
|
options = options || {};
|
|
498
518
|
return parse(JSON.stringify(ejson), options);
|
|
499
519
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ByteUtils } from '../../utils/byte_utils';
|
|
2
|
+
import { NumberUtils } from '../../utils/number_utils';
|
|
1
3
|
import { type BSONElement, parseToElements } from './parse_to_elements';
|
|
2
4
|
/**
|
|
3
5
|
* @experimental
|
|
@@ -9,6 +11,10 @@ export type OnDemand = {
|
|
|
9
11
|
parseToElements: (this: void, bytes: Uint8Array, startOffset?: number) => Iterable<BSONElement>;
|
|
10
12
|
// Types
|
|
11
13
|
BSONElement: BSONElement;
|
|
14
|
+
|
|
15
|
+
// Utils
|
|
16
|
+
ByteUtils: ByteUtils;
|
|
17
|
+
NumberUtils: NumberUtils;
|
|
12
18
|
};
|
|
13
19
|
|
|
14
20
|
/**
|
|
@@ -18,6 +24,8 @@ export type OnDemand = {
|
|
|
18
24
|
const onDemand: OnDemand = Object.create(null);
|
|
19
25
|
|
|
20
26
|
onDemand.parseToElements = parseToElements;
|
|
27
|
+
onDemand.ByteUtils = ByteUtils;
|
|
28
|
+
onDemand.NumberUtils = NumberUtils;
|
|
21
29
|
|
|
22
30
|
Object.freeze(onDemand);
|
|
23
31
|
|
package/src/utils/byte_utils.ts
CHANGED
|
@@ -21,6 +21,14 @@ export type ByteUtils = {
|
|
|
21
21
|
compare: (buffer1: Uint8Array, buffer2: Uint8Array) => -1 | 0 | 1;
|
|
22
22
|
/** Concatenating all the Uint8Arrays in new Uint8Array. */
|
|
23
23
|
concat: (list: Uint8Array[]) => Uint8Array;
|
|
24
|
+
/** Copy bytes from source Uint8Array to target Uint8Array */
|
|
25
|
+
copy: (
|
|
26
|
+
source: Uint8Array,
|
|
27
|
+
target: Uint8Array,
|
|
28
|
+
targetStart?: number,
|
|
29
|
+
sourceStart?: number,
|
|
30
|
+
sourceEnd?: number
|
|
31
|
+
) => number;
|
|
24
32
|
/** Check if two Uint8Arrays are deep equal */
|
|
25
33
|
equals: (a: Uint8Array, b: Uint8Array) => boolean;
|
|
26
34
|
/** Create a Uint8Array from an array of numbers */
|
|
@@ -104,6 +104,18 @@ export const nodeJsByteUtils = {
|
|
|
104
104
|
return Buffer.concat(list);
|
|
105
105
|
},
|
|
106
106
|
|
|
107
|
+
copy(
|
|
108
|
+
source: Uint8Array,
|
|
109
|
+
target: Uint8Array,
|
|
110
|
+
targetStart?: number,
|
|
111
|
+
sourceStart?: number,
|
|
112
|
+
sourceEnd?: number
|
|
113
|
+
): number {
|
|
114
|
+
return nodeJsByteUtils
|
|
115
|
+
.toLocalBufferType(source)
|
|
116
|
+
.copy(target, targetStart ?? 0, sourceStart ?? 0, sourceEnd ?? source.length);
|
|
117
|
+
},
|
|
118
|
+
|
|
107
119
|
equals(a: Uint8Array, b: Uint8Array): boolean {
|
|
108
120
|
return nodeJsByteUtils.toLocalBufferType(a).equals(b);
|
|
109
121
|
},
|
|
@@ -155,6 +155,49 @@ export const webByteUtils = {
|
|
|
155
155
|
return result;
|
|
156
156
|
},
|
|
157
157
|
|
|
158
|
+
copy(
|
|
159
|
+
source: Uint8Array,
|
|
160
|
+
target: Uint8Array,
|
|
161
|
+
targetStart?: number,
|
|
162
|
+
sourceStart?: number,
|
|
163
|
+
sourceEnd?: number
|
|
164
|
+
): number {
|
|
165
|
+
// validate and standardize passed-in sourceEnd
|
|
166
|
+
if (sourceEnd !== undefined && sourceEnd < 0) {
|
|
167
|
+
throw new RangeError(
|
|
168
|
+
`The value of "sourceEnd" is out of range. It must be >= 0. Received ${sourceEnd}`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
sourceEnd = sourceEnd ?? source.length;
|
|
172
|
+
|
|
173
|
+
// validate and standardize passed-in sourceStart
|
|
174
|
+
if (sourceStart !== undefined && (sourceStart < 0 || sourceStart > sourceEnd)) {
|
|
175
|
+
throw new RangeError(
|
|
176
|
+
`The value of "sourceStart" is out of range. It must be >= 0 and <= ${sourceEnd}. Received ${sourceStart}`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
sourceStart = sourceStart ?? 0;
|
|
180
|
+
|
|
181
|
+
// validate and standardize passed-in targetStart
|
|
182
|
+
if (targetStart !== undefined && targetStart < 0) {
|
|
183
|
+
throw new RangeError(
|
|
184
|
+
`The value of "targetStart" is out of range. It must be >= 0. Received ${targetStart}`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
targetStart = targetStart ?? 0;
|
|
188
|
+
|
|
189
|
+
// figure out how many bytes we can copy
|
|
190
|
+
const srcSlice = source.subarray(sourceStart, sourceEnd);
|
|
191
|
+
const maxLen = Math.min(srcSlice.length, target.length - targetStart);
|
|
192
|
+
if (maxLen <= 0) {
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// perform the copy
|
|
197
|
+
target.set(srcSlice.subarray(0, maxLen), targetStart);
|
|
198
|
+
return maxLen;
|
|
199
|
+
},
|
|
200
|
+
|
|
158
201
|
equals(uint8Array: Uint8Array, otherUint8Array: Uint8Array): boolean {
|
|
159
202
|
if (uint8Array.byteLength !== otherUint8Array.byteLength) {
|
|
160
203
|
return false;
|