From f95377012cc0889e9cfe6d0179909d6ffe2a2af1 Mon Sep 17 00:00:00 2001 From: Gaurav Patil Date: Tue, 13 Oct 2026 00:31:06 +0530 Subject: [PATCH] fix(core): evaluate nested exists false filter when parent key is nullish (#5017) Signed-off-by: Gaurav Patil --- packages/core/src/eventFilterMatches.ts | 10 ++-------- packages/core/test/eventFilterMatches.test.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/core/src/eventFilterMatches.ts b/packages/core/src/eventFilterMatches.ts index 86a78aef750..222d09746cb 100644 --- a/packages/core/src/eventFilterMatches.ts +++ b/packages/core/src/eventFilterMatches.ts @@ -5,16 +5,10 @@ import type { EventFilter } from "./schemas/eventFilter.js"; // If the values of the array are objects, then we are doing content filtering // An example would be [{ $endsWith: ".png" }, { $startsWith: "images/" } ] export function eventFilterMatches(payload: any, filter: EventFilter): boolean { - if (payload === undefined || payload === null) { - if (Object.entries(filter).length === 0) { - return true; - } else { - return false; - } - } + const safePayload = payload ?? {}; for (const [patternKey, patternValue] of Object.entries(filter)) { - const payloadValue = payload[patternKey]; + const payloadValue = safePayload[patternKey]; if (Array.isArray(patternValue)) { if (patternValue.length === 0) { diff --git a/packages/core/test/eventFilterMatches.test.ts b/packages/core/test/eventFilterMatches.test.ts index 4df17fa235a..a658822d93e 100644 --- a/packages/core/test/eventFilterMatches.test.ts +++ b/packages/core/test/eventFilterMatches.test.ts @@ -209,6 +209,20 @@ describe("eventFilterMatches", () => { expect(eventFilterMatches(payload, filter)).toBe(true); }); + it("should return true for nested $exists: false when parent key is missing or null", () => { + const filter: EventFilter = { + user: { + email: [{ $exists: false }], + }, + }; + + expect(eventFilterMatches({}, filter)).toBe(true); + expect(eventFilterMatches({ user: null }, filter)).toBe(true); + expect(eventFilterMatches({ user: {} }, filter)).toBe(true); + expect(eventFilterMatches({ user: { email: undefined } }, filter)).toBe(true); + expect(eventFilterMatches({ user: { email: "user@example.com" } }, filter)).toBe(false); + }); + it("should return true when payload does match numeric condition", () => { const payload = { name: "John",