From f07a57b7fc0ee54d14b266a72aca76c43baa94a8 Mon Sep 17 00:00:00 2001 From: Rishabh Rathod Date: Wed, 22 Nov 2023 15:03:00 +0530 Subject: [PATCH] chore: create evalContext for module instance CE changes (#29008) ## Description Change for set evalContext for module instance #### PR fixes following issue(s) Fixes # #### Type of change - Chore (housekeeping or task changes that don't impact user perception) ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] JUnit - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --- .../fns/utils/isRunNClearFnQualifierEntity.ts | 9 +++ .../Evaluation/getEntityForEvalContextMap.ts | 12 ++++ .../fns/utils/isRunNClearFnQualifierEntity.ts | 1 + .../Evaluation/getEntityForEvalContextMap.ts | 1 + .../src/workers/Evaluation/fns/index.ts | 10 ++-- .../workers/Evaluation/getEntityForContext.ts | 57 ++----------------- .../Evaluation/getJSActionForEvalContext.ts | 53 +++++++++++++++++ 7 files changed, 84 insertions(+), 59 deletions(-) create mode 100644 app/client/src/ce/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity.ts create mode 100644 app/client/src/ce/workers/Evaluation/getEntityForEvalContextMap.ts create mode 100644 app/client/src/ee/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity.ts create mode 100644 app/client/src/ee/workers/Evaluation/getEntityForEvalContextMap.ts create mode 100644 app/client/src/workers/Evaluation/getJSActionForEvalContext.ts diff --git a/app/client/src/ce/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity.ts b/app/client/src/ce/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity.ts new file mode 100644 index 0000000000..0e3216a899 --- /dev/null +++ b/app/client/src/ce/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity.ts @@ -0,0 +1,9 @@ +import type { ActionEntity } from "@appsmith/entities/DataTree/types"; +import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes"; +import { isAction } from "@appsmith/workers/Evaluation/evaluationUtils"; + +export function isRunNClearFnQualifierEntity( + entity: DataTreeEntity, +): entity is ActionEntity { + return isAction(entity); +} diff --git a/app/client/src/ce/workers/Evaluation/getEntityForEvalContextMap.ts b/app/client/src/ce/workers/Evaluation/getEntityForEvalContextMap.ts new file mode 100644 index 0000000000..3e3ab3c7fb --- /dev/null +++ b/app/client/src/ce/workers/Evaluation/getEntityForEvalContextMap.ts @@ -0,0 +1,12 @@ +import { ENTITY_TYPE_VALUE } from "entities/DataTree/dataTreeFactory"; +import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes"; +import { getJSActionForEvalContext } from "workers/Evaluation/getJSActionForEvalContext"; + +export const getEntityForEvalContextMap: Record< + string, + (entityName: string, entity: DataTreeEntity) => unknown +> = { + [ENTITY_TYPE_VALUE.JSACTION]: (entityName, entity) => { + return getJSActionForEvalContext(entityName, entity); + }, +}; diff --git a/app/client/src/ee/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity.ts b/app/client/src/ee/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity.ts new file mode 100644 index 0000000000..e3deec850c --- /dev/null +++ b/app/client/src/ee/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity.ts @@ -0,0 +1 @@ +export * from "ce/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity"; diff --git a/app/client/src/ee/workers/Evaluation/getEntityForEvalContextMap.ts b/app/client/src/ee/workers/Evaluation/getEntityForEvalContextMap.ts new file mode 100644 index 0000000000..faa1ae4686 --- /dev/null +++ b/app/client/src/ee/workers/Evaluation/getEntityForEvalContextMap.ts @@ -0,0 +1 @@ +export * from "ce/workers/Evaluation/getEntityForEvalContextMap"; diff --git a/app/client/src/workers/Evaluation/fns/index.ts b/app/client/src/workers/Evaluation/fns/index.ts index ff6ab3316c..5287033e29 100644 --- a/app/client/src/workers/Evaluation/fns/index.ts +++ b/app/client/src/workers/Evaluation/fns/index.ts @@ -42,10 +42,7 @@ import type { TRunDescription, } from "./actionFns"; import run, { clear } from "./actionFns"; -import { - isAction, - isAppsmithEntity, -} from "@appsmith/workers/Evaluation/evaluationUtils"; +import { isAppsmithEntity } from "@appsmith/workers/Evaluation/evaluationUtils"; import type { ActionEntity } from "@appsmith/entities/DataTree/types"; import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes"; import type { @@ -62,6 +59,7 @@ import { watchGeoLocation, } from "./geolocationFns"; import { getFnWithGuards, isAsyncGuard } from "./utils/fnGuard"; +import { isRunNClearFnQualifierEntity } from "@appsmith/workers/Evaluation/fns/utils/isRunNClearFnQualifierEntity"; export const getPlatformFunctions = () => { return platformFns; @@ -117,7 +115,7 @@ const platformFns = [ export const entityFns = [ { name: "run", - qualifier: (entity: DataTreeEntity) => isAction(entity), + qualifier: (entity: DataTreeEntity) => isRunNClearFnQualifierEntity(entity), fn: (entity: DataTreeEntity, entityName: string) => { const actionEntity = entity as ActionEntity; // @ts-expect-error: name is not defined on ActionEntity @@ -131,7 +129,7 @@ export const entityFns = [ }, { name: "clear", - qualifier: (entity: DataTreeEntity) => isAction(entity), + qualifier: (entity: DataTreeEntity) => isRunNClearFnQualifierEntity(entity), fn: (entity: DataTreeEntity, entityName: string) => getFnWithGuards( clear.bind(entity as ActionEntity), diff --git a/app/client/src/workers/Evaluation/getEntityForContext.ts b/app/client/src/workers/Evaluation/getEntityForContext.ts index 39cebc5e69..2b77f88674 100644 --- a/app/client/src/workers/Evaluation/getEntityForContext.ts +++ b/app/client/src/workers/Evaluation/getEntityForContext.ts @@ -1,62 +1,13 @@ -import type { JSActionEntity } from "@appsmith/entities/DataTree/types"; +import { getEntityForEvalContextMap } from "@appsmith/workers/Evaluation/getEntityForEvalContextMap"; import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes"; -import { ENTITY_TYPE_VALUE } from "entities/DataTree/dataTreeFactory"; -import JSObjectCollection from "./JSObject/Collection"; -import { jsObjectFunctionFactory } from "./fns/utils/jsObjectFnFactory"; -import { isObject } from "lodash"; - -function getJSFunctionsForEntity({ - jsObject, - jsObjectName, -}: { - jsObjectName: string; - jsObject: JSActionEntity; -}) { - const jsObjectFunction: Record = {}; - const resolvedFunctions = JSObjectCollection.getResolvedFunctions(); - const resolvedObject = Object.assign({}, resolvedFunctions[jsObjectName]); - for (const fnName of Object.keys(resolvedObject || {})) { - const fn = resolvedObject[fnName]; - if (typeof fn !== "function") continue; - const data = jsObject[fnName]?.data; - jsObjectFunction[fnName] = jsObjectFunctionFactory( - fn, - jsObjectName + "." + fnName, - ); - - if (!!data) { - jsObjectFunction[fnName]["data"] = data; - } - } - return jsObjectFunction; -} export function getEntityForEvalContext( entity: DataTreeEntity, entityName: string, ) { - if (entity && isObject(entity) && "ENTITY_TYPE" in entity) { - switch (entity.ENTITY_TYPE) { - case ENTITY_TYPE_VALUE.JSACTION: { - const jsObjectName = entityName; - const jsObject = entity as JSActionEntity; + const getterMethod = getEntityForEvalContextMap[entity.ENTITY_TYPE]; - let jsObjectForEval = JSObjectCollection.getVariableState(entityName); + if (!getterMethod) return entity; - const fns = getJSFunctionsForEntity({ - jsObjectName, - jsObject, - }); - - if (!jsObjectForEval) { - return Object.assign({}, jsObject, fns); - } - - jsObjectForEval = - JSObjectCollection.getVariablesForEvaluationContext(entityName); - return Object.assign(jsObjectForEval, fns); - } - } - } - return entity; + return getterMethod(entityName, entity); } diff --git a/app/client/src/workers/Evaluation/getJSActionForEvalContext.ts b/app/client/src/workers/Evaluation/getJSActionForEvalContext.ts new file mode 100644 index 0000000000..efd4b4c949 --- /dev/null +++ b/app/client/src/workers/Evaluation/getJSActionForEvalContext.ts @@ -0,0 +1,53 @@ +import type { JSActionEntity } from "@appsmith/entities/DataTree/types"; +import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes"; +import JSObjectCollection from "workers/Evaluation/JSObject/Collection"; +import { jsObjectFunctionFactory } from "workers/Evaluation/fns/utils/jsObjectFnFactory"; + +function getJSFunctionsForEntity({ + jsObject, + jsObjectName, +}: { + jsObjectName: string; + jsObject: JSActionEntity; +}) { + const jsObjectFunction: Record = {}; + const resolvedFunctions = JSObjectCollection.getResolvedFunctions(); + const resolvedObject = Object.assign({}, resolvedFunctions[jsObjectName]); + for (const fnName of Object.keys(resolvedObject || {})) { + const fn = resolvedObject[fnName]; + if (typeof fn !== "function") continue; + const data = jsObject[fnName]?.data; + jsObjectFunction[fnName] = jsObjectFunctionFactory( + fn, + jsObjectName + "." + fnName, + ); + + if (!!data) { + jsObjectFunction[fnName]["data"] = data; + } + } + return jsObjectFunction; +} + +export function getJSActionForEvalContext( + entityName: string, + entity: DataTreeEntity, +) { + const jsObjectName = entityName; + const jsObject = entity as JSActionEntity; + + let jsObjectForEval = JSObjectCollection.getVariableState(entityName); + + const fns = getJSFunctionsForEntity({ + jsObjectName, + jsObject, + }); + + if (!jsObjectForEval) { + return Object.assign({}, jsObject, fns); + } + + jsObjectForEval = + JSObjectCollection.getVariablesForEvaluationContext(entityName); + return Object.assign(jsObjectForEval, fns); +}