Skip to content

Conversation

@unrevised6419
Copy link
Member

Using this feature, one can extend PrismaClient, and add for example hooks at prisma level

export default withAuth(
  config<TypeInfo>({
    db: {
      extendPrismaClient(client: PrismaClient) {
        return client.$extends({
          query: {
            async $allOperations({ operation, model, args, query }) {
              // Raw Query is executed
              if (model === undefined) {
                const result: unknown = await query(args);
                return result;
              }

              const hooks = getPrismaHooks(model, operation);

              await hooks?.before?.(client, args);
              const result: unknown = await query(args);
              await hooks?.after?.(client, args, result);

              return result;
            },
          },
        });
      },
    },
  }),
);

@codesandbox-ci
Copy link

codesandbox-ci bot commented Apr 24, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit e842f7d:

Sandbox Source
@keystone-6/sandbox Configuration

@unrevised6419 unrevised6419 force-pushed the feat/allow-prisma-client-extend branch from d953b2f to e5062c7 Compare April 24, 2024 14:05
@gautamsi
Copy link
Member

I was looking to integrate @prisma/extension-read-replicas with this yesterday, right on time!
hope this gets into the release.

@unrevised6419
Copy link
Member Author

unrevised6419 commented Apr 24, 2024

We are already using this with a patch on top of KS

@dcousens
Copy link
Member

dcousens commented Apr 25, 2024

LGTM, doesn't resolve the issues raised by #8847, but I think we'll look at that another day - and there exists a workaround for that

@dcousens dcousens merged commit a9d1d22 into keystonejs:main Apr 25, 2024
@dcousens
Copy link
Member

Thanks @iamandrewluca! I'll try and release this asap

@unrevised6419 unrevised6419 deleted the feat/allow-prisma-client-extend branch April 25, 2024 07:21
@unrevised6419
Copy link
Member Author

Thanks! That is great!

@gautamsi
Copy link
Member

@iamandrewluca can you share the code of getPrismaHooks or is this exported by prisma?

@unrevised6419
Copy link
Member Author

unrevised6419 commented Apr 25, 2024

I have a big object mapper for all models/operations/lifecycles, and getPrismaHooks returns me the functions based on model/operation

import { type PrismaClient, type Prisma } from '@prisma/client';
import type { TypeInfo } from '.keystone/types';

type PrismaHook = (
	prismaClient: PrismaClient,
	args: unknown,
) => Promise<void> | Promise<unknown>;

type PrismaExtendedOperation = {
	[ListType in keyof TypeInfo['lists']]?: {
		[OperationType in Prisma.DMMF.ModelAction]?: Partial<
			Record<'before' | 'after', PrismaHook>
		>;
	};
};

const PrismaHooks: PrismaExtendedOperation = {
	Order: {
		create: {
			before: async (prismaClient: PrismaClient, args: unknown) => {
				// ...
			},
		},
		update: {
			before: async (prismaClient: PrismaClient, args: unknown) => {
				// ...
			},
		},
	},
};

export function getPrismaHooks(
	model: keyof TypeInfo['lists'],
	operation: string,
): Partial<Record<'before' | 'after', PrismaHook>> | undefined {
	const modelHooks = PrismaHooks[model];
	return modelHooks?.[operation as Prisma.DMMF.ModelAction];
}

@dcousens
Copy link
Member

@iamandrewluca out of interest, why use these by comparison to the Keystone hooks?

@unrevised6419
Copy link
Member Author

unrevised6419 commented Apr 29, 2024

@dcousens, we had to create custom GQL mutations that use Prisma transactions, and doing that KS hooks did not work.

@dcousens dcousens mentioned this pull request Apr 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants