import { execFileSync } from "node:child_process"; import { copyFileSync, existsSync, readFileSync } from "node:fs"; import { dirname, join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; const scriptDir = dirname(fileURLToPath(import.meta.url)); const rootDir = resolve(scriptDir, ".."); const clientDir = join(rootDir, "node_modules", ".prisma", "client"); const clientIndex = join(clientDir, "index.js"); const prismaBin = join(rootDir, "node_modules", ".bin", "prisma"); const genericEngine = join(clientDir, "libquery_engine.node"); function parseExpectedEngineFiles() { if (!existsSync(clientIndex)) return []; const content = readFileSync(clientIndex, "utf8"); const matches = content.match(/libquery_engine-[^"'\\/]+?\.node/g) ?? []; return [...new Set(matches)]; } function missingEngineFiles(expectedFiles) { return expectedFiles.filter((file) => !existsSync(join(clientDir, file))); } function runPrismaGenerate() { if (!existsSync(prismaBin)) { throw new Error( "Prisma CLI not found. Install dev dependencies and run `npm run prisma:generate`." ); } execFileSync(prismaBin, ["generate"], { cwd: rootDir, stdio: "inherit", }); } let expectedFiles = parseExpectedEngineFiles(); let missingFiles = missingEngineFiles(expectedFiles); if (!expectedFiles.length || missingFiles.length) { runPrismaGenerate(); expectedFiles = parseExpectedEngineFiles(); missingFiles = missingEngineFiles(expectedFiles); } if (missingFiles.length === 1 && existsSync(genericEngine)) { copyFileSync(genericEngine, join(clientDir, missingFiles[0])); missingFiles = missingEngineFiles(expectedFiles); } if (missingFiles.length) { throw new Error( `Missing Prisma engine file(s): ${missingFiles.join( ", " )}. Ensure deployment copies node_modules/.prisma (including dot-directories).` ); }