Files
gymflow/server/src/lib/prisma.ts

80 lines
2.0 KiB
TypeScript

import { PrismaClient } from '@prisma/client';
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
import 'dotenv/config';
declare global {
// allow global `var` declarations
// eslint-disable-next-line no-var
var prisma: PrismaClient | undefined;
}
const mode = process.env.APP_MODE || 'dev';
console.log(`[Prisma] Initializing in ${mode.toUpperCase()} mode`);
let dbPath: string;
switch (mode) {
case 'test':
dbPath = process.env.DATABASE_URL_TEST || './test.db';
break;
case 'prod':
dbPath = process.env.DATABASE_URL_PROD || './prod.db';
break;
case 'dev':
default:
dbPath = process.env.DATABASE_URL_DEV || './dev.db';
break;
}
// Remove 'file:' prefix if present
if (dbPath.startsWith('file:')) {
dbPath = dbPath.slice(5);
}
console.log('Initializing Prisma Client with database:', dbPath);
let prisma: PrismaClient;
// In Prisma 7, PrismaBetterSqlite3 is a factory.
// We use a wrapper to intercept the connection and disable WAL mode
// for NAS/Network share compatibility (journal_mode = DELETE).
try {
const factory = new PrismaBetterSqlite3({ url: dbPath });
const adapterWrapper = {
provider: 'sqlite',
adapterName: '@prisma/adapter-better-sqlite3',
async connect() {
const adapter = (await factory.connect()) as any;
if (adapter.client) {
console.log('[Prisma] Setting journal_mode = DELETE for NAS compatibility');
adapter.client.pragma('journal_mode = DELETE');
}
return adapter;
},
async connectToShadowDb() {
const adapter = (await factory.connectToShadowDb()) as any;
if (adapter.client) {
adapter.client.pragma('journal_mode = DELETE');
}
return adapter;
}
};
prisma =
global.prisma ||
new PrismaClient({
adapter: adapterWrapper as any,
});
} catch (e: any) {
console.error('Failed to initialize Prisma Client:', e.message);
process.exit(1);
}
if (process.env.NODE_ENV !== 'production') {
global.prisma = prisma;
}
export default prisma;