import fs from 'fs'; import path from 'path'; import { DataSource } from 'typeorm'; import { AuthUserEntity, ServerEntity, JoinRequestEntity, ServerMembershipEntity, ServerInviteEntity, ServerBanEntity } from '../entities'; import { serverMigrations } from '../migrations'; import { findExistingPath, resolveRuntimePath } from '../runtime-paths'; const DATA_DIR = resolveRuntimePath('data'); const DB_FILE = path.join(DATA_DIR, 'metoyou.sqlite'); let applicationDataSource: DataSource | undefined; function resolveSqlJsConfig(): { locateFile: (file: string) => string } { return { locateFile: (file) => { const bundledBinaryPath = path.join(__dirname, '..', '..', 'node_modules', 'sql.js', 'dist', file); return findExistingPath( resolveRuntimePath(file), bundledBinaryPath ) ?? bundledBinaryPath; } }; } export function getDataSource(): DataSource { if (!applicationDataSource?.isInitialized) { throw new Error('DataSource not initialised'); } return applicationDataSource; } export async function initDatabase(): Promise { if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true }); let database: Uint8Array | undefined; if (fs.existsSync(DB_FILE)) database = fs.readFileSync(DB_FILE); try { applicationDataSource = new DataSource({ type: 'sqljs', database, entities: [ AuthUserEntity, ServerEntity, JoinRequestEntity, ServerMembershipEntity, ServerInviteEntity, ServerBanEntity ], migrations: serverMigrations, synchronize: false, logging: false, autoSave: true, location: DB_FILE, sqlJsConfig: resolveSqlJsConfig() }); } catch (error) { console.error('[DB] Failed to configure the sql.js data source', error); throw error; } try { await applicationDataSource.initialize(); } catch (error) { console.error('[DB] Failed to initialise the sql.js data source', error); throw error; } console.log('[DB] Connection initialised at:', DB_FILE); await applicationDataSource.runMigrations(); console.log('[DB] Migrations executed'); } export async function destroyDatabase(): Promise { if (applicationDataSource?.isInitialized) { await applicationDataSource.destroy(); applicationDataSource = undefined; console.log('[DB] Connection closed'); } }