import { mkdirSync } from 'node:fs'; import { homedir } from 'node:os'; import { join } from 'node:path'; import { Global, Inject, Module, type OnApplicationShutdown } from '@nestjs/common'; import { createDb, createPgliteDb, type Db, type DbHandle } from '@mosaicstack/db'; import { createStorageAdapter, type StorageAdapter } from '@mosaicstack/storage'; import type { MosaicConfig } from '@mosaicstack/config'; import { MOSAIC_CONFIG } from '../config/config.module.js'; export const DB_HANDLE = 'DB_HANDLE'; export const DB = 'DB'; export const STORAGE_ADAPTER = 'STORAGE_ADAPTER'; @Global() @Module({ providers: [ { provide: DB_HANDLE, useFactory: (config: MosaicConfig): DbHandle => { if (config.tier === 'local') { const dataDir = join(homedir(), '.config', 'mosaic', 'gateway', 'pglite'); mkdirSync(dataDir, { recursive: true }); return createPgliteDb(dataDir); } return createDb(config.storage.type === 'postgres' ? config.storage.url : undefined); }, inject: [MOSAIC_CONFIG], }, { provide: DB, useFactory: (handle: DbHandle): Db => handle.db, inject: [DB_HANDLE], }, { provide: STORAGE_ADAPTER, useFactory: (config: MosaicConfig): StorageAdapter => createStorageAdapter(config.storage), inject: [MOSAIC_CONFIG], }, ], exports: [DB, STORAGE_ADAPTER], }) export class DatabaseModule implements OnApplicationShutdown { constructor( @Inject(DB_HANDLE) private readonly handle: DbHandle, @Inject(STORAGE_ADAPTER) private readonly storageAdapter: StorageAdapter, ) {} async onApplicationShutdown(): Promise { await Promise.all([this.handle.close(), this.storageAdapter.close()]); } }