From 7d17ec97fed39210c3737c7a271dfdc6a217191e Mon Sep 17 00:00:00 2001 From: chris-stafflink <84813115+bellcoTech@users.noreply.github.com> Date: Thu, 14 May 2026 23:22:38 +1000 Subject: [PATCH] fix(api-server): ignore Prisma generator output in dev watcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dev watcher already ignores the directory containing schema.prisma (api/db by default), but if a project configures the generator output to point outside that directory — e.g. output = "../src/lib/db/generated" — the watcher sees every regenerated file and schedules another rebuild, trapping the dev server in an infinite build loop. Resolves the generator output path from the Prisma config and appends it to chokidar's ignore list. When the output is undeclared or schema parsing fails, falls back to the existing behavior. --- packages/api-server/src/watchPaths.ts | 11 ++++++++++ packages/project-config/src/prisma.ts | 30 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/packages/api-server/src/watchPaths.ts b/packages/api-server/src/watchPaths.ts index 7b64e0338f..83e282120e 100644 --- a/packages/api-server/src/watchPaths.ts +++ b/packages/api-server/src/watchPaths.ts @@ -4,6 +4,7 @@ import path from 'node:path' import { getDbDir, getPaths, + getPrismaGeneratorOutputPath, importStatementPath, } from '@cedarjs/project-config' @@ -94,6 +95,16 @@ async function apiIgnorePaths() { dbDir, ] + // Always ignore the Prisma client generator output. It's usually inside + // `dbDir` (already ignored above), but projects that point the generator + // `output` outside the schema directory — e.g. into `api/src/lib/...` — + // otherwise trigger an infinite rebuild loop: each build regenerates the + // client, chokidar sees the writes, and another build is scheduled. + const prismaGeneratorOutputPath = await getPrismaGeneratorOutputPath() + if (prismaGeneratorOutputPath) { + ignoredApiPaths.push(prismaGeneratorOutputPath) + } + return ignoredApiPaths } diff --git a/packages/project-config/src/prisma.ts b/packages/project-config/src/prisma.ts index ba8fab357b..e22f72a039 100644 --- a/packages/project-config/src/prisma.ts +++ b/packages/project-config/src/prisma.ts @@ -159,6 +159,36 @@ type ResolveReturnType = | { clientPath: string; error: undefined } | { clientPath: string | undefined; error: string } +/** + * Resolves the absolute path the Prisma client generator writes to. + * Returns `undefined` if the schema or generator can't be read. + */ +export async function getPrismaGeneratorOutputPath(): Promise< + string | undefined +> { + try { + const prismaInternalsMod = await import('@prisma/internals') + const { getConfig } = prismaInternalsMod.default || prismaInternalsMod + + const { schemas, schemaRootDir } = await getPrismaSchemas() + const config = await getConfig({ datamodel: schemas }) + const generator = + config.generators.find((entry) => entry.name === 'client') ?? + config.generators[0] + const output = generator?.output?.value + + if (!output) { + return undefined + } + + return path.isAbsolute(output) + ? output + : path.resolve(schemaRootDir, output) + } catch { + return undefined + } +} + export async function resolveGeneratedPrismaClient(): Promise { let generatorOutputPath: string | undefined let ext = 'ts'