opusdev/vector-similarity-api
1
1import { randomBytes } from 'crypto';2 3const TypedArrayPrototypeGetSymbolToStringTag = (() => {4 const g = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), Symbol.toStringTag).get;5 return (value) => g.call(value);6})();7function isUint8Array(value) {8 return TypedArrayPrototypeGetSymbolToStringTag(value) === 'Uint8Array';9}10function isAnyArrayBuffer(value) {11 return (typeof value === 'object' &&12 value != null &&13 Symbol.toStringTag in value &&14 (value[Symbol.toStringTag] === 'ArrayBuffer' ||15 value[Symbol.toStringTag] === 'SharedArrayBuffer'));16}17function isRegExp(regexp) {18 return regexp instanceof RegExp || Object.prototype.toString.call(regexp) === '[object RegExp]';19}20function isMap(value) {21 return (typeof value === 'object' &&22 value != null &&23 Symbol.toStringTag in value &&24 value[Symbol.toStringTag] === 'Map');25}26function isDate(date) {27 return date instanceof Date || Object.prototype.toString.call(date) === '[object Date]';28}29function defaultInspect(x, _options) {30 return JSON.stringify(x, (k, v) => {31 if (typeof v === 'bigint') {32 return { $numberLong: `${v}` };33 }34 else if (isMap(v)) {35 return Object.fromEntries(v);36 }37 return v;38 });39}40function getStylizeFunction(options) {41 const stylizeExists = options != null &&42 typeof options === 'object' &&43 'stylize' in options &&44 typeof options.stylize === 'function';45 if (stylizeExists) {46 return options.stylize;47 }48}49 50const BSON_MAJOR_VERSION = 6;51const BSON_VERSION_SYMBOL = Symbol.for('@@mdb.bson.version');52const BSON_INT32_MAX = 0x7fffffff;53const BSON_INT32_MIN = -2147483648;54const BSON_INT64_MAX = Math.pow(2, 63) - 1;55const BSON_INT64_MIN = -Math.pow(2, 63);56const JS_INT_MAX = Math.pow(2, 53);57const JS_INT_MIN = -Math.pow(2, 53);58const BSON_DATA_NUMBER = 1;59const BSON_DATA_STRING = 2;60const BSON_DATA_OBJECT = 3;61const BSON_DATA_ARRAY = 4;62const BSON_DATA_BINARY = 5;63const BSON_DATA_UNDEFINED = 6;64const BSON_DATA_OID = 7;65const BSON_DATA_BOOLEAN = 8;66const BSON_DATA_DATE = 9;67const BSON_DATA_NULL = 10;68const BSON_DATA_REGEXP = 11;69const BSON_DATA_DBPOINTER = 12;70const BSON_DATA_CODE = 13;71const BSON_DATA_SYMBOL = 14;72const BSON_DATA_CODE_W_SCOPE = 15;73const BSON_DATA_INT = 16;74const BSON_DATA_TIMESTAMP = 17;75const BSON_DATA_LONG = 18;76const BSON_DATA_DECIMAL128 = 19;77const BSON_DATA_MIN_KEY = 0xff;78const BSON_DATA_MAX_KEY = 0x7f;79const BSON_BINARY_SUBTYPE_DEFAULT = 0;80const BSON_BINARY_SUBTYPE_UUID_NEW = 4;81const BSONType = Object.freeze({82 double: 1,83 string: 2,84 object: 3,85 array: 4,86 binData: 5,87 undefined: 6,88 objectId: 7,89 bool: 8,90 date: 9,91 null: 10,92 regex: 11,93 dbPointer: 12,94 javascript: 13,95 symbol: 14,96 javascriptWithScope: 15,97 int: 16,98 timestamp: 17,99 long: 18,100 decimal: 19,101 minKey: -1,102 maxKey: 127103});104 105class BSONError extends Error {106 get bsonError() {107 return true;108 }109 get name() {110 return 'BSONError';111 }112 constructor(message, options) {113 super(message, options);114 }115 static isBSONError(value) {116 return (value != null &&117 typeof value === 'object' &&118 'bsonError' in value &&119 value.bsonError === true &&120 'name' in value &&121 'message' in value &&122 'stack' in value);123 }124}125class BSONVersionError extends BSONError {126 get name() {127 return 'BSONVersionError';128 }129 constructor() {130 super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.x.x`);131 }132}133class BSONRuntimeError extends BSONError {134 get name() {135 return 'BSONRuntimeError';136 }137 constructor(message) {138 super(message);139 }140}141class BSONOffsetError extends BSONError {142 get name() {143 return 'BSONOffsetError';144 }145 constructor(message, offset, options) {146 super(`${message}. offset: ${offset}`, options);147 this.offset = offset;148 }149}150 151let TextDecoderFatal;152let TextDecoderNonFatal;153function parseUtf8(buffer, start, end, fatal) {154 if (fatal) {155 TextDecoderFatal ??= new TextDecoder('utf8', { fatal: true });156 try {157 return TextDecoderFatal.decode(buffer.subarray(start, end));158 }159 catch (cause) {160 throw new BSONError('Invalid UTF-8 string in BSON document', { cause });161 }162 }163 TextDecoderNonFatal ??= new TextDecoder('utf8', { fatal: false });164 return TextDecoderNonFatal.decode(buffer.subarray(start, end));165}166 167function tryReadBasicLatin(uint8array, start, end) {168 if (uint8array.length === 0) {169 return '';170 }171 const stringByteLength = end - start;172 if (stringByteLength === 0) {173 return '';174 }175 if (stringByteLength > 20) {176 return null;177 }178 if (stringByteLength === 1 && uint8array[start] < 128) {179 return String.fromCharCode(uint8array[start]);180 }181 if (stringByteLength === 2 && uint8array[start] < 128 && uint8array[start + 1] < 128) {182 return String.fromCharCode(uint8array[start]) + String.fromCharCode(uint8array[start + 1]);183 }184 if (stringByteLength === 3 &&185 uint8array[start] < 128 &&186 uint8array[start + 1] < 128 &&187 uint8array[start + 2] < 128) {188 return (String.fromCharCode(uint8array[start]) +189 String.fromCharCode(uint8array[start + 1]) +190 String.fromCharCode(uint8array[start + 2]));191 }192 const latinBytes = [];193 for (let i = start; i < end; i++) {194 const byte = uint8array[i];195 if (byte > 127) {196 return null;197 }198 latinBytes.push(byte);199 }200 return String.fromCharCode(...latinBytes);201}202function tryWriteBasicLatin(destination, source, offset) {203 if (source.length === 0)204 return 0;205 if (source.length > 25)206 return null;207 if (destination.length - offset < source.length)208 return null;209 for (let charOffset = 0, destinationOffset = offset; charOffset < source.length; charOffset++, destinationOffset++) {210 const char = source.charCodeAt(charOffset);211 if (char > 127)212 return null;213 destination[destinationOffset] = char;214 }215 return source.length;216}217 218const nodeJsByteUtils = {219 toLocalBufferType(potentialBuffer) {220 if (Buffer.isBuffer(potentialBuffer)) {221 return potentialBuffer;222 }223 if (ArrayBuffer.isView(potentialBuffer)) {224 return Buffer.from(potentialBuffer.buffer, potentialBuffer.byteOffset, potentialBuffer.byteLength);225 }226 const stringTag = potentialBuffer?.[Symbol.toStringTag] ?? Object.prototype.toString.call(potentialBuffer);227 if (stringTag === 'ArrayBuffer' ||228 stringTag === 'SharedArrayBuffer' ||229 stringTag === '[object ArrayBuffer]' ||230 stringTag === '[object SharedArrayBuffer]') {231 return Buffer.from(potentialBuffer);232 }233 throw new BSONError(`Cannot create Buffer from the passed potentialBuffer.`);234 },235 allocate(size) {236 return Buffer.alloc(size);237 },238 allocateUnsafe(size) {239 return Buffer.allocUnsafe(size);240 },241 equals(a, b) {242 return nodeJsByteUtils.toLocalBufferType(a).equals(b);243 },244 fromNumberArray(array) {245 return Buffer.from(array);246 },247 fromBase64(base64) {248 return Buffer.from(base64, 'base64');249 },250 toBase64(buffer) {251 return nodeJsByteUtils.toLocalBufferType(buffer).toString('base64');252 },253 fromISO88591(codePoints) {254 return Buffer.from(codePoints, 'binary');255 },256 toISO88591(buffer) {257 return nodeJsByteUtils.toLocalBufferType(buffer).toString('binary');258 },259 fromHex(hex) {260 return Buffer.from(hex, 'hex');261 },262 toHex(buffer) {263 return nodeJsByteUtils.toLocalBufferType(buffer).toString('hex');264 },265 toUTF8(buffer, start, end, fatal) {266 const basicLatin = end - start <= 20 ? tryReadBasicLatin(buffer, start, end) : null;267 if (basicLatin != null) {268 return basicLatin;269 }270 const string = nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8', start, end);271 if (fatal) {272 for (let i = 0; i < string.length; i++) {273 if (string.charCodeAt(i) === 0xfffd) {274 parseUtf8(buffer, start, end, true);275 break;276 }277 }278 }279 return string;280 },281 utf8ByteLength(input) {282 return Buffer.byteLength(input, 'utf8');283 },284 encodeUTF8Into(buffer, source, byteOffset) {285 const latinBytesWritten = tryWriteBasicLatin(buffer, source, byteOffset);286 if (latinBytesWritten != null) {287 return latinBytesWritten;288 }289 return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');290 },291 randomBytes: randomBytes,292 swap32(buffer) {293 return nodeJsByteUtils.toLocalBufferType(buffer).swap32();294 }295};296 297function isReactNative() {298 const { navigator } = globalThis;299 return typeof navigator === 'object' && navigator.product === 'ReactNative';300}301function webMathRandomBytes(byteLength) {302 if (byteLength < 0) {303 throw new RangeError(`The argument 'byteLength' is invalid. Received ${byteLength}`);304 }305 return webByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256)));306}307const webRandomBytes = (() => {308 const { crypto } = globalThis;309 if (crypto != null && typeof crypto.getRandomValues === 'function') {310 return (byteLength) => {311 return crypto.getRandomValues(webByteUtils.allocate(byteLength));312 };313 }314 else {315 if (isReactNative()) {316 const { console } = globalThis;317 console?.warn?.('BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.');318 }319 return webMathRandomBytes;320 }321})();322const HEX_DIGIT = /(\d|[a-f])/i;323const webByteUtils = {324 toLocalBufferType(potentialUint8array) {325 const stringTag = potentialUint8array?.[Symbol.toStringTag] ??326 Object.prototype.toString.call(potentialUint8array);327 if (stringTag === 'Uint8Array') {328 return potentialUint8array;329 }330 if (ArrayBuffer.isView(potentialUint8array)) {331 return new Uint8Array(potentialUint8array.buffer.slice(potentialUint8array.byteOffset, potentialUint8array.byteOffset + potentialUint8array.byteLength));332 }333 if (stringTag === 'ArrayBuffer' ||334 stringTag === 'SharedArrayBuffer' ||335 stringTag === '[object ArrayBuffer]' ||336 stringTag === '[object SharedArrayBuffer]') {337 return new Uint8Array(potentialUint8array);338 }339 throw new BSONError(`Cannot make a Uint8Array from passed potentialBuffer.`);340 },341 allocate(size) {342 if (typeof size !== 'number') {343 throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`);344 }345 return new Uint8Array(size);346 },347 allocateUnsafe(size) {348 return webByteUtils.allocate(size);349 },350 equals(a, b) {351 if (a.byteLength !== b.byteLength) {352 return false;353 }354 for (let i = 0; i < a.byteLength; i++) {355 if (a[i] !== b[i]) {356 return false;357 }358 }359 return true;360 },361 fromNumberArray(array) {362 return Uint8Array.from(array);363 },364 fromBase64(base64) {365 return Uint8Array.from(atob(base64), c => c.charCodeAt(0));366 },367 toBase64(uint8array) {368 return btoa(webByteUtils.toISO88591(uint8array));369 },370 fromISO88591(codePoints) {371 return Uint8Array.from(codePoints, c => c.charCodeAt(0) & 0xff);372 },373 toISO88591(uint8array) {374 return Array.from(Uint16Array.from(uint8array), b => String.fromCharCode(b)).join('');375 },376 fromHex(hex) {377 const evenLengthHex = hex.length % 2 === 0 ? hex : hex.slice(0, hex.length - 1);378 const buffer = [];379 for (let i = 0; i < evenLengthHex.length; i += 2) {380 const firstDigit = evenLengthHex[i];381 const secondDigit = evenLengthHex[i + 1];382 if (!HEX_DIGIT.test(firstDigit)) {383 break;384 }385 if (!HEX_DIGIT.test(secondDigit)) {386 break;387 }388 const hexDigit = Number.parseInt(`${firstDigit}${secondDigit}`, 16);389 buffer.push(hexDigit);390 }391 return Uint8Array.from(buffer);392 },393 toHex(uint8array) {394 return Array.from(uint8array, byte => byte.toString(16).padStart(2, '0')).join('');395 },396 toUTF8(uint8array, start, end, fatal) {397 const basicLatin = end - start <= 20 ? tryReadBasicLatin(uint8array, start, end) : null;398 if (basicLatin != null) {399 return basicLatin;400 }401 return parseUtf8(uint8array, start, end, fatal);402 },403 utf8ByteLength(input) {404 return new TextEncoder().encode(input).byteLength;405 },406 encodeUTF8Into(uint8array, source, byteOffset) {407 const bytes = new TextEncoder().encode(source);408 uint8array.set(bytes, byteOffset);409 return bytes.byteLength;410 },411 randomBytes: webRandomBytes,412 swap32(buffer) {413 if (buffer.length % 4 !== 0) {414 throw new RangeError('Buffer size must be a multiple of 32-bits');415 }416 for (let i = 0; i < buffer.length; i += 4) {417 const byte0 = buffer[i];418 const byte1 = buffer[i + 1];419 const byte2 = buffer[i + 2];420 const byte3 = buffer[i + 3];421 buffer[i] = byte3;422 buffer[i + 1] = byte2;423 buffer[i + 2] = byte1;424 buffer[i + 3] = byte0;425 }426 return buffer;427 }428};429 430const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;431const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;432 433class BSONValue {434 get [BSON_VERSION_SYMBOL]() {435 return BSON_MAJOR_VERSION;436 }437 [Symbol.for('nodejs.util.inspect.custom')](depth, options, inspect) {438 return this.inspect(depth, options, inspect);439 }440}441 442const FLOAT = new Float64Array(1);443const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);444FLOAT[0] = -1;445const isBigEndian = FLOAT_BYTES[7] === 0;446const NumberUtils = {447 isBigEndian,448 getNonnegativeInt32LE(source, offset) {449 if (source[offset + 3] > 127) {450 throw new RangeError(`Size cannot be negative at offset: ${offset}`);451 }452 return (source[offset] |453 (source[offset + 1] << 8) |454 (source[offset + 2] << 16) |455 (source[offset + 3] << 24));456 },457 getInt32LE(source, offset) {458 return (source[offset] |459 (source[offset + 1] << 8) |460 (source[offset + 2] << 16) |461 (source[offset + 3] << 24));462 },463 getUint32LE(source, offset) {464 return (source[offset] +465 source[offset + 1] * 256 +466 source[offset + 2] * 65536 +467 source[offset + 3] * 16777216);468 },469 getUint32BE(source, offset) {470 return (source[offset + 3] +471 source[offset + 2] * 256 +472 source[offset + 1] * 65536 +473 source[offset] * 16777216);474 },475 getBigInt64LE(source, offset) {476 const hi = BigInt(source[offset + 4] +477 source[offset + 5] * 256 +478 source[offset + 6] * 65536 +479 (source[offset + 7] << 24));480 const lo = BigInt(source[offset] +481 source[offset + 1] * 256 +482 source[offset + 2] * 65536 +483 source[offset + 3] * 16777216);484 return (hi << BigInt(32)) + lo;485 },486 getFloat64LE: isBigEndian487 ? (source, offset) => {488 FLOAT_BYTES[7] = source[offset];489 FLOAT_BYTES[6] = source[offset + 1];490 FLOAT_BYTES[5] = source[offset + 2];491 FLOAT_BYTES[4] = source[offset + 3];492 FLOAT_BYTES[3] = source[offset + 4];493 FLOAT_BYTES[2] = source[offset + 5];494 FLOAT_BYTES[1] = source[offset + 6];495 FLOAT_BYTES[0] = source[offset + 7];496 return FLOAT[0];497 }498 : (source, offset) => {499 FLOAT_BYTES[0] = source[offset];500 FLOAT_BYTES[1] = source[offset + 1];501 FLOAT_BYTES[2] = source[offset + 2];502 FLOAT_BYTES[3] = source[offset + 3];503 FLOAT_BYTES[4] = source[offset + 4];504 FLOAT_BYTES[5] = source[offset + 5];505 FLOAT_BYTES[6] = source[offset + 6];506 FLOAT_BYTES[7] = source[offset + 7];507 return FLOAT[0];508 },509 setInt32BE(destination, offset, value) {510 destination[offset + 3] = value;511 value >>>= 8;512 destination[offset + 2] = value;513 value >>>= 8;514 destination[offset + 1] = value;515 value >>>= 8;516 destination[offset] = value;517 return 4;518 },519 setInt32LE(destination, offset, value) {520 destination[offset] = value;521 value >>>= 8;522 destination[offset + 1] = value;523 value >>>= 8;524 destination[offset + 2] = value;525 value >>>= 8;526 destination[offset + 3] = value;527 return 4;528 },529 setBigInt64LE(destination, offset, value) {530 const mask32bits = BigInt(0xffff_ffff);531 let lo = Number(value & mask32bits);532 destination[offset] = lo;533 lo >>= 8;534 destination[offset + 1] = lo;535 lo >>= 8;536 destination[offset + 2] = lo;537 lo >>= 8;538 destination[offset + 3] = lo;539 let hi = Number((value >> BigInt(32)) & mask32bits);540 destination[offset + 4] = hi;541 hi >>= 8;542 destination[offset + 5] = hi;543 hi >>= 8;544 destination[offset + 6] = hi;545 hi >>= 8;546 destination[offset + 7] = hi;547 return 8;548 },549 setFloat64LE: isBigEndian550 ? (destination, offset, value) => {551 FLOAT[0] = value;552 destination[offset] = FLOAT_BYTES[7];553 destination[offset + 1] = FLOAT_BYTES[6];554 destination[offset + 2] = FLOAT_BYTES[5];555 destination[offset + 3] = FLOAT_BYTES[4];556 destination[offset + 4] = FLOAT_BYTES[3];557 destination[offset + 5] = FLOAT_BYTES[2];558 destination[offset + 6] = FLOAT_BYTES[1];559 destination[offset + 7] = FLOAT_BYTES[0];560 return 8;561 }562 : (destination, offset, value) => {563 FLOAT[0] = value;564 destination[offset] = FLOAT_BYTES[0];565 destination[offset + 1] = FLOAT_BYTES[1];566 destination[offset + 2] = FLOAT_BYTES[2];567 destination[offset + 3] = FLOAT_BYTES[3];568 destination[offset + 4] = FLOAT_BYTES[4];569 destination[offset + 5] = FLOAT_BYTES[5];570 destination[offset + 6] = FLOAT_BYTES[6];571 destination[offset + 7] = FLOAT_BYTES[7];572 return 8;573 }574};575 576class Binary extends BSONValue {577 get _bsontype() {578 return 'Binary';579 }580 constructor(buffer, subType) {581 super();582 if (!(buffer == null) &&583 typeof buffer === 'string' &&584 !ArrayBuffer.isView(buffer) &&585 !isAnyArrayBuffer(buffer) &&586 !Array.isArray(buffer)) {587 throw new BSONError('Binary can only be constructed from Uint8Array or number[]');588 }589 this.sub_type = subType ?? Binary.BSON_BINARY_SUBTYPE_DEFAULT;590 if (buffer == null) {591 this.buffer = ByteUtils.allocate(Binary.BUFFER_SIZE);592 this.position = 0;593 }594 else {595 this.buffer = Array.isArray(buffer)596 ? ByteUtils.fromNumberArray(buffer)597 : ByteUtils.toLocalBufferType(buffer);598 this.position = this.buffer.byteLength;599 }600 }601 put(byteValue) {602 if (typeof byteValue === 'string' && byteValue.length !== 1) {603 throw new BSONError('only accepts single character String');604 }605 else if (typeof byteValue !== 'number' && byteValue.length !== 1)606 throw new BSONError('only accepts single character Uint8Array or Array');607 let decodedByte;608 if (typeof byteValue === 'string') {609 decodedByte = byteValue.charCodeAt(0);610 }611 else if (typeof byteValue === 'number') {612 decodedByte = byteValue;613 }614 else {615 decodedByte = byteValue[0];616 }617 if (decodedByte < 0 || decodedByte > 255) {618 throw new BSONError('only accepts number in a valid unsigned byte range 0-255');619 }620 if (this.buffer.byteLength > this.position) {621 this.buffer[this.position++] = decodedByte;622 }623 else {624 const newSpace = ByteUtils.allocate(Binary.BUFFER_SIZE + this.buffer.length);625 newSpace.set(this.buffer, 0);626 this.buffer = newSpace;627 this.buffer[this.position++] = decodedByte;628 }629 }630 write(sequence, offset) {631 offset = typeof offset === 'number' ? offset : this.position;632 if (this.buffer.byteLength < offset + sequence.length) {633 const newSpace = ByteUtils.allocate(this.buffer.byteLength + sequence.length);634 newSpace.set(this.buffer, 0);635 this.buffer = newSpace;636 }637 if (ArrayBuffer.isView(sequence)) {638 this.buffer.set(ByteUtils.toLocalBufferType(sequence), offset);639 this.position =640 offset + sequence.byteLength > this.position ? offset + sequence.length : this.position;641 }642 else if (typeof sequence === 'string') {643 throw new BSONError('input cannot be string');644 }645 }646 read(position, length) {647 length = length && length > 0 ? length : this.position;648 const end = position + length;649 return this.buffer.subarray(position, end > this.position ? this.position : end);650 }651 value() {652 return this.buffer.length === this.position653 ? this.buffer654 : this.buffer.subarray(0, this.position);655 }656 length() {657 return this.position;658 }659 toJSON() {660 return ByteUtils.toBase64(this.buffer.subarray(0, this.position));661 }662 toString(encoding) {663 if (encoding === 'hex')664 return ByteUtils.toHex(this.buffer.subarray(0, this.position));665 if (encoding === 'base64')666 return ByteUtils.toBase64(this.buffer.subarray(0, this.position));667 if (encoding === 'utf8' || encoding === 'utf-8')668 return ByteUtils.toUTF8(this.buffer, 0, this.position, false);669 return ByteUtils.toUTF8(this.buffer, 0, this.position, false);670 }671 toExtendedJSON(options) {672 options = options || {};673 if (this.sub_type === Binary.SUBTYPE_VECTOR) {674 validateBinaryVector(this);675 }676 const base64String = ByteUtils.toBase64(this.buffer);677 const subType = Number(this.sub_type).toString(16);678 if (options.legacy) {679 return {680 $binary: base64String,681 $type: subType.length === 1 ? '0' + subType : subType682 };683 }684 return {685 $binary: {686 base64: base64String,687 subType: subType.length === 1 ? '0' + subType : subType688 }689 };690 }691 toUUID() {692 if (this.sub_type === Binary.SUBTYPE_UUID) {693 return new UUID(this.buffer.subarray(0, this.position));694 }695 throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${Binary.SUBTYPE_UUID}" is currently supported.`);696 }697 static createFromHexString(hex, subType) {698 return new Binary(ByteUtils.fromHex(hex), subType);699 }700 static createFromBase64(base64, subType) {701 return new Binary(ByteUtils.fromBase64(base64), subType);702 }703 static fromExtendedJSON(doc, options) {704 options = options || {};705 let data;706 let type;707 if ('$binary' in doc) {708 if (options.legacy && typeof doc.$binary === 'string' && '$type' in doc) {709 type = doc.$type ? parseInt(doc.$type, 16) : 0;710 data = ByteUtils.fromBase64(doc.$binary);711 }712 else {713 if (typeof doc.$binary !== 'string') {714 type = doc.$binary.subType ? parseInt(doc.$binary.subType, 16) : 0;715 data = ByteUtils.fromBase64(doc.$binary.base64);716 }717 }718 }719 else if ('$uuid' in doc) {720 type = 4;721 data = UUID.bytesFromString(doc.$uuid);722 }723 if (!data) {724 throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`);725 }726 return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new Binary(data, type);727 }728 inspect(depth, options, inspect) {729 inspect ??= defaultInspect;730 const base64 = ByteUtils.toBase64(this.buffer.subarray(0, this.position));731 const base64Arg = inspect(base64, options);732 const subTypeArg = inspect(this.sub_type, options);733 return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`;734 }735 toInt8Array() {736 if (this.sub_type !== Binary.SUBTYPE_VECTOR) {737 throw new BSONError('Binary sub_type is not Vector');738 }739 if (this.buffer[0] !== Binary.VECTOR_TYPE.Int8) {740 throw new BSONError('Binary datatype field is not Int8');741 }742 validateBinaryVector(this);743 return new Int8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));744 }745 toFloat32Array() {746 if (this.sub_type !== Binary.SUBTYPE_VECTOR) {747 throw new BSONError('Binary sub_type is not Vector');748 }749 if (this.buffer[0] !== Binary.VECTOR_TYPE.Float32) {750 throw new BSONError('Binary datatype field is not Float32');751 }752 validateBinaryVector(this);753 const floatBytes = new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));754 if (NumberUtils.isBigEndian)755 ByteUtils.swap32(floatBytes);756 return new Float32Array(floatBytes.buffer);757 }758 toPackedBits() {759 if (this.sub_type !== Binary.SUBTYPE_VECTOR) {760 throw new BSONError('Binary sub_type is not Vector');761 }762 if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {763 throw new BSONError('Binary datatype field is not packed bit');764 }765 validateBinaryVector(this);766 return new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));767 }768 toBits() {769 if (this.sub_type !== Binary.SUBTYPE_VECTOR) {770 throw new BSONError('Binary sub_type is not Vector');771 }772 if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {773 throw new BSONError('Binary datatype field is not packed bit');774 }775 validateBinaryVector(this);776 const byteCount = this.length() - 2;777 const bitCount = byteCount * 8 - this.buffer[1];778 const bits = new Int8Array(bitCount);779 for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {780 const byteOffset = (bitOffset / 8) | 0;781 const byte = this.buffer[byteOffset + 2];782 const shift = 7 - (bitOffset % 8);783 const bit = (byte >> shift) & 1;784 bits[bitOffset] = bit;785 }786 return bits;787 }788 static fromInt8Array(array) {789 const buffer = ByteUtils.allocate(array.byteLength + 2);790 buffer[0] = Binary.VECTOR_TYPE.Int8;791 buffer[1] = 0;792 const intBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);793 buffer.set(intBytes, 2);794 const bin = new this(buffer, this.SUBTYPE_VECTOR);795 validateBinaryVector(bin);796 return bin;797 }798 static fromFloat32Array(array) {799 const binaryBytes = ByteUtils.allocate(array.byteLength + 2);800 binaryBytes[0] = Binary.VECTOR_TYPE.Float32;801 binaryBytes[1] = 0;802 const floatBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);803 binaryBytes.set(floatBytes, 2);804 if (NumberUtils.isBigEndian)805 ByteUtils.swap32(new Uint8Array(binaryBytes.buffer, 2));806 const bin = new this(binaryBytes, this.SUBTYPE_VECTOR);807 validateBinaryVector(bin);808 return bin;809 }810 static fromPackedBits(array, padding = 0) {811 const buffer = ByteUtils.allocate(array.byteLength + 2);812 buffer[0] = Binary.VECTOR_TYPE.PackedBit;813 buffer[1] = padding;814 buffer.set(array, 2);815 const bin = new this(buffer, this.SUBTYPE_VECTOR);816 validateBinaryVector(bin);817 return bin;818 }819 static fromBits(bits) {820 const byteLength = (bits.length + 7) >>> 3;821 const bytes = new Uint8Array(byteLength + 2);822 bytes[0] = Binary.VECTOR_TYPE.PackedBit;823 const remainder = bits.length % 8;824 bytes[1] = remainder === 0 ? 0 : 8 - remainder;825 for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {826 const byteOffset = bitOffset >>> 3;827 const bit = bits[bitOffset];828 if (bit !== 0 && bit !== 1) {829 throw new BSONError(`Invalid bit value at ${bitOffset}: must be 0 or 1, found ${bits[bitOffset]}`);830 }831 if (bit === 0)832 continue;833 const shift = 7 - (bitOffset % 8);834 bytes[byteOffset + 2] |= bit << shift;835 }836 return new this(bytes, Binary.SUBTYPE_VECTOR);837 }838}839Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0;840Binary.BUFFER_SIZE = 256;841Binary.SUBTYPE_DEFAULT = 0;842Binary.SUBTYPE_FUNCTION = 1;843Binary.SUBTYPE_BYTE_ARRAY = 2;844Binary.SUBTYPE_UUID_OLD = 3;845Binary.SUBTYPE_UUID = 4;846Binary.SUBTYPE_MD5 = 5;847Binary.SUBTYPE_ENCRYPTED = 6;848Binary.SUBTYPE_COLUMN = 7;849Binary.SUBTYPE_SENSITIVE = 8;850Binary.SUBTYPE_VECTOR = 9;851Binary.SUBTYPE_USER_DEFINED = 128;852Binary.VECTOR_TYPE = Object.freeze({853 Int8: 0x03,854 Float32: 0x27,855 PackedBit: 0x10856});857function validateBinaryVector(vector) {858 if (vector.sub_type !== Binary.SUBTYPE_VECTOR)859 return;860 const size = vector.position;861 const datatype = vector.buffer[0];862 const padding = vector.buffer[1];863 if ((datatype === Binary.VECTOR_TYPE.Float32 || datatype === Binary.VECTOR_TYPE.Int8) &&864 padding !== 0) {865 throw new BSONError('Invalid Vector: padding must be zero for int8 and float32 vectors');866 }867 if (datatype === Binary.VECTOR_TYPE.Float32) {868 if (size !== 0 && size - 2 !== 0 && (size - 2) % 4 !== 0) {869 throw new BSONError('Invalid Vector: Float32 vector must contain a multiple of 4 bytes');870 }871 }872 if (datatype === Binary.VECTOR_TYPE.PackedBit && padding !== 0 && size === 2) {873 throw new BSONError('Invalid Vector: padding must be zero for packed bit vectors that are empty');874 }875 if (datatype === Binary.VECTOR_TYPE.PackedBit && padding > 7) {876 throw new BSONError(`Invalid Vector: padding must be a value between 0 and 7. found: ${padding}`);877 }878}879const UUID_BYTE_LENGTH = 16;880const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;881const UUID_WITH_DASHES = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i;882class UUID extends Binary {883 constructor(input) {884 let bytes;885 if (input == null) {886 bytes = UUID.generate();887 }888 else if (input instanceof UUID) {889 bytes = ByteUtils.toLocalBufferType(new Uint8Array(input.buffer));890 }891 else if (ArrayBuffer.isView(input) && input.byteLength === UUID_BYTE_LENGTH) {892 bytes = ByteUtils.toLocalBufferType(input);893 }894 else if (typeof input === 'string') {895 bytes = UUID.bytesFromString(input);896 }897 else {898 throw new BSONError('Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).');899 }900 super(bytes, BSON_BINARY_SUBTYPE_UUID_NEW);901 }902 get id() {903 return this.buffer;904 }905 set id(value) {906 this.buffer = value;907 }908 toHexString(includeDashes = true) {909 if (includeDashes) {910 return [911 ByteUtils.toHex(this.buffer.subarray(0, 4)),912 ByteUtils.toHex(this.buffer.subarray(4, 6)),913 ByteUtils.toHex(this.buffer.subarray(6, 8)),914 ByteUtils.toHex(this.buffer.subarray(8, 10)),915 ByteUtils.toHex(this.buffer.subarray(10, 16))916 ].join('-');917 }918 return ByteUtils.toHex(this.buffer);919 }920 toString(encoding) {921 if (encoding === 'hex')922 return ByteUtils.toHex(this.id);923 if (encoding === 'base64')924 return ByteUtils.toBase64(this.id);925 return this.toHexString();926 }927 toJSON() {928 return this.toHexString();929 }930 equals(otherId) {931 if (!otherId) {932 return false;933 }934 if (otherId instanceof UUID) {935 return ByteUtils.equals(otherId.id, this.id);936 }937 try {938 return ByteUtils.equals(new UUID(otherId).id, this.id);939 }940 catch {941 return false;942 }943 }944 toBinary() {945 return new Binary(this.id, Binary.SUBTYPE_UUID);946 }947 static generate() {948 const bytes = ByteUtils.randomBytes(UUID_BYTE_LENGTH);949 bytes[6] = (bytes[6] & 0x0f) | 0x40;950 bytes[8] = (bytes[8] & 0x3f) | 0x80;951 return bytes;952 }953 static isValid(input) {954 if (!input) {955 return false;956 }957 if (typeof input === 'string') {958 return UUID.isValidUUIDString(input);959 }960 if (isUint8Array(input)) {961 return input.byteLength === UUID_BYTE_LENGTH;962 }963 return (input._bsontype === 'Binary' &&964 input.sub_type === this.SUBTYPE_UUID &&965 input.buffer.byteLength === 16);966 }967 static createFromHexString(hexString) {968 const buffer = UUID.bytesFromString(hexString);969 return new UUID(buffer);970 }971 static createFromBase64(base64) {972 return new UUID(ByteUtils.fromBase64(base64));973 }974 static bytesFromString(representation) {975 if (!UUID.isValidUUIDString(representation)) {976 throw new BSONError('UUID string representation must be 32 hex digits or canonical hyphenated representation');977 }978 return ByteUtils.fromHex(representation.replace(/-/g, ''));979 }980 static isValidUUIDString(representation) {981 return UUID_WITHOUT_DASHES.test(representation) || UUID_WITH_DASHES.test(representation);982 }983 inspect(depth, options, inspect) {984 inspect ??= defaultInspect;985 return `new UUID(${inspect(this.toHexString(), options)})`;986 }987}988 989class Code extends BSONValue {990 get _bsontype() {991 return 'Code';992 }993 constructor(code, scope) {994 super();995 this.code = code.toString();996 this.scope = scope ?? null;997 }998 toJSON() {999 if (this.scope != null) {1000 return { code: this.code, scope: this.scope };1001 }1002 return { code: this.code };1003 }1004 toExtendedJSON() {1005 if (this.scope) {1006 return { $code: this.code, $scope: this.scope };1007 }1008 return { $code: this.code };1009 }1010 static fromExtendedJSON(doc) {1011 return new Code(doc.$code, doc.$scope);1012 }1013 inspect(depth, options, inspect) {1014 inspect ??= defaultInspect;1015 let parametersString = inspect(this.code, options);1016 const multiLineFn = parametersString.includes('\n');1017 if (this.scope != null) {1018 parametersString += `,${multiLineFn ? '\n' : ' '}${inspect(this.scope, options)}`;1019 }1020 const endingNewline = multiLineFn && this.scope === null;1021 return `new Code(${multiLineFn ? '\n' : ''}${parametersString}${endingNewline ? '\n' : ''})`;1022 }1023}1024 1025function isDBRefLike(value) {1026 return (value != null &&1027 typeof value === 'object' &&1028 '$id' in value &&1029 value.$id != null &&1030 '$ref' in value &&1031 typeof value.$ref === 'string' &&1032 (!('$db' in value) || ('$db' in value && typeof value.$db === 'string')));1033}1034class DBRef extends BSONValue {1035 get _bsontype() {1036 return 'DBRef';1037 }1038 constructor(collection, oid, db, fields) {1039 super();1040 const parts = collection.split('.');1041 if (parts.length === 2) {1042 db = parts.shift();1043 collection = parts.shift();1044 }1045 this.collection = collection;1046 this.oid = oid;1047 this.db = db;1048 this.fields = fields || {};1049 }1050 get namespace() {1051 return this.collection;1052 }1053 set namespace(value) {1054 this.collection = value;1055 }1056 toJSON() {1057 const o = Object.assign({1058 $ref: this.collection,1059 $id: this.oid1060 }, this.fields);1061 if (this.db != null)1062 o.$db = this.db;1063 return o;1064 }1065 toExtendedJSON(options) {1066 options = options || {};1067 let o = {1068 $ref: this.collection,1069 $id: this.oid1070 };1071 if (options.legacy) {1072 return o;1073 }1074 if (this.db)1075 o.$db = this.db;1076 o = Object.assign(o, this.fields);1077 return o;1078 }1079 static fromExtendedJSON(doc) {1080 const copy = Object.assign({}, doc);1081 delete copy.$ref;1082 delete copy.$id;1083 delete copy.$db;1084 return new DBRef(doc.$ref, doc.$id, doc.$db, copy);1085 }1086 inspect(depth, options, inspect) {1087 inspect ??= defaultInspect;1088 const args = [1089 inspect(this.namespace, options),1090 inspect(this.oid, options),1091 ...(this.db ? [inspect(this.db, options)] : []),1092 ...(Object.keys(this.fields).length > 0 ? [inspect(this.fields, options)] : [])1093 ];1094 args[1] = inspect === defaultInspect ? `new ObjectId(${args[1]})` : args[1];1095 return `new DBRef(${args.join(', ')})`;1096 }1097}1098 1099function removeLeadingZerosAndExplicitPlus(str) {1100 if (str === '') {1101 return str;1102 }1103 let startIndex = 0;1104 const isNegative = str[startIndex] === '-';1105 const isExplicitlyPositive = str[startIndex] === '+';1106 if (isExplicitlyPositive || isNegative) {1107 startIndex += 1;1108 }1109 let foundInsignificantZero = false;1110 for (; startIndex < str.length && str[startIndex] === '0'; ++startIndex) {1111 foundInsignificantZero = true;1112 }1113 if (!foundInsignificantZero) {1114 return isExplicitlyPositive ? str.slice(1) : str;1115 }1116 return `${isNegative ? '-' : ''}${str.length === startIndex ? '0' : str.slice(startIndex)}`;1117}1118function validateStringCharacters(str, radix) {1119 radix = radix ?? 10;1120 const validCharacters = '0123456789abcdefghijklmnopqrstuvwxyz'.slice(0, radix);1121 const regex = new RegExp(`[^-+${validCharacters}]`, 'i');1122 return regex.test(str) ? false : str;1123}1124 1125let wasm = undefined;1126try {1127 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;1128}1129catch {1130}1131const TWO_PWR_16_DBL = 1 << 16;1132const TWO_PWR_24_DBL = 1 << 24;1133const TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;1134const TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;1135const TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;1136const INT_CACHE = {};1137const UINT_CACHE = {};1138const MAX_INT64_STRING_LENGTH = 20;1139const DECIMAL_REG_EX = /^(\+?0|(\+|-)?[1-9][0-9]*)$/;1140class Long extends BSONValue {1141 get _bsontype() {1142 return 'Long';1143 }1144 get __isLong__() {1145 return true;1146 }1147 constructor(lowOrValue = 0, highOrUnsigned, unsigned) {1148 super();1149 const unsignedBool = typeof highOrUnsigned === 'boolean' ? highOrUnsigned : Boolean(unsigned);1150 const high = typeof highOrUnsigned === 'number' ? highOrUnsigned : 0;1151 const res = typeof lowOrValue === 'string'1152 ? Long.fromString(lowOrValue, unsignedBool)1153 : typeof lowOrValue === 'bigint'1154 ? Long.fromBigInt(lowOrValue, unsignedBool)1155 : { low: lowOrValue | 0, high: high | 0, unsigned: unsignedBool };1156 this.low = res.low;1157 this.high = res.high;1158 this.unsigned = res.unsigned;1159 }1160 static fromBits(lowBits, highBits, unsigned) {1161 return new Long(lowBits, highBits, unsigned);1162 }1163 static fromInt(value, unsigned) {1164 let obj, cachedObj, cache;1165 if (unsigned) {1166 value >>>= 0;1167 if ((cache = 0 <= value && value < 256)) {1168 cachedObj = UINT_CACHE[value];1169 if (cachedObj)1170 return cachedObj;1171 }1172 obj = Long.fromBits(value, (value | 0) < 0 ? -1 : 0, true);1173 if (cache)1174 UINT_CACHE[value] = obj;1175 return obj;1176 }1177 else {1178 value |= 0;1179 if ((cache = -128 <= value && value < 128)) {1180 cachedObj = INT_CACHE[value];1181 if (cachedObj)1182 return cachedObj;1183 }1184 obj = Long.fromBits(value, value < 0 ? -1 : 0, false);1185 if (cache)1186 INT_CACHE[value] = obj;1187 return obj;1188 }1189 }1190 static fromNumber(value, unsigned) {1191 if (isNaN(value))1192 return unsigned ? Long.UZERO : Long.ZERO;1193 if (unsigned) {1194 if (value < 0)1195 return Long.UZERO;1196 if (value >= TWO_PWR_64_DBL)1197 return Long.MAX_UNSIGNED_VALUE;1198 }1199 else {1200 if (value <= -9223372036854776e3)