Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prisma Client Extension query Typesafety

I'm trying to create a Prisma Client Extension that can add specific imports to a model.

const postExtention = Prisma.defineExtension((prisma) =>
  prisma.$extends({
    name: 'postExtention',
    query: {
      post: {
        $allOperations({ operation, args, query }) {
          if (
            operation === 'createMany' ||
            operation === 'updateMany' ||
            operation === 'deleteMany' ||
            operation === 'aggregate' ||
            operation === 'count' ||
            operation === 'groupBy'
          )
            return query(args)

          return query({
            ...args,
            include: {
              ...(args.include || {}),
              user: true
            }
          })
        }
      }
    }
  })
)

// Usage
function getPost (id: string) {
  return prisma.$extends(postExtention).post.findUnique({ where: { id } })
}

// NO user in PostOutput
type PostOutput = Awaited<ReturnType<typeof getPost>>

The problem is that the PostOutput type being a simple Prisma.Post type, lacking the user relation.

I experimented with using specific methods within the extension, such as findUnique instead of $allOperations, but this didn't resolve the issue as expected.

The only way I found is to modify a generic of the findUnique method:

prisma.$extends(postExtention).post.findUnique<{where: {id: string}, include: {user: boolean}}>({ where: { id } })

But its not a solution for me.

How can I modify the extension to ensure that it considers all the includes I specify in the result type, without adding to the generic of findUnique? I would greatly appreciate any guidance on this matter.

like image 696
smsh Avatar asked Mar 03 '26 08:03

smsh


1 Answers

import { PrismaClient } from "@prisma/client";
import cursorStream from "prisma-cursorstream";

declare global {
  var prisma: ReturnType<typeof initializePrisma>;
}

if (!global.prisma) {
  global.prisma = initializePrisma();
}

function initializePrisma() {
  return new PrismaClient().$extends(cursorStream.default);
}

export default global.prisma;

like image 125
Robin Bozan Avatar answered Mar 05 '26 19:03

Robin Bozan