## Description Fix linting error for `fetch` window API Fixes https://github.com/appsmithorg/appsmith/issues/33268 ## Automation /ok-to-test tags="@tag.JS" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/9023762582> > Commit: f235c91a7d3437eca91b0f900f05a28b42da3226 > Cypress dashboard url: <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=9023762582&attempt=1" target="_blank">Click here!</a> <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No
126 lines
5.2 KiB
TypeScript
126 lines
5.2 KiB
TypeScript
import { ECMA_VERSION } from "@shared/ast";
|
|
import type { LintOptions } from "jshint";
|
|
import isEntityFunction from "./utils/isEntityFunction";
|
|
|
|
export const lintOptions = (globalData: Record<string, boolean>) =>
|
|
({
|
|
indent: 2,
|
|
esversion: ECMA_VERSION,
|
|
eqeqeq: false, // Not necessary to use ===
|
|
curly: false, // Blocks can be added without {}, eg if (x) return true
|
|
freeze: true, // Overriding inbuilt classes like Array is not allowed
|
|
undef: true, // Undefined variables should be reported as error
|
|
forin: false, // Doesn't require filtering for..in loops with obj.hasOwnProperty()
|
|
noempty: false, // Empty blocks are allowed
|
|
strict: false, // We won't force strict mode
|
|
unused: "strict", // Unused variables are not allowed
|
|
asi: true, // Tolerate Automatic Semicolon Insertion (no semicolons)
|
|
boss: true, // Tolerate assignments where comparisons would be expected
|
|
evil: false, // Use of eval not allowed
|
|
funcscope: true, // Tolerate variable definition inside control statements
|
|
sub: true, // Don't force dot notation
|
|
expr: true, // suppresses warnings about the use of expressions where normally you would expect to see assignments or function calls
|
|
// environments
|
|
browser: false,
|
|
worker: true,
|
|
mocha: false,
|
|
// global values
|
|
globals: globalData,
|
|
loopfunc: true,
|
|
}) as LintOptions;
|
|
export const JS_OBJECT_START_STATEMENT = "export default";
|
|
export const INVALID_JSOBJECT_START_STATEMENT = `JSObject must start with '${JS_OBJECT_START_STATEMENT}'`;
|
|
export const INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE =
|
|
"INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE";
|
|
// https://github.com/jshint/jshint/blob/d3d84ae1695359aef077ddb143f4be98001343b4/src/messages.js#L204
|
|
export const IDENTIFIER_NOT_DEFINED_LINT_ERROR_CODE = "W117";
|
|
|
|
// For these error types, we want to show a warning
|
|
// All messages can be found here => https://github.com/jshint/jshint/blob/2.9.5/src/messages.js
|
|
export const WARNING_LINT_ERRORS = {
|
|
W098: "'{a}' is defined but never used.",
|
|
W014: "Misleading line break before '{a}'; readers may interpret this as an expression boundary.",
|
|
ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD:
|
|
"Cannot execute async code on functions bound to data fields",
|
|
ACTION_MODAL_STRING: 'Use Modal1.name instead of "Modal" as a string',
|
|
};
|
|
|
|
export function asyncActionInSyncFieldLintMessage(isJsObject = false) {
|
|
return isJsObject
|
|
? `Cannot execute async code on functions bound to data fields`
|
|
: `Data fields cannot execute async code`;
|
|
}
|
|
|
|
/** These errors should be overlooked
|
|
* E041 => Unrecoverable syntax error.
|
|
* W032 => Unnecessary semicolon.
|
|
*/
|
|
export const IGNORED_LINT_ERRORS = ["E041", "W032"];
|
|
export const SUPPORTED_WEB_APIS = {
|
|
console: true,
|
|
crypto: true,
|
|
fetch: true,
|
|
};
|
|
export enum CustomLintErrorCode {
|
|
INVALID_ENTITY_PROPERTY = "INVALID_ENTITY_PROPERTY",
|
|
ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD = "ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD",
|
|
// ButtonWidget.text = "test"
|
|
INVALID_WIDGET_PROPERTY_SETTER = "INVALID_WIDGET_PROPERTY_SETTER",
|
|
// appsmith.store.value = "test"
|
|
INVALID_APPSMITH_STORE_PROPERTY_SETTER = "INVALID_APPSMITH_STORE_PROPERTY_SETTER",
|
|
// showModal("Modal1")
|
|
ACTION_MODAL_STRING = "ACTION_MODAL_STRING",
|
|
}
|
|
|
|
export const CUSTOM_LINT_ERRORS: Record<
|
|
CustomLintErrorCode,
|
|
(...args: any[]) => string
|
|
> = {
|
|
[CustomLintErrorCode.INVALID_ENTITY_PROPERTY]: (
|
|
entityName: string,
|
|
propertyName: string,
|
|
entity: unknown,
|
|
isJsObject: boolean,
|
|
) =>
|
|
isEntityFunction(entity, propertyName, entityName)
|
|
? asyncActionInSyncFieldLintMessage(isJsObject)
|
|
: `"${propertyName}" doesn't exist in ${entityName}`,
|
|
|
|
[CustomLintErrorCode.ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD]: (
|
|
dataFieldBindings: string[],
|
|
fullName: string,
|
|
isMarkedAsync: boolean,
|
|
) => {
|
|
const hasMultipleBindings = dataFieldBindings.length > 1;
|
|
const bindings = dataFieldBindings.join(" , ");
|
|
return isMarkedAsync
|
|
? `Cannot bind async functions to data fields. Convert this to a sync function or remove references to "${fullName}" on the following data ${
|
|
hasMultipleBindings ? "fields" : "field"
|
|
}: ${bindings}`
|
|
: `Functions bound to data fields cannot execute async code. Remove async statements highlighted below or remove references to "${fullName}" on the following data ${
|
|
hasMultipleBindings ? "fields" : "field"
|
|
}: ${bindings}`;
|
|
},
|
|
[CustomLintErrorCode.INVALID_WIDGET_PROPERTY_SETTER]: (
|
|
methodName: string,
|
|
objectName: string,
|
|
propertyName: string,
|
|
isValidProperty: boolean,
|
|
) => {
|
|
const suggestionSentence = methodName
|
|
? `Use ${methodName}(value) instead.`
|
|
: `Use ${objectName} setter method instead.`;
|
|
|
|
const lintErrorMessage = !isValidProperty
|
|
? `${objectName} doesn't have a property named ${propertyName}`
|
|
: `Direct mutation of widget properties is not supported. ${suggestionSentence}`;
|
|
return lintErrorMessage;
|
|
},
|
|
[CustomLintErrorCode.INVALID_APPSMITH_STORE_PROPERTY_SETTER]: () => {
|
|
return "Use storeValue() method to modify the store";
|
|
},
|
|
[CustomLintErrorCode.ACTION_MODAL_STRING]: (modalName: string) => {
|
|
return `Use ${modalName}.name instead of "${modalName}" as a string`;
|
|
},
|
|
};
|