UNPKG

eslint-config-strictest

Version:

Super strict eslint rules for more reliable software

778 lines (671 loc) • 22.9 kB
module.exports = { rules: { // đŸ•¸ 'array-callback-return': 'error', 'no-undef': 'error', 'prefer-const': 'error', 'no-duplicate-case': 'error', 'for-direction': 'error', 'no-useless-backreference': 'error', // đŸ‘€ 'default-case-last': 'error', /** * #improves-code-stability * Bad: `length += await getLength()`, Good: `length = length + (await getLength())` * * Making it a warning for now because it started detecting some edge cases which aren't * optimal. More info here: https://github.com/eslint/eslint/issues/11899 */ 'require-atomic-updates': 'warn', /** * #improves-code-stability, #low * Bad: `value === NaN`, Good: `Number.isNaN(value)` */ 'use-isnan': 'error', /** * #improves-code-stability, #low * Enforce `return` statement in getters. */ 'getter-return': 'error', /** * #improves-code-stability, #low * Bad: `new Promise(async (resolve, reject) => {`, Good: `new Promise((resolve, reject) => {` */ 'no-async-promise-executor': 'error', /** * #improves-code-stability, #low * Bad: `x === -0`, Good: `x === 0` */ 'no-compare-neg-zero': 'error', /** * #improves-code-stability * Bad: `user.name = 'John'`, Good: `user.name === 'John'` */ 'no-cond-assign': 'error', /** * #improves-code-stability, #low * Bad: `if (false) {` */ 'no-constant-condition': ['error', { checkLoops: false }], /** * #improves-code-stability * Bad: `/^abc[]/`, Good: `/^abc/` */ 'no-empty-character-class': 'error', /** * #improves-code-stability, #low */ 'no-misleading-character-class': 'error', /** * #improves-code-stability * While the items array in this example `var items = [,,];` has a length of 2, there are * actually no values in `items[0]` or `items[1]`. The fact that the array literal is valid with * only commas inside, coupled with the length being set and actual item values not being set, * make sparse arrays confusing for many developers. */ 'no-sparse-arrays': 'error', /** * #improves-code-stability * Bad: `"Hello ${name}!"`, Good: ``Hello ${name}!`` */ 'no-template-curly-in-string': 'error', /** * #improves-code-stability * Don't use `var` declarations. Only `let` and `const`. */ 'no-var': 'error', /** * #improves-code-stability * @example * // Bad * var foo = bar * (1 || 2).baz() * * // Good * var foo = bar * ;(1 || 2).baz() */ 'no-unexpected-multiline': 'error', /** * #improves-code-stability * Don't allow unhandled exceptions. */ 'promise/catch-or-return': 'error', /** * #improves-code-stability, #low * Bad: `new Symbol('foo')`, Good: `Symbol('foo')` */ 'no-new-symbol': 'error', eqeqeq: 'error', /** * #improves-code-stability * Don't allow a `case` without a `break` inside of it. */ 'no-fallthrough': 'error', /** * #improves-code-stability, #consistency * Bad: `const n = +foo`, Good: `const n = Number(foo)` */ 'no-implicit-coercion': 'error', /** * #improves-code-stability * Bad: `const num = parseInt('71')`, Good: `const num = parseInt('71', 10)` */ radix: 'error', /** * #improves-code-stability * Bad: `RegExp('[')` */ 'no-invalid-regexp': 'error', /** * #improves-code-stability * Does two things: * 1. Make the regular expression handling UTF-16 surrogate pairs correctly * 2. Make the regular expression throwing syntax errors early. */ 'require-unicode-regexp': 'error', /** * #improves-code-stability * Enforces you to handle errors. `function loadData(err, callback)` */ 'handle-callback-err': 'error', /** * #improves-code-stability * Banning bitwise operators can lower mistakes when you actually want to use it's double form * which is way more common. The rare cases when it is intentional it can manually be disabled. * Bad: `a | b` * Good: `a || b` */ 'no-bitwise': 'error', /** * #improves-code-stability, #improves-code-understanding * @example * // Bad * while (node) { * doSomething(node); * } * // Good * while (node) { * doSomething(node); * node = node.parent * } */ 'no-unmodified-loop-condition': 'error', /** * #improves-code-stability * @example * // Bad * import mod, { named } from "./mod.mjs" * mod = 1 * named = 2 * // Good * import mod, { named } from "./mod.mjs" * mod.prop = 1 * named.prop = 2 */ 'no-import-assign': 'error', /** * #improves-code-stability * Don't allow duplicate code in different else if statements. Improves code stability because * you can change one code path without changing the other. */ 'no-dupe-else-if': 'error', /** * #improves-code-understanding * @example * // Bad * function doSomething(condition) { * if (condition) { * return true * } else { * return * } * } * // Bad * function doSomething(condition) { * if (condition) { * return true * } * } * // Good * function doSomething(condition) { * if (condition) { * return true * } else { * return false * } * } * // Good * function doSomething(condition) { * if (condition) { * return true * } * return false * } */ 'consistent-return': 'error', /** * #improves-code-understanding * Warn when using a `bind()` call in which `this` isn't used. */ 'no-extra-bind': 'error', /** * #improves-code-understanding, #low * If a loop contains no nested loops or switches, labeling the loop is unnecessary. */ 'no-extra-label': 'error', /** * #improves-code-understanding * Labels that are declared and not used anywhere in the code are most likely an error due to * incomplete refactoring. */ 'no-unused-labels': 'error', /** * #improves-code-understanding * Bad: `foo.call(undefined, 1, 2, 3)`, Good: `foo.call(obj, 1, 2, 3)` * Bad: `foo.apply(undefined, [1, 2, 3])`, Good: `foo.apply(obj, [1, 2, 3])` */ 'no-useless-call': 'error', /** * #improves-code-understanding * A `catch` clause that only rethrows the original error is redundant, and has no effect on the * runtime behavior of the program. These redundant clauses can be a source of confusion and * code bloat, so it’s better to disallow these unnecessary catch clauses. */ 'no-useless-catch': 'error', /** * #improves-code-understanding, #low */ 'no-useless-concat': 'error', /** * #improves-code-understanding */ 'no-useless-escape': 'error', /** * #improves-code-understanding */ 'prefer-promise-reject-errors': 'error', /** * #improves-code-understanding, #consistency * Yoda conditions are so named because the literal value of the condition comes first while the * variable comes second. * Bad: `if ('red' === color) {` */ yoda: 'error', /** * #improves-code-understanding * If an `if` block contains a `return` statement, the `else` block becomes unnecessary. Its * contents can be placed outside of the block. */ 'no-else-return': 'error', /** * #improves-code-understanding * Use `...args` as function argument instead of `arguments` global variable. */ 'prefer-rest-params': 'error', /** * #improves-code-understanding * Bad: `Math.max.apply(Math, args)`, Good: `Math.max(...args)` */ 'prefer-spread': 'error', /** * #improves-code-understanding * Bad: `"Hello, " + name + "!"`, Good: ``Hello, ${name}!`` */ 'prefer-template': 'error', /** * #improves-code-understanding */ 'require-yield': 'error', /** * #improves-code-understanding */ 'no-unsafe-finally': 'error', /** * #improves-code-understanding, #consistency * Bad: `{ method: function () {} }`, Good: `{ method() { } }` */ 'object-shorthand': ['error', 'methods'], /** * #improves-code-understanding, #low * Bad: `parseInt("111110111", 2)`, Good: `0b111110111` */ 'prefer-numeric-literals': 'error', /** * #improves-code-understanding * Bad: `function () { return 3 }`, Good: `() => 3` */ 'prefer-arrow-callback': 'error', /** * #improves-code-understanding * Bad: `Symbol()`, Good: `Symbol('description')` */ 'symbol-description': 'error', /** * #improves-code-understanding * In contexts such as an if statement’s test where the result of the expression will already be * coerced to a Boolean, casting to a Boolean via double negation (!!) or a Boolean call is * unnecessary. For example, these if statements are equivalent: */ 'no-extra-boolean-cast': 'error', /** * #improves-code-understanding * @example * // Bad * import { find } from 'module'; * import { merge } from 'module'; * // Good * import { find, merge } from 'module'; */ 'no-duplicate-imports': ['error', { includeExports: true }], /** * #improves-code-understanding * Bad: `var foo = {["a"]: "b"}`, Good: `var foo = {"a": "b"}` */ 'no-useless-computed-key': 'error', /** * #improves-code-understanding * @example * // Bad * import { foo as bar } from "baz" * export { foo as bar } * let { foo: bar } = baz * * // Good * import { foo } from "bar" * export { foo } * let { foo } = bar */ 'no-useless-rename': 'error', /** * #improves-code-understanding * Don't allow strings that span across multiple lines. */ 'no-multi-str': 'error', /** * #improves-code-understanding * Bad: `new String("Hello world")` * Bad: `new Number(33)` * Bad: `new Boolean(false)` */ 'no-new-wrappers': 'error', /** * #improves-code-understanding */ 'no-useless-return': 'error', /** * #improves-code-understanding * This rule aims to create clearer code by disallowing the bad practice of creating a label * that shares a name with a variable that is in scope. * @example * // Bad * var x = foo; * function bar() { * x: for (;;) { * break x; * } * } */ 'no-label-var': 'error', /** * #improves-code-understanding * Bad: `const appHeader = new require('app-header');` * Good: `const AppHeader = require('app-header'); const appHeader = new AppHeader();` */ 'no-new-require': 'error', /** * #improves-code-understanding, #experiment * Enforce a maximum depth that callbacks can be nested. * The value of `4` is found out by experimenting with the Nota codebase. */ 'max-nested-callbacks': ['error', { max: 4 }], /** * #improves-code-understanding * Bad: `const foo = function bar() {}` * Good: `const foo = function foo() {}` */ 'func-name-matching': 'error', /** * #improves-code-understanding * Bad: `const foo = bar === 'something' ? true : false` * Good: `const foo = bar === 'something'` */ 'no-unneeded-ternary': 'error', /** * #improves-code-understanding * Bad: */ 'operator-assignment': 'error', /** * #improves-code-understanding * When `Object.assign()` is called using an object literal as the first argument, this rule * requires using the object spread syntax instead. This rule also warns on cases where an * `Object.assign()` call is made using a single argument that is an object literal, in this * case, the `Object.assign()` call is not needed. */ 'prefer-object-spread': 'error', /** * #improves-code-understanding * Bad: `function f(a = 0, b) {}`, Good: `function f(a, b = 0) {}` * Bad: `function f(a, b = 0, c) {}`, Good: `function f(a, b, c = 0) {}` */ 'default-param-last': 'error', /** * #improves-code-understanding * Bad: `new RegExp('abc')`, Good: `/abc/` * Bad: `RegExp(`^\\d\\.$`)`, Good: `/^\d\.$/` */ 'prefer-regex-literals': 'error', /** * #improves-code-understanding * Don't allow `return` statements in a class constructor. This is a confusing JavaScript * feature which instead of creating a class instance returns a custom value. */ 'no-constructor-return': 'error', /** * #improves-code-understanding * While returning a value from a setter does not produce an error, the returned value is being * ignored. Therefore, returning a value from a setter is either unnecessary or a possible * error, since the returned value cannot be used. */ 'no-setter-return': 'error', /** * #improves-code-understanding, #consistency * This rule enforces getter and setter for the same property to be next to each other. */ 'grouped-accessor-pairs': 'error', /** * #consistency * Disallow the unary operators `++` and `--`. Unary operators are a shorthand for operator * assignments. It is a feature which is rarely used and the time it takes to understand the * concept is higher than just plain old `value += 1`. But still this is very opinionated so * won't add it a `#improves-code-understanding` tag. */ 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], /** * #consistency * Bad: `const num = .5`, Good: `const num = 0.5` */ 'no-floating-decimal': 'error', /** * #i-don't-know * It’s a common mistake in JavaScript to create an object with just a setter for a property but * never have a corresponding getter defined for it. Without a getter, you cannot read the * property, so it ends up not being used. */ 'accessor-pairs': 'error', /** * #i-don't-know * Don't declare variables inside a switch case without wrapping it with braces. */ 'no-case-declarations': 'error', /** * #consistency * Bad: `if (foo) foo++`, Good: `if (foo) { foo++ }` */ curly: 'error', /** * #consistency * Bad: `Math.pow(2, 4)`, Good: `2 ** 4` */ 'prefer-exponentiation-operator': 'error', /** * #consistency, #readability * Prettier handles it but not in comments. Turning it on only for comments. */ 'no-multi-spaces': 'error', /** * #consistency * Bad: `let bar = undefined`, Good: `let bar;` */ 'no-undef-init': 'error', /** * #ban * Don't allow reassigning functions. */ 'no-func-assign': 'error', /** * #ban * Ban the usage of `console`. */ 'no-console': 'error', /** * #ban * Ban the usage of `debugger`. */ 'no-debugger': 'error', /** * #ban * Ban empty block statements like empty if, while, switch */ 'no-empty': ['error', { allowEmptyCatch: true }], /** * #ban * Don't allow reassigning the `err` variable in the catch close of a try/catch. */ 'no-ex-assign': 'error', /** * #ban * Various whitespace characters can be inputted by programmers by mistake for example from * copying or keyboard shortcuts. Pressing Alt + Space on macOS adds in a non breaking space * character for example. */ 'no-irregular-whitespace': 'error', /** * #ban * Bad: `foo.hasOwnProperty("bar")`, Good: `Object.prototype.hasOwnProperty.call(foo, "bar")` * Bad: `foo.isPrototypeOf(bar)`, Good: `Object.prototype.isPrototypeOf.call(foo, bar)` * Bad: `foo.propertyIsEnumerable("bar")`, Good: `{}.propertyIsEnumerable.call(foo, "bar")` */ 'no-prototype-builtins': 'error', /** * #ban, #improve-code-understanding, #low * Bad: `/foo bar/`, Good: `/foo {3}bar/` */ 'no-regex-spaces': 'error', /** * #ban * Disallow the use of `alert`, `confirm`, and `prompt`. */ 'no-alert': 'error', /** * #ban, #performance */ 'no-caller': 'error', /** * #ban * Bad: `const {} = foo`, Good: `const {a = {}} = foo` */ 'no-empty-pattern': 'error', /** * #ban, #security * Don't allow `eval()` calls. */ 'no-eval': 'error', /** * #ban, #security * Bad: `setTimeout("alert('Hi!');", 100)` * Bad: `setInterval("alert('Hi!');", 100)` * Bad: `execScript("alert('Hi!')")` */ 'no-implied-eval': 'error', /** * #ban, #security * Bad: `new Function("a", "b", "return a + b")` * Bad: `Function("a", "b", "return a + b")` */ 'no-new-func': 'error', /** * #ban * Bad: `function NaN(){}` * Bad: `!function(Infinity){};` * Bad: `var undefined = 5;` * Bad: `try {} catch(eval){}` */ 'no-shadow-restricted-names': 'error', /** * #ban * Bad: `const fullPath = __dirname + '/foo.js'` * Bad: `const fullPath = __filename + '/foo.js'` * Good: `const fullPath = join(__dirname, '/foo.js')` */ 'no-path-concat': 'error', /** * #ban, #low * Disallow the use of the `__iterator__` property */ 'no-iterator': 'error', /** * #ban * Bad: `Object.prototype.a = "a"` * Bad: `Object.defineProperty(Array.prototype, "times", { value: 999 })` */ 'no-extend-native': 'error', /** * #ban * Bad: `window = {}` * Bad: `Object = null` * Bad: `length = 1` * Bad: `undefined = 1` */ 'no-global-assign': 'error', /** * #ban * Don't allow `with` statements. */ 'no-with': 'error', /** * #ban, #low * Bad: `const num = 071` * Bad: `const result = 5 + 07` */ 'no-octal': 'error', /** * #ban, #low * Bad: `const foo = "Copyright \251"` * Good: `const foo = "Copyright \u00A9"` * Good: `const foo = "Copyright \xA9"` */ 'no-octal-escape': 'error', /** * #ban, #low * Don't allow the usage of `__proto__` property. * Bad: `obj.__proto__` */ 'no-proto': 'error', /** * #ban * Bad: `return foo = bar + 2` */ 'no-return-assign': 'error', /** * #ban * Bad: `location.href = "javascript:void(0)"` */ 'no-script-url': 'error', /** * #ban, #low * Bad: `foo = foo` */ 'no-self-assign': 'error', /** * #ban, #low * Bad: `if (10 === 10)` */ 'no-self-compare': 'error', /** * #ban, #low * Bad: `throw "error"` * Bad: `throw 0` * Bad: `throw undefined` * Good: `throw new Error("error")` */ 'no-throw-literal': 'error', /** * #ban * Bad: `a = b += 5, a + b` * Bad: `foo = doSomething(), val` * Bad: `0, eval("doSomething();")` */ 'no-sequences': 'error', /** * #consistency * Bad: `const a = 3, b = 4`, Good: `const a = 3; const b = 4` */ 'one-var': ['error', 'never'], /** * #consistency, #improves-debugging * Bad: `Foo.prototype.bar = function() {}`, Good: `Foo.prototype.bar = function bar() {}` * Bad: `const bar = function () {}`, Good: `const bar = function () {}` */ 'func-names': 'error', /** * #consistency, #naming * Bad: `const friend = new person()`, Good: `const friend = new Person()` * Bad: `const colleague = Person()`, Good: `const colleague = new Person()` * Bad: `const friend = new person.acquaintance()` * Good: `const friend = new person.Acquaintance()` */ 'new-cap': 'error', }, }