diff --git a/src/env.mjs b/src/env.mjs index 34f9ddf3..98b6c55b 100644 --- a/src/env.mjs +++ b/src/env.mjs @@ -75,7 +75,7 @@ const sgidServerSchema = z.discriminatedUnion('NEXT_PUBLIC_ENABLE_SGID', [ */ const server = z .object({ - DATABASE_URL: z.string().url(), + DATABASE_URL: z.string().url().optional(), NODE_ENV: z.enum(['development', 'test', 'production']), OTP_EXPIRY: z.coerce.number().positive().optional().default(600), POSTMAN_API_KEY: z.string().optional(), @@ -122,6 +122,17 @@ const server = z message: 'SENDGRID_FROM_ADDRESS is required when SENDGRID_API_KEY is set', path: ['SENDGRID_FROM_ADDRESS'], }) + .refine( + (val) => + val.NODE_ENV === 'development' || + val.NODE_ENV === 'test' || + val.DATABASE_URL, + { + message: + 'DATABASE_URL has to be set if NODE_ENV is not development or test', + path: ['SENDGRID_FROM_ADDRESS'], + }, + ) /** * You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g. diff --git a/src/server/prisma/index.ts b/src/server/prisma/index.ts index f6d9c92a..9b5ecb2b 100644 --- a/src/server/prisma/index.ts +++ b/src/server/prisma/index.ts @@ -3,17 +3,36 @@ * @link https://www.prisma.io/docs/support/help-articles/nextjs-prisma-client-dev-practices */ import { PrismaClient } from '@prisma/client' +import pino from 'pino' import { env } from '~/env.mjs' +import { makePgliteClient, applyMigrations } from './pglite' const prismaGlobal = global as typeof global & { prisma?: PrismaClient } -export const prisma: PrismaClient = - prismaGlobal.prisma || - new PrismaClient({ - log: env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'], - }) +const choosePrismaClient = () => { + if ( + !env.DATABASE_URL && + (env.NODE_ENV === 'development' || env.NODE_ENV === 'test') + ) { + pino().warn({}, 'DATABASE_URL not set, using pglite') + const { client, prisma: pglitePrismaClient } = makePgliteClient() + // Inject an env var to appease Prisma + process.env.DATABASE_URL = 'postgres://using:pglite@localhost:5432/' + void applyMigrations(client) + return pglitePrismaClient + } else { + return ( + prismaGlobal.prisma || + new PrismaClient({ + log: env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'], + }) + ) + } +} + +export const prisma: PrismaClient = choosePrismaClient() if (env.NODE_ENV !== 'production') { prismaGlobal.prisma = prisma