PromucFlow_constructor/app/client/src/workers/Evaluation/setters.ts
Ilia d6f249b42d
chore: add blank line eslint rule (#36369)
## Description
Added ESLint rule to force blank lines between statements. 


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]
> 🔴 🔴 🔴 Some tests have failed.
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/10924926728>
> Commit: 34f57714a1575ee04e94e03cbcaf95e57a96c86c
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10924926728&attempt=1&selectiontype=test&testsstatus=failed&specsstatus=fail"
target="_blank">Cypress dashboard</a>.
> Tags: @tag.All
> Spec: 
> The following are new failures, please fix them before merging the PR:
<ol>
> <li>cypress/e2e/Regression/ClientSide/Anvil/AnvilModal_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts</ol>
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/identified-flaky-tests-65890b3c81d7400d08fa9ee3?branch=master"
target="_blank">List of identified flaky tests</a>.
> <hr>Wed, 18 Sep 2024 16:33:36 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No

---------

Co-authored-by: Valera Melnikov <valera@appsmith.com>
2024-09-18 19:35:28 +03:00

220 lines
6.0 KiB
TypeScript

import {
getEntityNameAndPropertyPath,
isWidget,
overrideWidgetProperties,
} from "ee/workers/Evaluation/evaluationUtils";
import type { EvalMetaUpdates } from "ee/workers/common/DataTreeEvaluator/types";
import { evalTreeWithChanges } from "./evalTreeWithChanges";
import { dataTreeEvaluator } from "./handlers/evalTree";
import { get, set } from "lodash";
import { validate } from "./validations";
import type {
DataTreeEntityConfig,
WidgetEntity,
} from "ee/entities/DataTree/types";
import type {
ConfigTree,
DataTree,
DataTreeEntity,
} from "entities/DataTree/dataTreeTypes";
import { getFnWithGuards, isAsyncGuard } from "./fns/utils/fnGuard";
import { shouldAddSetter } from "./evaluate";
import { EVAL_WORKER_SYNC_ACTION } from "ee/workers/Evaluation/evalWorkerActions";
class Setters {
/** stores the setter method accessor as key and true as value
*
* example - ```{ "Table1.setVisibility": true, "Table1.setData": true }```
*/
private setterMethodLookup: Record<string, true> = {};
/** stores the setter property accessor as key and setter method name as value
*
* example - ```{ "Table1.tableData": "Table1.setData" }```
*/
private setterAccessorMap: Record<string, string> = {};
private async applySetterMethod(
path: string,
value: unknown,
setterMethodName: string,
) {
const { entityName, propertyPath } = getEntityNameAndPropertyPath(path);
if (!dataTreeEvaluator) return;
const evalTree = dataTreeEvaluator.getEvalTree();
const configTree = dataTreeEvaluator.getConfigTree();
const entity = evalTree[entityName];
const entityConfig = configTree[entityName];
const updatedProperties: string[][] = [];
const overriddenProperties: string[] = [];
const evalMetaUpdates: EvalMetaUpdates = [];
let parsedValue = value;
if (value === undefined) {
const error = new Error(
`The value passed to ${entityName}.${setterMethodName}() evaluates to undefined.`,
);
error.name = entityName + "." + setterMethodName + " failed";
throw error;
}
const { validationPaths } = entityConfig;
if (validationPaths) {
const validationConfig = validationPaths[propertyPath] || {};
const config = {
...validationConfig,
params: { ...(validationConfig.params || {}) },
};
config.params.strict = true;
const { isValid, messages, parsed } = validate(
config,
value,
entity as Record<string, unknown>,
propertyPath,
);
parsedValue = parsed;
if (!isValid) {
const message = messages && messages[0] ? messages[0].message : "";
const error = new Error(
`${entityName + "." + setterMethodName}: ${message}`,
);
error.name = entityName + "." + setterMethodName + " failed";
throw error;
}
}
if (isWidget(entity)) {
overrideWidgetProperties({
entity: entity as WidgetEntity,
propertyPath,
value: parsedValue,
currentTree: evalTree,
configTree,
evalMetaUpdates,
fullPropertyPath: path,
isNewWidget: false,
shouldUpdateGlobalContext: true,
overriddenProperties,
});
overriddenProperties.forEach((propPath) => {
updatedProperties.push([entityName, propPath]);
});
}
set(evalTree, path, parsedValue);
set(self, path, parsedValue);
/**
* Making the update to dataTree async as there could be queue microtask updates that need to execute before this update.
* Issue:- https://github.com/appsmithorg/appsmith/issues/25364
*/
return new Promise((resolve) => {
resolve(parsedValue);
}).then((res) => {
updatedProperties.push([entityName, propertyPath]);
evalTreeWithChanges({
data: {
updatedValuePaths: updatedProperties,
metaUpdates: evalMetaUpdates,
},
method: EVAL_WORKER_SYNC_ACTION.EVAL_TREE_WITH_CHANGES,
webworkerTelemetry: {},
});
return res;
});
}
/** Generates a new setter method */
private createSetter(
path: string,
setterMethodName: string,
entityName: string,
) {
/** register the setter method in the lookup */
set(this.setterMethodLookup, [entityName, setterMethodName], true);
const fn = async (value: unknown) => {
if (!dataTreeEvaluator) return;
return this.applySetterMethod(path, value, setterMethodName);
};
return getFnWithGuards(fn, setterMethodName, [isAsyncGuard]);
}
clear() {
this.setterMethodLookup = {};
}
has(entityName: string, propertyName: string) {
return get(this.setterMethodLookup, [entityName, propertyName], false);
}
getMap() {
return this.setterMethodLookup;
}
getSetterAccessorMap() {
return this.setterAccessorMap;
}
getEntitySettersFromConfig(
entityConfig: DataTreeEntityConfig,
entityName: string,
entity: DataTreeEntity,
) {
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const setterMethodMap: Record<string, any> = {};
if (!entityConfig) return setterMethodMap;
if (entityConfig.__setters) {
for (const setterMethodName of Object.keys(entityConfig.__setters)) {
const pathToSet = entityConfig.__setters[setterMethodName].path;
if (!shouldAddSetter(entityConfig.__setters[setterMethodName], entity))
continue;
this.setterAccessorMap[pathToSet] = `${entityName}.${setterMethodName}`;
setterMethodMap[setterMethodName] = this.createSetter(
pathToSet,
setterMethodName,
entityName,
);
}
}
return setterMethodMap;
}
init(configTree: ConfigTree, dataTree: DataTree) {
const configTreeEntries = Object.entries(configTree);
for (const [entityName, entityConfig] of configTreeEntries) {
const entity = dataTree[entityName];
this.getEntitySettersFromConfig(entityConfig, entityName, entity);
}
}
}
const setters = new Setters();
export default setters;