bson 6.4.0 → 6.5.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 +50 -0
- package/lib/bson.bundle.js +160 -23
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +160 -23
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +160 -24
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.rn.cjs +161 -23
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +1 -1
- package/src/binary.ts +2 -0
- package/src/bson.ts +1 -0
- package/src/constants.ts +3 -0
- package/src/error.ts +22 -0
- package/src/parser/on_demand/index.ts +28 -0
- package/src/parser/on_demand/parse_to_elements.ts +174 -0
- package/src/utils/number_utils.ts +53 -23
package/bson.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export declare class Binary extends BSONValue {
|
|
|
24
24
|
static readonly SUBTYPE_ENCRYPTED = 6;
|
|
25
25
|
/** Column BSON type */
|
|
26
26
|
static readonly SUBTYPE_COLUMN = 7;
|
|
27
|
+
/** Sensitive BSON type */
|
|
28
|
+
static readonly SUBTYPE_SENSITIVE = 8;
|
|
27
29
|
/** User BSON type */
|
|
28
30
|
static readonly SUBTYPE_USER_DEFINED = 128;
|
|
29
31
|
buffer: Uint8Array;
|
|
@@ -140,12 +142,25 @@ declare namespace BSON {
|
|
|
140
142
|
BSONRuntimeError,
|
|
141
143
|
BSONType,
|
|
142
144
|
EJSON,
|
|
145
|
+
onDemand,
|
|
143
146
|
Document,
|
|
144
147
|
CalculateObjectSizeOptions
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
export { BSON }
|
|
148
151
|
|
|
152
|
+
/**
|
|
153
|
+
* @public
|
|
154
|
+
* @experimental
|
|
155
|
+
*/
|
|
156
|
+
declare type BSONElement = [
|
|
157
|
+
type: number,
|
|
158
|
+
nameOffset: number,
|
|
159
|
+
nameLength: number,
|
|
160
|
+
offset: number,
|
|
161
|
+
length: number
|
|
162
|
+
];
|
|
163
|
+
|
|
149
164
|
/**
|
|
150
165
|
* @public
|
|
151
166
|
* @category Error
|
|
@@ -172,6 +187,21 @@ export declare class BSONError extends Error {
|
|
|
172
187
|
static isBSONError(value: unknown): value is BSONError;
|
|
173
188
|
}
|
|
174
189
|
|
|
190
|
+
/**
|
|
191
|
+
* @public
|
|
192
|
+
* @category Error
|
|
193
|
+
*
|
|
194
|
+
* @experimental
|
|
195
|
+
*
|
|
196
|
+
* An error generated when BSON bytes are invalid.
|
|
197
|
+
* Reports the offset the parser was able to reach before encountering the error.
|
|
198
|
+
*/
|
|
199
|
+
declare class BSONOffsetError extends BSONError {
|
|
200
|
+
get name(): 'BSONOffsetError';
|
|
201
|
+
offset: number;
|
|
202
|
+
constructor(message: string, offset: number);
|
|
203
|
+
}
|
|
204
|
+
|
|
175
205
|
/**
|
|
176
206
|
* A class representation of the BSON RegExp type.
|
|
177
207
|
* @public
|
|
@@ -1106,6 +1136,26 @@ export declare interface ObjectIdLike {
|
|
|
1106
1136
|
toHexString(): string;
|
|
1107
1137
|
}
|
|
1108
1138
|
|
|
1139
|
+
/**
|
|
1140
|
+
* @experimental
|
|
1141
|
+
* @public
|
|
1142
|
+
*
|
|
1143
|
+
* A new set of BSON APIs that are currently experimental and not intended for production use.
|
|
1144
|
+
*/
|
|
1145
|
+
declare type OnDemand = {
|
|
1146
|
+
BSONOffsetError: {
|
|
1147
|
+
new (message: string, offset: number): BSONOffsetError;
|
|
1148
|
+
isBSONError(value: unknown): value is BSONError;
|
|
1149
|
+
};
|
|
1150
|
+
parseToElements: (this: void, bytes: Uint8Array, startOffset?: number) => Iterable<BSONElement>;
|
|
1151
|
+
};
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* @experimental
|
|
1155
|
+
* @public
|
|
1156
|
+
*/
|
|
1157
|
+
export declare const onDemand: OnDemand;
|
|
1158
|
+
|
|
1109
1159
|
/**
|
|
1110
1160
|
* Parse an Extended JSON string, constructing the JavaScript value or object described by that
|
|
1111
1161
|
* string.
|
package/lib/bson.bundle.js
CHANGED
|
@@ -127,6 +127,15 @@ class BSONRuntimeError extends BSONError {
|
|
|
127
127
|
super(message);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
+
class BSONOffsetError extends BSONError {
|
|
131
|
+
get name() {
|
|
132
|
+
return 'BSONOffsetError';
|
|
133
|
+
}
|
|
134
|
+
constructor(message, offset) {
|
|
135
|
+
super(`${message}. offset: ${offset}`);
|
|
136
|
+
this.offset = offset;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
130
139
|
|
|
131
140
|
const FIRST_BIT = 0x80;
|
|
132
141
|
const FIRST_TWO_BITS = 0xc0;
|
|
@@ -608,6 +617,7 @@ Binary.SUBTYPE_UUID = 4;
|
|
|
608
617
|
Binary.SUBTYPE_MD5 = 5;
|
|
609
618
|
Binary.SUBTYPE_ENCRYPTED = 6;
|
|
610
619
|
Binary.SUBTYPE_COLUMN = 7;
|
|
620
|
+
Binary.SUBTYPE_SENSITIVE = 8;
|
|
611
621
|
Binary.SUBTYPE_USER_DEFINED = 128;
|
|
612
622
|
const UUID_BYTE_LENGTH = 16;
|
|
613
623
|
const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;
|
|
@@ -2126,6 +2136,8 @@ class MinKey extends BSONValue {
|
|
|
2126
2136
|
|
|
2127
2137
|
const FLOAT = new Float64Array(1);
|
|
2128
2138
|
const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
|
|
2139
|
+
FLOAT[0] = -1;
|
|
2140
|
+
const isBigEndian = FLOAT_BYTES[7] === 0;
|
|
2129
2141
|
const NumberUtils = {
|
|
2130
2142
|
getInt32LE(source, offset) {
|
|
2131
2143
|
return (source[offset] |
|
|
@@ -2150,17 +2162,29 @@ const NumberUtils = {
|
|
|
2150
2162
|
const hi = NumberUtils.getUint32LE(source, offset + 4);
|
|
2151
2163
|
return (BigInt(hi) << BigInt(32)) + BigInt(lo);
|
|
2152
2164
|
},
|
|
2153
|
-
getFloat64LE
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2165
|
+
getFloat64LE: isBigEndian
|
|
2166
|
+
? (source, offset) => {
|
|
2167
|
+
FLOAT_BYTES[7] = source[offset];
|
|
2168
|
+
FLOAT_BYTES[6] = source[offset + 1];
|
|
2169
|
+
FLOAT_BYTES[5] = source[offset + 2];
|
|
2170
|
+
FLOAT_BYTES[4] = source[offset + 3];
|
|
2171
|
+
FLOAT_BYTES[3] = source[offset + 4];
|
|
2172
|
+
FLOAT_BYTES[2] = source[offset + 5];
|
|
2173
|
+
FLOAT_BYTES[1] = source[offset + 6];
|
|
2174
|
+
FLOAT_BYTES[0] = source[offset + 7];
|
|
2175
|
+
return FLOAT[0];
|
|
2176
|
+
}
|
|
2177
|
+
: (source, offset) => {
|
|
2178
|
+
FLOAT_BYTES[0] = source[offset];
|
|
2179
|
+
FLOAT_BYTES[1] = source[offset + 1];
|
|
2180
|
+
FLOAT_BYTES[2] = source[offset + 2];
|
|
2181
|
+
FLOAT_BYTES[3] = source[offset + 3];
|
|
2182
|
+
FLOAT_BYTES[4] = source[offset + 4];
|
|
2183
|
+
FLOAT_BYTES[5] = source[offset + 5];
|
|
2184
|
+
FLOAT_BYTES[6] = source[offset + 6];
|
|
2185
|
+
FLOAT_BYTES[7] = source[offset + 7];
|
|
2186
|
+
return FLOAT[0];
|
|
2187
|
+
},
|
|
2164
2188
|
setInt32BE(destination, offset, value) {
|
|
2165
2189
|
destination[offset + 3] = value;
|
|
2166
2190
|
value >>>= 8;
|
|
@@ -2201,18 +2225,31 @@ const NumberUtils = {
|
|
|
2201
2225
|
destination[offset + 7] = hi;
|
|
2202
2226
|
return 8;
|
|
2203
2227
|
},
|
|
2204
|
-
setFloat64LE
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2228
|
+
setFloat64LE: isBigEndian
|
|
2229
|
+
? (destination, offset, value) => {
|
|
2230
|
+
FLOAT[0] = value;
|
|
2231
|
+
destination[offset] = FLOAT_BYTES[7];
|
|
2232
|
+
destination[offset + 1] = FLOAT_BYTES[6];
|
|
2233
|
+
destination[offset + 2] = FLOAT_BYTES[5];
|
|
2234
|
+
destination[offset + 3] = FLOAT_BYTES[4];
|
|
2235
|
+
destination[offset + 4] = FLOAT_BYTES[3];
|
|
2236
|
+
destination[offset + 5] = FLOAT_BYTES[2];
|
|
2237
|
+
destination[offset + 6] = FLOAT_BYTES[1];
|
|
2238
|
+
destination[offset + 7] = FLOAT_BYTES[0];
|
|
2239
|
+
return 8;
|
|
2240
|
+
}
|
|
2241
|
+
: (destination, offset, value) => {
|
|
2242
|
+
FLOAT[0] = value;
|
|
2243
|
+
destination[offset] = FLOAT_BYTES[0];
|
|
2244
|
+
destination[offset + 1] = FLOAT_BYTES[1];
|
|
2245
|
+
destination[offset + 2] = FLOAT_BYTES[2];
|
|
2246
|
+
destination[offset + 3] = FLOAT_BYTES[3];
|
|
2247
|
+
destination[offset + 4] = FLOAT_BYTES[4];
|
|
2248
|
+
destination[offset + 5] = FLOAT_BYTES[5];
|
|
2249
|
+
destination[offset + 6] = FLOAT_BYTES[6];
|
|
2250
|
+
destination[offset + 7] = FLOAT_BYTES[7];
|
|
2251
|
+
return 8;
|
|
2252
|
+
}
|
|
2216
2253
|
};
|
|
2217
2254
|
|
|
2218
2255
|
const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
|
|
@@ -4090,6 +4127,104 @@ EJSON.serialize = EJSONserialize;
|
|
|
4090
4127
|
EJSON.deserialize = EJSONdeserialize;
|
|
4091
4128
|
Object.freeze(EJSON);
|
|
4092
4129
|
|
|
4130
|
+
function getSize(source, offset) {
|
|
4131
|
+
if (source[offset + 3] > 127) {
|
|
4132
|
+
throw new BSONOffsetError('BSON size cannot be negative', offset);
|
|
4133
|
+
}
|
|
4134
|
+
return (source[offset] |
|
|
4135
|
+
(source[offset + 1] << 8) |
|
|
4136
|
+
(source[offset + 2] << 16) |
|
|
4137
|
+
(source[offset + 3] << 24));
|
|
4138
|
+
}
|
|
4139
|
+
function findNull(bytes, offset) {
|
|
4140
|
+
let nullTerminatorOffset = offset;
|
|
4141
|
+
for (; bytes[nullTerminatorOffset] !== 0x00; nullTerminatorOffset++)
|
|
4142
|
+
;
|
|
4143
|
+
if (nullTerminatorOffset === bytes.length - 1) {
|
|
4144
|
+
throw new BSONOffsetError('Null terminator not found', offset);
|
|
4145
|
+
}
|
|
4146
|
+
return nullTerminatorOffset;
|
|
4147
|
+
}
|
|
4148
|
+
function parseToElements(bytes, startOffset = 0) {
|
|
4149
|
+
if (bytes.length < 5) {
|
|
4150
|
+
throw new BSONOffsetError(`Input must be at least 5 bytes, got ${bytes.length} bytes`, startOffset);
|
|
4151
|
+
}
|
|
4152
|
+
const documentSize = getSize(bytes, startOffset);
|
|
4153
|
+
if (documentSize > bytes.length - startOffset) {
|
|
4154
|
+
throw new BSONOffsetError(`Parsed documentSize (${documentSize} bytes) does not match input length (${bytes.length} bytes)`, startOffset);
|
|
4155
|
+
}
|
|
4156
|
+
if (bytes[startOffset + documentSize - 1] !== 0x00) {
|
|
4157
|
+
throw new BSONOffsetError('BSON documents must end in 0x00', startOffset + documentSize);
|
|
4158
|
+
}
|
|
4159
|
+
const elements = [];
|
|
4160
|
+
let offset = startOffset + 4;
|
|
4161
|
+
while (offset <= documentSize + startOffset) {
|
|
4162
|
+
const type = bytes[offset];
|
|
4163
|
+
offset += 1;
|
|
4164
|
+
if (type === 0) {
|
|
4165
|
+
if (offset - startOffset !== documentSize) {
|
|
4166
|
+
throw new BSONOffsetError(`Invalid 0x00 type byte`, offset);
|
|
4167
|
+
}
|
|
4168
|
+
break;
|
|
4169
|
+
}
|
|
4170
|
+
const nameOffset = offset;
|
|
4171
|
+
const nameLength = findNull(bytes, offset) - nameOffset;
|
|
4172
|
+
offset += nameLength + 1;
|
|
4173
|
+
let length;
|
|
4174
|
+
if (type === 1 || type === 18 || type === 9 || type === 17) {
|
|
4175
|
+
length = 8;
|
|
4176
|
+
}
|
|
4177
|
+
else if (type === 16) {
|
|
4178
|
+
length = 4;
|
|
4179
|
+
}
|
|
4180
|
+
else if (type === 7) {
|
|
4181
|
+
length = 12;
|
|
4182
|
+
}
|
|
4183
|
+
else if (type === 19) {
|
|
4184
|
+
length = 16;
|
|
4185
|
+
}
|
|
4186
|
+
else if (type === 8) {
|
|
4187
|
+
length = 1;
|
|
4188
|
+
}
|
|
4189
|
+
else if (type === 10 || type === 6 || type === 127 || type === 255) {
|
|
4190
|
+
length = 0;
|
|
4191
|
+
}
|
|
4192
|
+
else if (type === 11) {
|
|
4193
|
+
length = findNull(bytes, findNull(bytes, offset) + 1) + 1 - offset;
|
|
4194
|
+
}
|
|
4195
|
+
else if (type === 3 || type === 4 || type === 15) {
|
|
4196
|
+
length = getSize(bytes, offset);
|
|
4197
|
+
}
|
|
4198
|
+
else if (type === 2 ||
|
|
4199
|
+
type === 5 ||
|
|
4200
|
+
type === 12 ||
|
|
4201
|
+
type === 13 ||
|
|
4202
|
+
type === 14) {
|
|
4203
|
+
length = getSize(bytes, offset) + 4;
|
|
4204
|
+
if (type === 5) {
|
|
4205
|
+
length += 1;
|
|
4206
|
+
}
|
|
4207
|
+
if (type === 12) {
|
|
4208
|
+
length += 12;
|
|
4209
|
+
}
|
|
4210
|
+
}
|
|
4211
|
+
else {
|
|
4212
|
+
throw new BSONOffsetError(`Invalid 0x${type.toString(16).padStart(2, '0')} type byte`, offset);
|
|
4213
|
+
}
|
|
4214
|
+
if (length > documentSize) {
|
|
4215
|
+
throw new BSONOffsetError('value reports length larger than document', offset);
|
|
4216
|
+
}
|
|
4217
|
+
elements.push([type, nameOffset, nameLength, offset, length]);
|
|
4218
|
+
offset += length;
|
|
4219
|
+
}
|
|
4220
|
+
return elements;
|
|
4221
|
+
}
|
|
4222
|
+
|
|
4223
|
+
const onDemand = Object.create(null);
|
|
4224
|
+
onDemand.parseToElements = parseToElements;
|
|
4225
|
+
onDemand.BSONOffsetError = BSONOffsetError;
|
|
4226
|
+
Object.freeze(onDemand);
|
|
4227
|
+
|
|
4093
4228
|
const MAXSIZE = 1024 * 1024 * 17;
|
|
4094
4229
|
let buffer = ByteUtils.allocate(MAXSIZE);
|
|
4095
4230
|
function setInternalBufferSize(size) {
|
|
@@ -4166,6 +4301,7 @@ UUID: UUID,
|
|
|
4166
4301
|
calculateObjectSize: calculateObjectSize,
|
|
4167
4302
|
deserialize: deserialize,
|
|
4168
4303
|
deserializeStream: deserializeStream,
|
|
4304
|
+
onDemand: onDemand,
|
|
4169
4305
|
serialize: serialize,
|
|
4170
4306
|
serializeWithBufferAndIndex: serializeWithBufferAndIndex,
|
|
4171
4307
|
setInternalBufferSize: setInternalBufferSize
|
|
@@ -4195,6 +4331,7 @@ exports.UUID = UUID;
|
|
|
4195
4331
|
exports.calculateObjectSize = calculateObjectSize;
|
|
4196
4332
|
exports.deserialize = deserialize;
|
|
4197
4333
|
exports.deserializeStream = deserializeStream;
|
|
4334
|
+
exports.onDemand = onDemand;
|
|
4198
4335
|
exports.serialize = serialize;
|
|
4199
4336
|
exports.serializeWithBufferAndIndex = serializeWithBufferAndIndex;
|
|
4200
4337
|
exports.setInternalBufferSize = setInternalBufferSize;
|