import type { DataTree, DataTreeEntity, ConfigTree, } from "entities/DataTree/dataTreeFactory"; import type { Position } from "codemirror"; import type { LintError } from "utils/DynamicBindingUtils"; import type { DependencyMap } from "utils/DynamicBindingUtils"; import { MAIN_THREAD_ACTION } from "@appsmith/workers/Evaluation/evalWorkerActions"; import { JSHINT as jshint } from "jshint"; import type { LintError as JSHintError } from "jshint"; import { isEmpty, isNil, isNumber, keys, last } from "lodash"; import type { MemberExpressionData } from "@shared/ast"; import { extractInvalidTopLevelMemberExpressionsFromCode, isLiteralNode, } from "@shared/ast"; import { getDynamicBindings, PropertyEvaluationErrorType, } from "utils/DynamicBindingUtils"; import { createEvaluationContext, EvaluationScripts, EvaluationScriptType, getScriptToEval, getScriptType, ScriptTemplate, } from "workers/Evaluation/evaluate"; import { getEntityNameAndPropertyPath, isATriggerPath, isDataTreeEntity, isDynamicLeaf, isJSAction, } from "@appsmith/workers/Evaluation/evaluationUtils"; 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, INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE, JS_OBJECT_START_STATEMENT, lintOptions, SUPPORTED_WEB_APIS, WARNING_LINT_ERRORS, } from "./constants"; import { APPSMITH_GLOBAL_FUNCTIONS } from "components/editorComponents/ActionCreator/constants"; import type { getLintingErrorsProps, initiateLintingProps, lintBindingPathProps, LintTreeSagaRequestData, lintTriggerPathProps, } from "./types"; import { JSLibraries } from "workers/common/JSLibrary"; import { Severity } from "entities/AppsmithConsole"; import { entityFns, getActionTriggerFunctionNames, } from "workers/Evaluation/fns"; import type { TJSFunctionPropertyState, TJSpropertyState, } from "workers/Evaluation/JSObject/jsPropertiesState"; import type { JSActionEntity } from "entities/DataTree/types"; import { globalData } from "./globalData"; export function lintBindingPath({ dynamicBinding, entity, fullPropertyPath, globalData, }: lintBindingPathProps) { let lintErrors: LintError[] = []; 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, }); lintErrors = lintErrors.concat(lintErrorsFromSnippet); } }); } return lintErrors; } export function lintTriggerPath({ entity, 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, }); } // 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 = {}; function getEvaluationScriptPosition(scriptType: EvaluationScriptType) { if (isEmpty(EvaluationScriptPositions)) { // We are computing position of <