diff --git a/.changeset/wise-goats-scream.md b/.changeset/wise-goats-scream.md new file mode 100644 index 0000000000000000000000000000000000000000..20f9c1898acff21ab080a31439409109e5443cd7 --- /dev/null +++ b/.changeset/wise-goats-scream.md @@ -0,0 +1,5 @@ +--- +"@llamaindex/mongodb": patch +--- + +Added mongo db document and key value store diff --git a/packages/providers/storage/mongodb/package.json b/packages/providers/storage/mongodb/package.json index 2378fc48978b415961a95446bd800f3e2c03625d..80375d5dcdde45639cc7e2fe2a202fe1a4c7067f 100644 --- a/packages/providers/storage/mongodb/package.json +++ b/packages/providers/storage/mongodb/package.json @@ -35,10 +35,13 @@ }, "scripts": { "build": "bunchee", - "dev": "bunchee --watch" + "dev": "bunchee --watch", + "test": "vitest" }, "devDependencies": { - "bunchee": "6.4.0" + "bunchee": "6.4.0", + "vitest": "2.1.0", + "mongodb-memory-server": "^10.1.4" }, "dependencies": { "@llamaindex/core": "workspace:*", diff --git a/packages/providers/storage/mongodb/src/docStore/MongoDBDocumentStore.ts b/packages/providers/storage/mongodb/src/docStore/MongoDBDocumentStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..47f167ed53941a3014ab1107b181ec227bddb52a --- /dev/null +++ b/packages/providers/storage/mongodb/src/docStore/MongoDBDocumentStore.ts @@ -0,0 +1,76 @@ +import { KVDocumentStore } from "@llamaindex/core/storage/doc-store"; +import { MongoClient } from "mongodb"; +import { MongoKVStore } from "../kvStore/MongoKVStore"; + +const DEFAULT_DATABASE = "DocumentStoreDB"; +const DEFAULT_COLLECTION = "DocumentStoreCollection"; + +interface MongoDBDocumentStoreConfig { + mongoKVStore: MongoKVStore; + namespace?: string; +} + +export class MongoDocumentStore extends KVDocumentStore { + constructor({ mongoKVStore, namespace }: MongoDBDocumentStoreConfig) { + super(mongoKVStore, namespace); + } + + /** + * Static method for creating an instance using a MongoClient. + * @returns Instance of MongoDBDocumentStore + * @param mongoClient - MongoClient instance + * @param dbName - Database name + * @param collectionName - Collection name + * @example + * ```ts + * const mongoClient = new MongoClient("mongodb://localhost:27017"); + * const documentStore = MongoDBDocumentStore.fromMongoClient(mongoClient, "my_db", "my_collection"); + * ``` + */ + static fromMongoClient( + mongoClient: MongoClient, + dbName: string = DEFAULT_DATABASE, + collectionName: string = DEFAULT_COLLECTION, + ): MongoDocumentStore { + const mongoKVStore = new MongoKVStore({ + mongoClient, + dbName, + }); + + return new MongoDocumentStore({ + mongoKVStore, + namespace: `${dbName}.${collectionName}`, + }); + } + + /** + * Static method for creating an instance using a connection string. + * @returns Instance of MongoDBDocumentStore + * @param connectionString - MongoDB connection string + * @param dbName - Database name + * @param collectionName - Collection name + * @example + * ```ts + * const documentStore = MongoDBDocumentStore.fromConnectionString("mongodb://localhost:27017", "my_db", "my_collection"); + * ``` + */ + static fromConnectionString( + connectionString: string, + dbName: string = DEFAULT_DATABASE, + collectionName: string = DEFAULT_COLLECTION, + ): MongoDocumentStore { + const mongoClient = new MongoClient(connectionString, { + appName: "LLAMAINDEX_JS", + }); + + const mongoKVStore = new MongoKVStore({ + mongoClient, + dbName, + }); + + return new MongoDocumentStore({ + mongoKVStore, + namespace: `${dbName}.${collectionName}`, + }); + } +} diff --git a/packages/providers/storage/mongodb/src/index.ts b/packages/providers/storage/mongodb/src/index.ts index 513fcd77ff84e678918346935b876f3e0ef2266a..6b05ee34cca7ecf90d9da59df5a45e34476158c7 100644 --- a/packages/providers/storage/mongodb/src/index.ts +++ b/packages/providers/storage/mongodb/src/index.ts @@ -1 +1,3 @@ +export * from "./docStore/MongoDBDocumentStore"; +export * from "./kvStore/MongoKVStore"; export * from "./MongoDBAtlasVectorStore"; diff --git a/packages/providers/storage/mongodb/src/kvStore/MongoKVStore.ts b/packages/providers/storage/mongodb/src/kvStore/MongoKVStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..c506f6d4260c4ee77935c0a041527f67b88e8b93 --- /dev/null +++ b/packages/providers/storage/mongodb/src/kvStore/MongoKVStore.ts @@ -0,0 +1,93 @@ +import type { StoredValue } from "@llamaindex/core/schema"; +import { BaseKVStore } from "@llamaindex/core/storage/kv-store"; +import type { Collection, MongoClient } from "mongodb"; + +const DEFAULT_DB_NAME = "KVStoreDB"; +const DEFAULT_COLLECTION_NAME = "KVStoreCollection"; + +interface MongoKVStoreConfig { + mongoClient: MongoClient; + dbName?: string; +} + +export class MongoKVStore extends BaseKVStore { + private mongoClient: MongoClient; + private dbName: string; + + constructor({ mongoClient, dbName = DEFAULT_DB_NAME }: MongoKVStoreConfig) { + super(); + if (!mongoClient) { + throw new Error( + "MongoClient is required for MongoKVStore initialization", + ); + } + + this.mongoClient = mongoClient; + this.dbName = dbName; + } + + get client(): MongoClient { + return this.mongoClient; + } + + private async ensureCollection(collectionName: string): Promise<Collection> { + const collection = this.mongoClient + .db(this.dbName) + .collection(collectionName); + return collection; + } + + async put( + key: string, + val: Exclude<StoredValue, null>, + collectionName: string = DEFAULT_COLLECTION_NAME, + ): Promise<void> { + const collection = await this.ensureCollection(collectionName); + + await collection.updateOne({ id: key }, { $set: val }, { upsert: true }); + } + + async get( + key: string, + collectionName: string = DEFAULT_COLLECTION_NAME, + ): Promise<StoredValue> { + const collection = await this.ensureCollection(collectionName); + + const result = await collection.findOne( + { id: key }, + { projection: { _id: 0 } }, + ); + + if (!result) { + return null; + } + + return result; + } + + async getAll( + collectionName: string = DEFAULT_COLLECTION_NAME, + ): Promise<Record<string, StoredValue>> { + const collection = await this.ensureCollection(collectionName); + const cursor = collection.find({}, { projection: { _id: 0 } }); + + const output: Record<string, StoredValue> = {}; + + await cursor.forEach((item) => { + output[item.id] = item; + }); + + return output; + } + + async delete( + key: string, + collectionName: string = DEFAULT_COLLECTION_NAME, + ): Promise<boolean> { + const collection = await this.ensureCollection(collectionName); + + await collection.deleteOne({ id: key }); + + return true; + } +} diff --git a/packages/providers/storage/mongodb/src/tests/MongoDocumentStore.test.ts b/packages/providers/storage/mongodb/src/tests/MongoDocumentStore.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca30c0471fc6ff581c90774cb00802d9fba412cf --- /dev/null +++ b/packages/providers/storage/mongodb/src/tests/MongoDocumentStore.test.ts @@ -0,0 +1,150 @@ +import { Document, MetadataMode } from "@llamaindex/core/schema"; +import { MongoClient } from "mongodb"; +import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { MongoDocumentStore } from "../docStore/MongoDBDocumentStore"; +import { setupTestDb } from "./setuptTestDb"; + +describe("MongoDocumentStore", () => { + let cleanup: () => Promise<void>; + let mongoClient: MongoClient; + let documentStore: MongoDocumentStore; + let mongoUri: string; + + beforeAll(async () => { + const testDb = await setupTestDb(); + cleanup = testDb.cleanup; + mongoClient = testDb.mongoClient; + mongoUri = testDb.mongoUri; + documentStore = MongoDocumentStore.fromMongoClient(mongoClient); + }, 120000); + + afterAll(async () => { + await cleanup(); + }); + + describe("constructor", () => { + it("should create instance with mongoClient", () => { + const store = MongoDocumentStore.fromMongoClient(mongoClient); + expect(store).toBeInstanceOf(MongoDocumentStore); + }); + + it("should create instance with custom namespace", () => { + const store = MongoDocumentStore.fromMongoClient( + mongoClient, + "custom", + "namespace", + ); + expect(store).toBeInstanceOf(MongoDocumentStore); + }); + }); + + describe("static constructors", () => { + it("should create instance from connection string", () => { + const store = MongoDocumentStore.fromConnectionString(mongoUri); + expect(store).toBeInstanceOf(MongoDocumentStore); + }); + + it("should create instance from MongoClient", () => { + const store = MongoDocumentStore.fromMongoClient(mongoClient); + expect(store).toBeInstanceOf(MongoDocumentStore); + }); + }); + + describe("document operations", () => { + beforeEach(async () => { + await mongoClient.db("test").collection("test").deleteMany({}); + }); + + it("should store and retrieve a document", async () => { + const doc = new Document({ text: "test document", id_: "test_id" }); + await documentStore.addDocuments([doc]); + const retrievedDoc = await documentStore.getDocument("test_id"); + const text = retrievedDoc?.getContent(MetadataMode.ALL); + expect(text).toBe(doc.text); + }); + + it("should store and retrieve multiple documents", async () => { + const docs = [ + new Document({ text: "doc1", id_: "id1" }), + new Document({ text: "doc2", id_: "id2" }), + ]; + await documentStore.addDocuments(docs); + const retrievedDocs = await documentStore.getNodes(["id1", "id2"]); + expect(retrievedDocs.map((d) => d?.getContent(MetadataMode.ALL))).toEqual( + docs.map((d) => d.text), + ); + }); + + it("should handle missing documents", async () => { + const doc = await documentStore.getDocument("non_existent_id", false); + expect(doc).toBeUndefined(); + }); + }); + + describe("document updates", () => { + it("should update existing document when allowUpdate is true", async () => { + const doc1 = new Document({ text: "original", id_: "test_id" }); + const doc2 = new Document({ text: "updated", id_: "test_id" }); + await documentStore.addDocuments([doc1]); + await documentStore.addDocuments([doc2], true); + + const retrieved = await documentStore.getDocument("test_id"); + const text = retrieved?.getContent(MetadataMode.ALL); + expect(text).toBe("updated"); + }); + + it("should throw error when updating with allowUpdate false", async () => { + const doc1 = new Document({ text: "original", id_: "test_id" }); + await documentStore.addDocuments([doc1]); + + const doc2 = new Document({ text: "updated", id_: "test_id" }); + await expect(documentStore.addDocuments([doc2], false)).rejects.toThrow( + /doc_id.*already exists/, + ); + }); + }); + + describe("document deletion", () => { + it("should delete a document", async () => { + const doc = new Document({ text: "test document", id_: "test_id" }); + await documentStore.addDocuments([doc]); + await documentStore.deleteDocument("test_id"); + const retrieved = await documentStore.getDocument("test_id", false); + expect(retrieved).toBeUndefined(); + }); + + it("should handle deleting non-existent document", async () => { + await expect( + documentStore.deleteDocument("non_existent_id"), + ).resolves.not.toThrow(); + }); + }); + + describe("document existence", () => { + it("should check if document exists", async () => { + const doc = new Document({ text: "test document", id_: "test_id" }); + await documentStore.addDocuments([doc]); + const exists = await documentStore.documentExists("test_id"); + expect(exists).toBe(true); + }); + + it("should return false for non-existent document", async () => { + const exists = await documentStore.documentExists("non_existent_id"); + expect(exists).toBe(false); + }); + }); + + describe("document hash", () => { + it("should get document hash", async () => { + const doc = new Document({ text: "test document", id_: "test_id" }); + await documentStore.addDocuments([doc]); + const hash = await documentStore.getDocumentHash("test_id"); + expect(hash).toBe(doc.hash); + }); + + it("should return null for non-existent document hash", async () => { + const hash = await documentStore.getDocumentHash("non_existent_id"); + expect(hash).toBeUndefined(); + }); + }); +}); diff --git a/packages/providers/storage/mongodb/src/tests/MongokVStore.test.ts b/packages/providers/storage/mongodb/src/tests/MongokVStore.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..a34924ce733d4d43b3f87db8dc8f82808499dd9b --- /dev/null +++ b/packages/providers/storage/mongodb/src/tests/MongokVStore.test.ts @@ -0,0 +1,125 @@ +import type { MongoClient } from "mongodb"; +import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { MongoKVStore } from "../kvStore/MongoKVStore"; +import { setupTestDb } from "./setuptTestDb"; + +describe("MongoKVStore", () => { + let cleanUp: () => Promise<void>; + let mongoClient: MongoClient; + let mongoUri: string; + let kvStore: MongoKVStore; + + beforeAll(async () => { + const testDb = await setupTestDb(); + cleanUp = testDb.cleanup; + mongoClient = testDb.mongoClient; + mongoUri = testDb.mongoUri; + kvStore = new MongoKVStore({ + mongoClient, + dbName: "test", + }); + }, 120000); + + afterAll(async () => { + await cleanUp(); + }); + + describe("Mongod KV store constructor", () => { + it("should create instance with mongoClient", () => { + const kvStore = new MongoKVStore({ + mongoClient, + dbName: "test", + }); + + expect(kvStore).toBeInstanceOf(MongoKVStore); + }); + + it("should create db with custom db and collection name", () => { + const kvStore = new MongoKVStore({ + mongoClient, + dbName: "test", + }); + + expect(kvStore).toBeInstanceOf(MongoKVStore); + }); + }); + + describe("mongo kv store put ", () => { + it("should store a value", async () => { + const key = "test_key"; + + const value = { data: "test_value" }; + + await kvStore.put(key, value); + + const result = await kvStore.get(key); + expect(result).toMatchObject(value); + }); + + it("should update an existing value", async () => { + const key = "test_key2"; + + const value = { data: "test_value" }; + const value2 = { data: "test_value2" }; + await kvStore.put(key, value); + await kvStore.put(key, value2); + + const result = await kvStore.get(key); + + expect(result).toMatchObject(value2); + }); + }); + + describe("mongo kv store get", () => { + it("should return null for non-existent key", async () => { + const result = await kvStore.get("non_existent_key"); + expect(result).toBeNull(); + }); + + it("should return a value for stored key", async () => { + const key = "test_key"; + const value = { data: "test_value" }; + + const result = await kvStore.get(key); + expect(result).toMatchObject(value); + }); + }); + + describe("mongo kv store getAll", () => { + //reset the db before each test + beforeEach(async () => { + await mongoClient.db("test").collection("test").deleteMany({}); + }); + + it("should return all values", async () => { + const items = { + test_key1: { data: "test_value1" }, + test_key2: { data: "test_value2" }, + }; + + await Promise.all([ + kvStore.put("test_key1", items["test_key1"]), + kvStore.put("test_key2", items["test_key2"]), + ]); + + const result = await kvStore.getAll(); + + expect(result).toMatchObject(items); + }); + }); + + describe("mongo kv store delete", () => { + it("should delete a value", async () => { + const key = "test_key"; + const value = { data: "test_value" }; + + await kvStore.put(key, value); + const deleted = await kvStore.delete(key); + + const result = await kvStore.get(key); + + expect(result).toBeNull(); + expect(deleted).toBe(true); + }); + }); +}); diff --git a/packages/providers/storage/mongodb/src/tests/setuptTestDb.ts b/packages/providers/storage/mongodb/src/tests/setuptTestDb.ts new file mode 100644 index 0000000000000000000000000000000000000000..a9bf9e6e5055d92d7ec4adc5a3ede0f31c6e1c90 --- /dev/null +++ b/packages/providers/storage/mongodb/src/tests/setuptTestDb.ts @@ -0,0 +1,21 @@ +import { MongoClient } from "mongodb"; +import { MongoMemoryServer } from "mongodb-memory-server"; + +//setup a in memory test db for testing +export async function setupTestDb() { + const mongoServer = await MongoMemoryServer.create(); + const mongoUri = mongoServer.getUri(); + const mongoClient = new MongoClient(mongoUri); + await mongoClient.connect(); + + return { + mongoServer, + mongoClient, + mongoUri, + // return a cleanup function to close the db and stop the server + cleanup: async () => { + await mongoClient.close(); + await mongoServer.stop(); + }, + }; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21278abca363df3ae26f25b5a209e4ef844c2c70..dcce69d027c893ec805c0e117500715305bf8516 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -119,7 +119,7 @@ importers: version: 1.6.0(@aws-sdk/credential-provider-web-identity@3.744.0) ai: specifier: ^3.4.33 - version: 3.4.33(openai@4.86.0(zod@3.24.2))(react@19.0.0)(sswr@2.1.0(svelte@5.19.10))(svelte@5.19.10)(vue@3.5.13(typescript@5.7.3))(zod@3.24.2) + version: 3.4.33(openai@4.86.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2))(react@19.0.0)(sswr@2.1.0(svelte@5.19.10))(svelte@5.19.10)(vue@3.5.13(typescript@5.7.3))(zod@3.24.2) class-variance-authority: specifier: ^0.7.0 version: 0.7.1 @@ -791,7 +791,7 @@ importers: version: 2.10.2(@types/react@19.0.10)(react@19.0.0) openai: specifier: ^4 - version: 4.83.0(ws@8.18.0)(zod@3.24.2) + version: 4.83.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2) typedoc: specifier: ^0.26.11 version: 0.26.11(typescript@5.7.3) @@ -843,7 +843,7 @@ importers: version: link:../../../llamaindex openai: specifier: ^4.73.1 - version: 4.83.0(ws@8.18.0)(zod@3.24.2) + version: 4.83.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2) devDependencies: tsx: specifier: ^4.19.3 @@ -1331,7 +1331,7 @@ importers: version: link:../../env openai: specifier: ^4.86.0 - version: 4.86.0(ws@8.18.0)(zod@3.24.2) + version: 4.86.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2) zod: specifier: ^3.24.2 version: 3.24.2 @@ -1454,7 +1454,7 @@ importers: version: link:../../../env chromadb: specifier: 1.10.3 - version: 1.10.3(cohere-ai@7.14.0)(openai@4.86.0)(voyageai@0.0.3-1) + version: 1.10.3(cohere-ai@7.14.0)(openai@4.86.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2))(voyageai@0.0.3-1) chromadb-default-embed: specifier: ^2.13.2 version: 2.13.2 @@ -1519,6 +1519,12 @@ importers: bunchee: specifier: 6.4.0 version: 6.4.0(typescript@5.7.3) + mongodb-memory-server: + specifier: ^10.1.4 + version: 10.1.4(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4) + vitest: + specifier: 2.1.0 + version: 2.1.0(@edge-runtime/vm@4.0.4)(@types/node@22.13.5)(happy-dom@15.11.7)(lightningcss@1.29.1)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(terser@5.38.2) packages/providers/storage/pinecone: dependencies: @@ -5652,9 +5658,24 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + '@vitest/expect@2.1.0': + resolution: {integrity: sha512-N3/xR4fSu0+6sVZETEtPT1orUs2+Y477JOXTcU3xKuu3uBlsgbD7/7Mz2LZ1Jr1XjwilEWlrIgSCj4N1+5ZmsQ==} + '@vitest/expect@2.1.5': resolution: {integrity: sha512-nZSBTW1XIdpZvEJyoP/Sy8fUg0b8od7ZpGDkTUcfJ7wz/VoZAFzFfLyxVxGFhUjJzhYqSbIpfMtl/+k/dpWa3Q==} + '@vitest/mocker@2.1.0': + resolution: {integrity: sha512-ZxENovUqhzl+QiOFpagiHUNUuZ1qPd5yYTCYHomGIZOFArzn4mgX2oxZmiAItJWAaXHG6bbpb/DpSPhlk5DgtA==} + peerDependencies: + '@vitest/spy': 2.1.0 + msw: ^2.3.5 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/mocker@2.1.5': resolution: {integrity: sha512-XYW6l3UuBmitWqSUXTNXcVBUCRytDogBsWuNXQijc00dtnU/9OqpXWp4OJroVrad/gLIomAq9aW8yWDBtMthhQ==} peerDependencies: @@ -5666,21 +5687,36 @@ packages: vite: optional: true + '@vitest/pretty-format@2.1.0': + resolution: {integrity: sha512-7sxf2F3DNYatgmzXXcTh6cq+/fxwB47RIQqZJFoSH883wnVAoccSRT6g+dTKemUBo8Q5N4OYYj1EBXLuRKvp3Q==} + '@vitest/pretty-format@2.1.5': resolution: {integrity: sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw==} '@vitest/pretty-format@2.1.9': resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + '@vitest/runner@2.1.0': + resolution: {integrity: sha512-D9+ZiB8MbMt7qWDRJc4CRNNUlne/8E1X7dcKhZVAbcOKG58MGGYVDqAq19xlhNfMFZsW0bpVKgztBwks38Ko0w==} + '@vitest/runner@2.1.5': resolution: {integrity: sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==} + '@vitest/snapshot@2.1.0': + resolution: {integrity: sha512-x69CygGMzt9VCO283K2/FYQ+nBrOj66OTKpsPykjCR4Ac3lLV+m85hj9reaIGmjBSsKzVvbxWmjWE3kF5ha3uQ==} + '@vitest/snapshot@2.1.5': resolution: {integrity: sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==} + '@vitest/spy@2.1.0': + resolution: {integrity: sha512-IXX5NkbdgTYTog3F14i2LgnBc+20YmkXMx0IWai84mcxySUDRgm0ihbOfR4L0EVRBDFG85GjmQQEZNNKVVpkZw==} + '@vitest/spy@2.1.5': resolution: {integrity: sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==} + '@vitest/utils@2.1.0': + resolution: {integrity: sha512-rreyfVe0PuNqJfKYUwfPDfi6rrp0VSu0Wgvp5WBqJonP+4NvXHk48X6oBam1Lj47Hy6jbJtnMj3OcRdrkTP0tA==} + '@vitest/utils@2.1.5': resolution: {integrity: sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==} @@ -6155,6 +6191,9 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + async@2.6.4: resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} @@ -6398,6 +6437,10 @@ packages: resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} engines: {node: '>=4'} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + caniuse-lite@1.0.30001699: resolution: {integrity: sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==} @@ -6422,6 +6465,10 @@ packages: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -7466,6 +7513,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + find-chrome-bin@2.0.2: resolution: {integrity: sha512-KlggCilbbvgETk/WEq9NG894U8yu4erIW0SjMm1sMPm2xihCHeNoybpzGoxEzHRthwF3XrKOgHYtfqgJzpCH2w==} engines: {node: '>=18.0.0'} @@ -9340,6 +9391,14 @@ packages: mongodb-connection-string-url@3.0.2: resolution: {integrity: sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==} + mongodb-memory-server-core@10.1.4: + resolution: {integrity: sha512-o8fgY7ZalEd8pGps43fFPr/hkQu1L8i6HFEGbsTfA2zDOW0TopgpswaBCqDr0qD7ptibyPfB5DmC+UlIxbThzA==} + engines: {node: '>=16.20.1'} + + mongodb-memory-server@10.1.4: + resolution: {integrity: sha512-+oKQ/kc3CX+816oPFRtaF0CN4vNcGKNjpOQe4bHo/21A3pMD+lC7Xz1EX5HP7siCX4iCpVchDMmCOFXVQSGkUg==} + engines: {node: '>=16.20.1'} + mongodb@6.13.0: resolution: {integrity: sha512-KeESYR5TEaFxOuwRqkOm3XOsMqCSkdeDMjaW5u2nuKfX7rqaofp7JQGoi7sVqQcNJTKuveNbzZtWMstb8ABP6Q==} engines: {node: '>=16.20.1'} @@ -9487,6 +9546,10 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} + new-find-package-json@2.0.0: + resolution: {integrity: sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==} + engines: {node: '>=12.22.0'} + next-themes@0.4.4: resolution: {integrity: sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==} peerDependencies: @@ -10059,6 +10122,10 @@ packages: piscina@4.8.0: resolution: {integrity: sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==} + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} @@ -11852,6 +11919,11 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@2.1.0: + resolution: {integrity: sha512-+ybYqBVUjYyIscoLzMWodus2enQDZOpGhcU6HdOVD6n8WZdk12w1GFL3mbnxLs7hPtRtqs1Wo5YF6/Tsr6fmhg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite-node@2.1.5: resolution: {integrity: sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==} engines: {node: ^18.0.0 || >=20.0.0} @@ -11933,6 +12005,31 @@ packages: yaml: optional: true + vitest@2.1.0: + resolution: {integrity: sha512-XuuEeyNkqbfr0FtAvd9vFbInSSNY1ykCQTYQ0sj9wPy4hx+1gR7gqVNdW0AX2wrrM1wWlN5fnJDjF9xG6mYRSQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.0 + '@vitest/ui': 2.1.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vitest@2.1.5: resolution: {integrity: sha512-P4ljsdpuzRTPI/kbND2sDZ4VmieerR2c9szEZpjc+98Z9ebvnXmM5+0tHEKqYZumXqlvnmfWsjeFOjXVriDG7A==} engines: {node: ^18.0.0 || >=20.0.0} @@ -16834,6 +16931,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/expect@2.1.0': + dependencies: + '@vitest/spy': 2.1.0 + '@vitest/utils': 2.1.0 + chai: 5.2.0 + tinyrainbow: 1.2.0 + '@vitest/expect@2.1.5': dependencies: '@vitest/spy': 2.1.5 @@ -16841,6 +16945,15 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 + '@vitest/mocker@2.1.0(@vitest/spy@2.1.0)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(vite@5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2))': + dependencies: + '@vitest/spy': 2.1.0 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + msw: 2.7.0(@types/node@22.13.5)(typescript@5.7.3) + vite: 5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2) + '@vitest/mocker@2.1.5(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(vite@5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2))': dependencies: '@vitest/spy': 2.1.5 @@ -16859,6 +16972,10 @@ snapshots: msw: 2.7.0(@types/node@22.9.0)(typescript@5.7.3) vite: 5.4.14(@types/node@22.9.0)(lightningcss@1.29.1)(terser@5.38.2) + '@vitest/pretty-format@2.1.0': + dependencies: + tinyrainbow: 1.2.0 + '@vitest/pretty-format@2.1.5': dependencies: tinyrainbow: 1.2.0 @@ -16867,21 +16984,42 @@ snapshots: dependencies: tinyrainbow: 1.2.0 + '@vitest/runner@2.1.0': + dependencies: + '@vitest/utils': 2.1.0 + pathe: 1.1.2 + '@vitest/runner@2.1.5': dependencies: '@vitest/utils': 2.1.5 pathe: 1.1.2 + '@vitest/snapshot@2.1.0': + dependencies: + '@vitest/pretty-format': 2.1.0 + magic-string: 0.30.17 + pathe: 1.1.2 + '@vitest/snapshot@2.1.5': dependencies: '@vitest/pretty-format': 2.1.5 magic-string: 0.30.17 pathe: 1.1.2 + '@vitest/spy@2.1.0': + dependencies: + tinyspy: 3.0.2 + '@vitest/spy@2.1.5': dependencies: tinyspy: 3.0.2 + '@vitest/utils@2.1.0': + dependencies: + '@vitest/pretty-format': 2.1.0 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + '@vitest/utils@2.1.5': dependencies: '@vitest/pretty-format': 2.1.5 @@ -17209,7 +17347,7 @@ snapshots: dependencies: humanize-ms: 1.2.1 - ai@3.4.33(openai@4.86.0(zod@3.24.2))(react@19.0.0)(sswr@2.1.0(svelte@5.19.10))(svelte@5.19.10)(vue@3.5.13(typescript@5.7.3))(zod@3.24.2): + ai@3.4.33(openai@4.86.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2))(react@19.0.0)(sswr@2.1.0(svelte@5.19.10))(svelte@5.19.10)(vue@3.5.13(typescript@5.7.3))(zod@3.24.2): dependencies: '@ai-sdk/provider': 0.0.26 '@ai-sdk/provider-utils': 1.0.22(zod@3.24.2) @@ -17225,7 +17363,7 @@ snapshots: secure-json-parse: 2.7.0 zod-to-json-schema: 3.24.1(zod@3.24.2) optionalDependencies: - openai: 4.86.0(ws@8.18.0)(zod@3.24.2) + openai: 4.86.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2) react: 19.0.0 sswr: 2.1.0(svelte@5.19.10) svelte: 5.19.10 @@ -17438,6 +17576,10 @@ snapshots: async-function@1.0.0: {} + async-mutex@0.5.0: + dependencies: + tslib: 2.8.1 + async@2.6.4: dependencies: lodash: 4.17.21 @@ -17464,7 +17606,7 @@ snapshots: axios@1.7.9: dependencies: - follow-redirects: 1.15.9 + follow-redirects: 1.15.9(debug@4.4.0) form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -17730,6 +17872,8 @@ snapshots: camelcase@4.1.0: {} + camelcase@6.3.0: {} + caniuse-lite@1.0.30001699: {} caniuse-lite@1.0.30001701: {} @@ -17767,6 +17911,14 @@ snapshots: loupe: 3.1.3 pathval: 2.0.0 + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -17819,13 +17971,13 @@ snapshots: transitivePeerDependencies: - bare-buffer - chromadb@1.10.3(cohere-ai@7.14.0)(openai@4.86.0)(voyageai@0.0.3-1): + chromadb@1.10.3(cohere-ai@7.14.0)(openai@4.86.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2))(voyageai@0.0.3-1): dependencies: cliui: 8.0.1 isomorphic-fetch: 3.0.0 optionalDependencies: cohere-ai: 7.14.0 - openai: 4.86.0(ws@8.18.0)(zod@3.24.2) + openai: 4.86.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2) voyageai: 0.0.3-1 transitivePeerDependencies: - encoding @@ -18592,8 +18744,8 @@ snapshots: '@typescript-eslint/parser': 8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3) eslint: 9.16.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.16.0(jiti@2.4.2)) eslint-plugin-react: 7.37.2(eslint@9.16.0(jiti@2.4.2)) eslint-plugin-react-hooks: 5.1.0(eslint@9.16.0(jiti@2.4.2)) @@ -18642,7 +18794,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)): + eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -18654,7 +18806,7 @@ snapshots: is-glob: 4.0.3 stable-hash: 0.0.4 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -18674,18 +18826,18 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3) eslint: 9.16.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: @@ -18696,7 +18848,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -18707,7 +18859,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.16.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -18736,7 +18888,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.22.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -19204,6 +19356,12 @@ snapshots: dependencies: to-regex-range: 5.0.1 + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + find-chrome-bin@2.0.2: dependencies: '@puppeteer/browsers': 2.7.1 @@ -19242,7 +19400,9 @@ snapshots: dependencies: tabbable: 6.2.0 - follow-redirects@1.15.9: {} + follow-redirects@1.15.9(debug@4.4.0): + optionalDependencies: + debug: 4.4.0 for-each@0.3.5: dependencies: @@ -20128,7 +20288,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9 + follow-redirects: 1.15.9(debug@4.4.0) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -20878,7 +21038,6 @@ snapshots: make-dir@3.1.0: dependencies: semver: 6.3.1 - optional: true make-dir@4.0.0: dependencies: @@ -21845,6 +22004,44 @@ snapshots: '@types/whatwg-url': 11.0.5 whatwg-url: 14.1.1 + mongodb-memory-server-core@10.1.4(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4): + dependencies: + async-mutex: 0.5.0 + camelcase: 6.3.0 + debug: 4.4.0 + find-cache-dir: 3.3.2 + follow-redirects: 1.15.9(debug@4.4.0) + https-proxy-agent: 7.0.6 + mongodb: 6.13.0(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4) + new-find-package-json: 2.0.0 + semver: 7.7.1 + tar-stream: 3.1.7 + tslib: 2.8.1 + yauzl: 3.2.0 + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - gcp-metadata + - kerberos + - mongodb-client-encryption + - snappy + - socks + - supports-color + + mongodb-memory-server@10.1.4(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4): + dependencies: + mongodb-memory-server-core: 10.1.4(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4) + tslib: 2.8.1 + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - gcp-metadata + - kerberos + - mongodb-client-encryption + - snappy + - socks + - supports-color + mongodb@6.13.0(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4): dependencies: '@mongodb-js/saslprep': 1.2.0 @@ -22014,6 +22211,12 @@ snapshots: netmask@2.0.2: {} + new-find-package-json@2.0.0: + dependencies: + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + next-themes@0.4.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: react: 19.0.0 @@ -22292,7 +22495,7 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openai@4.83.0(ws@8.18.0)(zod@3.24.2): + openai@4.83.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2): dependencies: '@types/node': 18.19.75 '@types/node-fetch': 2.6.12 @@ -22307,7 +22510,7 @@ snapshots: transitivePeerDependencies: - encoding - openai@4.86.0(ws@8.18.0)(zod@3.24.2): + openai@4.86.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2): dependencies: '@types/node': 18.19.76 '@types/node-fetch': 2.6.12 @@ -22642,6 +22845,10 @@ snapshots: optionalDependencies: '@napi-rs/nice': 1.0.1 + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -24826,6 +25033,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 + vite-node@2.1.0(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + pathe: 1.1.2 + vite: 5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@2.1.5(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2): dependencies: cac: 6.7.14 @@ -24902,6 +25126,42 @@ snapshots: tsx: 4.19.3 yaml: 2.7.0 + vitest@2.1.0(@edge-runtime/vm@4.0.4)(@types/node@22.13.5)(happy-dom@15.11.7)(lightningcss@1.29.1)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(terser@5.38.2): + dependencies: + '@vitest/expect': 2.1.0 + '@vitest/mocker': 2.1.0(@vitest/spy@2.1.0)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(vite@5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.0 + '@vitest/snapshot': 2.1.0 + '@vitest/spy': 2.1.0 + '@vitest/utils': 2.1.0 + chai: 5.2.0 + debug: 4.4.0 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2) + vite-node: 2.1.0(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@edge-runtime/vm': 4.0.4 + '@types/node': 22.13.5 + happy-dom: 15.11.7 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@2.1.5(@edge-runtime/vm@4.0.4)(@types/node@22.13.5)(happy-dom@15.11.7)(lightningcss@1.29.1)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(terser@5.38.2): dependencies: '@vitest/expect': 2.1.5