{ "parser": "@typescript-eslint/parser", "env": { "browser": true, "es6": true, "serviceworker": true }, "extends": [ "eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended-type-checked", "plugin:@typescript-eslint/stylistic-type-checked", "prettier", "plugin:array-func/all", "plugin:css-modules/recommended", "plugin:sonarjs/recommended" ], "globals": { "Atomics": "readonly", "SharedArrayBuffer": "readonly", "$featureFlags": "readonly", "ga": true, "$DIM_FLAVOR": "readonly", "$DIM_VERSION": "readonly", "$DIM_BUILD_DATE": "readonly", "$DIM_WEB_API_KEY": "readonly", "$DIM_WEB_CLIENT_ID": "readonly", "$DIM_WEB_CLIENT_SECRET": "readonly", "$DIM_API_KEY": "readonly", "$BROWSERS": "readonly", "workbox": true, "React": true, "require": true, "module": "readonly" }, "parserOptions": { "ecmaFeatures": { "jsx": true }, "ecmaVersion": 2018, "sourceType": "module", "project": "./tsconfig.json" }, "settings": { "react": { "version": "detect", "linkComponents": [ // Components used as alternatives to <a> for linking, eg. <Link to={ url } /> { "name": "Link", "linkAttribute": "to" }, { "name": "NavLink", "linkAttribute": "to" } ] } }, "plugins": [ "react", "react-hooks", "@typescript-eslint", "lodash", "jsx-a11y", "array-func", "react-redux", "css-modules", "sonarjs", "jsx-expressions", "github" ], "reportUnusedDisableDirectives": true, "rules": { "no-alert": "error", "no-console": "error", "no-debugger": "error", "no-empty": "off", "no-implicit-coercion": "error", "no-restricted-globals": [ "error", "name", "location", "history", "menubar", "scrollbars", "statusbar", "toolbar", "status", "closed", "frames", "length", "top", "opener", "parent", "origin", "external", "screen", "defaultstatus", "crypto", "close", "find", "focus", "open", "print", "scroll", "stop", "chrome", "caches", "scheduler" ], "no-restricted-properties": [ 1, { "object": "_", "property": "forEach", "message": "Please use a for in loop." }, { "object": "_", "property": "filter", "message": "Please use the native js filter." }, { "object": "_", "property": "map", "message": "Please use the native js map." }, { "object": "_", "property": "uniq", "message": "Please use Array.from(new Set(foo)) or [...new Set(foo)] instead." }, { "object": "_", "property": "uniqBy", "message": "Please use the uniqBy from app/utils/util instead" }, { "object": "_", "property": "forIn", "message": "Please use Object.values or Object.entries instead" }, { "object": "_", "property": "noop", "message": "Import noop directly instead of using it through _.noop, to satisfy the unbound-method lint" } ], "no-restricted-imports": [ "error", { "patterns": [ { "group": ["testing/*"], "message": "You cannot use test helpers in regular code." } ] } ], "no-restricted-syntax": [ "error", { "selector": "CallExpression[callee.property.name='compact'][callee.object.name='_'][arguments.0.callee.property.name='map']", "message": "Please use `filterMap` instead" }, { "selector": "TSEnumDeclaration:not([const=true])", "message": "Please only use `const enum`s." } ], "spaced-comment": [ "error", "always", { "exceptions": ["@__INLINE__"], "block": { "balanced": true } } ], "arrow-body-style": ["error", "as-needed"], "curly": ["error", "all"], "eqeqeq": ["error", "always"], "no-return-await": "off", "@typescript-eslint/return-await": ["error", "in-try-catch"], "prefer-regex-literals": "error", "prefer-promise-reject-errors": "error", "prefer-spread": "error", "radix": "error", "yoda": "error", "prefer-template": "error", "class-methods-use-this": ["error", { "exceptMethods": ["render"] }], "no-unmodified-loop-condition": "error", "no-unreachable-loop": "error", "no-unused-private-class-members": "error", "func-name-matching": "error", "logical-assignment-operators": "error", "no-lonely-if": "error", "no-unneeded-ternary": "error", "no-useless-call": "error", "no-useless-concat": "error", "no-useless-rename": "error", "react/jsx-uses-react": "off", "react/react-in-jsx-scope": "off", "react/no-unescaped-entities": "off", "react/jsx-no-target-blank": "off", "react/display-name": "off", "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn", "react/prefer-stateless-function": "warn", "react/no-access-state-in-setstate": "error", "react/no-this-in-sfc": "error", "react/no-children-prop": "error", "react/no-unused-state": "error", "react/button-has-type": "error", "react/prop-types": "off", "react/self-closing-comp": "error", "react/function-component-definition": "error", "react/no-redundant-should-component-update": "error", "react/no-unsafe": "error", "react/jsx-no-constructed-context-values": "error", "react/jsx-pascal-case": "error", "react/jsx-curly-brace-presence": [ "error", { "props": "never", "children": "never", "propElementValues": "always" } ], "react/iframe-missing-sandbox": "error", "react/jsx-key": ["error", { "checkFragmentShorthand": true, "warnOnDuplicates": true }], "react/forbid-component-props": [ "error", { "forbid": [ "onMouseEnter", "onMouseLeave", "onMouseOver", "onMouseOut", "onTouchStart", "onTouchEnd", "onTouchCancel" ] } ], "jsx-a11y/aria-props": "error", "jsx-a11y/aria-proptypes": "error", "jsx-a11y/aria-role": "error", "jsx-a11y/aria-unsupported-elements": "error", "jsx-a11y/autocomplete-valid": "error", "jsx-a11y/label-has-associated-control": "error", "jsx-a11y/no-noninteractive-element-interactions": "error", "jsx-a11y/no-noninteractive-element-to-interactive-role": "error", "jsx-a11y/no-noninteractive-tabindex": "error", "jsx-a11y/no-redundant-roles": "error", "jsx-a11y/role-has-required-aria-props": "error", "jsx-a11y/role-supports-aria-props": "error", "lodash/collection-method-value": "error", "lodash/collection-return": "error", "lodash/no-extra-args": "error", "lodash/chaining": ["error", "never"], "lodash/identity-shorthand": ["error", "never"], "lodash/matches-shorthand": ["error", "never"], "lodash/matches-prop-shorthand": ["error", "never"], "lodash/prop-shorthand": ["error", "never"], "lodash/prefer-compact": "error", "lodash/prefer-filter": "error", "lodash/prefer-find": "error", "lodash/prefer-flat-map": "error", "lodash/prefer-immutable-method": "error", "lodash/prefer-map": "error", "lodash/prefer-reject": "error", "lodash/prefer-times": "error", "lodash/preferred-alias": "error", "@typescript-eslint/await-thenable": "error", "@typescript-eslint/no-misused-promises": [ "error", { "checksVoidReturn": false } ], "@typescript-eslint/ban-types": [ "error", { "types": { "BigInt": "BigInt isn't supported in old versions (pre-14) of Safari", "bigint": "BigInt isn't supported in old versions (pre-14) of Safari" }, "extendDefaults": false } ], "@typescript-eslint/explicit-member-accessibility": "off", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/method-signature-style": "error", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-var-requires": "off", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-use-before-define": ["error", { "functions": false }], "@typescript-eslint/no-parameter-properties": "off", "@typescript-eslint/no-extraneous-class": "error", "@typescript-eslint/no-this-alias": "error", "@typescript-eslint/no-unnecessary-type-constraint": "error", "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error", "@typescript-eslint/no-unnecessary-qualifier": "error", "@typescript-eslint/no-unnecessary-type-assertion": "error", "@typescript-eslint/no-unnecessary-type-arguments": "error", "@typescript-eslint/prefer-function-type": "error", "@typescript-eslint/prefer-for-of": "error", "@typescript-eslint/prefer-optional-chain": "error", "@typescript-eslint/prefer-as-const": "error", "@typescript-eslint/prefer-reduce-type-parameter": "error", "@typescript-eslint/prefer-includes": "error", "@typescript-eslint/prefer-string-starts-ends-with": "error", "@typescript-eslint/prefer-ts-expect-error": "error", "@typescript-eslint/array-type": "error", "@typescript-eslint/no-non-null-asserted-optional-chain": "error", "@typescript-eslint/unified-signatures": "error", "@typescript-eslint/no-base-to-string": "error", "@typescript-eslint/non-nullable-type-assertion-style": "error", "@typescript-eslint/switch-exhaustiveness-check": "error", "@typescript-eslint/consistent-type-definitions": "error", "@typescript-eslint/consistent-generic-constructors": "error", "@typescript-eslint/no-duplicate-enum-values": "error", "@typescript-eslint/no-throw-literal": "error", "@typescript-eslint/no-unused-vars": [ "error", { "varsIgnorePattern": "^_.", "argsIgnorePattern": "^_.", "ignoreRestSiblings": true } ], "@typescript-eslint/no-for-in-array": "error", "@typescript-eslint/consistent-indexed-object-style": "off", "@typescript-eslint/no-floating-promises": "off", "@typescript-eslint/require-await": "off", "@typescript-eslint/no-unsafe-enum-comparison": "off", "@typescript-eslint/prefer-nullish-coalescing": [ "off", { "ignoreConditionalTests": true, "ignoreTernaryTests": false, "ignoreMixedLogicalExpressions": true, "ignorePrimitives": { "boolean": true, "number": false, "string": true } } ], "@typescript-eslint/no-unsafe-argument": "error", "@typescript-eslint/no-unsafe-assignment": "error", "@typescript-eslint/no-unsafe-call": "error", "@typescript-eslint/no-unsafe-member-access": "error", "@typescript-eslint/no-unsafe-return": "error", "@typescript-eslint/no-redundant-type-constituents": "off", "no-implied-eval": "off", "@typescript-eslint/no-implied-eval": "error", "array-func/prefer-array-from": "off", "react-redux/mapStateToProps-prefer-hoisted": "error", "react-redux/no-unused-prop-types": "error", "react/no-unused-prop-types": "off", "css-modules/no-undef-class": "off", "sonarjs/cognitive-complexity": "off", "sonarjs/no-small-switch": "off", "sonarjs/no-duplicate-string": "off", "sonarjs/prefer-immediate-return": "off", "sonarjs/no-nested-switch": "off", "sonarjs/no-nested-template-literals": "off", "jsx-expressions/strict-logical-expressions": ["error", { "allowString": true }], "github/array-foreach": "error", "github/async-currenttarget": "error", "github/async-preventdefault": "error", "github/no-innerText": "error" }, "overrides": [ { "files": ["*.test.ts"], "rules": { "no-restricted-imports": "off" } } ] }