From c56ac32b43e5422ed99cab4d4b69adf2aad1712c Mon Sep 17 00:00:00 2001 From: Jemilu Mohammed Date: Mon, 22 May 2023 14:27:08 +0000 Subject: [PATCH 1/5] override jsonLogic operators on string operands to allow for case insensitive comparisons. Affected Operators: "==", "===", "!=", "!==", "in" --- .../routing-forms/lib/jsonLogicOverrides.ts | 31 +++++++++++++++++++ .../routing-forms/lib/processRoute.tsx | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 packages/app-store/routing-forms/lib/jsonLogicOverrides.ts diff --git a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts new file mode 100644 index 00000000000000..a8e3c24a69a108 --- /dev/null +++ b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts @@ -0,0 +1,31 @@ +import jsonLogic from "json-logic-js"; + +// converts input to lowercase if string +function normalize(input: any) { + return typeof input === "string" ? input.toLowerCase() : input; +} + +jsonLogic.add_operation("==", function (a: any, b: any) { + return normalize(a) == normalize(b) +}) + +jsonLogic.add_operation("===", function (a: any, b: any) { + return normalize(a) === normalize(b) +}) + +jsonLogic.add_operation("!==", function (a: any, b: any) { + return normalize(a) !== normalize(b) +}) + +jsonLogic.add_operation("!=", function (a: any, b: any) { + return normalize(a) != normalize(b) +}) + +jsonLogic.add_operation("in", function (a: any, b: any) { + const first = normalize(a) + const second = normalize(b) + if (!second || typeof second.indexOf === "undefined") return false; + return (second.indexOf(first) !== -1); +}) + +export default jsonLogic \ No newline at end of file diff --git a/packages/app-store/routing-forms/lib/processRoute.tsx b/packages/app-store/routing-forms/lib/processRoute.tsx index d3268d2b439ff6..701770e6c13ba0 100644 --- a/packages/app-store/routing-forms/lib/processRoute.tsx +++ b/packages/app-store/routing-forms/lib/processRoute.tsx @@ -1,5 +1,5 @@ import type { App_RoutingForms_Form } from "@prisma/client"; -import jsonLogic from "json-logic-js"; +import jsonLogic from "./jsonLogicOverrides"; import { Utils as QbUtils } from "react-awesome-query-builder"; import type { z } from "zod"; From 78d47b6458e532a12d89adc1dc8e7a83da6cea7f Mon Sep 17 00:00:00 2001 From: Jemilu Mohammed Date: Mon, 22 May 2023 23:10:44 +0000 Subject: [PATCH 2/5] disable no-explicit-any on jsonLogicOverrides file since most of the code there will be from jsonLogic and may not meet our coding style. Majority of overrides require us to copy over functions and their signatures from jsonLogic and then modify their implementation. The signature of functions implementing most operators take the operands typed as "any", which is intended, but doesn't adhere to our coding style. Hence the need to override the eslint rule --- packages/app-store/routing-forms/lib/jsonLogicOverrides.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts index a8e3c24a69a108..3919ec21ea2e83 100644 --- a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts +++ b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import jsonLogic from "json-logic-js"; // converts input to lowercase if string From 41d0732a5878ab4de43cd890c3e8f1d4af7d1616 Mon Sep 17 00:00:00 2001 From: Jemilu Mohammed Date: Tue, 23 May 2023 00:32:26 +0000 Subject: [PATCH 3/5] run linter to fix issues --- .../routing-forms/lib/jsonLogicOverrides.ts | 26 +++++++++---------- .../routing-forms/lib/processRoute.tsx | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts index 3919ec21ea2e83..09fb4499efb83d 100644 --- a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts +++ b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts @@ -7,26 +7,26 @@ function normalize(input: any) { } jsonLogic.add_operation("==", function (a: any, b: any) { - return normalize(a) == normalize(b) -}) + return normalize(a) == normalize(b); +}); jsonLogic.add_operation("===", function (a: any, b: any) { - return normalize(a) === normalize(b) -}) + return normalize(a) === normalize(b); +}); jsonLogic.add_operation("!==", function (a: any, b: any) { - return normalize(a) !== normalize(b) -}) + return normalize(a) !== normalize(b); +}); jsonLogic.add_operation("!=", function (a: any, b: any) { - return normalize(a) != normalize(b) -}) + return normalize(a) != normalize(b); +}); jsonLogic.add_operation("in", function (a: any, b: any) { - const first = normalize(a) - const second = normalize(b) + const first = normalize(a); + const second = normalize(b); if (!second || typeof second.indexOf === "undefined") return false; - return (second.indexOf(first) !== -1); -}) + return second.indexOf(first) !== -1; +}); -export default jsonLogic \ No newline at end of file +export default jsonLogic; diff --git a/packages/app-store/routing-forms/lib/processRoute.tsx b/packages/app-store/routing-forms/lib/processRoute.tsx index 701770e6c13ba0..6565da7af1f3e1 100644 --- a/packages/app-store/routing-forms/lib/processRoute.tsx +++ b/packages/app-store/routing-forms/lib/processRoute.tsx @@ -1,5 +1,4 @@ import type { App_RoutingForms_Form } from "@prisma/client"; -import jsonLogic from "./jsonLogicOverrides"; import { Utils as QbUtils } from "react-awesome-query-builder"; import type { z } from "zod"; @@ -8,6 +7,7 @@ import type { zodNonRouterRoute } from "../zod"; import { getQueryBuilderConfig } from "./getQueryBuilderConfig"; import { isFallbackRoute } from "./isFallbackRoute"; import isRouter from "./isRouter"; +import jsonLogic from "./jsonLogicOverrides"; export function processRoute({ form, From 49f23b6f072009805506277962c4aa17c5bbec36 Mon Sep 17 00:00:00 2001 From: Hariom Balhara Date: Tue, 23 May 2023 16:34:18 +0530 Subject: [PATCH 4/5] Fix bug in in operator when second arg is an array --- .../routing-forms/lib/jsonLogicOverrides.ts | 27 ++++++++++++++++--- playwright.config.ts | 6 ++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts index 09fb4499efb83d..1e4dff1daa592e 100644 --- a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts +++ b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts @@ -2,10 +2,26 @@ import jsonLogic from "json-logic-js"; // converts input to lowercase if string -function normalize(input: any) { - return typeof input === "string" ? input.toLowerCase() : input; +function normalize(input: T): T { + if (typeof input === "string") { + return input.toLowerCase() as T; + } + if (input instanceof Array) { + return input.map((item) => { + if (typeof item === "string") { + return item.toLowerCase(); + } + // if array item is not a string, return it as is + return item; + }) as T; + } + return input; } +/** + * Single Select equals and not equals uses it + * Short Text equals and not equals uses it + */ jsonLogic.add_operation("==", function (a: any, b: any) { return normalize(a) == normalize(b); }); @@ -22,7 +38,12 @@ jsonLogic.add_operation("!=", function (a: any, b: any) { return normalize(a) != normalize(b); }); -jsonLogic.add_operation("in", function (a: any, b: any) { +/** + * Multiselect "equals" and "not equals" uses it + * Singleselect "any in" and "not in" uses it + * Long Text/Short Text/Email/Phone "contains" also uses it. + */ +jsonLogic.add_operation("in", function (a: string, b: string | string[]) { const first = normalize(a); const second = normalize(b); if (!second || typeof second.indexOf === "undefined") return false; diff --git a/playwright.config.ts b/playwright.config.ts index e5255fb47ae99d..0b5b248732753b 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -11,12 +11,12 @@ const outputDir = path.join(__dirname, "test-results"); // Dev Server on local can be slow to start up and process requests. So, keep timeouts really high on local, so that tests run reliably locally // So, if not in CI, keep the timers high, if the test is stuck somewhere and there is unnecessary wait developer can see in browser that it's stuck -const DEFAULT_NAVIGATION_TIMEOUT = process.env.CI ? 15000 : 50000; -const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 15000 : 50000; +const DEFAULT_NAVIGATION_TIMEOUT = process.env.CI ? 15000 : 120000; +const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 15000 : 120000; // Test Timeout can hit due to slow expect, slow navigation. // So, it should me much higher than sum of expect and navigation timeouts as there can be many async expects and navigations in a single test -const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 120000; +const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; const headless = !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS; From 29e8f993e101620420ada347942f728bdbe5de3e Mon Sep 17 00:00:00 2001 From: Jemilu Mohammed Date: Tue, 23 May 2023 22:16:52 +0000 Subject: [PATCH 5/5] remove redundant indexOf check on overriden jsonLogic "in" operator. Note: this deviates from the original implementation in the jsonLogic library because our current useage ensures that the second operand is always a string or string[] and will therefore always have .index function. Whenever our invariants change in the future, make sure to modify this implementation to prevent any unexpected --- packages/app-store/routing-forms/lib/jsonLogicOverrides.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts index 1e4dff1daa592e..5627a29df1f6c3 100644 --- a/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts +++ b/packages/app-store/routing-forms/lib/jsonLogicOverrides.ts @@ -46,7 +46,7 @@ jsonLogic.add_operation("!=", function (a: any, b: any) { jsonLogic.add_operation("in", function (a: string, b: string | string[]) { const first = normalize(a); const second = normalize(b); - if (!second || typeof second.indexOf === "undefined") return false; + if (!second) return false; return second.indexOf(first) !== -1; });