diff --git a/proto/src/lib/mongodb.test.ts b/proto/src/lib/mongodb.test.ts index 88f2554..9ad135e 100755 --- a/proto/src/lib/mongodb.test.ts +++ b/proto/src/lib/mongodb.test.ts @@ -32,6 +32,7 @@ const originalEnv = process.env describe('MongoDB Connection (Unit Tests)', () => { beforeEach(() => { + jest.resetModules() process.env = { ...originalEnv, MONGODB_URI: 'mongodb://localhost:27017/test', @@ -58,9 +59,8 @@ describe('MongoDB Connection (Unit Tests)', () => { // Clear module cache to force re-import jest.resetModules() - expect(() => { - require('./mongodb') - }).toThrow('Please add MONGODB_URI to your environment variables') + const { getClientPromise } = require('./mongodb') + expect(() => getClientPromise()).toThrow('Please add MONGODB_URI to your environment variables') // Restore environment process.env.MONGODB_URI = originalMongodbUri @@ -70,9 +70,9 @@ describe('MongoDB Connection (Unit Tests)', () => { describe('Database connection', () => { it('should create MongoClient with correct URI and options', async () => { // Import after setting up the mock - const { clientPromise } = await import('./mongodb') + const { getClientPromise } = await import('./mongodb') - await clientPromise + await getClientPromise() expect(MockedMongoClient).toHaveBeenCalledWith( process.env.MONGODB_URI, @@ -131,13 +131,13 @@ describe('MongoDB Connection (Unit Tests)', () => { describe('Connection reuse and caching', () => { it('should reuse the same MongoClient instance for multiple calls', async () => { - const { clientPromise } = await import('./mongodb') + const { getClientPromise } = await import('./mongodb') - const client1 = await clientPromise - const client2 = await clientPromise + const client1 = await getClientPromise() + const client2 = await getClientPromise() // Should be the same client instance expect(client1).toBe(client2) }) }) -}) \ No newline at end of file +}) diff --git a/proto/src/lib/mongodb.ts b/proto/src/lib/mongodb.ts index 7d1576c..8eb1c85 100755 --- a/proto/src/lib/mongodb.ts +++ b/proto/src/lib/mongodb.ts @@ -1,39 +1,41 @@ import { MongoClient, Db, Collection, Document } from 'mongodb' -if (!process.env.MONGODB_URI) { - throw new Error('Please add MONGODB_URI to your environment variables') -} - -const uri = process.env.MONGODB_URI const options = { maxPoolSize: 10, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000, } -let client: MongoClient -let clientPromise: Promise +let clientPromise: Promise | undefined -// In development mode, use a global variable so that the client is not recreated between hot reloads -if (process.env.NODE_ENV === 'development') { - // @ts-expect-error - Global variable for development hot reload - if (!global._mongoClientPromise) { - client = new MongoClient(uri, options) - // @ts-expect-error - Global variable for development hot reload - global._mongoClientPromise = client.connect() +function createClientPromise(): Promise { + const uri = process.env.MONGODB_URI + if (!uri) { + throw new Error('Please add MONGODB_URI to your environment variables') } - // @ts-expect-error - Global variable for development hot reload - clientPromise = global._mongoClientPromise -} else { - // In production mode, it's best to not use a global variable - client = new MongoClient(uri, options) - clientPromise = client.connect() + + return new MongoClient(uri, options).connect() } -export default clientPromise +export function getClientPromise(): Promise { + // In development mode, use a global variable so that the client is not recreated between hot reloads. + // The connection is intentionally created lazily: `next build` must not require runtime secrets. + if (process.env.NODE_ENV === 'development') { + // @ts-expect-error - Global variable for development hot reload + if (!global._mongoClientPromise) { + // @ts-expect-error - Global variable for development hot reload + global._mongoClientPromise = createClientPromise() + } + // @ts-expect-error - Global variable for development hot reload + return global._mongoClientPromise + } + + clientPromise ??= createClientPromise() + return clientPromise +} export async function getDb(): Promise { - const client = await clientPromise + const client = await getClientPromise() return client.db(process.env.MONGODB_DB || 'mozdit') }