2026-02-13 22:43:55 -08:00
|
|
|
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");
|
2026-02-13 23:15:12 -08:00
|
|
|
const prismaJs = join(rootDir, "node_modules", "prisma", "build", "index.js");
|
2026-02-13 22:43:55 -08:00
|
|
|
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() {
|
2026-02-13 23:15:12 -08:00
|
|
|
if (existsSync(prismaJs)) {
|
|
|
|
|
execFileSync(process.execPath, [prismaJs, "generate"], {
|
|
|
|
|
cwd: rootDir,
|
|
|
|
|
stdio: "inherit",
|
|
|
|
|
env: { ...process.env, PRISMA_HIDE_UPDATE_MESSAGE: "1" },
|
|
|
|
|
});
|
|
|
|
|
return;
|
2026-02-13 22:43:55 -08:00
|
|
|
}
|
2026-02-13 23:15:12 -08:00
|
|
|
|
|
|
|
|
throw new Error(
|
|
|
|
|
"Prisma CLI not found at node_modules/prisma/build/index.js. Install dependencies and run `npm run prisma:generate`."
|
|
|
|
|
);
|
2026-02-13 22:43:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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).`
|
|
|
|
|
);
|
|
|
|
|
}
|