{
  "plugins": ["jsdoc"],
  "extends": [
    "eslint:recommended",
    "plugin:jsdoc/recommended",
    "plugin:n/recommended",
    "plugin:unicorn/recommended",
    "prettier"
  ],
  "env": { "node": true },
  "rules": {
    "array-callback-return": [
      2,
      {
        "allowImplicit": true
      }
    ],
    "no-lonely-if": 2,
    "no-proto": 2,
    "eqeqeq": [2, "smart"],
    "no-caller": 2,
    "dot-notation": 2,
    "no-var": 2,
    "prefer-const": 2,
    "prefer-arrow-callback": [2, { "allowNamedFunctions": true }],
    "arrow-body-style": [2, "as-needed"],
    "object-shorthand": 2,
    "prefer-template": 2,
    "one-var": [2, "never"],
    "prefer-destructuring": [2, { "object": true }],
    "capitalized-comments": 2,
    "multiline-comment-style": [2, "starred-block"],
    "spaced-comment": 2,
    "yoda": [2, "never"],
    "curly": [2, "multi-line"],

    "no-else-return": [
      2,
      {
        "allowElseIf": false
      }
    ],
    "no-unused-expressions": 2,
    "no-useless-call": 2,
    "no-use-before-define": [2, "nofunc"],
    "no-constant-binary-expression": 2,
    "no-void": 2,

    "jsdoc/require-jsdoc": 0,
    "jsdoc/check-tag-names": 2,
    "jsdoc/tag-lines": [2, "any", { "startLines": 1 }],
    "jsdoc/require-description-complete-sentence": 2,
    "jsdoc/require-hyphen-before-param-description": 2,
    "jsdoc/require-param-description": 2,
    "jsdoc/require-param-name": 2,
    "jsdoc/require-param-type": 0,
    "jsdoc/require-returns-type": 0,
    "jsdoc/no-types": 2,
    "jsdoc/valid-types": 2,

    "n/file-extension-in-import": [2, "always"],
    "n/no-missing-import": 0,

    "unicorn/no-null": 0,
    "unicorn/prevent-abbreviations": 0,
    "unicorn/prefer-code-point": 0,
    "unicorn/no-for-loop": 0,
    "unicorn/no-array-callback-reference": 0,
    "unicorn/prefer-spread": 0,
    "unicorn/no-useless-undefined": 0,
    "unicorn/no-array-reduce": 0,
    "unicorn/prefer-array-find": 0,
    "unicorn/prefer-module": 0,
    "unicorn/prefer-at": 0,
    "unicorn/prefer-string-replace-all": 0,
    "unicorn/prefer-switch": [2, { "emptyDefaultCase": "do-nothing-comment" }]
  },
  "settings": {
    "jsdoc": {
      "mode": "typescript",
      "tagNamePreference": {
        "category": "category"
      }
    }
  },
  "overrides": [
    {
      "files": "*.ts",
      "plugins": ["expect-type"],
      "extends": [
        "plugin:expect-type/recommended",
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended",
        "prettier"
      ],
      "parserOptions": {
        "sourceType": "module",
        "project": "./tsconfig.eslint.json"
      },
      "rules": {
        "dot-notation": 0,
        "curly": [2, "multi-line"],
        "n/no-unsupported-features/es-syntax": 0,

        "jsdoc/require-returns-check": 0, // Broken with overloaded fns

        "@typescript-eslint/prefer-for-of": 0,
        "@typescript-eslint/member-ordering": 0,
        "@typescript-eslint/explicit-function-return-type": 0,
        "@typescript-eslint/no-unused-vars": 0,
        "no-use-before-define": 0,
        "@typescript-eslint/no-use-before-define": [2, { "functions": false }],
        "@typescript-eslint/consistent-type-definitions": [2, "interface"],
        "@typescript-eslint/prefer-function-type": 2,
        "@typescript-eslint/no-unnecessary-type-arguments": 2,
        "@typescript-eslint/prefer-string-starts-ends-with": 2,
        "@typescript-eslint/prefer-readonly": 2,
        "@typescript-eslint/prefer-includes": 2,
        "@typescript-eslint/switch-exhaustiveness-check": 2,
        "@typescript-eslint/prefer-nullish-coalescing": 2,
        "@typescript-eslint/no-non-null-assertion": 1,
        "@typescript-eslint/consistent-type-imports": 2,

        "@typescript-eslint/no-explicit-any": 1 // TODO
      }
    },
    {
      "files": "*.spec.ts",
      "extends": "plugin:jest/recommended",
      "rules": {
        "@typescript-eslint/no-explicit-any": 0
      }
    }
  ]
}
