const { spawnSync } = require('child_process'); const fs = require('fs'); const path = require('path'); const repoRoot = path.resolve(__dirname, '..'); const prismaSchemaPath = path.join(repoRoot, 'prisma', 'schema.prisma'); const generatedSchemaPath = path.join( repoRoot, 'node_modules', '.prisma', 'client', 'schema.prisma' ); function readFileIfExists(filePath) { try { return fs.readFileSync(filePath, 'utf8'); } catch (error) { if (error && error.code === 'ENOENT') { return null; } throw error; } } function normalizeSchema(schema) { return schema.replace(/\s+/g, ''); } function schemasMatch() { const sourceSchema = readFileIfExists(prismaSchemaPath); const generatedSchema = readFileIfExists(generatedSchemaPath); return Boolean( sourceSchema && generatedSchema && normalizeSchema(sourceSchema) === normalizeSchema(generatedSchema) ); } function run(command, args, options = {}) { const shouldUseShell = process.platform === 'win32' && command.toLowerCase().endsWith('.cmd'); const result = spawnSync(command, args, { cwd: repoRoot, encoding: 'utf8', stdio: 'pipe', shell: shouldUseShell, env: { ...process.env, ...options.env, }, }); if (result.stdout) { process.stdout.write(result.stdout); } if (result.stderr) { process.stderr.write(result.stderr); } return result; } function isWindowsPrismaRenameLock(output) { const text = [output.stdout, output.stderr] .filter(Boolean) .join('\n'); return ( process.platform === 'win32' && text.includes('EPERM: operation not permitted, rename') && text.includes('query_engine-windows.dll.node') ); } function runPrismaGenerate() { const prismaBin = process.platform === 'win32' ? path.join(repoRoot, 'node_modules', '.bin', 'prisma.cmd') : path.join(repoRoot, 'node_modules', '.bin', 'prisma'); const result = run(prismaBin, ['generate']); if (result.error) { throw result.error; } if ((result.status ?? 1) === 0) { return 0; } if (!isWindowsPrismaRenameLock(result) || !schemasMatch()) { return result.status ?? 1; } console.warn( '\nPrisma generate hit a Windows file lock, but the generated client already matches prisma/schema.prisma. Continuing with the existing client.\n' ); return 0; } function runNextBuild() { const nextBin = process.platform === 'win32' ? path.join(repoRoot, 'node_modules', '.bin', 'next.cmd') : path.join(repoRoot, 'node_modules', '.bin', 'next'); // WSL needs more aggressive memory settings const isWSL = process.platform === 'linux' && require('fs').existsSync('/proc/version') && require('fs').readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft'); const memoryLimit = isWSL ? '8192' : '4096'; return run(nextBin, ['build'], { env: { NODE_OPTIONS: `--max-old-space-size=${memoryLimit}`, SKIP_ENV_VALIDATION: 'true', }, }); } const prismaExitCode = runPrismaGenerate(); if (prismaExitCode !== 0) { process.exit(prismaExitCode); } const nextResult = runNextBuild(); if (nextResult.error) { throw nextResult.error; } process.exit(nextResult.status ?? 1);