module.exports = { root: true, env: { browser: true, es6: true, node: true, webextensions: true, }, ignorePatterns: ['*.html', 'tsconfig.json'], extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react/recommended', 'plugin:react-hooks/recommended', 'plugin:storybook/recommended', 'airbnb-base', 'airbnb/rules/react', 'airbnb-typescript', '@unocss', 'prettier', ], plugins: [ 'import', 'import-essentials', 'jsdoc', 'eslint-plugin-tsdoc', 'react-prefer-function-component', '@typescript-eslint', 'simple-import-sort', ], globals: { Atomics: 'readonly', SharedArrayBuffer: 'readonly', debugger: true, browser: true, context: true, JSX: true, }, parser: '@typescript-eslint/parser', parserOptions: { project: './tsconfig.json', ecmaVersion: 2022, sourceType: 'module', ecmaFeatures: { jsx: true, modules: true, experimentalObjectRestSpread: true, }, }, settings: { react: { version: 'detect', }, jsdoc: { mode: 'typescript', }, 'import/parsers': { '@typescript-eslint/parser': ['.ts', '.tsx'], }, 'import/resolver': { typescript: { alwaysTryTypes: true, project: './tsconfig.json', }, }, }, rules: { 'prefer-const': [ 'off', { destructuring: 'any', ignoreReadBeforeAssign: false, }, ], 'no-plusplus': 'off', 'no-inner-declarations': 'off', 'sort-imports': 'off', 'no-case-declarations': 'off', 'no-unreachable': 'warn', 'no-constant-condition': 'error', 'space-before-function-paren': 'off', 'no-undef': 'off', 'no-return-await': 'off', '@typescript-eslint/return-await': 'off', '@typescript-eslint/no-shadow': ['off'], '@typescript-eslint/no-use-before-define': ['off'], 'class-methods-use-this': 'off', 'react-hooks/exhaustive-deps': 'warn', '@typescript-eslint/lines-between-class-members': 'off', 'no-param-reassign': [ 'error', { props: false, }, ], 'no-console': 'off', 'consistent-return': 'off', 'react/destructuring-assignment': 'off', 'import/prefer-default-export': 'off', 'no-promise-executor-return': 'off', 'import/no-cycle': 'off', 'import/no-extraneous-dependencies': 'off', 'react/jsx-props-no-spreading': 'off', 'react/jsx-no-useless-fragment': [ 'error', { allowExpressions: true, }, ], 'keyword-spacing': [ 'error', { before: true, after: true, }, ], 'no-continue': 'off', 'space-before-blocks': [ 'error', { functions: 'always', keywords: 'always', classes: 'always', }, ], 'react/jsx-filename-extension': [ 1, { extensions: ['.tsx'], }, ], 'react/no-deprecated': 'warn', 'react/prop-types': 'off', 'react-prefer-function-component/react-prefer-function-component': [ 'warn', { allowComponentDidCatch: false, }, ], 'react/function-component-definition': 'off', 'react/button-has-type': 'off', 'jsdoc/require-param-type': 'off', 'jsdoc/require-returns-type': 'off', 'jsdoc/newline-after-description': 'off', 'react/require-default-props': 'off', 'jsdoc/require-jsdoc': [ 'error', { enableFixer: false, publicOnly: true, checkConstructors: false, require: { ArrowFunctionExpression: true, ClassDeclaration: true, ClassExpression: true, FunctionExpression: true, }, contexts: [ 'MethodDefinition:not([key.name="componentDidMount"]):not([key.name="render"])', 'ArrowFunctionExpression', 'ClassDeclaration', 'ClassExpression', 'ClassProperty:not([key.name="state"]):not([key.name="componentDidMount"])', 'FunctionDeclaration', 'FunctionExpression', 'TSDeclareFunction', 'TSEnumDeclaration', 'TSInterfaceDeclaration', 'TSMethodSignature', 'TSModuleDeclaration', 'TSTypeAliasDeclaration', ], }, ], 'tsdoc/syntax': 'error', '@typescript-eslint/no-explicit-any': 'error', '@typescript-eslint/no-unused-vars': [ 'warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_', }, ], '@typescript-eslint/naming-convention': 'off', '@typescript-eslint/space-before-function-paren': 'off', '@typescript-eslint/ban-ts-comment': 'off', '@typescript-eslint/no-empty-interface': 'warn', 'import/no-restricted-paths': [ 'error', { zones: [ { target: './src/background', from: './src/views', message: 'You cannot import into the `background` directory from the `views` directory (i.e. content script files) because it will break the build!', }, { target: './src/views', from: './src/background', message: 'You cannot import into the `views` directory from the `background` directory (i.e. background script files) because it will break the build!', }, { target: './src/shared', from: './', except: ['./src/shared', './node_modules', './src/lib/chrome-extension-toolkit'], message: 'You cannot import into `shared` from an external directory.', }, ], }, ], 'import/extensions': 'off', 'no-restricted-syntax': [ 'error', 'ForInStatement', 'LabeledStatement', 'WithStatement', { selector: 'TSEnumDeclaration', message: "Don't declare enums", }, ], '@typescript-eslint/consistent-type-exports': 'error', '@typescript-eslint/consistent-type-imports': 'error', 'simple-import-sort/imports': 'error', 'simple-import-sort/exports': 'error', 'import-essentials/restrict-import-depth': 'error', // 'import-essentials/check-path-alias': 'error', }, };