diff --git a/libs/langchain-community/package.json b/libs/langchain-community/package.json index 7b826ad1e106..9220f5723b45 100644 --- a/libs/langchain-community/package.json +++ b/libs/langchain-community/package.json @@ -116,6 +116,7 @@ "@types/d3-dsv": "^3.0.7", "@types/flat": "^5.0.2", "@types/html-to-text": "^9", + "@types/jest": "^29.5.14", "@types/jsdom": "^21.1.1", "@types/jsonwebtoken": "^9", "@types/lodash": "^4", @@ -178,7 +179,7 @@ "interface-datastore": "^8.2.11", "ioredis": "^5.3.2", "it-all": "^3.0.4", - "jest": "^29.5.0", + "jest": "^29.7.0", "jest-environment-node": "^29.6.4", "jsdom": "^22.1.0", "jsonwebtoken": "^9.0.2", @@ -208,7 +209,7 @@ "rollup": "^3.19.1", "sonix-speech-recognition": "^2.1.1", "srt-parser-2": "^1.2.3", - "ts-jest": "^29.1.0", + "ts-jest": "^29.2.5", "typeorm": "^0.3.20", "typescript": "~5.1.6", "typesense": "^1.5.3", diff --git a/libs/langchain-community/src/document_loaders/tests/oracleai.test.ts b/libs/langchain-community/src/document_loaders/tests/oracleai.test.ts index 08f6500d7d5f..dad25a0b90ba 100644 --- a/libs/langchain-community/src/document_loaders/tests/oracleai.test.ts +++ b/libs/langchain-community/src/document_loaders/tests/oracleai.test.ts @@ -1,60 +1,65 @@ import { jest } from "@jest/globals"; -import { ParseOracleDocMetadata, OracleDocLoader, OracleLoadFromType } from "../web/oracleai.js"; +import { ParseOracleDocMetadata, OracleDocLoader, OracleLoadFromType, TableRow } from "../web/oracleai.js"; import oracledb from "oracledb"; describe("ParseOracleDocMetadata", () => { - let parser: ParseOracleDocMetadata; + jest.mock("oracledb"); + let parser: ParseOracleDocMetadata; - beforeEach(() => { - parser = new ParseOracleDocMetadata(); - }); + beforeEach(() => { + parser = new ParseOracleDocMetadata(); + }); - test("should parse title and meta tags correctly", () => { - const htmlString = "Sample Title"; - parser.parse(htmlString); - const metadata = parser.getMetadata(); - expect(metadata).toEqual({ - title: "Sample Title", - description: "Sample Content", - }); + test("should parse title and meta tags correctly", () => { + const htmlString = + "Sample Title"; + parser.parse(htmlString); + const metadata = parser.getMetadata(); + expect(metadata).toEqual({ + title: "Sample Title", + description: "Sample Content", }); + }); - test("should handle missing meta content gracefully", () => { - const htmlString = "Sample Title"; - parser.parse(htmlString); - const metadata = parser.getMetadata(); - expect(metadata).toEqual({ - title: "Sample Title", - description: "N/A", - }); + test("should handle missing meta content gracefully", () => { + const htmlString = + "Sample Title"; + parser.parse(htmlString); + const metadata = parser.getMetadata(); + expect(metadata).toEqual({ + title: "Sample Title", + description: "N/A", }); + }); - test("should handle multiple meta tags", () => { - const htmlString = "Sample Title"; - parser.parse(htmlString); - const metadata = parser.getMetadata(); - expect(metadata).toEqual({ - title: "Sample Title", - description: "Sample Content", - author: "John Doe", - }); + test("should handle multiple meta tags", () => { + const htmlString = + "Sample Title"; + parser.parse(htmlString); + const metadata = parser.getMetadata(); + expect(metadata).toEqual({ + title: "Sample Title", + description: "Sample Content", + author: "John Doe", }); + }); - test("should handle no title tag", () => { - const htmlString = ""; - parser.parse(htmlString); - const metadata = parser.getMetadata(); - expect(metadata).toEqual({ - description: "Sample Content", - }); + test("should handle no title tag", () => { + const htmlString = + ""; + parser.parse(htmlString); + const metadata = parser.getMetadata(); + expect(metadata).toEqual({ + description: "Sample Content", }); + }); - test("should handle empty html string", () => { - const htmlString = ""; - parser.parse(htmlString); - const metadata = parser.getMetadata(); - expect(metadata).toEqual({}); - }); + test("should handle empty html string", () => { + const htmlString = ""; + parser.parse(htmlString); + const metadata = parser.getMetadata(); + expect(metadata).toEqual({}); + }); }); describe("OracleDocLoader", () => { @@ -115,3 +120,352 @@ describe("OracleDocLoader", () => { } }); }); + +describe('OracleDocLoader - loadFromTable', () => { + let conn: Partial; + let executeMock: any; + + beforeEach(() => { + executeMock = jest.fn(); + conn = { + execute: executeMock, + }; + }); + + test('loadFromTable with valid parameters', async () => { + // Mock the execute method for the column type query + executeMock.mockResolvedValueOnce({ + rows: [ + { COLUMN_NAME: 'COL1', DATA_TYPE: 'VARCHAR2' }, + { COLUMN_NAME: 'COL2', DATA_TYPE: 'NUMBER' }, + { COLUMN_NAME: 'COL3', DATA_TYPE: 'DATE' }, + ], + } as oracledb.Result<{ COLUMN_NAME: string; DATA_TYPE: string }>); + + // Mock the execute method for getting username + executeMock.mockResolvedValueOnce({ + rows: [{ USER: 'TESTUSER' }], + } as oracledb.Result<{ USER: string }>); + + // Mock the execute method for the main query + executeMock.mockResolvedValueOnce({ + rows: [ + { + MDATA: { getData: jest.fn().mockImplementation( () => 'Title1' ) }, + TEXT: 'Text content 1', + ROWID: 'AAABBBCCC', + COL1: 'Value1', + COL2: 123, + COL3: new Date('2021-01-01'), + }, + { + MDATA: { getData: jest.fn().mockImplementation( () => 'Title2' ) }, + TEXT: 'Text content 2', + ROWID: 'AAABBBCCD', + COL1: 'Value2', + COL2: 456, + COL3: new Date('2021-02-01'), + }, + ], + }); + + const loader = new OracleDocLoader( + conn as oracledb.Connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + 'MYSCHEMA', + 'MYCOLUMN', + ['COL1', 'COL2', 'COL3'] + ); + + const documents = await loader.load(); + + expect(documents).toHaveLength(2); + + expect(documents[0].pageContent).toBe('Text content 1'); + expect(documents[0].metadata).toEqual({ + title: 'Title1', + author: 'Author1', + _oid: expect.any(String), + _rowid: 'AAABBBCCC', + COL1: 'Value1', + COL2: 123, + COL3: new Date('2021-01-01'), + }); + + expect(documents[1].pageContent).toBe('Text content 2'); + expect(documents[1].metadata).toEqual({ + title: 'Title2', + author: 'Author2', + _oid: expect.any(String), + _rowid: 'AAABBBCCD', + COL1: 'Value2', + COL2: 456, + COL3: new Date('2021-02-01'), + }); + }); + + test('loadFromTable with missing owner', async () => { + const loader = new OracleDocLoader( + conn as oracledb.Connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + undefined, // owner is missing + 'MYCOLUMN', + ['COL1'] + ); + + await expect(loader.load()).rejects.toThrow( + "Owner and column name must be specified for loading from a table" + ); + }); + + test('loadFromTable with missing column name', async () => { + const loader = new OracleDocLoader( + conn as oracledb.Connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + 'MYSCHEMA', + undefined, // column name is missing + ['COL1'] + ); + + await expect(loader.load()).rejects.toThrow( + "Owner and column name must be specified for loading from a table" + ); + }); + + test('loadFromTable with mdata_cols exceeding 3 columns', async () => { + const loader = new OracleDocLoader( + conn as oracledb.Connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + 'MYSCHEMA', + 'MYCOLUMN', + ['COL1', 'COL2', 'COL3', 'COL4'] // 4 columns, exceeding limit + ); + + await expect(loader.load()).rejects.toThrow( + "Exceeds the max number of columns you can request for metadata." + ); + }); + + test('loadFromTable with invalid column names in mdata_cols', async () => { + const loader = new OracleDocLoader( + conn as oracledb.Connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + 'MYSCHEMA', + 'MYCOLUMN', + ['INVALID-COL1'] // invalid column name + ); + + await expect(loader.load()).rejects.toThrow( + "Invalid column name in mdata_cols: INVALID-COL1" + ); + }); + + test('loadFromTable with mdata_cols containing unsupported data types', async () => { + // Mock the execute method for the column type query + executeMock.mockResolvedValueOnce({ + rows: [ + { COLUMN_NAME: 'COL1', DATA_TYPE: 'CLOB' }, // Unsupported data type + ], + } as oracledb.Result<{ COLUMN_NAME: string; DATA_TYPE: string }>); + + const loader = new OracleDocLoader( + conn as oracledb.Connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + 'MYSCHEMA', + 'MYCOLUMN', + ['COL1'] + ); + + await expect(loader.load()).rejects.toThrow( + 'The datatype for the column COL1 is not supported' + ); + }); + + test('loadFromTable with empty table', async () => { + // Mock the execute method for the column type query + executeMock.mockResolvedValueOnce({ + rows: [ + { COLUMN_NAME: 'COL1', DATA_TYPE: 'VARCHAR2' }, + ], + } as oracledb.Result<{ COLUMN_NAME: string; DATA_TYPE: string }>); + + // Mock the execute method for getting username + executeMock.mockResolvedValueOnce({ + rows: [{ USER: 'TESTUSER' }], + } as oracledb.Result<{ USER: string }>); + + // Mock the execute method for the main query (empty result set) + executeMock.mockResolvedValueOnce({ + rows: [], + } as oracledb.Result); + + const loader = new OracleDocLoader( + conn as oracledb.Connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + 'MYSCHEMA', + 'MYCOLUMN', + ['COL1'] + ); + + const documents = await loader.load(); + + expect(documents).toHaveLength(0); + }); + + test('loadFromTable with null column data', async () => { + // Mock the execute method for the column type query + executeMock.mockResolvedValueOnce({ + rows: [ + { COLUMN_NAME: 'COL1', DATA_TYPE: 'VARCHAR2' }, + ], + } as oracledb.Result<{ COLUMN_NAME: string; DATA_TYPE: string }>); + + // Mock the execute method for getting username + executeMock.mockResolvedValueOnce({ + rows: [{ USER: 'TESTUSER' }], + } as oracledb.Result<{ USER: string }>); + + // Mock the execute method for the main query with null TEXT and MDATA + executeMock.mockResolvedValueOnce({ + rows: [ + { + MDATA: null, + TEXT: null, + ROWID: 'AAABBBCCC', + COL1: 'Value1', + }, + ], + } as oracledb.Result); + + const loader = new OracleDocLoader( + conn as oracledb.Connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + 'MYSCHEMA', + 'MYCOLUMN', + ['COL1'] + ); + + const documents = await loader.load(); + + expect(documents).toHaveLength(1); + + expect(documents[0].pageContent).toBe(''); + expect(documents[0].metadata).toEqual({ + _oid: expect.any(String), + _rowid: 'AAABBBCCC', + COL1: 'Value1', + }); + }); + }); + + describe('OracleDocLoader - Integration Tests', () => { + let connection: oracledb.Connection; + const expectedDate1 = new Date('2021-01-01') + const expectedDate2 = new Date('2021-02-01') + + beforeAll(async () => { + try { + // Create a connection pool or a single connection + connection = await oracledb.getConnection({ + user: 'myuser', + password: 'mypassword', + connectString: 'localhost:1521/FREEPDB1', + }); + + // Drop the table if it exists + try { + await connection.execute(`DROP TABLE MYTABLE PURGE`); + } catch (err: any) { + // If the table doesn't exist, ignore the error + if (err.errorNum !== 942) { + // ORA-00942: table or view does not exist + throw err; + } + } + + // Set up the database schema and data + await connection.execute(` + CREATE TABLE MYTABLE ( + ID NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + MYCOLUMN CLOB, + COL1 VARCHAR2(100), + COL2 NUMBER, + COL3 DATE + ) + `); + + await connection.execute(` + INSERT INTO MYTABLE (MYCOLUMN, COL1, COL2, COL3) VALUES ( + 'Title1', + 'Value1', + 123, + :date1 + ) + `, {date1: expectedDate1}); + + await connection.execute(` + INSERT INTO MYTABLE (MYCOLUMN, COL1, COL2, COL3) VALUES ( + 'Title2', + 'Value2', + 456, + :date2 + ) + `, {date2: expectedDate2}); + + await connection.commit(); + } catch (err) { + console.error('Error during setup:', err); + throw err; // Rethrow the error to fail the tests if setup fails + } + }); + + afterAll(async () => { + try { + // Clean up the database + await connection.execute(`DROP TABLE MYTABLE PURGE`); + await connection.close(); + } catch (err) { + console.error('Error during teardown:', err); + // You might choose to ignore errors during teardown + } + }); + + test('loadFromTable with actual database connection', async () => { + const loader = new OracleDocLoader( + connection, + 'MYTABLE', + OracleLoadFromType.TABLE, + 'MYUSER', // Schema owner, replace with your actual username + 'MYCOLUMN', + ['COL1', 'COL2', 'COL3'] + ); + + const documents = await loader.load(); + + expect(documents).toHaveLength(2); + + expect(documents[0].metadata).toMatchObject({ + title: 'Title1', + author: 'Author1', + COL1: 'Value1', + COL2: 123, + COL3: expectedDate1, + }); + + expect(documents[1].metadata).toMatchObject({ + title: 'Title2', + author: 'Author2', + COL1: 'Value2', + COL2: 456, + COL3: expectedDate2, + }); + }); + }); \ No newline at end of file diff --git a/libs/langchain-community/src/document_loaders/tests/oracleaiDB.test.js b/libs/langchain-community/src/document_loaders/tests/oracleaiDB.test.js new file mode 100644 index 000000000000..85d83e3c01c4 --- /dev/null +++ b/libs/langchain-community/src/document_loaders/tests/oracleaiDB.test.js @@ -0,0 +1,26 @@ +import oracledb from 'oracledb'; + +async function testConnection() { + try { + const connection = await oracledb.getConnection({ + user: 'myuser', // Replace with your actual username + password: 'mypassword', // Replace with your actual password + connectString: 'localhost:1521/FREEPDB1', + }); + console.log('Connection successful!'); + + // Execute a query against your table + const result = await connection.execute(` + SELECT ID, MYCOLUMN, COL1, COL2, COL3 + FROM MYTABLE + `); + + console.log('Query result:', result.rows); + + await connection.close(); + } catch (err) { + console.error('Connection failed:', err); + } +} + +testConnection(); diff --git a/libs/langchain-community/src/document_loaders/web/oracleai.ts b/libs/langchain-community/src/document_loaders/web/oracleai.ts index 0874c3d82842..2044e6b2ac0d 100644 --- a/libs/langchain-community/src/document_loaders/web/oracleai.ts +++ b/libs/langchain-community/src/document_loaders/web/oracleai.ts @@ -17,6 +17,13 @@ interface OutBinds { text: oracledb.Lob | null; } +export interface TableRow { + MDATA?: string | null; + TEXT?: string | null; + ROWID?: string; + [key: string]: any; +} + export class ParseOracleDocMetadata { private metadata: Metadata; private match: boolean; @@ -215,15 +222,17 @@ export class OracleDocLoader extends BaseDocumentLoader { private loadFromType: OracleLoadFromType; private owner?: string; private colname?: string; + private mdata_cols?: string[]; constructor(conn: oracledb.Connection, loadFrom: string, loadFromType: OracleLoadFromType, - owner?: string, colname?: string) { + owner?: string, colname?: string, mdata_cols?: string[]) { super(); this.conn = conn; this.loadFrom = loadFrom; this.loadFromType = loadFromType; this.owner = owner; this.colname = colname; + this.mdata_cols = mdata_cols; } public async load(): Promise { @@ -258,10 +267,185 @@ export class OracleDocLoader extends BaseDocumentLoader { break; case OracleLoadFromType.TABLE: - + return await this.loadFromTable(m_params); default: throw new Error("Invalid type to load from"); } return documents } + + private isValidIdentifier(identifier: string): boolean { + return /^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier); + } + + private async getUsername(): Promise { + const result = await this.conn.execute<{ USER: string }>('SELECT USER FROM dual'); + return (result.rows?.[0]?.USER) || "unknown_user"; + } + + + private async loadFromTable(m_params: any): Promise { + const results: Document[] = []; + try { + if (!this.owner || !this.colname) { + throw new Error("Owner and column name must be specified for loading from a table"); + } + + // Validate identifiers to prevent SQL injection + if (!this.isValidIdentifier(this.owner)) { + throw new Error("Invalid owner name"); + } + + if (!this.isValidIdentifier(this.loadFrom)) { + throw new Error("Invalid table name"); + } + + if (!this.isValidIdentifier(this.colname)) { + throw new Error("Invalid column name"); + } + + let mdataColsSql = ", t.ROWID"; + + if (this.mdata_cols) { + if (this.mdata_cols.length > 3) { + throw new Error("Exceeds the max number of columns you can request for metadata."); + } + + // **First, check if the column names are valid identifiers** + for (const col of this.mdata_cols) { + if (!this.isValidIdentifier(col)) { + throw new Error(`Invalid column name in mdata_cols: ${col}`); + } + } + + // Execute a query to get column data types + const colSql = ` + SELECT COLUMN_NAME, DATA_TYPE + FROM ALL_TAB_COLUMNS + WHERE OWNER = :ownername AND TABLE_NAME = :tablename + `; + + const colBinds = { + ownername: this.owner.toUpperCase(), + tablename: this.loadFrom.toUpperCase(), + }; + + const colResult = await this.conn.execute<{ COLUMN_NAME: string; DATA_TYPE: string }>( + colSql, + colBinds, + { outFormat: oracledb.OUT_FORMAT_OBJECT } + ); + + const colRows = colResult.rows; + + if (!colRows) { + throw new Error("Failed to retrieve column information"); + } + + const colTypes: Record = {}; + for (const row of colRows) { + const colName = row.COLUMN_NAME; + const dataType = row.DATA_TYPE; + colTypes[colName] = dataType; + } + + for (const col of this.mdata_cols) { + if (!this.isValidIdentifier(col)) { + throw new Error(`Invalid column name in mdata_cols: ${col}`); + } + + const dataType = colTypes[col]; + if (!dataType) { + throw new Error(`Column ${col} not found in table ${this.loadFrom}`); + } + + if ( + ![ + "NUMBER", + "BINARY_DOUBLE", + "BINARY_FLOAT", + "LONG", + "DATE", + "TIMESTAMP", + "VARCHAR2", + ].includes(dataType) + ) { + throw new Error(`The datatype for the column ${col} is not supported`); + } + } + + for (const col of this.mdata_cols) { + mdataColsSql += `, t.${col}`; + } + } + + const mainSql = ` + SELECT dbms_vector_chain.utl_to_text(t.${this.colname}, json(:params)) AS MDATA, + dbms_vector_chain.utl_to_text(t.${this.colname}) AS TEXT + ${mdataColsSql} + FROM ${this.owner}.${this.loadFrom} t + `; + + const mainBinds = { + params: JSON.stringify(m_params), + }; + + const options = { + outFormat: oracledb.OUT_FORMAT_OBJECT, + }; + + // Get the username + const userResult = await this.conn.execute<{ USER: string }>('SELECT USER FROM dual'); + const username = userResult.rows?.[0]?.USER || "unknown_user"; + + // Execute the main SQL query + const result = await this.conn.execute(mainSql, mainBinds, options); + const rows = result.rows as TableRow[]; + + if (rows) { + for (const row of rows) { + let metadata: Record = {}; + + if (row["MDATA"]) { + const data = (await (row["MDATA"] as unknown as oracledb.Lob).getData()).toString(); + if ( + data.trim().startsWith("") + ) { + const parser = new ParseOracleDocMetadata(); + parser.parse(data); + metadata = { ...metadata, ...parser.getMetadata() }; + } + } + + const docId = OracleDocReader.generateObjectId( + `${username}$${this.owner}$${this.loadFrom}$${this.colname}$${row["ROWID"]}` + ); + + metadata["_oid"] = docId; + metadata["_rowid"] = row["ROWID"]; + + if (this.mdata_cols) { + for (const colName of this.mdata_cols) { + metadata[colName] = row[colName]; + } + } + + const text = row["TEXT"] as string; + + if (text === null || text === undefined) { + results.push(new Document({ pageContent: "", metadata })); + } else { + results.push(new Document({ pageContent: text, metadata })); + } + } + } + + return results; + } catch (ex) { + console.error(`An exception occurred: ${ex}`); + throw ex; + } + } + } diff --git a/package.json b/package.json index d647515dcbcf..09f148fa452c 100644 --- a/package.json +++ b/package.json @@ -46,13 +46,16 @@ "license": "MIT", "devDependencies": { "@tsconfig/recommended": "^1.0.2", - "@types/jest": "^29.5.3", + "@types/jest": "^29.5.14", + "@types/oracledb": "^6", "@types/semver": "^7", "commander": "^11.1.0", "dotenv": "^16.0.3", + "jest": "^29.7.0", "lint-staged": "^13.1.1", "prettier": "^2.8.3", "semver": "^7.5.4", + "ts-jest": "^29.2.5", "turbo": "^1.13.3", "typescript": "~5.1.6" }, @@ -69,5 +72,8 @@ "eslint --cache --fix" ], "*.md": "prettier --config .prettierrc --write" + }, + "dependencies": { + "oracledb": "^6.7.0" } } diff --git a/yarn.lock b/yarn.lock index 5e6b6ed60a57..5d565c6d8c9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11758,6 +11758,7 @@ __metadata: "@types/d3-dsv": ^3.0.7 "@types/flat": ^5.0.2 "@types/html-to-text": ^9 + "@types/jest": ^29.5.14 "@types/jsdom": ^21.1.1 "@types/jsonwebtoken": ^9 "@types/lodash": ^4 @@ -11823,7 +11824,7 @@ __metadata: interface-datastore: ^8.2.11 ioredis: ^5.3.2 it-all: ^3.0.4 - jest: ^29.5.0 + jest: ^29.7.0 jest-environment-node: ^29.6.4 js-yaml: ^4.1.0 jsdom: ^22.1.0 @@ -11856,7 +11857,7 @@ __metadata: rollup: ^3.19.1 sonix-speech-recognition: ^2.1.1 srt-parser-2: ^1.2.3 - ts-jest: ^29.1.0 + ts-jest: ^29.2.5 typeorm: ^0.3.20 typescript: ~5.1.6 typesense: ^1.5.3 @@ -19312,13 +19313,13 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:^29.5.3": - version: 29.5.3 - resolution: "@types/jest@npm:29.5.3" +"@types/jest@npm:^29.5.14": + version: 29.5.14 + resolution: "@types/jest@npm:29.5.14" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: e36bb92e0b9e5ea7d6f8832baa42f087fc1697f6cd30ec309a07ea4c268e06ec460f1f0cfd2581daf5eff5763475190ec1ad8ac6520c49ccfe4f5c0a48bfa676 + checksum: 18dba4623f26661641d757c63da2db45e9524c9be96a29ef713c703a9a53792df9ecee9f7365a0858ddbd6440d98fe6b65ca67895ca5884b73cbc7ffc11f3838 languageName: node linkType: hard @@ -19614,6 +19615,15 @@ __metadata: languageName: node linkType: hard +"@types/oracledb@npm:^6": + version: 6.5.2 + resolution: "@types/oracledb@npm:6.5.2" + dependencies: + "@types/node": "*" + checksum: 02abec363e8ca1455310e930826095461c2b1e01ca7031aed99f5f0a029ee236a0a4df9c5e6d97e8757ef8e3e8531a1ce906cd65636acf355e72527bb96d4003 + languageName: node + linkType: hard + "@types/pad-left@npm:2.1.1": version: 2.1.1 resolution: "@types/pad-left@npm:2.1.1" @@ -22519,7 +22529,7 @@ __metadata: languageName: node linkType: hard -"bs-logger@npm:0.x": +"bs-logger@npm:0.x, bs-logger@npm:^0.2.6": version: 0.2.6 resolution: "bs-logger@npm:0.2.6" dependencies: @@ -22969,7 +22979,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2": +"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -25973,6 +25983,17 @@ __metadata: languageName: node linkType: hard +"ejs@npm:^3.1.10": + version: 3.1.10 + resolution: "ejs@npm:3.1.10" + dependencies: + jake: ^10.8.5 + bin: + ejs: bin/cli.js + checksum: ce90637e9c7538663ae023b8a7a380b2ef7cc4096de70be85abf5a3b9641912dde65353211d05e24d56b1f242d71185c6d00e02cb8860701d571786d92c71f05 + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.4.284": version: 1.4.322 resolution: "electron-to-chromium@npm:1.4.322" @@ -31981,6 +32002,20 @@ __metadata: languageName: node linkType: hard +"jake@npm:^10.8.5": + version: 10.9.2 + resolution: "jake@npm:10.9.2" + dependencies: + async: ^3.2.3 + chalk: ^4.0.2 + filelist: ^1.0.4 + minimatch: ^3.1.2 + bin: + jake: bin/cli.js + checksum: f2dc4a086b4f58446d02cb9be913c39710d9ea570218d7681bb861f7eeaecab7b458256c946aeaa7e548c5e0686cc293e6435501e4047174a3b6a504dcbfcaae + languageName: node + linkType: hard + "javascript-stringify@npm:^2.0.1": version: 2.1.0 resolution: "javascript-stringify@npm:2.1.0" @@ -32724,7 +32759,7 @@ __metadata: languageName: node linkType: hard -"jest@npm:^29.5.0": +"jest@npm:^29.5.0, jest@npm:^29.7.0": version: 29.7.0 resolution: "jest@npm:29.7.0" dependencies: @@ -33396,13 +33431,17 @@ __metadata: resolution: "langchainjs@workspace:." dependencies: "@tsconfig/recommended": ^1.0.2 - "@types/jest": ^29.5.3 + "@types/jest": ^29.5.14 + "@types/oracledb": ^6 "@types/semver": ^7 commander: ^11.1.0 dotenv: ^16.0.3 + jest: ^29.7.0 lint-staged: ^13.1.1 + oracledb: ^6.7.0 prettier: ^2.8.3 semver: ^7.5.4 + ts-jest: ^29.2.5 turbo: ^1.13.3 typescript: ~5.1.6 languageName: unknown @@ -34245,7 +34284,7 @@ __metadata: languageName: node linkType: hard -"make-error@npm:1.x": +"make-error@npm:1.x, make-error@npm:^1.3.6": version: 1.3.6 resolution: "make-error@npm:1.3.6" checksum: b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 @@ -36375,6 +36414,13 @@ __metadata: languageName: node linkType: hard +"oracledb@npm:^6.7.0": + version: 6.7.0 + resolution: "oracledb@npm:6.7.0" + checksum: f4424e30afc85256a09a23a0772e59ce551a6cbc9d12559d572a944e1278d9420fc537b5783617955e187904a6f6319ed58ef8ae7319253cdcebb01a15d8250a + languageName: node + linkType: hard + "os-name@npm:5.1.0": version: 5.1.0 resolution: "os-name@npm:5.1.0" @@ -42062,6 +42108,43 @@ __metadata: languageName: node linkType: hard +"ts-jest@npm:^29.2.5": + version: 29.2.5 + resolution: "ts-jest@npm:29.2.5" + dependencies: + bs-logger: ^0.2.6 + ejs: ^3.1.10 + fast-json-stable-stringify: ^2.1.0 + jest-util: ^29.0.0 + json5: ^2.2.3 + lodash.memoize: ^4.1.2 + make-error: ^1.3.6 + semver: ^7.6.3 + yargs-parser: ^21.1.1 + peerDependencies: + "@babel/core": ">=7.0.0-beta.0 <8" + "@jest/transform": ^29.0.0 + "@jest/types": ^29.0.0 + babel-jest: ^29.0.0 + jest: ^29.0.0 + typescript: ">=4.3 <6" + peerDependenciesMeta: + "@babel/core": + optional: true + "@jest/transform": + optional: true + "@jest/types": + optional: true + babel-jest: + optional: true + esbuild: + optional: true + bin: + ts-jest: cli.js + checksum: d60d1e1d80936f6002b1bb27f7e062408bc733141b9d666565503f023c340a3196d506c836a4316c5793af81a5f910ab49bb9c13f66e2dc66de4e0f03851dbca + languageName: node + linkType: hard + "ts-md5@npm:^1.3.1": version: 1.3.1 resolution: "ts-md5@npm:1.3.1"