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 prismaJs = join(rootDir, "node_modules", "prisma", "build", "index.js"); 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(prismaJs)) { execFileSync(process.execPath, [prismaJs, "generate"], { cwd: rootDir, stdio: "inherit", env: { ...process.env, PRISMA_HIDE_UPDATE_MESSAGE: "1" }, }); return; } throw new Error( "Prisma CLI not found at node_modules/prisma/build/index.js. Install dependencies and run `npm run prisma:generate`." ); } 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).` ); }