import fs from 'node:fs' import path from 'node:path' import { createRequire } from 'node:module' const ROOT = process.cwd() const SOURCE_SCHEMA = path.join(ROOT, 'prisma', 'schema.prisma') const require = createRequire(import.meta.url) const clientPackage = require.resolve('@prisma/client/package.json') const GENERATED_SCHEMA = path.resolve(path.dirname(clientPackage), '..', '..', '.prisma', 'client', 'schema.prisma') function readSchemaShape(schemaPath) { const source = fs.readFileSync(schemaPath, 'utf8') const shape = {} const declaration = /(?:^|\n)(model|enum)\s+(\w+)\s*\{([\s\S]*?)\n\}/g for (const match of source.matchAll(declaration)) { const [, kind, name, body] = match const members = [] for (const rawLine of body.split(/\r?\n/)) { const line = rawLine.trim() if (!line || line.startsWith('//') || line.startsWith('@@')) continue const [memberName, memberType] = line.split(/\s+/) members.push(kind === 'model' ? `${memberName}:${memberType}` : memberName) } shape[`${kind}:${name}`] = members.sort() } return shape } if (!fs.existsSync(GENERATED_SCHEMA)) { throw new Error(`Prisma Client schema is missing: ${GENERATED_SCHEMA}`) } const sourceShape = readSchemaShape(SOURCE_SCHEMA) const generatedShape = readSchemaShape(GENERATED_SCHEMA) if (JSON.stringify(sourceShape) !== JSON.stringify(generatedShape)) { const sourceKeys = new Set(Object.keys(sourceShape)) const generatedKeys = new Set(Object.keys(generatedShape)) const missingDeclarations = [...sourceKeys].filter((key) => !generatedKeys.has(key)) const staleDeclarations = [...sourceKeys].filter((key) => ( generatedKeys.has(key) && JSON.stringify(sourceShape[key]) !== JSON.stringify(generatedShape[key]) )) throw new Error( `Prisma Client does not match prisma/schema.prisma; regenerate it before building. ` + `Missing declarations: ${missingDeclarations.join(', ') || 'none'}. ` + `Stale declarations: ${staleDeclarations.join(', ') || 'none'}.`, ) } console.log(`Prisma Client schema verified (${Object.keys(sourceShape).length} declarations)`)