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