bson 6.1.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bson.d.ts +70 -18
- package/lib/bson.bundle.js +201 -139
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +201 -139
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +201 -139
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.rn.cjs +201 -139
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +19 -16
- package/src/binary.ts +12 -17
- package/src/bson_value.ts +15 -2
- package/src/code.ts +10 -10
- package/src/db_ref.ts +13 -11
- package/src/decimal128.ts +5 -8
- package/src/double.ts +4 -8
- package/src/error.ts +4 -6
- package/src/int_32.ts +4 -7
- package/src/long.ts +6 -7
- package/src/max_key.ts +0 -5
- package/src/min_key.ts +0 -5
- package/src/objectid.ts +46 -10
- package/src/parser/deserializer.ts +10 -31
- package/src/parser/utils.ts +27 -0
- package/src/regexp.ts +7 -7
- package/src/symbol.ts +4 -7
- package/src/timestamp.ts +6 -7
- package/src/utils/byte_utils.ts +2 -2
- package/src/utils/latin.ts +61 -0
- package/src/utils/node_byte_utils.ts +21 -2
- package/src/utils/web_byte_utils.ts +15 -2
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
|
-
|
|
55
|
-
|
|
56
|
-
return this.
|
|
51
|
+
inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
|
|
52
|
+
inspect ??= defaultInspect;
|
|
53
|
+
return `new BSONSymbol(${inspect(this.value, options)})`;
|
|
57
54
|
}
|
|
58
55
|
}
|
package/src/timestamp.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BSONError } from './error';
|
|
2
2
|
import type { Int32 } from './int_32';
|
|
3
3
|
import { Long } from './long';
|
|
4
|
+
import { type InspectFn, defaultInspect } from './parser/utils';
|
|
4
5
|
|
|
5
6
|
/** @public */
|
|
6
7
|
export type TimestampOverrides = '_bsontype' | 'toExtendedJSON' | 'fromExtendedJSON' | 'inspect';
|
|
@@ -141,12 +142,10 @@ export class Timestamp extends LongWithoutOverridesClass {
|
|
|
141
142
|
return new Timestamp({ t, i });
|
|
142
143
|
}
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
inspect(): string {
|
|
150
|
-
return `new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`;
|
|
145
|
+
inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
|
|
146
|
+
inspect ??= defaultInspect;
|
|
147
|
+
const t = inspect(this.high >>> 0, options);
|
|
148
|
+
const i = inspect(this.low >>> 0, options);
|
|
149
|
+
return `new Timestamp({ t: ${t}, i: ${i} })`;
|
|
151
150
|
}
|
|
152
151
|
}
|
package/src/utils/byte_utils.ts
CHANGED
|
@@ -25,8 +25,8 @@ export type ByteUtils = {
|
|
|
25
25
|
toHex: (buffer: Uint8Array) => string;
|
|
26
26
|
/** Create a Uint8Array containing utf8 code units from a string */
|
|
27
27
|
fromUTF8: (text: string) => Uint8Array;
|
|
28
|
-
/** Create a string from utf8 code units */
|
|
29
|
-
toUTF8: (buffer: Uint8Array, start: number, end: number) => string;
|
|
28
|
+
/** 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 */
|
|
29
|
+
toUTF8: (buffer: Uint8Array, start: number, end: number, fatal: boolean) => string;
|
|
30
30
|
/** Get the utf8 code unit count from a string if it were to be transformed to utf8 */
|
|
31
31
|
utf8ByteLength: (input: string) => number;
|
|
32
32
|
/** Encode UTF8 bytes generated from `source` string into `destination` at byteOffset. Returns the number of bytes encoded. */
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This function is an optimization for small basic latin strings.
|
|
3
|
+
* @internal
|
|
4
|
+
* @remarks
|
|
5
|
+
* ### Important characteristics:
|
|
6
|
+
* - If the uint8array or distance between start and end is 0 this function returns an empty string
|
|
7
|
+
* - If the byteLength of the string is 1, 2, or 3 we invoke String.fromCharCode and manually offset into the buffer
|
|
8
|
+
* - If the byteLength of the string is less than or equal to 20 an array of bytes is built and `String.fromCharCode.apply` is called with the result
|
|
9
|
+
* - If any byte exceeds 128 this function returns null
|
|
10
|
+
*
|
|
11
|
+
* @param uint8array - A sequence of bytes that may contain basic latin characters
|
|
12
|
+
* @param start - The start index from which to search the uint8array
|
|
13
|
+
* @param end - The index to stop searching the uint8array
|
|
14
|
+
* @returns string if all bytes are within the basic latin range, otherwise null
|
|
15
|
+
*/
|
|
16
|
+
export function tryLatin(uint8array: Uint8Array, start: number, end: number): string | null {
|
|
17
|
+
if (uint8array.length === 0) {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const stringByteLength = end - start;
|
|
22
|
+
if (stringByteLength === 0) {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (stringByteLength > 20) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (stringByteLength === 1 && uint8array[start] < 128) {
|
|
31
|
+
return String.fromCharCode(uint8array[start]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (stringByteLength === 2 && uint8array[start] < 128 && uint8array[start + 1] < 128) {
|
|
35
|
+
return String.fromCharCode(uint8array[start]) + String.fromCharCode(uint8array[start + 1]);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (
|
|
39
|
+
stringByteLength === 3 &&
|
|
40
|
+
uint8array[start] < 128 &&
|
|
41
|
+
uint8array[start + 1] < 128 &&
|
|
42
|
+
uint8array[start + 2] < 128
|
|
43
|
+
) {
|
|
44
|
+
return (
|
|
45
|
+
String.fromCharCode(uint8array[start]) +
|
|
46
|
+
String.fromCharCode(uint8array[start + 1]) +
|
|
47
|
+
String.fromCharCode(uint8array[start + 2])
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const latinBytes = [];
|
|
52
|
+
for (let i = start; i < end; i++) {
|
|
53
|
+
const byte = uint8array[i];
|
|
54
|
+
if (byte > 127) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
latinBytes.push(byte);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return String.fromCharCode(...latinBytes);
|
|
61
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { BSONError } from '../error';
|
|
2
|
+
import { validateUtf8 } from '../validate_utf8';
|
|
3
|
+
import { tryLatin } from './latin';
|
|
2
4
|
|
|
3
5
|
type NodeJsEncoding = 'base64' | 'hex' | 'utf8' | 'binary';
|
|
4
6
|
type NodeJsBuffer = ArrayBufferView &
|
|
@@ -125,8 +127,25 @@ export const nodeJsByteUtils = {
|
|
|
125
127
|
return Buffer.from(text, 'utf8');
|
|
126
128
|
},
|
|
127
129
|
|
|
128
|
-
toUTF8(buffer: Uint8Array, start: number, end: number): string {
|
|
129
|
-
|
|
130
|
+
toUTF8(buffer: Uint8Array, start: number, end: number, fatal: boolean): string {
|
|
131
|
+
const basicLatin = end - start <= 20 ? tryLatin(buffer, start, end) : null;
|
|
132
|
+
if (basicLatin != null) {
|
|
133
|
+
return basicLatin;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const string = nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8', start, end);
|
|
137
|
+
if (fatal) {
|
|
138
|
+
// TODO(NODE-4930): Insufficiently strict BSON UTF8 validation
|
|
139
|
+
for (let i = 0; i < string.length; i++) {
|
|
140
|
+
if (string.charCodeAt(i) === 0xfffd) {
|
|
141
|
+
if (!validateUtf8(buffer, start, end)) {
|
|
142
|
+
throw new BSONError('Invalid UTF-8 string in BSON document');
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return string;
|
|
130
149
|
},
|
|
131
150
|
|
|
132
151
|
utf8ByteLength(input: string): number {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BSONError } from '../error';
|
|
2
|
+
import { tryLatin } from './latin';
|
|
2
3
|
|
|
3
4
|
type TextDecoder = {
|
|
4
5
|
readonly encoding: string;
|
|
@@ -172,8 +173,20 @@ export const webByteUtils = {
|
|
|
172
173
|
return new TextEncoder().encode(text);
|
|
173
174
|
},
|
|
174
175
|
|
|
175
|
-
toUTF8(uint8array: Uint8Array, start: number, end: number): string {
|
|
176
|
-
|
|
176
|
+
toUTF8(uint8array: Uint8Array, start: number, end: number, fatal: boolean): string {
|
|
177
|
+
const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null;
|
|
178
|
+
if (basicLatin != null) {
|
|
179
|
+
return basicLatin;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (fatal) {
|
|
183
|
+
try {
|
|
184
|
+
return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
|
|
185
|
+
} catch (cause) {
|
|
186
|
+
throw new BSONError('Invalid UTF-8 string in BSON document', { cause });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
|
|
177
190
|
},
|
|
178
191
|
|
|
179
192
|
utf8ByteLength(input: string): number {
|