Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core/db): allow to extend PrismaClient #9114

Merged

Conversation

iamandrewluca
Copy link
Contributor

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;
            },
          },
        });
      },
    },
  }),
);

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

@iamandrewluca iamandrewluca 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.

@iamandrewluca
Copy link
Contributor Author

iamandrewluca 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

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

Thanks! That is great!

@gautamsi
Copy link
Member

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

@iamandrewluca
Copy link
Contributor Author

iamandrewluca 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?

@iamandrewluca
Copy link
Contributor Author

iamandrewluca 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