Skip to content

Commit

Permalink
fix: Repeated Prisma calls in extended Prisma clients
Browse files Browse the repository at this point in the history
  • Loading branch information
zermelo-wisen committed Apr 8, 2024
1 parent 9799fe0 commit 61db1ec
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 133 deletions.
42 changes: 34 additions & 8 deletions src/hooks/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,7 @@ function getFunctionInfo(model: string, action: string, moduleId: string) {
const key = model + "." + action;

if (!functionInfos.has(key)) {
const params = ["data", "include", "where"].map((k) => {
return { type: "Identifier", name: k } as ESTree.Identifier;
});
const params = [{ type: "Identifier", name: "args" } as ESTree.Identifier];
const info: FunctionInfo = {
async: true,
generator: false,
Expand All @@ -101,6 +99,13 @@ function getFunctionInfo(model: string, action: string, moduleId: string) {
return functionInfos.get(key)!;
}

interface PrismaCallDetails {
model: string;
action: string;
argsValue: string;
}
let lastPrismaCallDetails: PrismaCallDetails | undefined;

function createPrismaClientMethodProxy<T extends (...args: unknown[]) => unknown>(
prismaClientMethod: T,
moduleId: string,
Expand All @@ -112,11 +117,32 @@ function createPrismaClientMethodProxy<T extends (...args: unknown[]) => unknown
if (argArray?.length > 0) {
const requestParams = argArray[0] as PrismaRequestParams;
if (requestParams.action && requestParams.model) {
prismaCall = recording.functionCall(
getFunctionInfo(requestParams.model, requestParams.action, moduleId),
requestParams.model,
[requestParams.args?.data, requestParams.args?.include, requestParams.args?.where],
);
// In extended prisma clients, we receive repeated calls
// with the same action, module and args. It can be seen
// with the example project cal.com. Looks like it's related
// to the Prisma client extension mechanism. To prevent filling
// appmaps with repeated calls we don't record them if they are
// exactly the same with the previous one.

const funInfo = getFunctionInfo(requestParams.model, requestParams.action, moduleId);
// We use JSON.stringify to stringify details deeper in a compact string than
// event.ts:resolveParameters() will do.
const argsValue = JSON.stringify(requestParams.args);
const prismaCallDetails = {
model: requestParams.model,
action: requestParams.action,
argsValue,
};

if (
prismaCallDetails.action == lastPrismaCallDetails?.action &&
prismaCallDetails.model == lastPrismaCallDetails?.model &&
prismaCallDetails.argsValue == lastPrismaCallDetails.argsValue
)
return; // Repeated call, don't record
lastPrismaCallDetails = prismaCallDetails;

prismaCall = recording.functionCall(funInfo, requestParams.model, [argsValue]);
}
}

Expand Down
142 changes: 17 additions & 125 deletions test/__snapshots__/prisma.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ exports[`mapping Prisma tests 1`] = `
"parent_id": 15,
"return_value": {
"class": "Promise<Object>",
"object_id": 5,
"object_id": 4,
"value": "Promise { { id: 1, email: 'alice@prisma.io', name: 'Alice' } }",
},
"thread_id": 0,
Expand All @@ -102,7 +102,7 @@ exports[`mapping Prisma tests 1`] = `
"parent_id": 19,
"return_value": {
"class": "Promise<Object>",
"object_id": 7,
"object_id": 5,
"value": "Promise { { id: 2, email: 'bob@prisma.io', name: 'Bob' } }",
},
"thread_id": 0,
Expand All @@ -114,7 +114,7 @@ exports[`mapping Prisma tests 1`] = `
"parent_id": 31,
"return_value": {
"class": "Promise<Array>",
"object_id": 10,
"object_id": 6,
"value": "Promise { [ [Object] ] }",
},
"thread_id": 0,
Expand Down Expand Up @@ -177,17 +177,7 @@ exports[`mapping Prisma tests 1`] = `
"parameters": [
{
"class": "undefined",
"name": "data",
"value": "undefined",
},
{
"class": "undefined",
"name": "include",
"value": "undefined",
},
{
"class": "undefined",
"name": "where",
"name": "args",
"value": "undefined",
},
],
Expand Down Expand Up @@ -236,17 +226,7 @@ exports[`mapping Prisma tests 1`] = `
"parameters": [
{
"class": "undefined",
"name": "data",
"value": "undefined",
},
{
"class": "undefined",
"name": "include",
"value": "undefined",
},
{
"class": "undefined",
"name": "where",
"name": "args",
"value": "undefined",
},
],
Expand Down Expand Up @@ -326,30 +306,9 @@ exports[`mapping Prisma tests 1`] = `
"method_id": "create",
"parameters": [
{
"class": "Object",
"name": "data",
"object_id": 4,
"properties": [
{
"class": "String",
"name": "name",
},
{
"class": "String",
"name": "email",
},
],
"value": "{ name: 'Alice', email: 'alice@prisma.io' }",
},
{
"class": "undefined",
"name": "include",
"value": "undefined",
},
{
"class": "undefined",
"name": "where",
"value": "undefined",
"class": "String",
"name": "args",
"value": "'{"data":{"name":"Alice","email":"alice@prisma.io"}}'",
},
],
"path": "@prisma/client/User",
Expand All @@ -367,7 +326,7 @@ exports[`mapping Prisma tests 1`] = `
"parent_id": 15,
"return_value": {
"class": "Promise",
"object_id": 5,
"object_id": 4,
"value": "Promise { <pending> }",
},
"thread_id": 0,
Expand Down Expand Up @@ -396,46 +355,9 @@ exports[`mapping Prisma tests 1`] = `
"method_id": "create",
"parameters": [
{
"class": "Object",
"name": "data",
"object_id": 6,
"properties": [
{
"class": "String",
"name": "name",
},
{
"class": "String",
"name": "email",
},
{
"class": "Object",
"name": "posts",
"properties": [
{
"class": "Object",
"name": "create",
"properties": [
{
"class": "String",
"name": "title",
},
],
},
],
},
],
"value": "{ name: 'Bob', email: 'bob@prisma.io', posts: { create: [Object] } }",
},
{
"class": "undefined",
"name": "include",
"value": "undefined",
},
{
"class": "undefined",
"name": "where",
"value": "undefined",
"class": "String",
"name": "args",
"value": "'{"data":{"name":"Bob","email":"bob@prisma.io","posts":{"create":{"title":"Hello World"}}}}'",
},
],
"path": "@prisma/client/User",
Expand All @@ -453,7 +375,7 @@ exports[`mapping Prisma tests 1`] = `
"parent_id": 19,
"return_value": {
"class": "Promise",
"object_id": 7,
"object_id": 5,
"value": "Promise { <pending> }",
},
"thread_id": 0,
Expand Down Expand Up @@ -546,39 +468,9 @@ exports[`mapping Prisma tests 1`] = `
"method_id": "findMany",
"parameters": [
{
"class": "undefined",
"name": "data",
"value": "undefined",
},
{
"class": "Object",
"name": "include",
"object_id": 8,
"properties": [
{
"class": "Boolean",
"name": "posts",
},
],
"value": "{ posts: true }",
},
{
"class": "Object",
"name": "where",
"object_id": 9,
"properties": [
{
"class": "Object",
"name": "name",
"properties": [
{
"class": "String",
"name": "contains",
},
],
},
],
"value": "{ name: { contains: 'Bob' } }",
"class": "String",
"name": "args",
"value": "'{"include":{"posts":true},"where":{"name":{"contains":"Bob"}}}'",
},
],
"path": "@prisma/client/User",
Expand All @@ -596,7 +488,7 @@ exports[`mapping Prisma tests 1`] = `
"parent_id": 31,
"return_value": {
"class": "Promise",
"object_id": 10,
"object_id": 6,
"value": "Promise { <pending> }",
},
"thread_id": 0,
Expand Down

0 comments on commit 61db1ec

Please sign in to comment.