diff --git a/packages/database/scripts/db-deploy.cjs b/packages/database/scripts/db-deploy.cjs index a9cfe43..63e5d83 100644 --- a/packages/database/scripts/db-deploy.cjs +++ b/packages/database/scripts/db-deploy.cjs @@ -15,6 +15,30 @@ const prismaBin = path.join(repoRoot, 'node_modules', '.bin', 'prisma') const schemaPath = path.join(repoRoot, 'packages/database/prisma/schema.prisma') const migrationsDir = path.join(repoRoot, 'packages/database/prisma/migrations') +function getDatabaseName(databaseUrl) { + try { + const parsed = new URL(databaseUrl) + const databaseName = parsed.pathname.replace(/^\/+/, '') + return databaseName ? decodeURIComponent(databaseName) : null + } catch { + return null + } +} + +function getMaintenanceDatabaseUrl(databaseUrl) { + try { + const parsed = new URL(databaseUrl) + parsed.pathname = '/postgres' + return parsed.toString() + } catch { + return databaseUrl + } +} + +function quoteIdentifier(value) { + return `"${String(value).replace(/"/g, '""')}"` +} + function run(command, args) { const result = spawnSync(command, args, { stdio: 'inherit', @@ -31,6 +55,37 @@ async function main() { loadDefaultEnvFiles(repoRoot) ensureDatabaseUrl() normalizeDatabaseUrlForExecution() + const targetDatabaseUrl = process.env.DATABASE_URL + const targetDatabaseName = getDatabaseName(targetDatabaseUrl) + + if (targetDatabaseUrl && targetDatabaseName && targetDatabaseName !== 'postgres') { + const adminPrisma = new PrismaClient({ + datasources: { + db: { + url: getMaintenanceDatabaseUrl(targetDatabaseUrl), + }, + }, + }) + + try { + const existingDatabase = await adminPrisma.$queryRaw` + SELECT datname + FROM pg_database + WHERE datname = ${targetDatabaseName} + LIMIT 1 + ` + + if (existingDatabase.length === 0) { + console.log(`[db:deploy] Creating missing database ${targetDatabaseName}`) + await adminPrisma.$executeRawUnsafe( + `CREATE DATABASE ${quoteIdentifier(targetDatabaseName)}`, + ) + } + } finally { + await adminPrisma.$disconnect() + } + } + const prisma = new PrismaClient() try {