UNPKG

multibridge

Version:

A multi-database connection framework with centralized configuration

124 lines (123 loc) 4.77 kB
"use strict"; /** * Mongoose adapter for MultiBridge * Supports: MongoDB */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMongooseConnection = getMongooseConnection; exports.closeMongooseConnection = closeMongooseConnection; exports.closeAllMongooseConnections = closeAllMongooseConnections; const mongoose_1 = __importDefault(require("mongoose")); const base_1 = require("./base"); const loggers_1 = __importDefault(require("../utils/loggers")); const errors_1 = require("../utils/errors"); // Cache for Mongoose connections per tenant const mongooseConnections = new Map(); /** * Get or create a Mongoose connection for the current tenant * * @param options - Optional Mongoose connection options * @returns Mongoose connection instance configured for the current tenant * * @example * ```typescript * await runWithTenant(tenant, async () => { * const connection = await getMongooseConnection(); * const User = connection.model('User', userSchema); * await User.find(); * }); * ``` */ async function getMongooseConnection(options) { const { tenant, connectionData, dbType } = await (0, base_1.getTenantConnection)(); // Validate database type (0, base_1.validateORMSupport)(dbType, ["mongodb"]); const cacheKey = `${tenant.appid}-${tenant.orgid}-${tenant.appdbname}`; // Check cache const cached = mongooseConnections.get(cacheKey); if (cached && cached.readyState === 1) { loggers_1.default.debug(`Reusing cached Mongoose connection for ${cacheKey}`); return cached; } // Get database configuration to build connection string const { dbConfig } = await (0, base_1.getTenantDBConfig)(); const database = tenant.appdbname; // Build MongoDB connection string from config let connectionString; if (dbConfig.host.endsWith(".mongodb.net")) { // MongoDB Atlas (Cluster) using SRV connectionString = `mongodb+srv://${dbConfig.username}:${dbConfig.password}@${dbConfig.host}/${database}?authSource=admin`; } else { // Self-hosted MongoDB (Local/Remote) connectionString = `mongodb://${dbConfig.username}:${dbConfig.password}@${dbConfig.host}:${dbConfig.port}/${database}?authSource=admin`; } // Create Mongoose connection const mongooseConnection = mongoose_1.default.createConnection(connectionString, { dbName: database, ...options, }); // Wait for connection to be ready with timeout await new Promise((resolve, reject) => { const timeout = setTimeout(() => { reject(new errors_1.ConnectionError("Mongoose connection timeout", { cacheKey })); }, 10000); // 10 second timeout const cleanup = () => { clearTimeout(timeout); mongooseConnection.removeListener("connected", onConnected); mongooseConnection.removeListener("error", onError); }; const onConnected = () => { cleanup(); resolve(); }; const onError = (error) => { cleanup(); reject(error); }; mongooseConnection.once("connected", onConnected); mongooseConnection.once("error", onError); // If already connected, resolve immediately if (mongooseConnection.readyState === 1) { cleanup(); resolve(); } }); // Cache the connection mongooseConnections.set(cacheKey, mongooseConnection); loggers_1.default.info(`Created Mongoose connection for ${cacheKey}`, { dbType, database, }); return mongooseConnection; } /** * Close Mongoose connection for a specific tenant */ async function closeMongooseConnection(tenant) { if (!tenant) { const { tenant: currentTenant } = await (0, base_1.getTenantConnection)(); tenant = currentTenant; } const cacheKey = `${tenant.appid}-${tenant.orgid}-${tenant.appdbname}`; const connection = mongooseConnections.get(cacheKey); if (connection) { await connection.close(); mongooseConnections.delete(cacheKey); loggers_1.default.debug(`Closed Mongoose connection for ${cacheKey}`); } } /** * Close all Mongoose connections */ async function closeAllMongooseConnections() { const closePromises = Array.from(mongooseConnections.values()).map((conn) => conn.close().catch((error) => { loggers_1.default.warn(`Error closing Mongoose connection: ${error.message}`); })); await Promise.all(closePromises); mongooseConnections.clear(); loggers_1.default.info("All Mongoose connections closed"); }