UNPKG

mongodb-rag-core

Version:

Common elements used by MongoDB Chatbot Framework components.

80 lines 2.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.executeMongoshQuery = void 0; const mongodb_1 = require("mongodb"); const child_process_1 = require("child_process"); const util_1 = require("util"); const redactMongoDbConnectionUri_1 = require("./redactMongoDbConnectionUri"); const execAsync = (0, util_1.promisify)(child_process_1.exec); /** Executes MongoDB query using `mongosh` CLI. Note that Mongosh must be installed on the system running this function for it to successfully execute. */ const executeMongoshQuery = async ({ query, uri, databaseName, execOptions, }) => { let result = null; let error = undefined; let executionTimeMs = null; try { const connectionUrl = new URL(uri); connectionUrl.pathname = databaseName; const startTime = Date.now(); const modifiedQuery = appendToArrayIfNeeded(query); const escapedQuery = modifiedQuery.replace(/'/g, "'\\''"); const { stdout, stderr } = await execAsync(`mongosh "${connectionUrl.toString()}" --quiet --json=relaxed --eval '${escapedQuery}'`, { maxBuffer: 1024 * 1024 * 30, // 30 MB timeout: 30000, ...execOptions, }); const endTime = Date.now(); executionTimeMs = endTime - startTime; if (stderr && stderr.trim()) { error = { message: stderr.trim() }; executionTimeMs = null; } else if (stdout.trim()) { try { result = mongodb_1.BSON.EJSON.parse(stdout.trim(), { relaxed: true }); } catch (parseError) { error = { message: `Failed to parse mongosh output: ${parseError.message}`, }; executionTimeMs = null; } } } catch (execError) { error = { message: execError.message || "Failed to execute mongosh command", }; } // Redact any MongoDB connection URIs in error messages if (error && error.message) { error.message = (0, redactMongoDbConnectionUri_1.redactMongoDbConnectionUri)(error.message); } const data = { result, executionTimeMs, error, }; return data; }; exports.executeMongoshQuery = executeMongoshQuery; /** Append .toArray() to cursor-returning operations if not already present. */ function appendToArrayIfNeeded(query) { query = query.trim(); // Don't add .toArray() if .explain() is present or .toArray() already exists if (query.includes(".explain(") || query.includes(".toArray()")) { return query; } // Regex to match cursor-returning operations const cursorReturningOperations = /(db\.\w+\.(find|aggregate|listCollections|listIndexes)\()/; if (cursorReturningOperations.test(query)) { return query.replace(/\)\s*;?$/, ").toArray();"); } return query; } //# sourceMappingURL=executeMongoshQuery.js.map