## 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>
129 lines
3.8 KiB
TypeScript
129 lines
3.8 KiB
TypeScript
import { isWidgetEntity } from "ee/plugins/Linting/lib/entity";
|
|
import {
|
|
convertPathToString,
|
|
getEntityNameAndPropertyPath,
|
|
isTrueObject,
|
|
} from "ee/workers/Evaluation/evaluationUtils";
|
|
import { toPath, union } from "lodash";
|
|
import { isDynamicEntity } from "ee/plugins/Linting/lib/entity/isDynamicEntity";
|
|
import type { IEntity } from "ee/plugins/Linting/lib/entity/types";
|
|
|
|
export class PathUtils {
|
|
static getReactivePaths(entity: IEntity) {
|
|
if (!isDynamicEntity(entity)) return [];
|
|
|
|
const config = entity.getConfig();
|
|
const name = entity.getName();
|
|
const reactivePaths = config.reactivePaths;
|
|
|
|
if (!reactivePaths) return [];
|
|
|
|
return PathUtils.getFullNamesFromPropertyPaths(
|
|
Object.keys(reactivePaths),
|
|
name,
|
|
);
|
|
}
|
|
static getBindingPaths(entity: IEntity) {
|
|
if (!isDynamicEntity(entity)) return [];
|
|
|
|
const config = entity.getConfig();
|
|
const name = entity.getName();
|
|
const bindingPaths = config.bindingPaths;
|
|
|
|
if (!bindingPaths) return [];
|
|
|
|
return PathUtils.getFullNamesFromPropertyPaths(
|
|
Object.keys(bindingPaths),
|
|
name,
|
|
);
|
|
}
|
|
|
|
static getTriggerPaths(entity: IEntity) {
|
|
if (!isWidgetEntity(entity)) return [];
|
|
|
|
const config = entity.getConfig();
|
|
const name = entity.getName();
|
|
const triggerPaths = config.triggerPaths;
|
|
|
|
return PathUtils.getFullNamesFromPropertyPaths(
|
|
Object.keys(triggerPaths),
|
|
name,
|
|
);
|
|
}
|
|
|
|
static getDynamicPaths(entity: IEntity) {
|
|
if (!isDynamicEntity(entity)) return [];
|
|
|
|
const reactivePaths = PathUtils.getReactivePaths(entity);
|
|
const triggerPaths = PathUtils.getTriggerPaths(entity);
|
|
const bindingPaths = PathUtils.getBindingPaths(entity);
|
|
|
|
return union(reactivePaths, triggerPaths, bindingPaths);
|
|
}
|
|
static getFullNamesFromPropertyPaths(paths: string[], parentName: string) {
|
|
return paths.map((path) => `${parentName}.${path}`);
|
|
}
|
|
static isDataPath(fullPath: string, entity: IEntity) {
|
|
if (!isWidgetEntity(entity) || !this.isDynamicLeaf(entity, fullPath))
|
|
return false;
|
|
|
|
const entityConfig = entity.getConfig();
|
|
const { propertyPath } = getEntityNameAndPropertyPath(fullPath);
|
|
|
|
return !(propertyPath in entityConfig.triggerPaths);
|
|
}
|
|
static getDataPaths(entity: IEntity) {
|
|
if (!isWidgetEntity(entity)) return [];
|
|
|
|
return PathUtils.getBindingPaths(entity);
|
|
}
|
|
static isDynamicLeaf(entity: IEntity, fullPropertyPath: string) {
|
|
const [entityName, ...propPathEls] = toPath(fullPropertyPath);
|
|
|
|
// Framework feature: Top level items are never leaves
|
|
if (entityName === fullPropertyPath) return false;
|
|
|
|
const entityConfig = entity.getConfig() as Record<string, unknown>;
|
|
|
|
if (!entityConfig) return false;
|
|
|
|
const reactivePaths = entityConfig.reactivePaths as Record<string, unknown>;
|
|
|
|
if (!isDynamicEntity(entity) || !entityConfig) return false;
|
|
|
|
const relativePropertyPath = convertPathToString(propPathEls);
|
|
|
|
return (
|
|
relativePropertyPath in reactivePaths ||
|
|
(isWidgetEntity(entity) &&
|
|
relativePropertyPath in entity.getConfig().triggerPaths)
|
|
);
|
|
}
|
|
|
|
static getAllPaths = (
|
|
// TODO: Fix this the next time the file is edited
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
records: any,
|
|
curKey = "",
|
|
result: Record<string, true> = {},
|
|
): Record<string, true> => {
|
|
if (curKey) result[curKey] = true;
|
|
|
|
if (Array.isArray(records)) {
|
|
for (let i = 0; i < records.length; i++) {
|
|
const tempKey = curKey ? `${curKey}[${i}]` : `${i}`;
|
|
|
|
PathUtils.getAllPaths(records[i], tempKey, result);
|
|
}
|
|
} else if (isTrueObject(records)) {
|
|
for (const key of Object.keys(records)) {
|
|
const tempKey = curKey ? `${curKey}.${key}` : `${key}`;
|
|
|
|
PathUtils.getAllPaths(records[key], tempKey, result);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
}
|