npm package: @honcho/eslint-plugin
Description: Honcho ESLint rules
Author: Vadim Polosatov
Latest version: 1.0.3

# Fairwords ESLint rules

#### Installation

```shell
# Install this package:
npm i -D eslint @honcho/eslint-plugin

# If you want to lint your JSDocs, install this:
npm i -D eslint-plugin-jsdoc

# If you're using TS, install and configure this package:
npm i -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

# Another recommended linting rules package:
npm i -D eslint-plugin-sonarjs
```

#### Usage

This package has several (rather strict) preconfigured ESLint rule sets you can use in your JS / TS project:

- `plugin:@honcho/js` All JS rules. Doesn't include recommended.
  - `plugin:@honcho/js-base` base JS ESLint rules. 
  - `plugin:@honcho/js-best-practices` ESLint [best practices](https://eslint.org/docs/rules/#best-practices).
  - `plugin:@honcho/js-complexity` Complexity related rules.
  - `plugin:@honcho/js-ecma6` ECMA6 features related rules.
  - `plugin:@honcho/js-only` JS-only rules. These rules seem to cause problem, if you're not using them on JS files only.
  - `plugin:@honcho/js-prettier` We had Prettier and ESLint rules fighting with each other, so I moved most of the
Prettier configs here to this section.
  - `plugin:@honcho/js-spacing` Rules that regulates spaces in code
- `plugin:@honcho/js-best-practices` JSDoc rules. Doesn't turn recommended JSDoc rules on, you should turn them on
separately. If you're using it, you must install and set up [JSDoc eslint plugin package](https://www.npmjs.com/package/eslint-plugin-jsdoc) (we use `36.0.7` version). 
- `plugin:@honcho/ts` TypeScript rules. Doesn't turn recommended TS rules on, you should turn them on separately.
If you're using any rule from this section, you must install and set up [TS ESLint plugin package](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin) (we use `4.28.4` version).
Configs that has `typed` in their name require type-checking and will build your code to run the checks.
You will need to [set up your project](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/docs/getting-started/linting/TYPED_LINTING.md)
to utilize these advanced rules.
  - `plugin:@honcho/ts-extensions` [Vanilla ESLint extension rules](https://github.com/typescript-eslint/typescript-eslint/blob/5e1a61500472ff186eede686b2257464476d3d87/packages/eslint-plugin/README.md#extension-rules). 
Quote from docs: "In some cases, ESLint provides a rule itself, but it doesn't support TypeScript syntax; either it crashes, or it ignores
the syntax, or it falsely reports against it. In these cases, we create what we call an extension rule; a rule within
our plugin that has the same functionality, but also supports TypeScript". These rules turn the vanilla ESLint rules off
and use its "patched" version.
    - `plugin:@honcho/ts-extensions-untyped` Extension rules that doesn't require type-checking.
    - `plugin:@honcho/ts-extensions-typed` Extension rules that require type-checking and will build your code to run the checks.
  - `plugin:@honcho/ts-additions` Additional rules that were not present in vanilla ESLint.
    - `plugin:@honcho/ts-additions-untyped` Additional rules that doesn't require type-checking.
    - `plugin:@honcho/ts-additions-typed` Additional rules that require type-checking.
    - `plugin:@honcho/ts-additions-typed-strict` Additional rules that require type-checking and `strictNullChecks` (or `strict`) option set.

We also recommend using [SonarJS ESLint plugin](https://www.npmjs.com/package/eslint-plugin-sonarjs).

#### Example:

You can use this example .eslintrc.js config as a starting point for your new project:

```js
// .eslintrc.js
const ecmaVersion = 2020;

module.exports = {
  'plugins': [],
  'env': {
    'browser': true,
    'es6': true,
    'node': true,
    'jest': true,
  },
  'parserOptions': {
    ecmaVersion,
    'sourceType': 'module',
    'ecmaFeatures': {},
  },
  'overrides': [
    {
      'files': ['*.ts', '*.js'],
      'extends': [
        'eslint:recommended',
        'plugin:jsdoc/recommended',
        'plugin:sonarjs/recommended',
        'plugin:@honcho/js',
        'plugin:@honcho/jsdoc',
      ],
      'plugins': [
        'sonarjs',
        '@honcho',
        'jsdoc',
      ],
      'rules': {
        // Disallow declarations in the global scope, crashes linter for non-JS or non-TS files
        'no-implicit-globals': 'error',
      },
    },
    {
      'files': ['*.js'],
      'extends': ['plugin:@honcho/js-only'],
      'plugins': ['@honcho'],
      'rules': {},
    },
    {
      'files': ['*.ts'],
      'plugins': [
        '@typescript-eslint',
        '@honcho',
      ],
      'extends': [
        'plugin:@typescript-eslint/recommended',
        'plugin:@honcho/ts-extensions',
        'plugin:@honcho/ts-additions-untyped',
        'plugin:@honcho/ts-additions-typed',
        'plugin:@typescript-eslint/recommended-requiring-type-checking',
      ],

      'parser': '@typescript-eslint/parser',
      'parserOptions': {
        'tsconfigRootDir': __dirname,
        'project': ['./tsconfig.base.json'],
      },
      'rules': {},
    },
    {
      'files': ['*.test.js', '*.test.ts'],
      'rules': {
        // Jest is built on callbacks, so we have to increase the counts here
        'max-nested-callbacks': ['error', 5],
        
        'max-lines-per-function': 'off',
        
        // It's somewhat ok to use magic numbers in tests
        '@typescript-eslint/no-magic-numbers': 'off',
        
        // SonarJS doesn't like it when you use the same names for tests a lot of times
        'sonarjs/no-duplicate-string': 'off',
      },
    },
  ],

  /*
   * https://github.com/angular-eslint/angular-eslint#seriously-move-mostly-all-configuration-into-overrides
   * > Even though you may be more familiar with including ESLint rules, plugins etc at the top level of your config
   * object, we strongly recommend only really having overrides (and a couple of other things like ignorePatterns, root
   * etc) at the top level and including all plugins, rules etc within the relevant block in the overrides array.
   */
  'extends': [],
  'rules': {},
};

```