diff --git a/JS/edgechains/arakoodev/src/vector-db/src/index.ts b/JS/edgechains/arakoodev/src/vector-db/src/index.ts index 557104a14..e68d60f2d 100644 --- a/JS/edgechains/arakoodev/src/vector-db/src/index.ts +++ b/JS/edgechains/arakoodev/src/vector-db/src/index.ts @@ -1 +1,2 @@ export { Supabase } from "./lib/supabase/supabase.js"; +export { Qdrant } from "./lib/qdrant/qdrant.js"; diff --git a/JS/edgechains/arakoodev/src/vector-db/src/lib/qdrant/qdrant.ts b/JS/edgechains/arakoodev/src/vector-db/src/lib/qdrant/qdrant.ts new file mode 100644 index 000000000..30fcfc2e8 --- /dev/null +++ b/JS/edgechains/arakoodev/src/vector-db/src/lib/qdrant/qdrant.ts @@ -0,0 +1,274 @@ +import retry from "retry"; +import { config } from "dotenv"; +config(); + +type QdrantPointId = string | number; +type QdrantPayload = Record; +type QdrantVector = number[] | Record; +type QdrantFilter = Record; + +interface QdrantPoint { + id: QdrantPointId; + vector: QdrantVector; + payload?: QdrantPayload; +} + +interface QdrantRequestArgs { + body?: any; + method?: "GET" | "POST" | "PUT" | "DELETE"; + path: string; + query?: Record; +} + +interface CreateCollectionArgs { + collectionName: string; + distance?: "Cosine" | "Dot" | "Euclid" | "Manhattan"; + onDisk?: boolean; + vectorName?: string; + vectorSize: number; +} + +interface InsertVectorDataArgs { + collectionName: string; + points: QdrantPoint[]; + wait?: boolean; +} + +interface GetDataFromQueryArgs { + collectionName: string; + filter?: QdrantFilter; + limit?: number; + scoreThreshold?: number; + vector: QdrantVector; + withPayload?: boolean | string[] | Record; + withVector?: boolean | string[]; +} + +interface GetDataArgs { + collectionName: string; + filter?: QdrantFilter; + limit?: number; + offset?: QdrantPointId | Record; + withPayload?: boolean | string[] | Record; + withVector?: boolean | string[]; +} + +export class Qdrant { + QDRANT_URL: string; + QDRANT_API_KEY?: string; + + constructor(QDRANT_URL?: string, QDRANT_API_KEY?: string) { + this.QDRANT_URL = (QDRANT_URL || process.env.QDRANT_URL || "").replace(/\/+$/, ""); + this.QDRANT_API_KEY = QDRANT_API_KEY || process.env.QDRANT_API_KEY; + } + + async createCollection({ + collectionName, + distance = "Cosine", + onDisk, + vectorName, + vectorSize, + }: CreateCollectionArgs): Promise { + const vectorConfig = { + distance, + on_disk: onDisk, + size: vectorSize, + }; + + return this.request({ + body: { + vectors: vectorName ? { [vectorName]: vectorConfig } : vectorConfig, + }, + method: "PUT", + path: `/collections/${encodeURIComponent(collectionName)}`, + }); + } + + async deleteCollection({ collectionName }: { collectionName: string }): Promise { + return this.request({ + method: "DELETE", + path: `/collections/${encodeURIComponent(collectionName)}`, + }); + } + + async insertVectorData({ collectionName, points, wait = true }: InsertVectorDataArgs): Promise { + return this.request({ + body: { points }, + method: "PUT", + path: `/collections/${encodeURIComponent(collectionName)}/points`, + query: { wait }, + }); + } + + async getDataFromQuery({ + collectionName, + filter, + limit = 10, + scoreThreshold, + vector, + withPayload = true, + withVector = false, + }: GetDataFromQueryArgs): Promise { + return this.request({ + body: { + filter, + limit, + score_threshold: scoreThreshold, + vector, + with_payload: withPayload, + with_vector: withVector, + }, + method: "POST", + path: `/collections/${encodeURIComponent(collectionName)}/points/search`, + }); + } + + async getData({ + collectionName, + filter, + limit = 10, + offset, + withPayload = true, + withVector = false, + }: GetDataArgs): Promise { + return this.request({ + body: { + filter, + limit, + offset, + with_payload: withPayload, + with_vector: withVector, + }, + method: "POST", + path: `/collections/${encodeURIComponent(collectionName)}/points/scroll`, + }); + } + + async getDataById({ + collectionName, + id, + withPayload = true, + withVector = false, + }: { + collectionName: string; + id: QdrantPointId; + withPayload?: boolean | string[] | Record; + withVector?: boolean | string[]; + }): Promise { + const result = await this.request({ + body: { + ids: [id], + with_payload: withPayload, + with_vector: withVector, + }, + method: "POST", + path: `/collections/${encodeURIComponent(collectionName)}/points`, + }); + + return Array.isArray(result) ? result[0] || null : result; + } + + async updateById({ + collectionName, + id, + payload, + wait = true, + }: { + collectionName: string; + id: QdrantPointId; + payload: QdrantPayload; + wait?: boolean; + }): Promise { + return this.request({ + body: { + payload, + points: [id], + }, + method: "PUT", + path: `/collections/${encodeURIComponent(collectionName)}/points/payload`, + query: { wait }, + }); + } + + async deleteById({ + collectionName, + id, + wait = true, + }: { + collectionName: string; + id: QdrantPointId; + wait?: boolean; + }): Promise { + return this.request({ + body: { points: [id] }, + method: "POST", + path: `/collections/${encodeURIComponent(collectionName)}/points/delete`, + query: { wait }, + }); + } + + async request({ body, method = "GET", path, query }: QdrantRequestArgs): Promise { + if (!this.QDRANT_URL) { + throw new Error("QDRANT_URL is required"); + } + + return new Promise((resolve, reject) => { + const operation = retry.operation({ + factor: 3, + maxTimeout: 60 * 1000, + minTimeout: 1 * 1000, + randomize: true, + retries: 5, + }); + + operation.attempt(async () => { + try { + const response = await fetch(this.buildUrl(path, query), { + body: body === undefined ? undefined : JSON.stringify(body), + headers: this.createHeaders(body), + method, + }); + const text = await response.text(); + const data = text ? JSON.parse(text) : {}; + + if (!response.ok) { + const errorMessage = data?.status?.error || data?.message || response.statusText; + if (operation.retry(new Error(errorMessage))) { + return; + } + reject(new Error(`Qdrant request failed: ${errorMessage}`)); + return; + } + + resolve(data?.result ?? data); + } catch (error: any) { + if (operation.retry(error)) { + return; + } + reject(error); + } + }); + }); + } + + private buildUrl(path: string, query?: Record) { + const url = new URL(`${this.QDRANT_URL}${path}`); + Object.entries(query || {}).forEach(([key, value]) => { + if (value !== undefined) { + url.searchParams.set(key, String(value)); + } + }); + return url.toString(); + } + + private createHeaders(body: any) { + const headers: Record = {}; + if (body !== undefined) { + headers["content-type"] = "application/json"; + } + if (this.QDRANT_API_KEY) { + headers["api-key"] = this.QDRANT_API_KEY; + } + return headers; + } +} diff --git a/JS/edgechains/arakoodev/src/vector-db/src/tests/qdrant/qdrant.test.ts b/JS/edgechains/arakoodev/src/vector-db/src/tests/qdrant/qdrant.test.ts new file mode 100644 index 000000000..cc670a627 --- /dev/null +++ b/JS/edgechains/arakoodev/src/vector-db/src/tests/qdrant/qdrant.test.ts @@ -0,0 +1,98 @@ +import { describe, expect, it, vi, beforeEach, afterEach } from "vitest"; +import { Qdrant } from "../../lib/qdrant/qdrant.js"; + +const createFetchResponse = (body: any, ok = true) => + ({ + ok, + statusText: ok ? "OK" : "Bad Request", + text: vi.fn(async () => JSON.stringify(body)), + }) as any; + +describe("Qdrant", () => { + beforeEach(() => { + vi.stubGlobal("fetch", vi.fn(async () => createFetchResponse({ result: { status: "ok" } }))); + }); + + afterEach(() => { + vi.unstubAllGlobals(); + vi.clearAllMocks(); + }); + + it("creates a collection through the Qdrant REST API", async () => { + const qdrant = new Qdrant("https://qdrant.example.com", "api-key"); + + await qdrant.createCollection({ + collectionName: "documents", + distance: "Cosine", + vectorSize: 1536, + }); + + expect(fetch).toHaveBeenCalledWith("https://qdrant.example.com/collections/documents", { + body: JSON.stringify({ + vectors: { + distance: "Cosine", + size: 1536, + }, + }), + headers: { + "api-key": "api-key", + "content-type": "application/json", + }, + method: "PUT", + }); + }); + + it("inserts vector points without using a qdrant package", async () => { + const qdrant = new Qdrant("https://qdrant.example.com"); + + await qdrant.insertVectorData({ + collectionName: "documents", + points: [ + { + id: 1, + payload: { content: "hello" }, + vector: [0.1, 0.2, 0.3], + }, + ], + }); + + expect(fetch).toHaveBeenCalledWith("https://qdrant.example.com/collections/documents/points?wait=true", { + body: JSON.stringify({ + points: [ + { + id: 1, + payload: { content: "hello" }, + vector: [0.1, 0.2, 0.3], + }, + ], + }), + headers: { + "content-type": "application/json", + }, + method: "PUT", + }); + }); + + it("searches points with a vector query", async () => { + const qdrant = new Qdrant("https://qdrant.example.com"); + + await qdrant.getDataFromQuery({ + collectionName: "documents", + limit: 3, + vector: [0.1, 0.2, 0.3], + }); + + expect(fetch).toHaveBeenCalledWith("https://qdrant.example.com/collections/documents/points/search", { + body: JSON.stringify({ + limit: 3, + vector: [0.1, 0.2, 0.3], + with_payload: true, + with_vector: false, + }), + headers: { + "content-type": "application/json", + }, + method: "POST", + }); + }); +}); diff --git a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/deleteById.test.ts b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/deleteById.test.ts index aaf1d3dcd..e4cc865e3 100644 --- a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/deleteById.test.ts +++ b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/deleteById.test.ts @@ -1,45 +1,46 @@ +import { describe, expect, it, vi } from "vitest"; import { Supabase } from "../../../../../dist/vector-db/src/lib/supabase/supabase.js"; const MOCK_SUPABASE_API_KEY = "mock-api-key"; const MOCK_SUPABASE_URL = "https://mock-supabase.co"; // Mock the deleteById method of the Supabase class -jest.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { - return { - Supabase: jest.fn().mockImplementation(() => ({ - createClient: jest.fn(() => ({ - // Mock client methods - from: jest.fn().mockReturnThis(), - })), +vi.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { + return { + Supabase: vi.fn().mockImplementation(() => ({ + createClient: vi.fn(() => ({ + // Mock client methods + from: vi.fn().mockReturnThis(), + })), - deleteById: jest.fn().mockImplementation(async ({ client, tableName, id }) => { - // Mock response for a successful deletion - const mockResponse = { - status: 200, - message: "Deleted successfully", // Message indicating successful deletion - }; + deleteById: vi.fn().mockImplementation(async ({ client, tableName, id }) => { + // Mock response for a successful deletion + const mockResponse = { + status: 200, + message: "Deleted successfully", // Message indicating successful deletion + }; - // Return the mocked response - return mockResponse; - }), - })), - }; + // Return the mocked response + return mockResponse; + }), + })), + }; }); describe("deleteById", () => { - it("should delete data by id from the database", async () => { - let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); - const client = supabase.createClient(); - // Call the deleteById method with mock parameters - const res = await supabase.deleteById({ - client, // Mock client - tableName: "documents", - id: 549, // Id of the row to delete - }); + it("should delete data by id from the database", async () => { + let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); + const client = supabase.createClient(); + // Call the deleteById method with mock parameters + const res = await supabase.deleteById({ + client, // Mock client + tableName: "documents", + id: 549, // Id of the row to delete + }); - // Check if the response indicates successful deletion - expect(res).toEqual( - expect.objectContaining({ status: 200, message: "Deleted successfully" }) - ); - }); + // Check if the response indicates successful deletion + expect(res).toEqual( + expect.objectContaining({ status: 200, message: "Deleted successfully" }) + ); + }); }); diff --git a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getData.test.ts b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getData.test.ts index 1cf19cddf..1317e5dbc 100644 --- a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getData.test.ts +++ b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getData.test.ts @@ -1,37 +1,38 @@ +import { describe, expect, it, vi } from "vitest"; import { Supabase } from "../../../../../dist/vector-db/src/lib/supabase/supabase.js"; const MOCK_SUPABASE_API_KEY = "mock-api-key"; const MOCK_SUPABASE_URL = "https://mock-supabase.co"; // Mock the getDataFromQuery method of the Supabase class -jest.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { - return { - Supabase: jest.fn().mockImplementation(() => ({ - createClient: jest.fn(() => ({ - // Mock client methods - from: jest.fn().mockReturnThis(), - })), - getData: jest.fn().mockImplementation(async ({ client, tableName, columns }) => { - // Mock response data - const responseData = [{ id: 1, content: "Sample content" }]; +vi.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { + return { + Supabase: vi.fn().mockImplementation(() => ({ + createClient: vi.fn(() => ({ + // Mock client methods + from: vi.fn().mockReturnThis(), + })), + getData: vi.fn().mockImplementation(async ({ client, tableName, columns }) => { + // Mock response data + const responseData = [{ id: 1, content: "Sample content" }]; - // Return the mock response - return responseData; - }), - })), - }; + // Return the mock response + return responseData; + }), + })), + }; }); describe("Supabase getData method", () => { - it("should fetch data from the database", async () => { - let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); - const client = supabase.createClient(); + it("should fetch data from the database", async () => { + let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); + const client = supabase.createClient(); - // Call the getData method with mocked parameters - const tableName = "documents"; - const columns = "content"; - const result = await supabase.getData({ client, tableName, columns }); + // Call the getData method with mocked parameters + const tableName = "documents"; + const columns = "content"; + const result = await supabase.getData({ client, tableName, columns }); - // Check if the result matches the expected data - expect(result).toEqual([{ id: 1, content: "Sample content" }]); - }); + // Check if the result matches the expected data + expect(result).toEqual([{ id: 1, content: "Sample content" }]); + }); }); diff --git a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getDataById.test.ts b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getDataById.test.ts index 877561eea..77bbf3405 100644 --- a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getDataById.test.ts +++ b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getDataById.test.ts @@ -1,60 +1,61 @@ +import { describe, expect, it, vi } from "vitest"; import { Supabase } from "../../../../../dist/vector-db/src/lib/supabase/supabase.js"; const MOCK_SUPABASE_API_KEY = "mock-api-key"; const MOCK_SUPABASE_URL = "https://mock-supabase.co"; // Mock the getDataById method of the Supabase class -jest.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { - return { - Supabase: jest.fn().mockImplementation(() => ({ - createClient: jest.fn(() => ({ - // Mock client methods - from: jest.fn().mockReturnThis(), - })), - getDataById: jest.fn().mockImplementation(async ({ client, tableName, id }) => { - // Assuming 'id' corresponds to the index of the data in the mock data array - const mockData = [ - { id: 546, content: "Mocked content for id 546" }, - // Add more mock data as needed - ]; - - // Find the mock data corresponding to the provided id - const data = mockData.find((item) => item.id === id); - - if (data) { - return data; // Return the mock data - } else { - throw new Error(`Data with id ${id} not found`); // Throw an error if data not found - } - }), - })), - }; +vi.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { + return { + Supabase: vi.fn().mockImplementation(() => ({ + createClient: vi.fn(() => ({ + // Mock client methods + from: vi.fn().mockReturnThis(), + })), + getDataById: vi.fn().mockImplementation(async ({ client, tableName, id }) => { + // Assuming 'id' corresponds to the index of the data in the mock data array + const mockData = [ + { id: 546, content: "Mocked content for id 546" }, + // Add more mock data as needed + ]; + + // Find the mock data corresponding to the provided id + const data = mockData.find((item) => item.id === id); + + if (data) { + return data; // Return the mock data + } else { + throw new Error(`Data with id ${id} not found`); // Throw an error if data not found + } + }), + })), + }; }); let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); const client = supabase.createClient(); describe("getDataById", () => { - it("should fetch data by id from the database", async () => { - // Call the getDataById method - const res = await supabase.getDataById({ - client, // Mock client - tableName: "documents", - id: 546, // Id of the data to fetch + it("should fetch data by id from the database", async () => { + // Call the getDataById method + const res = await supabase.getDataById({ + client, // Mock client + tableName: "documents", + id: 546, // Id of the data to fetch + }); + + // Check if the fetched data matches the expected content + expect(res.content).toEqual("Mocked content for id 546"); }); - // Check if the fetched data matches the expected content - expect(res.content).toEqual("Mocked content for id 546"); - }); - - it("should throw an error if data with the provided id is not found", async () => { - // Call the getDataById method with an id that does not exist in the mock data - await expect( - supabase.getDataById({ - client, // Mock client - tableName: "documents", - id: 999, // Id of non-existent data - }) - ).rejects.toThrow("Data with id 999 not found"); // Expect the method to throw an error - }); + it("should throw an error if data with the provided id is not found", async () => { + // Call the getDataById method with an id that does not exist in the mock data + await expect( + supabase.getDataById({ + client, // Mock client + tableName: "documents", + id: 999, // Id of non-existent data + }) + ).rejects.toThrow("Data with id 999 not found"); // Expect the method to throw an error + }); }); diff --git a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getDataFromQuery.test.ts b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getDataFromQuery.test.ts index 2b6dae04b..8770774b1 100644 --- a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getDataFromQuery.test.ts +++ b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/getDataFromQuery.test.ts @@ -1,47 +1,48 @@ +import { describe, expect, it, vi } from "vitest"; import { Supabase } from "../../../../../dist/vector-db/src/lib/supabase/supabase.js"; const MOCK_SUPABASE_API_KEY = "mock-api-key"; const MOCK_SUPABASE_URL = "https://mock-supabase.co"; // Mock the getDataFromQuery method of the Supabase class -jest.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { - return { - Supabase: jest.fn().mockImplementation(() => ({ - createClient: jest.fn(() => ({ - // Mock client methods - from: jest.fn().mockReturnThis(), - })), - getDataFromQuery: jest - .fn() - .mockImplementation(async ({ client, functionNameToCall, args }) => { - // Mock response data - const responseData = { id: 1, content: "Hello, world!" }; +vi.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { + return { + Supabase: vi.fn().mockImplementation(() => ({ + createClient: vi.fn(() => ({ + // Mock client methods + from: vi.fn().mockReturnThis(), + })), + getDataFromQuery: vi + .fn() + .mockImplementation(async ({ client, functionNameToCall, args }) => { + // Mock response data + const responseData = { id: 1, content: "Hello, world!" }; - // Return the mock response - return responseData; - }), - })), - }; + // Return the mock response + return responseData; + }), + })), + }; }); describe("getDataFromQuery", () => { - it("should fetch data from the vector database", async () => { - const tableName = "documents"; - const columns = "content"; - const mockResponseData = { id: 1, content: "Hello, world!" }; + it("should fetch data from the vector database", async () => { + const tableName = "documents"; + const columns = "content"; + const mockResponseData = { id: 1, content: "Hello, world!" }; - let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); + let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); - const client = supabase.createClient(); - // Call the method that uses getDataFromQuery - const res = await supabase.getDataFromQuery({ - client, - functionNameToCall: "fetchData", - tableName, - columns, - }); + const client = supabase.createClient(); + // Call the method that uses getDataFromQuery + const res = await supabase.getDataFromQuery({ + client, + functionNameToCall: "fetchData", + tableName, + columns, + }); - // Expect the result to match the mock response data - expect(res).toEqual(mockResponseData); - }); + // Expect the result to match the mock response data + expect(res).toEqual(mockResponseData); + }); }); diff --git a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/insertVectorData.test.ts b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/insertVectorData.test.ts index 35f0fb053..7c25faab2 100644 --- a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/insertVectorData.test.ts +++ b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/insertVectorData.test.ts @@ -1,58 +1,59 @@ +import { expect, it, vi } from "vitest"; import { Supabase } from "../../../../../dist/vector-db/src/lib/supabase/supabase.js"; const MOCK_SUPABASE_API_KEY = "mock-api-key"; const MOCK_SUPABASE_URL = "https://mock-supabase.co"; // Mock the Supabase class to return a mock client -jest.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { - return { - Supabase: jest.fn().mockImplementation(() => ({ - createClient: jest.fn(() => ({ - // Mock client methods - from: jest.fn().mockReturnThis(), - })), - insertVectorData: jest - .fn() - .mockImplementation(async ({ tableName, content, embedding }) => { - // Assuming content is a string and embedding is an array of length 1536 - const mockResponse = { - tableName: tableName, - data: [ - { - content: content, - embedding: embedding, // Mock embedding vector - }, - ], - }; - return mockResponse; - }), - })), - }; +vi.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { + return { + Supabase: vi.fn().mockImplementation(() => ({ + createClient: vi.fn(() => ({ + // Mock client methods + from: vi.fn().mockReturnThis(), + })), + insertVectorData: vi + .fn() + .mockImplementation(async ({ tableName, content, embedding }) => { + // Assuming content is a string and embedding is an array of length 1536 + const mockResponse = { + tableName: tableName, + data: [ + { + content: content, + embedding: embedding, // Mock embedding vector + }, + ], + }; + return mockResponse; + }), + })), + }; }); it("should insert data into the database", async () => { - let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); - const client = supabase.createClient(); - const tableName = "test_table"; - const content = "test"; - // Insert data into the database - const result = await supabase.insertVectorData({ - client, - tableName, - content, - embedding: Array.from({ length: 1536 }, (_, i) => i), - }); + let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); + const client = supabase.createClient(); + const tableName = "test_table"; + const content = "test"; + // Insert data into the database + const result = await supabase.insertVectorData({ + client, + tableName, + content, + embedding: Array.from({ length: 1536 }, (_, i) => i), + }); - // Check if the insertion was successful - expect(result).toEqual( - expect.objectContaining({ - tableName: tableName, - data: expect.arrayContaining([ - expect.objectContaining({ - content, - embedding: expect.arrayContaining(Array.from({ length: 1536 }, (_, i) => i)), // Mocked embedding vector - }), - ]), - }) - ); + // Check if the insertion was successful + expect(result).toEqual( + expect.objectContaining({ + tableName: tableName, + data: expect.arrayContaining([ + expect.objectContaining({ + content, + embedding: expect.arrayContaining(Array.from({ length: 1536 }, (_, i) => i)), // Mocked embedding vector + }), + ]), + }) + ); }, 10000); diff --git a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/updateById.test.ts b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/updateById.test.ts index c759f5504..c361f34dc 100644 --- a/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/updateById.test.ts +++ b/JS/edgechains/arakoodev/src/vector-db/src/tests/supabase/updateById.test.ts @@ -1,48 +1,49 @@ +import { describe, expect, it, vi } from "vitest"; import { Supabase } from "../../../../../dist/vector-db/src/lib/supabase/supabase.js"; const MOCK_SUPABASE_API_KEY = "mock-api-key"; const MOCK_SUPABASE_URL = "https://mock-supabase.co"; // Mock the updateById method of the Supabase class -jest.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { - return { - Supabase: jest.fn().mockImplementation(() => ({ - createClient: jest.fn(() => ({ - // Mock client methods - from: jest.fn().mockReturnThis(), - })), +vi.mock("../../../../../dist/vector-db/src/lib/supabase/supabase.js", () => { + return { + Supabase: vi.fn().mockImplementation(() => ({ + createClient: vi.fn(() => ({ + // Mock client methods + from: vi.fn().mockReturnThis(), + })), - updateById: jest - .fn() - .mockImplementation(async ({ client, tableName, id, updatedContent }) => { - // Mock response for a successful update - const mockResponse = { - id: id, // Assuming the id remains the same after update - ...updatedContent, // Assuming updatedContent contains updated fields - }; + updateById: vi + .fn() + .mockImplementation(async ({ client, tableName, id, updatedContent }) => { + // Mock response for a successful update + const mockResponse = { + id: id, // Assuming the id remains the same after update + ...updatedContent, // Assuming updatedContent contains updated fields + }; - // Return the mocked response - return mockResponse; - }), - })), - }; + // Return the mocked response + return mockResponse; + }), + })), + }; }); describe("updateById", () => { - it("should update data by id in the database", async () => { - let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); - const client = supabase.createClient(); - // Call the updateById method with mock parameters - const updatedContent = { name: "Updated Name" }; // Assuming 'name' is one of the fields to update - const res = await supabase.updateById({ - client, // Mock client - tableName: "documents", - id: 546, // Id of the row to update - updatedContent: updatedContent, - }); + it("should update data by id in the database", async () => { + let supabase = new Supabase(MOCK_SUPABASE_URL, MOCK_SUPABASE_API_KEY); + const client = supabase.createClient(); + // Call the updateById method with mock parameters + const updatedContent = { name: "Updated Name" }; // Assuming 'name' is one of the fields to update + const res = await supabase.updateById({ + client, // Mock client + tableName: "documents", + id: 546, // Id of the row to update + updatedContent: updatedContent, + }); - // Check if the returned data matches the updated content - expect(res).toEqual(expect.objectContaining(updatedContent)); - }); + // Check if the returned data matches the updated content + expect(res).toEqual(expect.objectContaining(updatedContent)); + }); - // Add more test cases as needed, e.g., to test error handling + // Add more test cases as needed, e.g., to test error handling });