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