/** * باندل تک‌فایل برای Docker (release/app.js) بعد از nest build. * Prisma client + engines را در release/vendor می‌گذارد (نه node_modules تا gitignore نخورد). */ const esbuild = require('esbuild'); const { existsSync, mkdirSync, rmSync, cpSync, realpathSync, readdirSync, } = require('fs'); const path = require('path'); // Only this engine ships to Docker; see apps/api/Dockerfile (bookworm/OpenSSL 3). const RUNTIME_ENGINE = 'libquery_engine-debian-openssl-3.0.x.so.node'; const root = path.join(__dirname, '..'); const config = require(path.join(root, 'esbuild.release.config.cjs')); const releaseDir = path.join(root, 'release'); const vendorDir = path.join(releaseDir, 'vendor'); function resolvePkg(name) { return path.dirname(require.resolve(`${name}/package.json`, { paths: [root] })); } function copyPrismaIntoRelease() { const prismaClientSrc = resolvePkg('@prisma/client'); const prismaClientDest = path.join(vendorDir, '@prisma', 'client'); mkdirSync(path.dirname(prismaClientDest), { recursive: true }); cpSync(prismaClientSrc, prismaClientDest, { recursive: true }); const candidates = [ path.join(root, 'node_modules', '.prisma', 'client'), path.join(prismaClientSrc, '..', '.prisma', 'client'), path.join(path.dirname(prismaClientSrc), '.prisma', 'client'), path.join(prismaClientSrc, '..', '..', '.prisma', 'client'), ]; const prismaEngineSrc = candidates.find((p) => existsSync(p)); if (!prismaEngineSrc) { throw new Error( 'Prisma generated client (.prisma/client) یافت نشد. ابتدا: pnpm --filter api exec prisma generate', ); } const prismaEngineDest = path.join(vendorDir, '.prisma', 'client'); mkdirSync(path.dirname(prismaEngineDest), { recursive: true }); cpSync(realpathSync(prismaEngineSrc), prismaEngineDest, { recursive: true }); // Drop engines for other platforms (local Windows dll, stale musl builds) so the // committed artifact stays small. for (const name of readdirSync(prismaEngineDest)) { const isEngine = name.endsWith('.so.node') || name.endsWith('.dll.node'); if (isEngine && name !== RUNTIME_ENGINE) { rmSync(path.join(prismaEngineDest, name), { force: true }); } } if (!existsSync(path.join(prismaEngineDest, RUNTIME_ENGINE))) { throw new Error( `${RUNTIME_ENGINE} تولید نشد. binaryTargets در prisma/schema.prisma را بررسی کنید.`, ); } } async function main() { const entry = config.entryPoints[0]; const fallbackEntry = path.join(root, 'dist', 'src', 'main.js'); if (!existsSync(entry)) { if (existsSync(fallbackEntry)) { config.entryPoints = [fallbackEntry]; } else { console.error('dist/main.js یافت نشد. ابتدا اجرا کنید: pnpm --filter api build'); process.exit(1); } } rmSync(releaseDir, { recursive: true, force: true }); mkdirSync(releaseDir, { recursive: true }); await esbuild.build(config); copyPrismaIntoRelease(); console.log('نوشت:', config.outfile); console.log('Prisma client در release/vendor کپی شد.'); } main().catch((err) => { console.error(err); process.exit(1); });