{ "extends": [ "teact-app", "airbnb", "airbnb-typescript" ], "plugins": [ "no-async-without-await", "no-null", "simple-import-sort", "react-hooks-static-deps", "eslint-multitab-tt" ], "rules": { "eslint-multitab-tt/no-immediate-global": "error", "eslint-multitab-tt/must-update-global-after-await": "off", "eslint-multitab-tt/set-global-only-variable": "error", "eslint-multitab-tt/no-getactions-in-actions": "error", "eslint-multitab-tt/must-specify-action-handler-return-type": "error", "indent": [ "error", 2, { "SwitchCase": 1 } ], "max-len": [ "error", { "code": 120, "ignoreComments": true, "ignorePattern": "\\sd=\".+\"" // Ignore lines with "d" attribute } ], "array-bracket-newline": [ 2, "consistent" ], "no-null/no-null": 2, "no-console": "error", "semi": "error", "no-implicit-coercion": "error", "react-hooks/exhaustive-deps": "off", "react-hooks-static-deps/exhaustive-deps": [ "error", { "additionalHooks": "(useSyncEffect|useAsync|useDebouncedCallback|useThrottledCallback|useEffectWithPrevDeps|useLayoutEffectWithPrevDeps|useDerivedState|useDerivedSignal|useThrottledResolver|useDebouncedResolver)$", "staticHooks": { "getActions": true, "useFlag": [false, true, true], "useForceUpdate": true, "useReducer": [false, true], "useLastCallback": true } } ], "arrow-body-style": "off", "no-else-return": "off", "no-plusplus": "off", "no-void": "off", "no-continue": "off", "default-case": "off", "no-param-reassign": "off", "no-prototype-builtins": "off", "no-await-in-loop": "off", "no-nested-ternary": "off", "function-paren-newline": [ "error", "consistent" ], "prefer-destructuring": "off", // Allow for...of. Edited from: // https://github.com/airbnb/javascript/blob/b4377fb03089dd7f08955242695860d47f9caab4/packages/eslint-config-airbnb-base/rules/style.js#L333 "no-restricted-syntax": [ "error", { "selector": "ForInStatement", "message": "for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array." }, { "selector": "LabeledStatement", "message": "Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand." }, { "selector": "WithStatement", "message": "`with` is disallowed in strict mode because it makes code impossible to predict and optimize." } ], "import/no-extraneous-dependencies": "off", "import/prefer-default-export": "off", "import/named": "off", "import/no-webpack-loader-syntax": "off", "import/no-cycle": [ "error", { "allowUnsafeDynamicCyclicDependency": true // TODO: Fix this } ], "react/prop-types": "off", "react/jsx-one-expression-per-line": "off", "react/button-has-type": "off", "react/require-default-props": "off", "react/function-component-definition": "off", // Teact feature "react/style-prop-object": "off", "react/no-unknown-property": "off", "react/jsx-no-bind": [ "error", { "ignoreRefs": true, "allowArrowFunctions": false, "allowFunctions": false, "allowBind": false, "ignoreDOMComponents": true } ], "jsx-a11y/click-events-have-key-events": "off", "jsx-a11y/no-static-element-interactions": "off", "jsx-a11y/label-has-associated-control": "off", "jsx-a11y/anchor-is-valid": "off", "jsx-a11y/no-noninteractive-element-to-interactive-role": "off", "jsx-a11y/media-has-caption": "off", "no-async-without-await/no-async-without-await": 1, "@typescript-eslint/no-use-before-define": [ "error", { "functions": false } ], "@typescript-eslint/camelcase": "off", "@typescript-eslint/member-delimiter-style": "error", "@typescript-eslint/default-param-last": "off", "@typescript-eslint/return-await": [ "error", "in-try-catch" ], "@typescript-eslint/consistent-type-imports": [ "error", { "prefer": "type-imports", "disallowTypeAnnotations": false } ], "simple-import-sort/imports": [ "error", { "groups": [ // Side effect imports ["^\\u0000"], // Lib and global imports [ "^react", "^@?\\w", "dist(/.*|$)", "^(\\.+/)+(lib/(teact|gramjs))(/.*|$)", "^(\\.+/)+global$" ], // Type imports [ "^(\\.+/)+.+\\u0000$", "^(\\.+/|\\w+/)+(types)(/.*|$)", "^(\\.+/|\\w+/)+(types)\\u0000" ], // Config, utils, helpers [ "^(\\.+/)+config", "^(\\.+/)+(lib)(?!/(gramjs|teact))(/.*|$)", "^(\\.+/)+global/.+", "^(\\.+/)+(util)(/.*|$)", "^\\.\\.(?!/?$)", "^\\.\\./?$", "^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$" ], // Hooks [ ".+(/hooks/)(.*|$)" ], // Components [ "\/[A-Z](([a-z]+[A-Z]?)*)" ], // Styles and CSS modules [ "^.+\\.s?css$" ], // Assets: images, stickers, etc [ "^(\\.+/)+(assets)(/.*|$)" ] ] } ] }, "settings": { "import/resolver": { "webpack": { "extensions": [".js", ".jsx", ".ts", ".tsx"] } }, "import/core-modules": [ "fs", "path", "crypto" ] }, "parserOptions": { "project": "./tsconfig.json" } }