{
  "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"
      }
    }
  ]
}