root: true
parser: "@typescript-eslint/parser"
plugins:
  - "@typescript-eslint"
  - eslint-plugin-react
  - eslint-plugin-react-hooks
  - eslint-plugin-tsdoc
parserOptions:
  ecmaVersion: latest
  sourceType: module
  project:
    - ./tsconfig.json
  ecmaFeatures:
    jsx: true
env:
  commonjs: true
  node: true
  es6: true
  browser: true
rules:
  # Possible errors
  for-direction: 2
  getter-return: 2
  no-async-promise-executor: 1
  no-compare-neg-zero: 1
  no-cond-assign: 2
  no-constant-condition: 2
  no-control-regex: 2
  no-debugger: 2
  no-duplicate-case: 2
  no-empty-character-class: 2
  no-ex-assign: 2
  no-inner-declarations: 1
  no-invalid-regexp: 2
  no-irregular-whitespace: 2
  no-misleading-character-class: 2
  no-prototype-builtins: 2
  no-regex-spaces: 2
  no-sparse-arrays: 2
  no-template-curly-in-string: 2
  no-unreachable: 2
  no-unsafe-finally: 2
  no-unsafe-negation: 2
  require-atomic-updates: 2
  use-isnan: 2

  # Best Practices
  accessor-pairs: 2
  class-methods-use-this: 1
  # complexity: 2
  curly:
    - 2
    - all
  default-case: 2
  dot-location:
    - 2
    - property
  # dot-notation:
  #   - 2
  #   - allowKeywords: false
  eqeqeq: 2
  guard-for-in: 2
  no-alert: 2
  no-caller: 2
  no-case-declarations: 2
  no-div-regex: 2
  # no-else-return:
  #   - 2
  #   - allowElseIf: true
  # no-empty-function: 2
  no-empty-pattern: 2
  no-eq-null: 2
  no-eval: 2
  no-extend-native:
    - 2
    - exceptions:
        - "Array"
        - "Map"
        - "Set"
  no-extra-bind: 2
  no-extra-label: 2
  no-fallthrough: 2
  no-floating-decimal: 2
  no-global-assign: 2
  no-implicit-coercion:
    - 2
    - allow:
      - "!!"
  no-implied-eval: 2
  # no-invalid-this: 2
  no-iterator: 2
  no-labels: 2
  no-lone-blocks: 2
  no-loop-func: 2
  no-multi-spaces: 2
  no-multi-str: 2
  no-new: 2
  no-new-func: 2
  no-new-wrappers: 2
  no-octal: 2
  no-octal-escape: 2
  no-param-reassign: 2
  no-proto: 2
  no-redeclare: 0
  no-return-assign: 2
  no-script-url: 2
  no-self-assign: 2
  no-self-compare: 2
  no-throw-literal: 2
  no-unmodified-loop-condition: 2
  no-unused-labels: 2
  no-useless-call: 2
  no-useless-catch: 2
  no-useless-concat: 2
  no-useless-escape: 2
  no-useless-return: 2
  no-void: 2
  no-warning-comments: 1
  no-with: 2
  prefer-named-capture-group: 1
  prefer-promise-reject-errors: 2
  radix: 2
  require-unicode-regexp: 2
  wrap-iife: 2
  yoda: 2

  # Variables
  init-declarations: 2
  no-delete-var: 2
  no-label-var: 2
  no-shadow: 0
  no-shadow-restricted-names: 2
  # no-undef: 2

  # Stylistic Issues
  array-bracket-spacing:
    - 2
    - always
  array-element-newline:
    - 2
    - consistent
  block-spacing: 2
  # capitalized-comments: 2
  comma-dangle:
    - 2
    - arrays: always-multiline
      objects: always-multiline
      imports: always-multiline
      exports: always-multiline
      functions: only-multiline
  comma-style: 2
  computed-property-spacing: 2
  eol-last: 2
  func-name-matching: 2
  func-names: 2
  func-style:
    - 2
    - declaration
    - allowArrowFunctions: true
  function-call-argument-newline:
    - 2
    - consistent
  function-paren-newline:
    - 2
    - multiline-arguments
  jsx-quotes: 2
  key-spacing: 2
  keyword-spacing: 2
  line-comment-position: 2
  lines-around-comment:
    - 0
      # requires an empty line before block comments
    - beforeBlockComment: true
      # requires an empty line after block comments
      afterBlockComment: false
      # requires an empty line before line comments
      beforeLineComment: true
      # requires an empty line after line comments
      afterLineComment: false
      # allows comments to appear at the start of block statements
      allowBlockStart: true
      # allows comments to appear at the end of block statements
      allowBlockEnd: false
      # allows comments to appear at the start of object literals
      allowObjectStart: true
      # allows comments to appear at the end of object literals
      allowObjectEnd: false
      # allows comments to appear at the start of array literals
      allowArrayStart: true
      # allows comments to appear at the end of array literals
      allowArrayEnd: false
      # allows comments to appear at the start of classes
      allowClassStart: true
      # allows comments to appear at the end of classes
      allowClassEnd: false
      ignorePattern: "^ *@"
  lines-between-class-members: 2
  max-len:
    - 2
    - code: 100
      ignoreComments: true
      ignoreTemplateLiterals: true
      ignorePattern: "^import |^export \\{(.*?)\\}|^ \\* |^ *it ?\\(\"\\w+"
  max-statements-per-line: [2, { max: 2 }]
  multiline-ternary:
    - 2
    - always-multiline
  new-parens: 2
  newline-per-chained-call:
    - 2
    - ignoreChainWithDepth: 2
  no-bitwise: 2
  no-continue: 2
  no-inline-comments: 2
  no-lonely-if: 2
  no-mixed-operators:
    - 2
    - groups:
      - ["&", "|", "^", "~", "<<", ">>", ">>>"]
      - ["==", "!=", "===", "!==", ">", ">=", "<", "<="]
      - ["&&", "||"]
      - ["in", "instanceof"]
      allowSamePrecedence: true
  no-mixed-spaces-and-tabs: 2
  no-multi-assign: 2
  no-multiple-empty-lines: 2
  no-negated-condition: 2
  no-new-object: 2
  no-tabs: 2
  no-trailing-spaces: 2
  no-unneeded-ternary: 2
  nonblock-statement-body-position: 2
  # object-curly-newline:
  #   - 2
  #   - multiline: true
  object-curly-spacing:
    - 2
    - always
  operator-assignment: 2
  operator-linebreak:
    - 2
    - before
    - overrides:
        "=": ignore
  padded-blocks:
    - 2
    - blocks: never
      classes: never
      switches: never
  padding-line-between-statements:
    - 2
    - blankLine: always
      prev: "*"
      next: return
  prefer-object-spread: 2
  quote-props:
    - 2
    - as-needed
  semi-spacing: 2
  semi-style: 2
  space-before-blocks: 2
  space-in-parens: 2
  space-infix-ops:
    - 2
    - int32Hint: true
  space-unary-ops: 2
  spaced-comment: 2
  switch-colon-spacing: 2
  template-tag-spacing:
    - 2
    - always

  # ECMAScript 6
  arrow-body-style: 2
  arrow-parens:
    - 2
    - as-needed
  arrow-spacing: 2
  constructor-super: 2
  generator-star-spacing:
    - 2
    - after
  no-class-assign: 2
  no-new-symbol: 2
  no-this-before-super: 2
  no-useless-computed-key: 2
  no-useless-rename: 2
  no-var: 2
  object-shorthand: 2
  prefer-arrow-callback: 2
  prefer-const: 2
  prefer-destructuring:
    - 2
    - object: true
      array: false
  prefer-numeric-literals: 2
  prefer-rest-params: 2
  prefer-spread: 2
  prefer-template: 2
  require-yield: 2
  rest-spread-spacing: 2
  # sort-imports:
  #   - 2
  #   - ignoreCase: true
  #     ignoreMemberSort: true
  symbol-description: 2
  template-curly-spacing: 2
  yield-star-spacing:
    - 2
    - after

  # TypeScript
  "@typescript-eslint/adjacent-overload-signatures": 2
  "@typescript-eslint/array-type": 2
  "@typescript-eslint/await-thenable": 2
  # "@typescript-eslint/class-name-casing": 2
  "@typescript-eslint/consistent-type-assertions": 2
  "@typescript-eslint/member-delimiter-style":
    - 2
    - multiline:
        delimiter: none
      singleline:
        delimiter: semi
        requireLast: false
  "@typescript-eslint/naming-convention":
    - error
    - selector: interface
      format:
        - PascalCase
      custom:
        regex: "^I[A-Z]"
        match: false
  "@typescript-eslint/no-floating-promises": 2
  "@typescript-eslint/no-for-in-array": 2
  "@typescript-eslint/no-inferrable-types": 2
  "@typescript-eslint/no-misused-new": 2
  "@typescript-eslint/no-misused-promises": 2
  "@typescript-eslint/no-this-alias": 2
  "@typescript-eslint/no-unnecessary-type-arguments": 2
  "@typescript-eslint/no-unnecessary-type-assertion": 2
  "@typescript-eslint/prefer-for-of": 2
  "@typescript-eslint/prefer-includes": 2
  "@typescript-eslint/prefer-readonly": 2
  "@typescript-eslint/promise-function-async": 2
  # "@typescript-eslint/quotes": 2
  "@typescript-eslint/require-array-sort-compare": 2
  "@typescript-eslint/require-await": 2
  "@typescript-eslint/restrict-plus-operands": 2
  # "@typescript-eslint/semi":
  #   - 2
  #   - never
  "@typescript-eslint/strict-boolean-expressions": 2
  "@typescript-eslint/triple-slash-reference": 2
  "@typescript-eslint/type-annotation-spacing": 2
  # "@typescript-eslint/unbound-method": 2
  "@typescript-eslint/unified-signatures": 2

  # TypeScript Extension
  brace-style: 0
  "@typescript-eslint/brace-style":
    - 2
    - stroustrup
  comma-spacing: 0
  "@typescript-eslint/comma-spacing": 2
  func-call-spacing: 0
  "@typescript-eslint/func-call-spacing":
    - 2
    - always
    - allowNewlines: true
  indent: 0
  "@typescript-eslint/indent": 0
  no-array-constructor: 0
  "@typescript-eslint/no-array-constructor": 2
  no-extra-parens: 0
  "@typescript-eslint/no-extra-parens": 0
  no-extra-semi: 0
  "@typescript-eslint/no-extra-semi": 2
  no-unused-expressions: 0
  "@typescript-eslint/no-redeclare": 2
  "@typescript-eslint/no-shadow": 2
  "@typescript-eslint/no-unused-expressions": 2
  "@typescript-eslint/no-unused-vars":
    - 2
    - argsIgnorePattern: "^_"
      varsIgnorePattern: "^_"
  "@typescript-eslint/no-use-before-define": 2
  no-useless-constructor: 0
  "@typescript-eslint/no-useless-constructor": 2
  quotes: 0
  "@typescript-eslint/quotes":
    - 2
    - double
    - avoidEscape: true
      allowTemplateLiterals: true
  no-return-await: 0
  "@typescript-eslint/return-await": 2
  semi: 0
  "@typescript-eslint/semi":
    - 2
    - never
    - beforeStatementContinuationChars: never
  space-before-function-paren: 0
  "@typescript-eslint/space-before-function-paren": 2

  # React
  react/boolean-prop-naming: 2
  react/destructuring-assignment: 2
  react/no-access-state-in-setstate: 2
  react/no-array-index-key: 2
  react/no-children-prop: 2
  react/no-danger: 2
  react/no-danger-with-children: 2
  react/no-deprecated: 2
  react/no-did-mount-set-state: 2
  react/no-did-update-set-state: 1
  react/no-direct-mutation-state: 2
  react/no-find-dom-node: 2
  react/no-is-mounted: 2
  # react/no-multi-comp: 2
  react/no-redundant-should-component-update: 2
  react/no-render-return-value: 2
  react/no-typos: 2
  react/no-string-refs: 2
  react/no-this-in-sfc: 2
  react/no-unescaped-entities: 2
  react/no-unsafe: 2
  react/no-unused-prop-types: 2
  react/no-unused-state: 2
  react/no-will-update-set-state: 2
  react/prefer-es6-class: 2
  react/prefer-stateless-function: 2
  react/react-in-jsx-scope: 2
  react/require-render-return: 2
  react/self-closing-comp: 2
  react/state-in-constructor:
    - 2
    - never
  react/style-prop-object: 2
  react/void-dom-elements-no-children: 2
  react/jsx-boolean-value:
    - 2
    - never
  react/jsx-child-element-spacing: 2
  react/jsx-closing-bracket-location:
    - 2
    - props-aligned
  react/jsx-closing-tag-location: 2
  react/jsx-curly-newline: 2
  react/jsx-curly-spacing: 2
  react/jsx-equals-spacing: 2
  react/jsx-first-prop-new-line: 2
  react/jsx-handler-names: 2
  # react/jsx-indent:
  #   - 2
  #   - 2
  react/jsx-indent-props:
    - 2
    - 2
  react/jsx-max-props-per-line:
    - 2
    - maximum: 3
  react/jsx-no-bind: 2
  react/jsx-no-comment-textnodes: 2
  react/jsx-no-literals: 2
  react/jsx-no-target-blank: 2
  react/jsx-one-expression-per-line:
    - 2
    - allow: single-child
  react/jsx-curly-brace-presence:
    - 2
    - props: never
      children: ignore
  react/jsx-fragments: 2
  react/jsx-pascal-case: 2
  react/jsx-props-no-multi-spaces: 2
  react/jsx-props-no-spreading: 2
  react/jsx-tag-spacing: 2
  react/jsx-wrap-multilines:
    - 2
    - declaration: parens-new-line
      assignment: parens-new-line
      return: parens-new-line
      arrow: parens-new-line
      condition: parens-new-line
      logical: parens-new-line
      prop: ignore

  # React Hooks
  react-hooks/rules-of-hooks: 2
  react-hooks/exhaustive-deps: 2

  # TSDoc
  tsdoc/syntax: warn
settings:
  react:
    version: detect
