56 lines
2.1 KiB
JavaScript
56 lines
2.1 KiB
JavaScript
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)`)
|