chore: Add Prisma extension to block deleteMany/updateMany with undefined 'in' (#15721)
* chore: Add Prisma extension to block updateMany with undefined 'in' * Fix type * types * Added check for deleteMany as well * Improved in check * type * Updated check to only check undefined and not isArray * Renamed the guard * another rename * Changed undefined check to use typeof * Types * Added check * Update packages/prisma/extensions/disallow-undefined-in-delete-update-many.ts Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> * Added unit tests * Added a good case * Rename * Rename fix * Types * Temporarily disabling the extension for testing * Added back the extension * Trying to also log to see if there are swallowed errors * Update * removed unused params * removed console.log --------- Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
This commit is contained in:
co-authored by
Hariom Balhara
Anik Dhabal Babu
parent
6e7012757f
commit
fd8afbc418
@@ -0,0 +1,38 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
|
||||
import { checkUndefinedInValue } from "./disallow-undefined-delete-update-many";
|
||||
|
||||
describe("Disallow undefined delete/update many", () => {
|
||||
it("checkUndefinedInValue should throw exception when the 'in' field of where object is undefined", async () => {
|
||||
const where = {
|
||||
id: {
|
||||
in: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
expect(() => checkUndefinedInValue(where)).toThrowError(
|
||||
'The "in" value for the field "id" cannot be undefined.'
|
||||
);
|
||||
});
|
||||
|
||||
it("checkUndefinedInValue should throw exception when a field of where object is undefined", async () => {
|
||||
const where = {
|
||||
from: undefined,
|
||||
};
|
||||
|
||||
expect(() => checkUndefinedInValue(where)).toThrowError(
|
||||
'The value for the field "from" cannot be undefined.'
|
||||
);
|
||||
});
|
||||
|
||||
it("checkUndefinedInValue should not throw exception when the where object does not contain undefined values", async () => {
|
||||
const where = {
|
||||
id: {
|
||||
in: [1, 2, 3],
|
||||
},
|
||||
name: "test name",
|
||||
};
|
||||
|
||||
checkUndefinedInValue(where);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
export const checkUndefinedInValue = (where: any) => {
|
||||
if (where) {
|
||||
for (const key in where) {
|
||||
// INFO: Since this is for $allModels, we don't have a way to get the correct
|
||||
// where type
|
||||
const whereInput = where[key as any] as any;
|
||||
let message;
|
||||
if (whereInput === undefined) {
|
||||
message = `The value for the field "${key}" cannot be undefined.`;
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
if (whereInput.hasOwnProperty("in") && typeof whereInput.in === "undefined") {
|
||||
message = `The "in" value for the field "${key}" cannot be undefined.`;
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export function disallowUndefinedDeleteUpdateManyExtension() {
|
||||
return Prisma.defineExtension({
|
||||
query: {
|
||||
$allModels: {
|
||||
async deleteMany({ args, query }) {
|
||||
checkUndefinedInValue(args.where);
|
||||
return query(args);
|
||||
},
|
||||
async updateMany({ args, query }) {
|
||||
checkUndefinedInValue(args.where);
|
||||
return query(args);
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { PrismaClient as PrismaClientWithoutExtension } from "@prisma/client";
|
||||
import { withAccelerate } from "@prisma/extension-accelerate";
|
||||
|
||||
import { bookingIdempotencyKeyExtension } from "./extensions/booking-idempotency-key";
|
||||
import { disallowUndefinedDeleteUpdateManyExtension } from "./extensions/disallow-undefined-delete-update-many";
|
||||
import { excludePendingPaymentsExtension } from "./extensions/exclude-pending-payment-teams";
|
||||
import { usageTrackingExtention } from "./extensions/usage-tracking";
|
||||
import { bookingReferenceMiddleware } from "./middleware";
|
||||
@@ -25,6 +26,7 @@ export const customPrisma = (options?: Prisma.PrismaClientOptions) =>
|
||||
.$extends(usageTrackingExtention())
|
||||
.$extends(excludePendingPaymentsExtension())
|
||||
.$extends(bookingIdempotencyKeyExtension())
|
||||
.$extends(disallowUndefinedDeleteUpdateManyExtension())
|
||||
.$extends(withAccelerate());
|
||||
|
||||
// If any changed on middleware server restart is required
|
||||
@@ -37,6 +39,7 @@ const prismaWithClientExtensions = prismaWithoutClientExtensions
|
||||
.$extends(usageTrackingExtention())
|
||||
.$extends(excludePendingPaymentsExtension())
|
||||
.$extends(bookingIdempotencyKeyExtension())
|
||||
.$extends(disallowUndefinedDeleteUpdateManyExtension())
|
||||
.$extends(withAccelerate());
|
||||
|
||||
export const prisma = globalForPrisma.prismaWithClientExtensions || prismaWithClientExtensions;
|
||||
|
||||
Reference in New Issue
Block a user