bson 6.4.0 → 6.6.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 +125 -0
- package/lib/bson.bundle.js +185 -28
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +185 -28
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +184 -29
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.rn.cjs +186 -28
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +1 -1
- package/src/binary.ts +7 -5
- package/src/bson.ts +2 -1
- package/src/constants.ts +3 -0
- package/src/error.ts +22 -0
- package/src/parser/on_demand/index.ts +32 -0
- package/src/parser/on_demand/parse_to_elements.ts +188 -0
- package/src/utils/byte_utils.ts +10 -4
- package/src/utils/number_utils.ts +90 -25
package/lib/bson.cjs
CHANGED
|
@@ -126,6 +126,15 @@ class BSONRuntimeError extends BSONError {
|
|
|
126
126
|
super(message);
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
+
class BSONOffsetError extends BSONError {
|
|
130
|
+
get name() {
|
|
131
|
+
return 'BSONOffsetError';
|
|
132
|
+
}
|
|
133
|
+
constructor(message, offset, options) {
|
|
134
|
+
super(`${message}. offset: ${offset}`, options);
|
|
135
|
+
this.offset = offset;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
129
138
|
|
|
130
139
|
const FIRST_BIT = 0x80;
|
|
131
140
|
const FIRST_TWO_BITS = 0xc0;
|
|
@@ -524,16 +533,16 @@ class Binary extends BSONValue {
|
|
|
524
533
|
return this.position;
|
|
525
534
|
}
|
|
526
535
|
toJSON() {
|
|
527
|
-
return ByteUtils.toBase64(this.buffer);
|
|
536
|
+
return ByteUtils.toBase64(this.buffer.subarray(0, this.position));
|
|
528
537
|
}
|
|
529
538
|
toString(encoding) {
|
|
530
539
|
if (encoding === 'hex')
|
|
531
|
-
return ByteUtils.toHex(this.buffer);
|
|
540
|
+
return ByteUtils.toHex(this.buffer.subarray(0, this.position));
|
|
532
541
|
if (encoding === 'base64')
|
|
533
|
-
return ByteUtils.toBase64(this.buffer);
|
|
542
|
+
return ByteUtils.toBase64(this.buffer.subarray(0, this.position));
|
|
534
543
|
if (encoding === 'utf8' || encoding === 'utf-8')
|
|
535
|
-
return ByteUtils.toUTF8(this.buffer, 0, this.
|
|
536
|
-
return ByteUtils.toUTF8(this.buffer, 0, this.
|
|
544
|
+
return ByteUtils.toUTF8(this.buffer, 0, this.position, false);
|
|
545
|
+
return ByteUtils.toUTF8(this.buffer, 0, this.position, false);
|
|
537
546
|
}
|
|
538
547
|
toExtendedJSON(options) {
|
|
539
548
|
options = options || {};
|
|
@@ -607,6 +616,7 @@ Binary.SUBTYPE_UUID = 4;
|
|
|
607
616
|
Binary.SUBTYPE_MD5 = 5;
|
|
608
617
|
Binary.SUBTYPE_ENCRYPTED = 6;
|
|
609
618
|
Binary.SUBTYPE_COLUMN = 7;
|
|
619
|
+
Binary.SUBTYPE_SENSITIVE = 8;
|
|
610
620
|
Binary.SUBTYPE_USER_DEFINED = 128;
|
|
611
621
|
const UUID_BYTE_LENGTH = 16;
|
|
612
622
|
const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;
|
|
@@ -2125,7 +2135,18 @@ class MinKey extends BSONValue {
|
|
|
2125
2135
|
|
|
2126
2136
|
const FLOAT = new Float64Array(1);
|
|
2127
2137
|
const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
|
|
2138
|
+
FLOAT[0] = -1;
|
|
2139
|
+
const isBigEndian = FLOAT_BYTES[7] === 0;
|
|
2128
2140
|
const NumberUtils = {
|
|
2141
|
+
getNonnegativeInt32LE(source, offset) {
|
|
2142
|
+
if (source[offset + 3] > 127) {
|
|
2143
|
+
throw new RangeError(`Size cannot be negative at offset: ${offset}`);
|
|
2144
|
+
}
|
|
2145
|
+
return (source[offset] |
|
|
2146
|
+
(source[offset + 1] << 8) |
|
|
2147
|
+
(source[offset + 2] << 16) |
|
|
2148
|
+
(source[offset + 3] << 24));
|
|
2149
|
+
},
|
|
2129
2150
|
getInt32LE(source, offset) {
|
|
2130
2151
|
return (source[offset] |
|
|
2131
2152
|
(source[offset + 1] << 8) |
|
|
@@ -2149,17 +2170,29 @@ const NumberUtils = {
|
|
|
2149
2170
|
const hi = NumberUtils.getUint32LE(source, offset + 4);
|
|
2150
2171
|
return (BigInt(hi) << BigInt(32)) + BigInt(lo);
|
|
2151
2172
|
},
|
|
2152
|
-
getFloat64LE
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2173
|
+
getFloat64LE: isBigEndian
|
|
2174
|
+
? (source, offset) => {
|
|
2175
|
+
FLOAT_BYTES[7] = source[offset];
|
|
2176
|
+
FLOAT_BYTES[6] = source[offset + 1];
|
|
2177
|
+
FLOAT_BYTES[5] = source[offset + 2];
|
|
2178
|
+
FLOAT_BYTES[4] = source[offset + 3];
|
|
2179
|
+
FLOAT_BYTES[3] = source[offset + 4];
|
|
2180
|
+
FLOAT_BYTES[2] = source[offset + 5];
|
|
2181
|
+
FLOAT_BYTES[1] = source[offset + 6];
|
|
2182
|
+
FLOAT_BYTES[0] = source[offset + 7];
|
|
2183
|
+
return FLOAT[0];
|
|
2184
|
+
}
|
|
2185
|
+
: (source, offset) => {
|
|
2186
|
+
FLOAT_BYTES[0] = source[offset];
|
|
2187
|
+
FLOAT_BYTES[1] = source[offset + 1];
|
|
2188
|
+
FLOAT_BYTES[2] = source[offset + 2];
|
|
2189
|
+
FLOAT_BYTES[3] = source[offset + 3];
|
|
2190
|
+
FLOAT_BYTES[4] = source[offset + 4];
|
|
2191
|
+
FLOAT_BYTES[5] = source[offset + 5];
|
|
2192
|
+
FLOAT_BYTES[6] = source[offset + 6];
|
|
2193
|
+
FLOAT_BYTES[7] = source[offset + 7];
|
|
2194
|
+
return FLOAT[0];
|
|
2195
|
+
},
|
|
2163
2196
|
setInt32BE(destination, offset, value) {
|
|
2164
2197
|
destination[offset + 3] = value;
|
|
2165
2198
|
value >>>= 8;
|
|
@@ -2200,18 +2233,31 @@ const NumberUtils = {
|
|
|
2200
2233
|
destination[offset + 7] = hi;
|
|
2201
2234
|
return 8;
|
|
2202
2235
|
},
|
|
2203
|
-
setFloat64LE
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2236
|
+
setFloat64LE: isBigEndian
|
|
2237
|
+
? (destination, offset, value) => {
|
|
2238
|
+
FLOAT[0] = value;
|
|
2239
|
+
destination[offset] = FLOAT_BYTES[7];
|
|
2240
|
+
destination[offset + 1] = FLOAT_BYTES[6];
|
|
2241
|
+
destination[offset + 2] = FLOAT_BYTES[5];
|
|
2242
|
+
destination[offset + 3] = FLOAT_BYTES[4];
|
|
2243
|
+
destination[offset + 4] = FLOAT_BYTES[3];
|
|
2244
|
+
destination[offset + 5] = FLOAT_BYTES[2];
|
|
2245
|
+
destination[offset + 6] = FLOAT_BYTES[1];
|
|
2246
|
+
destination[offset + 7] = FLOAT_BYTES[0];
|
|
2247
|
+
return 8;
|
|
2248
|
+
}
|
|
2249
|
+
: (destination, offset, value) => {
|
|
2250
|
+
FLOAT[0] = value;
|
|
2251
|
+
destination[offset] = FLOAT_BYTES[0];
|
|
2252
|
+
destination[offset + 1] = FLOAT_BYTES[1];
|
|
2253
|
+
destination[offset + 2] = FLOAT_BYTES[2];
|
|
2254
|
+
destination[offset + 3] = FLOAT_BYTES[3];
|
|
2255
|
+
destination[offset + 4] = FLOAT_BYTES[4];
|
|
2256
|
+
destination[offset + 5] = FLOAT_BYTES[5];
|
|
2257
|
+
destination[offset + 6] = FLOAT_BYTES[6];
|
|
2258
|
+
destination[offset + 7] = FLOAT_BYTES[7];
|
|
2259
|
+
return 8;
|
|
2260
|
+
}
|
|
2215
2261
|
};
|
|
2216
2262
|
|
|
2217
2263
|
const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
|
|
@@ -4089,6 +4135,113 @@ EJSON.serialize = EJSONserialize;
|
|
|
4089
4135
|
EJSON.deserialize = EJSONdeserialize;
|
|
4090
4136
|
Object.freeze(EJSON);
|
|
4091
4137
|
|
|
4138
|
+
function getSize(source, offset) {
|
|
4139
|
+
try {
|
|
4140
|
+
return NumberUtils.getNonnegativeInt32LE(source, offset);
|
|
4141
|
+
}
|
|
4142
|
+
catch (cause) {
|
|
4143
|
+
throw new BSONOffsetError('BSON size cannot be negative', offset, { cause });
|
|
4144
|
+
}
|
|
4145
|
+
}
|
|
4146
|
+
function findNull(bytes, offset) {
|
|
4147
|
+
let nullTerminatorOffset = offset;
|
|
4148
|
+
for (; bytes[nullTerminatorOffset] !== 0x00; nullTerminatorOffset++)
|
|
4149
|
+
;
|
|
4150
|
+
if (nullTerminatorOffset === bytes.length - 1) {
|
|
4151
|
+
throw new BSONOffsetError('Null terminator not found', offset);
|
|
4152
|
+
}
|
|
4153
|
+
return nullTerminatorOffset;
|
|
4154
|
+
}
|
|
4155
|
+
function parseToElements(bytes, startOffset = 0) {
|
|
4156
|
+
startOffset ??= 0;
|
|
4157
|
+
if (bytes.length < 5) {
|
|
4158
|
+
throw new BSONOffsetError(`Input must be at least 5 bytes, got ${bytes.length} bytes`, startOffset);
|
|
4159
|
+
}
|
|
4160
|
+
const documentSize = getSize(bytes, startOffset);
|
|
4161
|
+
if (documentSize > bytes.length - startOffset) {
|
|
4162
|
+
throw new BSONOffsetError(`Parsed documentSize (${documentSize} bytes) does not match input length (${bytes.length} bytes)`, startOffset);
|
|
4163
|
+
}
|
|
4164
|
+
if (bytes[startOffset + documentSize - 1] !== 0x00) {
|
|
4165
|
+
throw new BSONOffsetError('BSON documents must end in 0x00', startOffset + documentSize);
|
|
4166
|
+
}
|
|
4167
|
+
const elements = [];
|
|
4168
|
+
let offset = startOffset + 4;
|
|
4169
|
+
while (offset <= documentSize + startOffset) {
|
|
4170
|
+
const type = bytes[offset];
|
|
4171
|
+
offset += 1;
|
|
4172
|
+
if (type === 0) {
|
|
4173
|
+
if (offset - startOffset !== documentSize) {
|
|
4174
|
+
throw new BSONOffsetError(`Invalid 0x00 type byte`, offset);
|
|
4175
|
+
}
|
|
4176
|
+
break;
|
|
4177
|
+
}
|
|
4178
|
+
const nameOffset = offset;
|
|
4179
|
+
const nameLength = findNull(bytes, offset) - nameOffset;
|
|
4180
|
+
offset += nameLength + 1;
|
|
4181
|
+
let length;
|
|
4182
|
+
if (type === 1 ||
|
|
4183
|
+
type === 18 ||
|
|
4184
|
+
type === 9 ||
|
|
4185
|
+
type === 17) {
|
|
4186
|
+
length = 8;
|
|
4187
|
+
}
|
|
4188
|
+
else if (type === 16) {
|
|
4189
|
+
length = 4;
|
|
4190
|
+
}
|
|
4191
|
+
else if (type === 7) {
|
|
4192
|
+
length = 12;
|
|
4193
|
+
}
|
|
4194
|
+
else if (type === 19) {
|
|
4195
|
+
length = 16;
|
|
4196
|
+
}
|
|
4197
|
+
else if (type === 8) {
|
|
4198
|
+
length = 1;
|
|
4199
|
+
}
|
|
4200
|
+
else if (type === 10 ||
|
|
4201
|
+
type === 6 ||
|
|
4202
|
+
type === 127 ||
|
|
4203
|
+
type === 255) {
|
|
4204
|
+
length = 0;
|
|
4205
|
+
}
|
|
4206
|
+
else if (type === 11) {
|
|
4207
|
+
length = findNull(bytes, findNull(bytes, offset) + 1) + 1 - offset;
|
|
4208
|
+
}
|
|
4209
|
+
else if (type === 3 ||
|
|
4210
|
+
type === 4 ||
|
|
4211
|
+
type === 15) {
|
|
4212
|
+
length = getSize(bytes, offset);
|
|
4213
|
+
}
|
|
4214
|
+
else if (type === 2 ||
|
|
4215
|
+
type === 5 ||
|
|
4216
|
+
type === 12 ||
|
|
4217
|
+
type === 13 ||
|
|
4218
|
+
type === 14) {
|
|
4219
|
+
length = getSize(bytes, offset) + 4;
|
|
4220
|
+
if (type === 5) {
|
|
4221
|
+
length += 1;
|
|
4222
|
+
}
|
|
4223
|
+
if (type === 12) {
|
|
4224
|
+
length += 12;
|
|
4225
|
+
}
|
|
4226
|
+
}
|
|
4227
|
+
else {
|
|
4228
|
+
throw new BSONOffsetError(`Invalid 0x${type.toString(16).padStart(2, '0')} type byte`, offset);
|
|
4229
|
+
}
|
|
4230
|
+
if (length > documentSize) {
|
|
4231
|
+
throw new BSONOffsetError('value reports length larger than document', offset);
|
|
4232
|
+
}
|
|
4233
|
+
elements.push([type, nameOffset, nameLength, offset, length]);
|
|
4234
|
+
offset += length;
|
|
4235
|
+
}
|
|
4236
|
+
return elements;
|
|
4237
|
+
}
|
|
4238
|
+
|
|
4239
|
+
const onDemand = Object.create(null);
|
|
4240
|
+
onDemand.parseToElements = parseToElements;
|
|
4241
|
+
onDemand.ByteUtils = ByteUtils;
|
|
4242
|
+
onDemand.NumberUtils = NumberUtils;
|
|
4243
|
+
Object.freeze(onDemand);
|
|
4244
|
+
|
|
4092
4245
|
const MAXSIZE = 1024 * 1024 * 17;
|
|
4093
4246
|
let buffer = ByteUtils.allocate(MAXSIZE);
|
|
4094
4247
|
function setInternalBufferSize(size) {
|
|
@@ -4143,6 +4296,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
|
|
|
4143
4296
|
var bson = /*#__PURE__*/Object.freeze({
|
|
4144
4297
|
__proto__: null,
|
|
4145
4298
|
BSONError: BSONError,
|
|
4299
|
+
BSONOffsetError: BSONOffsetError,
|
|
4146
4300
|
BSONRegExp: BSONRegExp,
|
|
4147
4301
|
BSONRuntimeError: BSONRuntimeError,
|
|
4148
4302
|
BSONSymbol: BSONSymbol,
|
|
@@ -4165,6 +4319,7 @@ var bson = /*#__PURE__*/Object.freeze({
|
|
|
4165
4319
|
calculateObjectSize: calculateObjectSize,
|
|
4166
4320
|
deserialize: deserialize,
|
|
4167
4321
|
deserializeStream: deserializeStream,
|
|
4322
|
+
onDemand: onDemand,
|
|
4168
4323
|
serialize: serialize,
|
|
4169
4324
|
serializeWithBufferAndIndex: serializeWithBufferAndIndex,
|
|
4170
4325
|
setInternalBufferSize: setInternalBufferSize
|
|
@@ -4172,6 +4327,7 @@ var bson = /*#__PURE__*/Object.freeze({
|
|
|
4172
4327
|
|
|
4173
4328
|
exports.BSON = bson;
|
|
4174
4329
|
exports.BSONError = BSONError;
|
|
4330
|
+
exports.BSONOffsetError = BSONOffsetError;
|
|
4175
4331
|
exports.BSONRegExp = BSONRegExp;
|
|
4176
4332
|
exports.BSONRuntimeError = BSONRuntimeError;
|
|
4177
4333
|
exports.BSONSymbol = BSONSymbol;
|
|
@@ -4194,6 +4350,7 @@ exports.UUID = UUID;
|
|
|
4194
4350
|
exports.calculateObjectSize = calculateObjectSize;
|
|
4195
4351
|
exports.deserialize = deserialize;
|
|
4196
4352
|
exports.deserializeStream = deserializeStream;
|
|
4353
|
+
exports.onDemand = onDemand;
|
|
4197
4354
|
exports.serialize = serialize;
|
|
4198
4355
|
exports.serializeWithBufferAndIndex = serializeWithBufferAndIndex;
|
|
4199
4356
|
exports.setInternalBufferSize = setInternalBufferSize;
|