PromucFlow_constructor/app/client/src/workers/Linting/utils.ts

443 lines
13 KiB
TypeScript
Raw Normal View History

import { DataTree, DataTreeEntity } from "entities/DataTree/dataTreeFactory";
import { Position } from "codemirror";
import {
isDynamicValue,
isPathADynamicBinding,
LintError,
PropertyEvaluationErrorType,
} from "utils/DynamicBindingUtils";
import { MAIN_THREAD_ACTION } from "@appsmith/workers/Evaluation/evalWorkerActions";
import { JSHINT as jshint, LintError as JSHintError } from "jshint";
import { get, isEmpty, isNumber, keys, last } from "lodash";
feat: Linting in entity properties and methods (#16171) * Initial commit * Remove arrow function params from identifiers * Remove invalid identifiers from extracted identifiers * Remove invalid identifiers which are derived from function params and variable declarations * Fix typo error * Correctly remove invalid identifiers * Remove invalid names from identifier list * fix build failure * Add Promise to list of unacceptable entity name * Keep track of unreferenced identifiers in bindings * Add Global scope object names as unusable entity names * Keep track of unreferenced identifiers * Prevent traversal of data tree for addition of new paths and entities * Sync linting in trigger fields * Support linting of invalid properties * Fix linting reactivity bug in trigger field * Remove unused objects * Fix conflict in merging * Lint jsobject body for function change * Remove unused map from tests * Code cleanup * Modify jest tests * Update jest tests * Fix cypress tests * Code cleanup * Support linting of multiple bindings * Set squiggle line as long as invalid property length * Add jest tests * Minor code refactor * Move ast to shared repo * Rename confusing identifiers * Improve naming of functions and their return values * move shared widget validation utils and constants to shared folder * Add jest test for invalid entity names * Add cypress tests * Modify test comment * Extend list of dedicated worker scope identifiers * Resolve code review comments * Resolve review comments * Annonate code where necessary * Code refactor * Improve worker global scope object * Code refactor * Fix merge conflict * Code refactor * Minor bug fix * Redundant commit to retrigger vercel build * Add null checks to dependecy chain
2022-09-17 17:40:28 +00:00
import {
extractInvalidTopLevelMemberExpressionsFromCode,
isLiteralNode,
MemberExpressionData,
} from "@shared/ast";
import { getDynamicBindings } from "utils/DynamicBindingUtils";
import {
fix: improve error message and performance in JS functions (#19137) ## Description - Added logic to replace async function undefined error with "{{actionName}} cannot be used in this field". - This change improves performance for - ParseJSActions - Triggers execution - Each Appsmith framework action execution. - This change adds all platform functions to evalContext permanently. Fixes #12179 Fixes #13273 Internal discussion for error message :- https://theappsmith.slack.com/archives/C02K0SZQ7V3/p1667457021297869?thread_ts=1667385039.225229&cid=C02K0SZQ7V3 ## Type of change - Bug fix (non-breaking change which fixes an issue) - Performance improvement ## How Has This Been Tested? - Manual - Jest - Cypress ### Test Plan - [ ] https://github.com/appsmithorg/TestSmith/issues/2086 ### 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: - [ ] Test plan has been approved by relevant developers - [ ] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reveiwing all Cypress test Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
2022-12-23 10:04:39 +00:00
createEvaluationContext,
EvaluationScripts,
EvaluationScriptType,
getScriptToEval,
getScriptType,
ScriptTemplate,
} from "workers/Evaluation/evaluate";
import {
getEntityNameAndPropertyPath,
isAction,
isATriggerPath,
isJSAction,
isWidget,
} from "@appsmith/workers/Evaluation/evaluationUtils";
import { Severity } from "entities/AppsmithConsole";
import { JSLibraries } from "workers/common/JSLibrary";
fix: access outer scope variables inside callbacks (#20168) ## Description Any platform function that accepts a callback were unable to access the variables declared in its parent scopes. This was a implementation miss when we originally designed platform functions and again when we turned almost every platform function into a Promise. This PR fixes this limitation along with some other edge cases. - Access outer scope variables inside the callback of run, postMessage, setInterval, getGeoLocation and watchGeolocation functions. - Fixes certain edge cases where functions with callbacks when called inside the then block doesn't get executed. Eg `showAlert.then(() => /* Doesn't execute */ Api1.run(() => {}))` - Changes the implementation of all the platform function in appsmith to maintain the execution metadata (info on from where a function was invoked, event associated with it etc) #### Refactor changes - Added a new folder **_fns_** that would now hold all the platform functions. - Introduced a new ExecutionMetadata singleton class that is now responsible for hold all the meta data related to the current evaluation. - Remove TRIGGER_COLLECTOR array where all callback based platform functions were batched and introduced an Event Emitter based implementation to handle batched fn calls. - All callback based functions now emits event when invoked. These events have handlers attached to the TriggerEmitter object. These handler does the job of batching these invocations and telling the main thread. It also ensures that platform fn calls that gets triggered out the the context of a request/response cycle work. #### Architecture <img width="751" alt="Screenshot 2023-02-07 at 10 04 26" src="https://user-images.githubusercontent.com/32433245/217259200-5eac71bc-f0d3-4d3c-9b69-2a8dc81351bc.png"> Fixes #13156 Fixes #20225 ## Type of change - Bug fix (non-breaking change which fixes an issue) - Refactor ## How Has This Been Tested? - Jest - Cypress - Manual ### Test Plan - [ ] https://github.com/appsmithorg/TestSmith/issues/2181 - [ ] https://github.com/appsmithorg/TestSmith/issues/2182 - [ ] Post message - https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/post-msg-app/page1-635fcfba2987b442a739b938/edit - [ ] Apps: https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/earworm-1/home-630c9d85b4658d0f257c4987/edit - [ ] https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/automation-test-cases/page-1-630c6b90d4ecd573f6bb01e9/edit#0hmn8m90ei ### 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 - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag ### QA activity: - [ ] Test plan has been approved by relevant developers - [ ] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reviewing all Cypress test
2023-02-11 18:33:20 +00:00
import { WorkerMessenger } from "workers/Evaluation/fns/utils/Messenger";
import {
asyncActionInSyncFieldLintMessage,
CustomLintErrorCode,
CUSTOM_LINT_ERRORS,
IDENTIFIER_NOT_DEFINED_LINT_ERROR_CODE,
IGNORED_LINT_ERRORS,
INVALID_JSOBJECT_START_STATEMENT,
JS_OBJECT_START_STATEMENT,
lintOptions,
SUPPORTED_WEB_APIS,
WARNING_LINT_ERRORS,
} from "./constants";
import { APPSMITH_GLOBAL_FUNCTIONS } from "components/editorComponents/ActionCreator/constants";
interface lintBindingPathProps {
dynamicBinding: string;
entity: DataTreeEntity;
fullPropertyPath: string;
globalData: ReturnType<typeof createEvaluationContext>;
}
export function lintBindingPath({
dynamicBinding,
entity,
fullPropertyPath,
globalData,
}: lintBindingPathProps) {
let lintErrors: LintError[] = [];
if (isJSAction(entity)) {
if (!entity.body) return lintErrors;
if (!entity.body.startsWith(JS_OBJECT_START_STATEMENT)) {
return lintErrors.concat([
{
errorType: PropertyEvaluationErrorType.LINT,
errorSegment: "",
originalBinding: entity.body,
line: 0,
ch: 0,
code: entity.body,
variables: [],
raw: entity.body,
feat: Error handling phase 1 (#20629) ## Description This PR updates the error logs - Establishing a consistent format for all error messages. - Revising error titles and details for improved understanding. - Compiling internal documentation of all error categories, subcategories, and error descriptions. Updated Error Interface: https://www.notion.so/appsmith/Error-Interface-for-Plugin-Execution-Error-7b3f5323ba4c40bfad281ae717ccf79b PRD: https://www.notion.so/appsmith/PRD-Error-Handling-Framework-4ac9747057fd4105a9d52cb8b42f4452?pvs=4#008e9c79ff3c484abf0250a5416cf052 >TL;DR Fixes # Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video ## Type of change - New feature (non-breaking change which adds functionality) ## How Has This Been Tested? - Manual - Jest - Cypress ### Test Plan ### Issues raised during DP testing ## Checklist: ### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] PR is being merged under a feature flag ### QA activity: - [ ] Test plan has been approved by relevant developers - [ ] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reveiwing all Cypress test --------- Co-authored-by: subrata <subrata@appsmith.com>
2023-02-18 12:55:46 +00:00
errorMessage: {
name: "LintingError",
message: INVALID_JSOBJECT_START_STATEMENT,
},
severity: Severity.ERROR,
},
]);
}
}
const { propertyPath } = getEntityNameAndPropertyPath(fullPropertyPath);
// Get the {{binding}} bound values
const { jsSnippets, stringSegments } = getDynamicBindings(
dynamicBinding,
entity,
);
if (stringSegments) {
jsSnippets.forEach((jsSnippet, index) => {
if (jsSnippet) {
const jsSnippetToLint = getJSToLint(entity, jsSnippet, propertyPath);
// {{user's code}}
const originalBinding = getJSToLint(
entity,
stringSegments[index],
propertyPath,
);
const scriptType = getScriptType(false, false);
const scriptToLint = getScriptToEval(jsSnippetToLint, scriptType);
const lintErrorsFromSnippet = getLintingErrors({
script: scriptToLint,
data: globalData,
originalBinding,
scriptType,
entity,
fullPropertyPath,
});
lintErrors = lintErrors.concat(lintErrorsFromSnippet);
}
});
}
return lintErrors;
}
interface lintTriggerPathProps {
userScript: string;
entity: DataTreeEntity;
globalData: ReturnType<typeof createEvaluationContext>;
fullPropertyPath: string;
}
export function lintTriggerPath({
entity,
fullPropertyPath,
globalData,
userScript,
}: lintTriggerPathProps) {
const { jsSnippets } = getDynamicBindings(userScript, entity);
const script = getScriptToEval(jsSnippets[0], EvaluationScriptType.TRIGGERS);
return getLintingErrors({
script,
data: globalData,
originalBinding: jsSnippets[0],
scriptType: EvaluationScriptType.TRIGGERS,
entity,
fullPropertyPath,
});
}
export function pathRequiresLinting(
dataTree: DataTree,
entity: DataTreeEntity,
fullPropertyPath: string,
): boolean {
const { propertyPath } = getEntityNameAndPropertyPath(fullPropertyPath);
const unEvalPropertyValue = (get(
dataTree,
fullPropertyPath,
) as unknown) as string;
if (isATriggerPath(entity, propertyPath)) {
return isDynamicValue(unEvalPropertyValue);
}
const isADynamicBindingPath =
(isAction(entity) || isWidget(entity) || isJSAction(entity)) &&
isPathADynamicBinding(entity, propertyPath);
const requiresLinting =
feat: Linting in entity properties and methods (#16171) * Initial commit * Remove arrow function params from identifiers * Remove invalid identifiers from extracted identifiers * Remove invalid identifiers which are derived from function params and variable declarations * Fix typo error * Correctly remove invalid identifiers * Remove invalid names from identifier list * fix build failure * Add Promise to list of unacceptable entity name * Keep track of unreferenced identifiers in bindings * Add Global scope object names as unusable entity names * Keep track of unreferenced identifiers * Prevent traversal of data tree for addition of new paths and entities * Sync linting in trigger fields * Support linting of invalid properties * Fix linting reactivity bug in trigger field * Remove unused objects * Fix conflict in merging * Lint jsobject body for function change * Remove unused map from tests * Code cleanup * Modify jest tests * Update jest tests * Fix cypress tests * Code cleanup * Support linting of multiple bindings * Set squiggle line as long as invalid property length * Add jest tests * Minor code refactor * Move ast to shared repo * Rename confusing identifiers * Improve naming of functions and their return values * move shared widget validation utils and constants to shared folder * Add jest test for invalid entity names * Add cypress tests * Modify test comment * Extend list of dedicated worker scope identifiers * Resolve code review comments * Resolve review comments * Annonate code where necessary * Code refactor * Improve worker global scope object * Code refactor * Fix merge conflict * Code refactor * Minor bug fix * Redundant commit to retrigger vercel build * Add null checks to dependecy chain
2022-09-17 17:40:28 +00:00
(isADynamicBindingPath && isDynamicValue(unEvalPropertyValue)) ||
isJSAction(entity);
return requiresLinting;
}
// Removes "export default" statement from js Object
export function getJSToLint(
entity: DataTreeEntity,
snippet: string,
propertyPath: string,
): string {
return entity && isJSAction(entity) && propertyPath === "body"
? snippet.replace(/export default/g, "")
: snippet;
}
export function getPositionInEvaluationScript(
type: EvaluationScriptType,
): Position {
const script = EvaluationScripts[type];
const index = script.indexOf(ScriptTemplate);
const substr = script.slice(0, index !== -1 ? index : 0);
const lines = substr.split("\n");
const lastLine = last(lines) || "";
return { line: lines.length, ch: lastLine.length };
}
const EvaluationScriptPositions: Record<string, Position> = {};
function getEvaluationScriptPosition(scriptType: EvaluationScriptType) {
if (isEmpty(EvaluationScriptPositions)) {
// We are computing position of <<script>> in our templates.
// This will be used to get the exact location of error in linting
keys(EvaluationScripts).forEach((type) => {
EvaluationScriptPositions[type] = getPositionInEvaluationScript(
type as EvaluationScriptType,
);
});
}
return EvaluationScriptPositions[scriptType];
}
function generateLintingGlobalData(data: Record<string, unknown>) {
const globalData: Record<string, boolean> = {};
for (const dataKey in data) {
globalData[dataKey] = true;
}
// Add all js libraries
const libAccessors = ([] as string[]).concat(
...JSLibraries.map((lib) => lib.accessor),
);
libAccessors.forEach((accessor) => (globalData[accessor] = true));
// Add all supported web apis
Object.keys(SUPPORTED_WEB_APIS).forEach(
(apiName) => (globalData[apiName] = true),
);
return globalData;
}
function sanitizeJSHintErrors(
lintErrors: JSHintError[],
scriptPos: Position,
): JSHintError[] {
return lintErrors.reduce((result: JSHintError[], lintError) => {
// Ignored errors should not be reported
if (IGNORED_LINT_ERRORS.includes(lintError.code)) return result;
/** Some error messages reference line numbers,
* Eg. Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'
* these line numbers need to be re-calculated based on the binding location.
* Errors referencing line numbers outside the user's script should also be ignored
* */
let message = lintError.reason;
const matchedLines = message.match(/line \d/gi);
const lineNumbersInErrorMessage = new Set<number>();
let isInvalidErrorMessage = false;
if (matchedLines) {
matchedLines.forEach((lineStatement) => {
const digitString = lineStatement.split(" ")[1];
const digit = Number(digitString);
if (isNumber(digit)) {
if (digit < scriptPos.line) {
// referenced line number is outside the scope of user's script
isInvalidErrorMessage = true;
} else {
lineNumbersInErrorMessage.add(digit);
}
}
});
}
if (isInvalidErrorMessage) return result;
if (lineNumbersInErrorMessage.size) {
Array.from(lineNumbersInErrorMessage).forEach((lineNumber) => {
message = message.replaceAll(
`line ${lineNumber}`,
`line ${lineNumber - scriptPos.line + 1}`,
);
});
}
result.push({
...lintError,
reason: message,
});
return result;
}, []);
}
const getLintSeverity = (code: string): Severity.WARNING | Severity.ERROR => {
const severity =
code in WARNING_LINT_ERRORS ? Severity.WARNING : Severity.ERROR;
return severity;
};
const getLintErrorMessage = (
reason: string,
code: string,
variables: string[],
): string => {
switch (code) {
case IDENTIFIER_NOT_DEFINED_LINT_ERROR_CODE: {
return getRefinedW117Error(variables[0], reason);
}
default: {
return reason;
}
}
};
function convertJsHintErrorToAppsmithLintError(
jsHintError: JSHintError,
script: string,
originalBinding: string,
scriptPos: Position,
): LintError {
const { a, b, c, code, d, evidence, reason } = jsHintError;
// Compute actual error position
const actualErrorLineNumber = jsHintError.line - scriptPos.line;
const actualErrorCh =
jsHintError.line === scriptPos.line
? jsHintError.character - scriptPos.ch
: jsHintError.character;
return {
errorType: PropertyEvaluationErrorType.LINT,
raw: script,
severity: getLintSeverity(code),
errorMessage: {
name: "LintingError",
message: getLintErrorMessage(reason, code, [a, b, c, d]),
},
errorSegment: evidence,
originalBinding,
// By keeping track of these variables we can highlight the exact text that caused the error.
variables: [a, b, c, d],
code: code,
line: actualErrorLineNumber,
ch: actualErrorCh,
};
}
interface getLintingErrorsProps {
script: string;
data: Record<string, unknown>;
// {{user's code}}
originalBinding: string;
scriptType: EvaluationScriptType;
entity: DataTreeEntity;
fullPropertyPath: string;
}
export function getLintingErrors({
data,
originalBinding,
script,
scriptType,
}: getLintingErrorsProps): LintError[] {
const scriptPos = getEvaluationScriptPosition(scriptType);
const lintingGlobalData = generateLintingGlobalData(data);
const lintingOptions = lintOptions(lintingGlobalData);
jshint(script, lintingOptions);
const sanitizedJSHintErrors = sanitizeJSHintErrors(jshint.errors, scriptPos);
const jshintErrors: LintError[] = sanitizedJSHintErrors.map((lintError) =>
convertJsHintErrorToAppsmithLintError(
lintError,
script,
originalBinding,
scriptPos,
),
);
const invalidPropertyErrors = getInvalidPropertyErrorsFromScript(
script,
data,
scriptPos,
originalBinding,
);
return jshintErrors.concat(invalidPropertyErrors);
}
feat: Linting in entity properties and methods (#16171) * Initial commit * Remove arrow function params from identifiers * Remove invalid identifiers from extracted identifiers * Remove invalid identifiers which are derived from function params and variable declarations * Fix typo error * Correctly remove invalid identifiers * Remove invalid names from identifier list * fix build failure * Add Promise to list of unacceptable entity name * Keep track of unreferenced identifiers in bindings * Add Global scope object names as unusable entity names * Keep track of unreferenced identifiers * Prevent traversal of data tree for addition of new paths and entities * Sync linting in trigger fields * Support linting of invalid properties * Fix linting reactivity bug in trigger field * Remove unused objects * Fix conflict in merging * Lint jsobject body for function change * Remove unused map from tests * Code cleanup * Modify jest tests * Update jest tests * Fix cypress tests * Code cleanup * Support linting of multiple bindings * Set squiggle line as long as invalid property length * Add jest tests * Minor code refactor * Move ast to shared repo * Rename confusing identifiers * Improve naming of functions and their return values * move shared widget validation utils and constants to shared folder * Add jest test for invalid entity names * Add cypress tests * Modify test comment * Extend list of dedicated worker scope identifiers * Resolve code review comments * Resolve review comments * Annonate code where necessary * Code refactor * Improve worker global scope object * Code refactor * Fix merge conflict * Code refactor * Minor bug fix * Redundant commit to retrigger vercel build * Add null checks to dependecy chain
2022-09-17 17:40:28 +00:00
// returns lint errors caused by accessing invalid properties. Eg. jsObject.unknownProperty
function getInvalidPropertyErrorsFromScript(
feat: Linting in entity properties and methods (#16171) * Initial commit * Remove arrow function params from identifiers * Remove invalid identifiers from extracted identifiers * Remove invalid identifiers which are derived from function params and variable declarations * Fix typo error * Correctly remove invalid identifiers * Remove invalid names from identifier list * fix build failure * Add Promise to list of unacceptable entity name * Keep track of unreferenced identifiers in bindings * Add Global scope object names as unusable entity names * Keep track of unreferenced identifiers * Prevent traversal of data tree for addition of new paths and entities * Sync linting in trigger fields * Support linting of invalid properties * Fix linting reactivity bug in trigger field * Remove unused objects * Fix conflict in merging * Lint jsobject body for function change * Remove unused map from tests * Code cleanup * Modify jest tests * Update jest tests * Fix cypress tests * Code cleanup * Support linting of multiple bindings * Set squiggle line as long as invalid property length * Add jest tests * Minor code refactor * Move ast to shared repo * Rename confusing identifiers * Improve naming of functions and their return values * move shared widget validation utils and constants to shared folder * Add jest test for invalid entity names * Add cypress tests * Modify test comment * Extend list of dedicated worker scope identifiers * Resolve code review comments * Resolve review comments * Annonate code where necessary * Code refactor * Improve worker global scope object * Code refactor * Fix merge conflict * Code refactor * Minor bug fix * Redundant commit to retrigger vercel build * Add null checks to dependecy chain
2022-09-17 17:40:28 +00:00
script: string,
data: Record<string, unknown>,
scriptPos: Position,
originalBinding: string,
): LintError[] {
feat: Linting in entity properties and methods (#16171) * Initial commit * Remove arrow function params from identifiers * Remove invalid identifiers from extracted identifiers * Remove invalid identifiers which are derived from function params and variable declarations * Fix typo error * Correctly remove invalid identifiers * Remove invalid names from identifier list * fix build failure * Add Promise to list of unacceptable entity name * Keep track of unreferenced identifiers in bindings * Add Global scope object names as unusable entity names * Keep track of unreferenced identifiers * Prevent traversal of data tree for addition of new paths and entities * Sync linting in trigger fields * Support linting of invalid properties * Fix linting reactivity bug in trigger field * Remove unused objects * Fix conflict in merging * Lint jsobject body for function change * Remove unused map from tests * Code cleanup * Modify jest tests * Update jest tests * Fix cypress tests * Code cleanup * Support linting of multiple bindings * Set squiggle line as long as invalid property length * Add jest tests * Minor code refactor * Move ast to shared repo * Rename confusing identifiers * Improve naming of functions and their return values * move shared widget validation utils and constants to shared folder * Add jest test for invalid entity names * Add cypress tests * Modify test comment * Extend list of dedicated worker scope identifiers * Resolve code review comments * Resolve review comments * Annonate code where necessary * Code refactor * Improve worker global scope object * Code refactor * Fix merge conflict * Code refactor * Minor bug fix * Redundant commit to retrigger vercel build * Add null checks to dependecy chain
2022-09-17 17:40:28 +00:00
let invalidTopLevelMemberExpressions: MemberExpressionData[] = [];
try {
invalidTopLevelMemberExpressions = extractInvalidTopLevelMemberExpressionsFromCode(
script,
data,
self.evaluationVersion,
);
} catch (e) {}
const invalidPropertyErrors = invalidTopLevelMemberExpressions.map(
({ object, property }): LintError => {
feat: Linting in entity properties and methods (#16171) * Initial commit * Remove arrow function params from identifiers * Remove invalid identifiers from extracted identifiers * Remove invalid identifiers which are derived from function params and variable declarations * Fix typo error * Correctly remove invalid identifiers * Remove invalid names from identifier list * fix build failure * Add Promise to list of unacceptable entity name * Keep track of unreferenced identifiers in bindings * Add Global scope object names as unusable entity names * Keep track of unreferenced identifiers * Prevent traversal of data tree for addition of new paths and entities * Sync linting in trigger fields * Support linting of invalid properties * Fix linting reactivity bug in trigger field * Remove unused objects * Fix conflict in merging * Lint jsobject body for function change * Remove unused map from tests * Code cleanup * Modify jest tests * Update jest tests * Fix cypress tests * Code cleanup * Support linting of multiple bindings * Set squiggle line as long as invalid property length * Add jest tests * Minor code refactor * Move ast to shared repo * Rename confusing identifiers * Improve naming of functions and their return values * move shared widget validation utils and constants to shared folder * Add jest test for invalid entity names * Add cypress tests * Modify test comment * Extend list of dedicated worker scope identifiers * Resolve code review comments * Resolve review comments * Annonate code where necessary * Code refactor * Improve worker global scope object * Code refactor * Fix merge conflict * Code refactor * Minor bug fix * Redundant commit to retrigger vercel build * Add null checks to dependecy chain
2022-09-17 17:40:28 +00:00
const propertyName = isLiteralNode(property)
? (property.value as string)
feat: Linting in entity properties and methods (#16171) * Initial commit * Remove arrow function params from identifiers * Remove invalid identifiers from extracted identifiers * Remove invalid identifiers which are derived from function params and variable declarations * Fix typo error * Correctly remove invalid identifiers * Remove invalid names from identifier list * fix build failure * Add Promise to list of unacceptable entity name * Keep track of unreferenced identifiers in bindings * Add Global scope object names as unusable entity names * Keep track of unreferenced identifiers * Prevent traversal of data tree for addition of new paths and entities * Sync linting in trigger fields * Support linting of invalid properties * Fix linting reactivity bug in trigger field * Remove unused objects * Fix conflict in merging * Lint jsobject body for function change * Remove unused map from tests * Code cleanup * Modify jest tests * Update jest tests * Fix cypress tests * Code cleanup * Support linting of multiple bindings * Set squiggle line as long as invalid property length * Add jest tests * Minor code refactor * Move ast to shared repo * Rename confusing identifiers * Improve naming of functions and their return values * move shared widget validation utils and constants to shared folder * Add jest test for invalid entity names * Add cypress tests * Modify test comment * Extend list of dedicated worker scope identifiers * Resolve code review comments * Resolve review comments * Annonate code where necessary * Code refactor * Improve worker global scope object * Code refactor * Fix merge conflict * Code refactor * Minor bug fix * Redundant commit to retrigger vercel build * Add null checks to dependecy chain
2022-09-17 17:40:28 +00:00
: property.name;
const objectStartLine = object.loc.start.line - 1;
// For computed member expressions (entity["property"]), add an extra 1 to the start column to account for "[".
const propertyStartColumn = !isLiteralNode(property)
? property.loc.start.column + 1
: property.loc.start.column + 2;
return {
errorType: PropertyEvaluationErrorType.LINT,
raw: script,
severity: getLintSeverity(CustomLintErrorCode.INVALID_ENTITY_PROPERTY),
feat: Error handling phase 1 (#20629) ## Description This PR updates the error logs - Establishing a consistent format for all error messages. - Revising error titles and details for improved understanding. - Compiling internal documentation of all error categories, subcategories, and error descriptions. Updated Error Interface: https://www.notion.so/appsmith/Error-Interface-for-Plugin-Execution-Error-7b3f5323ba4c40bfad281ae717ccf79b PRD: https://www.notion.so/appsmith/PRD-Error-Handling-Framework-4ac9747057fd4105a9d52cb8b42f4452?pvs=4#008e9c79ff3c484abf0250a5416cf052 >TL;DR Fixes # Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video ## Type of change - New feature (non-breaking change which adds functionality) ## How Has This Been Tested? - Manual - Jest - Cypress ### Test Plan ### Issues raised during DP testing ## Checklist: ### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] PR is being merged under a feature flag ### QA activity: - [ ] Test plan has been approved by relevant developers - [ ] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reveiwing all Cypress test --------- Co-authored-by: subrata <subrata@appsmith.com>
2023-02-18 12:55:46 +00:00
errorMessage: {
name: "LintingError",
message: CUSTOM_LINT_ERRORS[
CustomLintErrorCode.INVALID_ENTITY_PROPERTY
](object.name, propertyName),
},
feat: Linting in entity properties and methods (#16171) * Initial commit * Remove arrow function params from identifiers * Remove invalid identifiers from extracted identifiers * Remove invalid identifiers which are derived from function params and variable declarations * Fix typo error * Correctly remove invalid identifiers * Remove invalid names from identifier list * fix build failure * Add Promise to list of unacceptable entity name * Keep track of unreferenced identifiers in bindings * Add Global scope object names as unusable entity names * Keep track of unreferenced identifiers * Prevent traversal of data tree for addition of new paths and entities * Sync linting in trigger fields * Support linting of invalid properties * Fix linting reactivity bug in trigger field * Remove unused objects * Fix conflict in merging * Lint jsobject body for function change * Remove unused map from tests * Code cleanup * Modify jest tests * Update jest tests * Fix cypress tests * Code cleanup * Support linting of multiple bindings * Set squiggle line as long as invalid property length * Add jest tests * Minor code refactor * Move ast to shared repo * Rename confusing identifiers * Improve naming of functions and their return values * move shared widget validation utils and constants to shared folder * Add jest test for invalid entity names * Add cypress tests * Modify test comment * Extend list of dedicated worker scope identifiers * Resolve code review comments * Resolve review comments * Annonate code where necessary * Code refactor * Improve worker global scope object * Code refactor * Fix merge conflict * Code refactor * Minor bug fix * Redundant commit to retrigger vercel build * Add null checks to dependecy chain
2022-09-17 17:40:28 +00:00
errorSegment: `${object.name}.${propertyName}`,
originalBinding,
variables: [propertyName, null, null, null],
code: CustomLintErrorCode.INVALID_ENTITY_PROPERTY,
line: objectStartLine - scriptPos.line,
ch:
objectStartLine === scriptPos.line
? propertyStartColumn - scriptPos.ch
: propertyStartColumn,
};
},
);
return invalidPropertyErrors;
}
export function initiateLinting(
lintOrder: string[],
unevalTree: DataTree,
requiresLinting: boolean,
) {
if (!requiresLinting) return;
fix: access outer scope variables inside callbacks (#20168) ## Description Any platform function that accepts a callback were unable to access the variables declared in its parent scopes. This was a implementation miss when we originally designed platform functions and again when we turned almost every platform function into a Promise. This PR fixes this limitation along with some other edge cases. - Access outer scope variables inside the callback of run, postMessage, setInterval, getGeoLocation and watchGeolocation functions. - Fixes certain edge cases where functions with callbacks when called inside the then block doesn't get executed. Eg `showAlert.then(() => /* Doesn't execute */ Api1.run(() => {}))` - Changes the implementation of all the platform function in appsmith to maintain the execution metadata (info on from where a function was invoked, event associated with it etc) #### Refactor changes - Added a new folder **_fns_** that would now hold all the platform functions. - Introduced a new ExecutionMetadata singleton class that is now responsible for hold all the meta data related to the current evaluation. - Remove TRIGGER_COLLECTOR array where all callback based platform functions were batched and introduced an Event Emitter based implementation to handle batched fn calls. - All callback based functions now emits event when invoked. These events have handlers attached to the TriggerEmitter object. These handler does the job of batching these invocations and telling the main thread. It also ensures that platform fn calls that gets triggered out the the context of a request/response cycle work. #### Architecture <img width="751" alt="Screenshot 2023-02-07 at 10 04 26" src="https://user-images.githubusercontent.com/32433245/217259200-5eac71bc-f0d3-4d3c-9b69-2a8dc81351bc.png"> Fixes #13156 Fixes #20225 ## Type of change - Bug fix (non-breaking change which fixes an issue) - Refactor ## How Has This Been Tested? - Jest - Cypress - Manual ### Test Plan - [ ] https://github.com/appsmithorg/TestSmith/issues/2181 - [ ] https://github.com/appsmithorg/TestSmith/issues/2182 - [ ] Post message - https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/post-msg-app/page1-635fcfba2987b442a739b938/edit - [ ] Apps: https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/earworm-1/home-630c9d85b4658d0f257c4987/edit - [ ] https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/automation-test-cases/page-1-630c6b90d4ecd573f6bb01e9/edit#0hmn8m90ei ### 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 - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag ### QA activity: - [ ] Test plan has been approved by relevant developers - [ ] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reviewing all Cypress test
2023-02-11 18:33:20 +00:00
WorkerMessenger.ping({
data: {
lintOrder,
unevalTree,
},
fix: access outer scope variables inside callbacks (#20168) ## Description Any platform function that accepts a callback were unable to access the variables declared in its parent scopes. This was a implementation miss when we originally designed platform functions and again when we turned almost every platform function into a Promise. This PR fixes this limitation along with some other edge cases. - Access outer scope variables inside the callback of run, postMessage, setInterval, getGeoLocation and watchGeolocation functions. - Fixes certain edge cases where functions with callbacks when called inside the then block doesn't get executed. Eg `showAlert.then(() => /* Doesn't execute */ Api1.run(() => {}))` - Changes the implementation of all the platform function in appsmith to maintain the execution metadata (info on from where a function was invoked, event associated with it etc) #### Refactor changes - Added a new folder **_fns_** that would now hold all the platform functions. - Introduced a new ExecutionMetadata singleton class that is now responsible for hold all the meta data related to the current evaluation. - Remove TRIGGER_COLLECTOR array where all callback based platform functions were batched and introduced an Event Emitter based implementation to handle batched fn calls. - All callback based functions now emits event when invoked. These events have handlers attached to the TriggerEmitter object. These handler does the job of batching these invocations and telling the main thread. It also ensures that platform fn calls that gets triggered out the the context of a request/response cycle work. #### Architecture <img width="751" alt="Screenshot 2023-02-07 at 10 04 26" src="https://user-images.githubusercontent.com/32433245/217259200-5eac71bc-f0d3-4d3c-9b69-2a8dc81351bc.png"> Fixes #13156 Fixes #20225 ## Type of change - Bug fix (non-breaking change which fixes an issue) - Refactor ## How Has This Been Tested? - Jest - Cypress - Manual ### Test Plan - [ ] https://github.com/appsmithorg/TestSmith/issues/2181 - [ ] https://github.com/appsmithorg/TestSmith/issues/2182 - [ ] Post message - https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/post-msg-app/page1-635fcfba2987b442a739b938/edit - [ ] Apps: https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/earworm-1/home-630c9d85b4658d0f257c4987/edit - [ ] https://appsmith-git-chore-outer-scope-variable-access-get-appsmith.vercel.app/app/automation-test-cases/page-1-630c6b90d4ecd573f6bb01e9/edit#0hmn8m90ei ### 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 - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag ### QA activity: - [ ] Test plan has been approved by relevant developers - [ ] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reviewing all Cypress test
2023-02-11 18:33:20 +00:00
method: MAIN_THREAD_ACTION.LINT_TREE,
});
}
export function getRefinedW117Error(
undefinedVar: string,
originalReason: string,
) {
// Refine error message for await using in field not marked as async
if (undefinedVar === "await") {
return "'await' expressions are only allowed within async functions. Did you mean to mark this function as 'async'?";
}
// Handle case where platform functions are used in sync fields
if (APPSMITH_GLOBAL_FUNCTIONS.hasOwnProperty(undefinedVar)) {
return asyncActionInSyncFieldLintMessage(undefinedVar);
}
return originalReason;
}