bson 6.5.0 → 6.7.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 +215 -7
- package/lib/bson.bundle.js +157 -78
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +157 -78
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +157 -79
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.rn.cjs +159 -79
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +15 -15
- package/src/binary.ts +5 -5
- package/src/bson.ts +2 -2
- package/src/constants.ts +1 -1
- package/src/double.ts +36 -0
- package/src/error.ts +2 -2
- package/src/int_32.ts +34 -0
- package/src/long.ts +168 -11
- package/src/parse_utf8.ts +35 -0
- package/src/parser/deserializer.ts +1 -7
- package/src/parser/on_demand/index.ts +10 -6
- package/src/parser/on_demand/parse_to_elements.ts +42 -28
- package/src/utils/byte_utils.ts +10 -4
- package/src/utils/node_byte_utils.ts +2 -5
- package/src/utils/number_utils.ts +37 -2
- package/src/utils/string_utils.ts +44 -0
- package/src/utils/web_byte_utils.ts +2 -8
- package/src/validate_utf8.ts +0 -47
package/bson.d.ts
CHANGED
|
@@ -140,9 +140,11 @@ declare namespace BSON {
|
|
|
140
140
|
BSONError,
|
|
141
141
|
BSONVersionError,
|
|
142
142
|
BSONRuntimeError,
|
|
143
|
+
BSONOffsetError,
|
|
143
144
|
BSONType,
|
|
144
145
|
EJSON,
|
|
145
146
|
onDemand,
|
|
147
|
+
OnDemand,
|
|
146
148
|
Document,
|
|
147
149
|
CalculateObjectSizeOptions
|
|
148
150
|
}
|
|
@@ -196,10 +198,12 @@ export declare class BSONError extends Error {
|
|
|
196
198
|
* An error generated when BSON bytes are invalid.
|
|
197
199
|
* Reports the offset the parser was able to reach before encountering the error.
|
|
198
200
|
*/
|
|
199
|
-
declare class BSONOffsetError extends BSONError {
|
|
201
|
+
export declare class BSONOffsetError extends BSONError {
|
|
200
202
|
get name(): 'BSONOffsetError';
|
|
201
203
|
offset: number;
|
|
202
|
-
constructor(message: string, offset: number
|
|
204
|
+
constructor(message: string, offset: number, options?: {
|
|
205
|
+
cause?: unknown;
|
|
206
|
+
});
|
|
203
207
|
}
|
|
204
208
|
|
|
205
209
|
/**
|
|
@@ -325,6 +329,48 @@ export declare class BSONVersionError extends BSONError {
|
|
|
325
329
|
constructor();
|
|
326
330
|
}
|
|
327
331
|
|
|
332
|
+
/**
|
|
333
|
+
* @public
|
|
334
|
+
* @experimental
|
|
335
|
+
*
|
|
336
|
+
* A collection of functions that help work with data in a Uint8Array.
|
|
337
|
+
* ByteUtils is configured at load time to use Node.js or Web based APIs for the internal implementations.
|
|
338
|
+
*/
|
|
339
|
+
declare type ByteUtils = {
|
|
340
|
+
/** Transforms the input to an instance of Buffer if running on node, otherwise Uint8Array */
|
|
341
|
+
toLocalBufferType: (buffer: Uint8Array | ArrayBufferView | ArrayBuffer) => Uint8Array;
|
|
342
|
+
/** Create empty space of size */
|
|
343
|
+
allocate: (size: number) => Uint8Array;
|
|
344
|
+
/** Create empty space of size, use pooled memory when available */
|
|
345
|
+
allocateUnsafe: (size: number) => Uint8Array;
|
|
346
|
+
/** Check if two Uint8Arrays are deep equal */
|
|
347
|
+
equals: (a: Uint8Array, b: Uint8Array) => boolean;
|
|
348
|
+
/** Check if two Uint8Arrays are deep equal */
|
|
349
|
+
fromNumberArray: (array: number[]) => Uint8Array;
|
|
350
|
+
/** Create a Uint8Array from a base64 string */
|
|
351
|
+
fromBase64: (base64: string) => Uint8Array;
|
|
352
|
+
/** Create a base64 string from bytes */
|
|
353
|
+
toBase64: (buffer: Uint8Array) => string;
|
|
354
|
+
/** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
|
|
355
|
+
fromISO88591: (codePoints: string) => Uint8Array;
|
|
356
|
+
/** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
|
|
357
|
+
toISO88591: (buffer: Uint8Array) => string;
|
|
358
|
+
/** Create a Uint8Array from a hex string */
|
|
359
|
+
fromHex: (hex: string) => Uint8Array;
|
|
360
|
+
/** Create a lowercase hex string from bytes */
|
|
361
|
+
toHex: (buffer: Uint8Array) => string;
|
|
362
|
+
/** Create a string from utf8 code units, fatal=true will throw an error if UTF-8 bytes are invalid, fatal=false will insert replacement characters */
|
|
363
|
+
toUTF8: (buffer: Uint8Array, start: number, end: number, fatal: boolean) => string;
|
|
364
|
+
/** Get the utf8 code unit count from a string if it were to be transformed to utf8 */
|
|
365
|
+
utf8ByteLength: (input: string) => number;
|
|
366
|
+
/** Encode UTF8 bytes generated from `source` string into `destination` at byteOffset. Returns the number of bytes encoded. */
|
|
367
|
+
encodeUTF8Into: (destination: Uint8Array, source: string, byteOffset: number) => number;
|
|
368
|
+
/** Generate a Uint8Array filled with random bytes with byteLength */
|
|
369
|
+
randomBytes: (byteLength: number) => Uint8Array;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
/* Excluded declaration from this release type: ByteUtils */
|
|
373
|
+
|
|
328
374
|
/**
|
|
329
375
|
* Calculate the bson size for a passed in Javascript object.
|
|
330
376
|
*
|
|
@@ -555,6 +601,20 @@ export declare class Double extends BSONValue {
|
|
|
555
601
|
* @param value - the number we want to represent as a double.
|
|
556
602
|
*/
|
|
557
603
|
constructor(value: number);
|
|
604
|
+
/**
|
|
605
|
+
* Attempt to create an double type from string.
|
|
606
|
+
*
|
|
607
|
+
* This method will throw a BSONError on any string input that is not representable as a IEEE-754 64-bit double.
|
|
608
|
+
* Notably, this method will also throw on the following string formats:
|
|
609
|
+
* - Strings in non-decimal and non-exponential formats (binary, hex, or octal digits)
|
|
610
|
+
* - Strings with characters other than numeric, floating point, or leading sign characters (Note: 'Infinity', '-Infinity', and 'NaN' input strings are still allowed)
|
|
611
|
+
* - Strings with leading and/or trailing whitespace
|
|
612
|
+
*
|
|
613
|
+
* Strings with leading zeros, however, are also allowed
|
|
614
|
+
*
|
|
615
|
+
* @param value - the string we want to represent as a double.
|
|
616
|
+
*/
|
|
617
|
+
static fromString(value: string): Double;
|
|
558
618
|
/**
|
|
559
619
|
* Access the number value.
|
|
560
620
|
*
|
|
@@ -631,6 +691,20 @@ export declare class Int32 extends BSONValue {
|
|
|
631
691
|
* @param value - the number we want to represent as an int32.
|
|
632
692
|
*/
|
|
633
693
|
constructor(value: number | string);
|
|
694
|
+
/**
|
|
695
|
+
* Attempt to create an Int32 type from string.
|
|
696
|
+
*
|
|
697
|
+
* This method will throw a BSONError on any string input that is not representable as an Int32.
|
|
698
|
+
* Notably, this method will also throw on the following string formats:
|
|
699
|
+
* - Strings in non-decimal formats (exponent notation, binary, hex, or octal digits)
|
|
700
|
+
* - Strings non-numeric and non-leading sign characters (ex: '2.0', '24,000')
|
|
701
|
+
* - Strings with leading and/or trailing whitespace
|
|
702
|
+
*
|
|
703
|
+
* Strings with leading zeros, however, are allowed.
|
|
704
|
+
*
|
|
705
|
+
* @param value - the string we want to represent as an int32.
|
|
706
|
+
*/
|
|
707
|
+
static fromString(value: string): Int32;
|
|
634
708
|
/**
|
|
635
709
|
* Access the number value.
|
|
636
710
|
*
|
|
@@ -745,8 +819,113 @@ export declare class Long extends BSONValue {
|
|
|
745
819
|
* @returns The corresponding Long value
|
|
746
820
|
*/
|
|
747
821
|
static fromBigInt(value: bigint, unsigned?: boolean): Long;
|
|
822
|
+
/* Excluded from this release type: _fromString */
|
|
823
|
+
/**
|
|
824
|
+
* Returns a signed Long representation of the given string, written using radix 10.
|
|
825
|
+
* Will throw an error if the given text is not exactly representable as a Long.
|
|
826
|
+
* Throws an error if any of the following conditions are true:
|
|
827
|
+
* - the string contains invalid characters for the radix 10
|
|
828
|
+
* - the string contains whitespace
|
|
829
|
+
* - the value the string represents is too large or too small to be a Long
|
|
830
|
+
* Unlike Long.fromString, this method does not coerce '+/-Infinity' and 'NaN' to Long.Zero
|
|
831
|
+
* @param str - The textual representation of the Long
|
|
832
|
+
* @returns The corresponding Long value
|
|
833
|
+
*/
|
|
834
|
+
static fromStringStrict(str: string): Long;
|
|
835
|
+
/**
|
|
836
|
+
* Returns a Long representation of the given string, written using the radix 10.
|
|
837
|
+
* Will throw an error if the given parameters are not exactly representable as a Long.
|
|
838
|
+
* Throws an error if any of the following conditions are true:
|
|
839
|
+
* - the string contains invalid characters for the given radix
|
|
840
|
+
* - the string contains whitespace
|
|
841
|
+
* - the value the string represents is too large or too small to be a Long
|
|
842
|
+
* Unlike Long.fromString, this method does not coerce '+/-Infinity' and 'NaN' to Long.Zero
|
|
843
|
+
* @param str - The textual representation of the Long
|
|
844
|
+
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
845
|
+
* @returns The corresponding Long value
|
|
846
|
+
*/
|
|
847
|
+
static fromStringStrict(str: string, unsigned?: boolean): Long;
|
|
848
|
+
/**
|
|
849
|
+
* Returns a signed Long representation of the given string, written using the specified radix.
|
|
850
|
+
* Will throw an error if the given parameters are not exactly representable as a Long.
|
|
851
|
+
* Throws an error if any of the following conditions are true:
|
|
852
|
+
* - the string contains invalid characters for the given radix
|
|
853
|
+
* - the string contains whitespace
|
|
854
|
+
* - the value the string represents is too large or too small to be a Long
|
|
855
|
+
* Unlike Long.fromString, this method does not coerce '+/-Infinity' and 'NaN' to Long.Zero
|
|
856
|
+
* @param str - The textual representation of the Long
|
|
857
|
+
* @param radix - The radix in which the text is written (2-36), defaults to 10
|
|
858
|
+
* @returns The corresponding Long value
|
|
859
|
+
*/
|
|
860
|
+
static fromStringStrict(str: string, radix?: boolean): Long;
|
|
748
861
|
/**
|
|
749
862
|
* Returns a Long representation of the given string, written using the specified radix.
|
|
863
|
+
* Will throw an error if the given parameters are not exactly representable as a Long.
|
|
864
|
+
* Throws an error if any of the following conditions are true:
|
|
865
|
+
* - the string contains invalid characters for the given radix
|
|
866
|
+
* - the string contains whitespace
|
|
867
|
+
* - the value the string represents is too large or too small to be a Long
|
|
868
|
+
* Unlike Long.fromString, this method does not coerce '+/-Infinity' and 'NaN' to Long.Zero
|
|
869
|
+
* @param str - The textual representation of the Long
|
|
870
|
+
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
871
|
+
* @param radix - The radix in which the text is written (2-36), defaults to 10
|
|
872
|
+
* @returns The corresponding Long value
|
|
873
|
+
*/
|
|
874
|
+
static fromStringStrict(str: string, unsigned?: boolean, radix?: number): Long;
|
|
875
|
+
/**
|
|
876
|
+
* Returns a signed Long representation of the given string, written using radix 10.
|
|
877
|
+
*
|
|
878
|
+
* If the input string is empty, this function will throw a BSONError.
|
|
879
|
+
*
|
|
880
|
+
* If input string does not have valid signed 64-bit Long representation, this method will return a coerced value:
|
|
881
|
+
* - inputs that overflow 64-bit signed long will be coerced to Long.MAX_VALUE and Long.MIN_VALUE respectively
|
|
882
|
+
* - 'NaN' or '+/-Infinity' are coerced to Long.ZERO
|
|
883
|
+
* - other invalid characters sequences have variable behavior
|
|
884
|
+
*
|
|
885
|
+
* @param str - The textual representation of the Long
|
|
886
|
+
* @returns The corresponding Long value
|
|
887
|
+
*/
|
|
888
|
+
static fromString(str: string): Long;
|
|
889
|
+
/**
|
|
890
|
+
* Returns a signed Long representation of the given string, written using the provided radix.
|
|
891
|
+
*
|
|
892
|
+
* If the input string is empty or a provided radix is not within (2-36), this function will throw a BSONError.
|
|
893
|
+
*
|
|
894
|
+
* If input parameters do not have valid signed 64-bit Long representation, this method will return a coerced value:
|
|
895
|
+
* - inputs that overflow 64-bit signed long will be coerced to Long.MAX_VALUE and Long.MIN_VALUE respectively
|
|
896
|
+
* - if the radix is less than 24, 'NaN' is coerced to Long.ZERO
|
|
897
|
+
* - if the radix is less than 35, '+/-Infinity' inputs are coerced to Long.ZERO
|
|
898
|
+
* - other invalid characters sequences have variable behavior
|
|
899
|
+
* @param str - The textual representation of the Long
|
|
900
|
+
* @param radix - The radix in which the text is written (2-36), defaults to 10
|
|
901
|
+
* @returns The corresponding Long value
|
|
902
|
+
*/
|
|
903
|
+
static fromString(str: string, radix?: number): Long;
|
|
904
|
+
/**
|
|
905
|
+
* Returns a Long representation of the given string, written using radix 10.
|
|
906
|
+
*
|
|
907
|
+
* If the input string is empty, this function will throw a BSONError.
|
|
908
|
+
*
|
|
909
|
+
* If input parameters do not have a valid 64-bit Long representation, this method will return a coerced value:
|
|
910
|
+
* - inputs that overflow 64-bit long will be coerced to max or min (if signed) values
|
|
911
|
+
* - if the radix is less than 24, 'NaN' is coerced to Long.ZERO
|
|
912
|
+
* - if the radix is less than 35, '+/-Infinity' inputs are coerced to Long.ZERO
|
|
913
|
+
* - other invalid characters sequences have variable behavior
|
|
914
|
+
* @param str - The textual representation of the Long
|
|
915
|
+
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
916
|
+
* @returns The corresponding Long value
|
|
917
|
+
*/
|
|
918
|
+
static fromString(str: string, unsigned?: boolean): Long;
|
|
919
|
+
/**
|
|
920
|
+
* Returns a Long representation of the given string, written using the specified radix.
|
|
921
|
+
*
|
|
922
|
+
* If the input string is empty or a provided radix is not within (2-36), this function will throw a BSONError.
|
|
923
|
+
*
|
|
924
|
+
* If input parameters do not have a valid 64-bit Long representation, this method will return a coerced value:
|
|
925
|
+
* - inputs that overflow 64-bit long will be coerced to max or min (if signed) values
|
|
926
|
+
* - if the radix is less than 24, 'NaN' is coerced to Long.ZERO
|
|
927
|
+
* - if the radix is less than 35, '+/-Infinity' inputs are coerced to Long.ZERO
|
|
928
|
+
* - other invalid characters sequences have variable behavior
|
|
750
929
|
* @param str - The textual representation of the Long
|
|
751
930
|
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
752
931
|
* @param radix - The radix in which the text is written (2-36), defaults to 10
|
|
@@ -1012,6 +1191,36 @@ export declare interface MinKeyExtended {
|
|
|
1012
1191
|
$minKey: 1;
|
|
1013
1192
|
}
|
|
1014
1193
|
|
|
1194
|
+
/**
|
|
1195
|
+
* @experimental
|
|
1196
|
+
* @public
|
|
1197
|
+
*
|
|
1198
|
+
* A collection of functions that get or set various numeric types and bit widths from a Uint8Array.
|
|
1199
|
+
*/
|
|
1200
|
+
declare type NumberUtils = {
|
|
1201
|
+
/**
|
|
1202
|
+
* Parses a signed int32 at offset. Throws a `RangeError` if value is negative.
|
|
1203
|
+
*/
|
|
1204
|
+
getNonnegativeInt32LE: (source: Uint8Array, offset: number) => number;
|
|
1205
|
+
getInt32LE: (source: Uint8Array, offset: number) => number;
|
|
1206
|
+
getUint32LE: (source: Uint8Array, offset: number) => number;
|
|
1207
|
+
getUint32BE: (source: Uint8Array, offset: number) => number;
|
|
1208
|
+
getBigInt64LE: (source: Uint8Array, offset: number) => bigint;
|
|
1209
|
+
getFloat64LE: (source: Uint8Array, offset: number) => number;
|
|
1210
|
+
setInt32BE: (destination: Uint8Array, offset: number, value: number) => 4;
|
|
1211
|
+
setInt32LE: (destination: Uint8Array, offset: number, value: number) => 4;
|
|
1212
|
+
setBigInt64LE: (destination: Uint8Array, offset: number, value: bigint) => 8;
|
|
1213
|
+
setFloat64LE: (destination: Uint8Array, offset: number, value: number) => 8;
|
|
1214
|
+
};
|
|
1215
|
+
|
|
1216
|
+
/**
|
|
1217
|
+
* Number parsing and serializing utilities.
|
|
1218
|
+
*
|
|
1219
|
+
* @experimental
|
|
1220
|
+
* @public
|
|
1221
|
+
*/
|
|
1222
|
+
declare const NumberUtils: NumberUtils;
|
|
1223
|
+
|
|
1015
1224
|
/**
|
|
1016
1225
|
* A class representation of the BSON ObjectId type.
|
|
1017
1226
|
* @public
|
|
@@ -1142,12 +1351,11 @@ export declare interface ObjectIdLike {
|
|
|
1142
1351
|
*
|
|
1143
1352
|
* A new set of BSON APIs that are currently experimental and not intended for production use.
|
|
1144
1353
|
*/
|
|
1145
|
-
declare type OnDemand = {
|
|
1146
|
-
BSONOffsetError: {
|
|
1147
|
-
new (message: string, offset: number): BSONOffsetError;
|
|
1148
|
-
isBSONError(value: unknown): value is BSONError;
|
|
1149
|
-
};
|
|
1354
|
+
export declare type OnDemand = {
|
|
1150
1355
|
parseToElements: (this: void, bytes: Uint8Array, startOffset?: number) => Iterable<BSONElement>;
|
|
1356
|
+
BSONElement: BSONElement;
|
|
1357
|
+
ByteUtils: ByteUtils;
|
|
1358
|
+
NumberUtils: NumberUtils;
|
|
1151
1359
|
};
|
|
1152
1360
|
|
|
1153
1361
|
/**
|
package/lib/bson.bundle.js
CHANGED
|
@@ -131,47 +131,26 @@ class BSONOffsetError extends BSONError {
|
|
|
131
131
|
get name() {
|
|
132
132
|
return 'BSONOffsetError';
|
|
133
133
|
}
|
|
134
|
-
constructor(message, offset) {
|
|
135
|
-
super(`${message}. offset: ${offset}
|
|
134
|
+
constructor(message, offset, options) {
|
|
135
|
+
super(`${message}. offset: ${offset}`, options);
|
|
136
136
|
this.offset = offset;
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const FOUR_BIT_CHAR = 0xf0;
|
|
148
|
-
const CONTINUING_CHAR = 0x80;
|
|
149
|
-
function validateUtf8(bytes, start, end) {
|
|
150
|
-
let continuation = 0;
|
|
151
|
-
for (let i = start; i < end; i += 1) {
|
|
152
|
-
const byte = bytes[i];
|
|
153
|
-
if (continuation) {
|
|
154
|
-
if ((byte & FIRST_TWO_BITS) !== CONTINUING_CHAR) {
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
continuation -= 1;
|
|
140
|
+
let TextDecoderFatal;
|
|
141
|
+
let TextDecoderNonFatal;
|
|
142
|
+
function parseUtf8(buffer, start, end, fatal) {
|
|
143
|
+
if (fatal) {
|
|
144
|
+
TextDecoderFatal ??= new TextDecoder('utf8', { fatal: true });
|
|
145
|
+
try {
|
|
146
|
+
return TextDecoderFatal.decode(buffer.subarray(start, end));
|
|
158
147
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
continuation = 1;
|
|
162
|
-
}
|
|
163
|
-
else if ((byte & FIRST_FOUR_BITS) === THREE_BIT_CHAR) {
|
|
164
|
-
continuation = 2;
|
|
165
|
-
}
|
|
166
|
-
else if ((byte & FIRST_FIVE_BITS) === FOUR_BIT_CHAR) {
|
|
167
|
-
continuation = 3;
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
148
|
+
catch (cause) {
|
|
149
|
+
throw new BSONError('Invalid UTF-8 string in BSON document', { cause });
|
|
172
150
|
}
|
|
173
151
|
}
|
|
174
|
-
|
|
152
|
+
TextDecoderNonFatal ??= new TextDecoder('utf8', { fatal: false });
|
|
153
|
+
return TextDecoderNonFatal.decode(buffer.subarray(start, end));
|
|
175
154
|
}
|
|
176
155
|
|
|
177
156
|
function tryReadBasicLatin(uint8array, start, end) {
|
|
@@ -292,9 +271,7 @@ const nodeJsByteUtils = {
|
|
|
292
271
|
if (fatal) {
|
|
293
272
|
for (let i = 0; i < string.length; i++) {
|
|
294
273
|
if (string.charCodeAt(i) === 0xfffd) {
|
|
295
|
-
|
|
296
|
-
throw new BSONError('Invalid UTF-8 string in BSON document');
|
|
297
|
-
}
|
|
274
|
+
parseUtf8(buffer, start, end, true);
|
|
298
275
|
break;
|
|
299
276
|
}
|
|
300
277
|
}
|
|
@@ -418,15 +395,7 @@ const webByteUtils = {
|
|
|
418
395
|
if (basicLatin != null) {
|
|
419
396
|
return basicLatin;
|
|
420
397
|
}
|
|
421
|
-
|
|
422
|
-
try {
|
|
423
|
-
return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
|
|
424
|
-
}
|
|
425
|
-
catch (cause) {
|
|
426
|
-
throw new BSONError('Invalid UTF-8 string in BSON document', { cause });
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
|
|
398
|
+
return parseUtf8(uint8array, start, end, fatal);
|
|
430
399
|
},
|
|
431
400
|
utf8ByteLength(input) {
|
|
432
401
|
return new TextEncoder().encode(input).byteLength;
|
|
@@ -534,16 +503,16 @@ class Binary extends BSONValue {
|
|
|
534
503
|
return this.position;
|
|
535
504
|
}
|
|
536
505
|
toJSON() {
|
|
537
|
-
return ByteUtils.toBase64(this.buffer);
|
|
506
|
+
return ByteUtils.toBase64(this.buffer.subarray(0, this.position));
|
|
538
507
|
}
|
|
539
508
|
toString(encoding) {
|
|
540
509
|
if (encoding === 'hex')
|
|
541
|
-
return ByteUtils.toHex(this.buffer);
|
|
510
|
+
return ByteUtils.toHex(this.buffer.subarray(0, this.position));
|
|
542
511
|
if (encoding === 'base64')
|
|
543
|
-
return ByteUtils.toBase64(this.buffer);
|
|
512
|
+
return ByteUtils.toBase64(this.buffer.subarray(0, this.position));
|
|
544
513
|
if (encoding === 'utf8' || encoding === 'utf-8')
|
|
545
|
-
return ByteUtils.toUTF8(this.buffer, 0, this.
|
|
546
|
-
return ByteUtils.toUTF8(this.buffer, 0, this.
|
|
514
|
+
return ByteUtils.toUTF8(this.buffer, 0, this.position, false);
|
|
515
|
+
return ByteUtils.toUTF8(this.buffer, 0, this.position, false);
|
|
547
516
|
}
|
|
548
517
|
toExtendedJSON(options) {
|
|
549
518
|
options = options || {};
|
|
@@ -839,6 +808,32 @@ class DBRef extends BSONValue {
|
|
|
839
808
|
}
|
|
840
809
|
}
|
|
841
810
|
|
|
811
|
+
function removeLeadingZerosAndExplicitPlus(str) {
|
|
812
|
+
if (str === '') {
|
|
813
|
+
return str;
|
|
814
|
+
}
|
|
815
|
+
let startIndex = 0;
|
|
816
|
+
const isNegative = str[startIndex] === '-';
|
|
817
|
+
const isExplicitlyPositive = str[startIndex] === '+';
|
|
818
|
+
if (isExplicitlyPositive || isNegative) {
|
|
819
|
+
startIndex += 1;
|
|
820
|
+
}
|
|
821
|
+
let foundInsignificantZero = false;
|
|
822
|
+
for (; startIndex < str.length && str[startIndex] === '0'; ++startIndex) {
|
|
823
|
+
foundInsignificantZero = true;
|
|
824
|
+
}
|
|
825
|
+
if (!foundInsignificantZero) {
|
|
826
|
+
return isExplicitlyPositive ? str.slice(1) : str;
|
|
827
|
+
}
|
|
828
|
+
return `${isNegative ? '-' : ''}${str.length === startIndex ? '0' : str.slice(startIndex)}`;
|
|
829
|
+
}
|
|
830
|
+
function validateStringCharacters(str, radix) {
|
|
831
|
+
radix = radix ?? 10;
|
|
832
|
+
const validCharacters = '0123456789abcdefghijklmnopqrstuvwxyz'.slice(0, radix);
|
|
833
|
+
const regex = new RegExp(`[^-+${validCharacters}]`, 'i');
|
|
834
|
+
return regex.test(str) ? false : str;
|
|
835
|
+
}
|
|
836
|
+
|
|
842
837
|
let wasm = undefined;
|
|
843
838
|
try {
|
|
844
839
|
wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11])), {}).exports;
|
|
@@ -927,25 +922,16 @@ class Long extends BSONValue {
|
|
|
927
922
|
static fromBigInt(value, unsigned) {
|
|
928
923
|
return Long.fromString(value.toString(), unsigned);
|
|
929
924
|
}
|
|
930
|
-
static
|
|
925
|
+
static _fromString(str, unsigned, radix) {
|
|
931
926
|
if (str.length === 0)
|
|
932
927
|
throw new BSONError('empty string');
|
|
933
|
-
if (str === 'NaN' || str === 'Infinity' || str === '+Infinity' || str === '-Infinity')
|
|
934
|
-
return Long.ZERO;
|
|
935
|
-
if (typeof unsigned === 'number') {
|
|
936
|
-
(radix = unsigned), (unsigned = false);
|
|
937
|
-
}
|
|
938
|
-
else {
|
|
939
|
-
unsigned = !!unsigned;
|
|
940
|
-
}
|
|
941
|
-
radix = radix || 10;
|
|
942
928
|
if (radix < 2 || 36 < radix)
|
|
943
929
|
throw new BSONError('radix');
|
|
944
930
|
let p;
|
|
945
931
|
if ((p = str.indexOf('-')) > 0)
|
|
946
932
|
throw new BSONError('interior hyphen');
|
|
947
933
|
else if (p === 0) {
|
|
948
|
-
return Long.
|
|
934
|
+
return Long._fromString(str.substring(1), unsigned, radix).neg();
|
|
949
935
|
}
|
|
950
936
|
const radixToPower = Long.fromNumber(Math.pow(radix, 8));
|
|
951
937
|
let result = Long.ZERO;
|
|
@@ -963,6 +949,45 @@ class Long extends BSONValue {
|
|
|
963
949
|
result.unsigned = unsigned;
|
|
964
950
|
return result;
|
|
965
951
|
}
|
|
952
|
+
static fromStringStrict(str, unsignedOrRadix, radix) {
|
|
953
|
+
let unsigned = false;
|
|
954
|
+
if (typeof unsignedOrRadix === 'number') {
|
|
955
|
+
(radix = unsignedOrRadix), (unsignedOrRadix = false);
|
|
956
|
+
}
|
|
957
|
+
else {
|
|
958
|
+
unsigned = !!unsignedOrRadix;
|
|
959
|
+
}
|
|
960
|
+
radix ??= 10;
|
|
961
|
+
if (str.trim() !== str) {
|
|
962
|
+
throw new BSONError(`Input: '${str}' contains leading and/or trailing whitespace`);
|
|
963
|
+
}
|
|
964
|
+
if (!validateStringCharacters(str, radix)) {
|
|
965
|
+
throw new BSONError(`Input: '${str}' contains invalid characters for radix: ${radix}`);
|
|
966
|
+
}
|
|
967
|
+
const cleanedStr = removeLeadingZerosAndExplicitPlus(str);
|
|
968
|
+
const result = Long._fromString(cleanedStr, unsigned, radix);
|
|
969
|
+
if (result.toString(radix).toLowerCase() !== cleanedStr.toLowerCase()) {
|
|
970
|
+
throw new BSONError(`Input: ${str} is not representable as ${result.unsigned ? 'an unsigned' : 'a signed'} 64-bit Long ${radix != null ? `with radix: ${radix}` : ''}`);
|
|
971
|
+
}
|
|
972
|
+
return result;
|
|
973
|
+
}
|
|
974
|
+
static fromString(str, unsignedOrRadix, radix) {
|
|
975
|
+
let unsigned = false;
|
|
976
|
+
if (typeof unsignedOrRadix === 'number') {
|
|
977
|
+
(radix = unsignedOrRadix), (unsignedOrRadix = false);
|
|
978
|
+
}
|
|
979
|
+
else {
|
|
980
|
+
unsigned = !!unsignedOrRadix;
|
|
981
|
+
}
|
|
982
|
+
radix ??= 10;
|
|
983
|
+
if (str === 'NaN' && radix < 24) {
|
|
984
|
+
return Long.ZERO;
|
|
985
|
+
}
|
|
986
|
+
else if ((str === 'Infinity' || str === '+Infinity' || str === '-Infinity') && radix < 35) {
|
|
987
|
+
return Long.ZERO;
|
|
988
|
+
}
|
|
989
|
+
return Long._fromString(str, unsigned, radix);
|
|
990
|
+
}
|
|
966
991
|
static fromBytes(bytes, unsigned, le) {
|
|
967
992
|
return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned);
|
|
968
993
|
}
|
|
@@ -2040,6 +2065,28 @@ class Double extends BSONValue {
|
|
|
2040
2065
|
}
|
|
2041
2066
|
this.value = +value;
|
|
2042
2067
|
}
|
|
2068
|
+
static fromString(value) {
|
|
2069
|
+
const coercedValue = Number(value);
|
|
2070
|
+
if (value === 'NaN')
|
|
2071
|
+
return new Double(NaN);
|
|
2072
|
+
if (value === 'Infinity')
|
|
2073
|
+
return new Double(Infinity);
|
|
2074
|
+
if (value === '-Infinity')
|
|
2075
|
+
return new Double(-Infinity);
|
|
2076
|
+
if (!Number.isFinite(coercedValue)) {
|
|
2077
|
+
throw new BSONError(`Input: ${value} is not representable as a Double`);
|
|
2078
|
+
}
|
|
2079
|
+
if (value.trim() !== value) {
|
|
2080
|
+
throw new BSONError(`Input: '${value}' contains whitespace`);
|
|
2081
|
+
}
|
|
2082
|
+
if (value === '') {
|
|
2083
|
+
throw new BSONError(`Input is an empty string`);
|
|
2084
|
+
}
|
|
2085
|
+
if (/[^-0-9.+eE]/.test(value)) {
|
|
2086
|
+
throw new BSONError(`Input: '${value}' is not in decimal or exponential notation`);
|
|
2087
|
+
}
|
|
2088
|
+
return new Double(coercedValue);
|
|
2089
|
+
}
|
|
2043
2090
|
valueOf() {
|
|
2044
2091
|
return this.value;
|
|
2045
2092
|
}
|
|
@@ -2081,6 +2128,23 @@ class Int32 extends BSONValue {
|
|
|
2081
2128
|
}
|
|
2082
2129
|
this.value = +value | 0;
|
|
2083
2130
|
}
|
|
2131
|
+
static fromString(value) {
|
|
2132
|
+
const cleanedValue = removeLeadingZerosAndExplicitPlus(value);
|
|
2133
|
+
const coercedValue = Number(value);
|
|
2134
|
+
if (BSON_INT32_MAX < coercedValue) {
|
|
2135
|
+
throw new BSONError(`Input: '${value}' is larger than the maximum value for Int32`);
|
|
2136
|
+
}
|
|
2137
|
+
else if (BSON_INT32_MIN > coercedValue) {
|
|
2138
|
+
throw new BSONError(`Input: '${value}' is smaller than the minimum value for Int32`);
|
|
2139
|
+
}
|
|
2140
|
+
else if (!Number.isSafeInteger(coercedValue)) {
|
|
2141
|
+
throw new BSONError(`Input: '${value}' is not a safe integer`);
|
|
2142
|
+
}
|
|
2143
|
+
else if (coercedValue.toString() !== cleanedValue) {
|
|
2144
|
+
throw new BSONError(`Input: '${value}' is not a valid Int32 string`);
|
|
2145
|
+
}
|
|
2146
|
+
return new Int32(coercedValue);
|
|
2147
|
+
}
|
|
2084
2148
|
valueOf() {
|
|
2085
2149
|
return this.value;
|
|
2086
2150
|
}
|
|
@@ -2139,6 +2203,15 @@ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
|
|
|
2139
2203
|
FLOAT[0] = -1;
|
|
2140
2204
|
const isBigEndian = FLOAT_BYTES[7] === 0;
|
|
2141
2205
|
const NumberUtils = {
|
|
2206
|
+
getNonnegativeInt32LE(source, offset) {
|
|
2207
|
+
if (source[offset + 3] > 127) {
|
|
2208
|
+
throw new RangeError(`Size cannot be negative at offset: ${offset}`);
|
|
2209
|
+
}
|
|
2210
|
+
return (source[offset] |
|
|
2211
|
+
(source[offset + 1] << 8) |
|
|
2212
|
+
(source[offset + 2] << 16) |
|
|
2213
|
+
(source[offset + 3] << 24));
|
|
2214
|
+
},
|
|
2142
2215
|
getInt32LE(source, offset) {
|
|
2143
2216
|
return (source[offset] |
|
|
2144
2217
|
(source[offset + 1] << 8) |
|
|
@@ -3159,12 +3232,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
3159
3232
|
stringSize > buffer.length - index ||
|
|
3160
3233
|
buffer[index + stringSize - 1] !== 0)
|
|
3161
3234
|
throw new BSONError('bad string length in bson');
|
|
3162
|
-
|
|
3163
|
-
if (!validateUtf8(buffer, index, index + stringSize - 1)) {
|
|
3164
|
-
throw new BSONError('Invalid UTF-8 string in BSON document');
|
|
3165
|
-
}
|
|
3166
|
-
}
|
|
3167
|
-
const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
|
|
3235
|
+
const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
|
|
3168
3236
|
index = index + stringSize;
|
|
3169
3237
|
const oidBuffer = ByteUtils.allocateUnsafe(12);
|
|
3170
3238
|
for (let i = 0; i < 12; i++)
|
|
@@ -4128,13 +4196,12 @@ EJSON.deserialize = EJSONdeserialize;
|
|
|
4128
4196
|
Object.freeze(EJSON);
|
|
4129
4197
|
|
|
4130
4198
|
function getSize(source, offset) {
|
|
4131
|
-
|
|
4132
|
-
|
|
4199
|
+
try {
|
|
4200
|
+
return NumberUtils.getNonnegativeInt32LE(source, offset);
|
|
4201
|
+
}
|
|
4202
|
+
catch (cause) {
|
|
4203
|
+
throw new BSONOffsetError('BSON size cannot be negative', offset, { cause });
|
|
4133
4204
|
}
|
|
4134
|
-
return (source[offset] |
|
|
4135
|
-
(source[offset + 1] << 8) |
|
|
4136
|
-
(source[offset + 2] << 16) |
|
|
4137
|
-
(source[offset + 3] << 24));
|
|
4138
4205
|
}
|
|
4139
4206
|
function findNull(bytes, offset) {
|
|
4140
4207
|
let nullTerminatorOffset = offset;
|
|
@@ -4146,6 +4213,7 @@ function findNull(bytes, offset) {
|
|
|
4146
4213
|
return nullTerminatorOffset;
|
|
4147
4214
|
}
|
|
4148
4215
|
function parseToElements(bytes, startOffset = 0) {
|
|
4216
|
+
startOffset ??= 0;
|
|
4149
4217
|
if (bytes.length < 5) {
|
|
4150
4218
|
throw new BSONOffsetError(`Input must be at least 5 bytes, got ${bytes.length} bytes`, startOffset);
|
|
4151
4219
|
}
|
|
@@ -4171,7 +4239,10 @@ function parseToElements(bytes, startOffset = 0) {
|
|
|
4171
4239
|
const nameLength = findNull(bytes, offset) - nameOffset;
|
|
4172
4240
|
offset += nameLength + 1;
|
|
4173
4241
|
let length;
|
|
4174
|
-
if (type === 1 ||
|
|
4242
|
+
if (type === 1 ||
|
|
4243
|
+
type === 18 ||
|
|
4244
|
+
type === 9 ||
|
|
4245
|
+
type === 17) {
|
|
4175
4246
|
length = 8;
|
|
4176
4247
|
}
|
|
4177
4248
|
else if (type === 16) {
|
|
@@ -4186,13 +4257,18 @@ function parseToElements(bytes, startOffset = 0) {
|
|
|
4186
4257
|
else if (type === 8) {
|
|
4187
4258
|
length = 1;
|
|
4188
4259
|
}
|
|
4189
|
-
else if (type === 10 ||
|
|
4260
|
+
else if (type === 10 ||
|
|
4261
|
+
type === 6 ||
|
|
4262
|
+
type === 127 ||
|
|
4263
|
+
type === 255) {
|
|
4190
4264
|
length = 0;
|
|
4191
4265
|
}
|
|
4192
4266
|
else if (type === 11) {
|
|
4193
4267
|
length = findNull(bytes, findNull(bytes, offset) + 1) + 1 - offset;
|
|
4194
4268
|
}
|
|
4195
|
-
else if (type === 3 ||
|
|
4269
|
+
else if (type === 3 ||
|
|
4270
|
+
type === 4 ||
|
|
4271
|
+
type === 15) {
|
|
4196
4272
|
length = getSize(bytes, offset);
|
|
4197
4273
|
}
|
|
4198
4274
|
else if (type === 2 ||
|
|
@@ -4222,7 +4298,8 @@ function parseToElements(bytes, startOffset = 0) {
|
|
|
4222
4298
|
|
|
4223
4299
|
const onDemand = Object.create(null);
|
|
4224
4300
|
onDemand.parseToElements = parseToElements;
|
|
4225
|
-
onDemand.
|
|
4301
|
+
onDemand.ByteUtils = ByteUtils;
|
|
4302
|
+
onDemand.NumberUtils = NumberUtils;
|
|
4226
4303
|
Object.freeze(onDemand);
|
|
4227
4304
|
|
|
4228
4305
|
const MAXSIZE = 1024 * 1024 * 17;
|
|
@@ -4279,6 +4356,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
|
|
|
4279
4356
|
var bson = /*#__PURE__*/Object.freeze({
|
|
4280
4357
|
__proto__: null,
|
|
4281
4358
|
BSONError: BSONError,
|
|
4359
|
+
BSONOffsetError: BSONOffsetError,
|
|
4282
4360
|
BSONRegExp: BSONRegExp,
|
|
4283
4361
|
BSONRuntimeError: BSONRuntimeError,
|
|
4284
4362
|
BSONSymbol: BSONSymbol,
|
|
@@ -4309,6 +4387,7 @@ setInternalBufferSize: setInternalBufferSize
|
|
|
4309
4387
|
|
|
4310
4388
|
exports.BSON = bson;
|
|
4311
4389
|
exports.BSONError = BSONError;
|
|
4390
|
+
exports.BSONOffsetError = BSONOffsetError;
|
|
4312
4391
|
exports.BSONRegExp = BSONRegExp;
|
|
4313
4392
|
exports.BSONRuntimeError = BSONRuntimeError;
|
|
4314
4393
|
exports.BSONSymbol = BSONSymbol;
|