271 lines
7.7 KiB
JavaScript
271 lines
7.7 KiB
JavaScript
module.exports = {
|
|
extends: [
|
|
"airbnb-base",
|
|
"airbnb-typescript/base",
|
|
"plugin:jest/recommended",
|
|
"plugin:jest/style",
|
|
"plugin:@typescript-eslint/recommended",
|
|
"plugin:import/typescript",
|
|
"prettier",
|
|
],
|
|
|
|
parserOptions: { tsconfigRootDir: __dirname, project: "./tsconfig.eslint.json" },
|
|
|
|
env: { es2021: true, node: true, "jest/globals": true },
|
|
|
|
plugins: ["jest"],
|
|
|
|
ignorePatterns: [
|
|
"node_modules",
|
|
"dist",
|
|
"coverage",
|
|
// "**/*.d.ts",
|
|
"!.*.js",
|
|
"!.*.cjs",
|
|
"!.*.mjs",
|
|
],
|
|
|
|
rules: {
|
|
// enforce curly brace usage
|
|
curly: ["error", "all"],
|
|
|
|
// allow class methods which do not use this
|
|
"class-methods-use-this": "off",
|
|
|
|
// Allow use of ForOfStatement - no-restricted-syntax does not allow us to turn off a rule. This block overrides the airbnb rule entirely
|
|
// https://github.com/airbnb/javascript/blob/7152396219e290426a03e47837e53af6bcd36bbe/packages/eslint-config-airbnb-base/rules/style.js#L257-L263
|
|
"no-restricted-syntax": [
|
|
"error",
|
|
{
|
|
selector: "ForInStatement",
|
|
message:
|
|
"for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.",
|
|
},
|
|
{
|
|
selector: "LabeledStatement",
|
|
message:
|
|
"Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.",
|
|
},
|
|
{
|
|
selector: "WithStatement",
|
|
message:
|
|
"`with` is disallowed in strict mode because it makes code impossible to predict and optimize.",
|
|
},
|
|
],
|
|
|
|
// underscore dangle will be handled by @typescript-eslint/naming-convention
|
|
"no-underscore-dangle": "off",
|
|
|
|
// enforce consistent sort order
|
|
"sort-imports": ["error", { ignoreCase: true, ignoreDeclarationSort: true }],
|
|
|
|
// enforce convention in import order
|
|
"import/order": [
|
|
"error",
|
|
{
|
|
"newlines-between": "never",
|
|
groups: ["builtin", "external", "internal", "parent", "sibling", "index"],
|
|
alphabetize: { order: "asc", caseInsensitive: true },
|
|
},
|
|
],
|
|
|
|
// ensure consistent array typings
|
|
"@typescript-eslint/array-type": "error",
|
|
|
|
// ban ts-comment except with description
|
|
"@typescript-eslint/ban-ts-comment": [
|
|
"error",
|
|
{
|
|
"ts-expect-error": "allow-with-description",
|
|
"ts-ignore": "allow-with-description",
|
|
"ts-nocheck": true,
|
|
"ts-check": false,
|
|
},
|
|
],
|
|
|
|
// prefer type imports and exports
|
|
"@typescript-eslint/consistent-type-exports": [
|
|
"error",
|
|
{ fixMixedExportsWithInlineTypeSpecifier: true },
|
|
],
|
|
"@typescript-eslint/consistent-type-imports": ["error", { prefer: "type-imports" }],
|
|
|
|
// enforce consistent order of class members
|
|
"@typescript-eslint/member-ordering": "error",
|
|
|
|
// set up naming convention rules
|
|
"@typescript-eslint/naming-convention": [
|
|
"error",
|
|
// camelCase for everything not otherwise indicated
|
|
{ selector: "default", format: ["camelCase"] },
|
|
// allow known default exclusions
|
|
{
|
|
selector: "default",
|
|
filter: { regex: "^(_id|__v)$", match: true },
|
|
format: null,
|
|
},
|
|
// allow variables to be camelCase or UPPER_CASE
|
|
{ selector: "variable", format: ["camelCase", "UPPER_CASE"] },
|
|
// allow known variable exclusions
|
|
{
|
|
selector: "variable",
|
|
filter: { regex: "^(_id|__v)$", match: true },
|
|
format: null,
|
|
},
|
|
{
|
|
// variables ending in Service should be PascalCase
|
|
selector: "variable",
|
|
filter: { regex: "^.*Service$", match: true },
|
|
format: ["PascalCase"],
|
|
},
|
|
// do not enforce format on property names
|
|
{ selector: "property", format: null },
|
|
// PascalCase for classes and TypeScript keywords
|
|
{
|
|
selector: ["typeLike"],
|
|
format: ["PascalCase"],
|
|
},
|
|
],
|
|
|
|
// disallow parameter properties in favor of explicit class declarations
|
|
"@typescript-eslint/no-parameter-properties": "error",
|
|
|
|
// ensure unused variables are treated as an error
|
|
// overrides @typescript-eslint/recommended -- '@typescript-eslint/no-unused-vars': 'warn'
|
|
// https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/recommended.ts
|
|
"@typescript-eslint/no-unused-vars": "warn",
|
|
},
|
|
|
|
overrides: [
|
|
{
|
|
files: ["**/*.ts"],
|
|
extends: ["plugin:@typescript-eslint/recommended-requiring-type-checking"],
|
|
rules: {
|
|
// disable rules turned on by @typescript-eslint/recommended-requiring-type-checking which are too noisy
|
|
// https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts
|
|
"@typescript-eslint/no-unsafe-argument": "off",
|
|
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
"@typescript-eslint/no-unsafe-call": "off",
|
|
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
"@typescript-eslint/no-unsafe-return": "off",
|
|
"@typescript-eslint/restrict-template-expressions": "off",
|
|
"@typescript-eslint/unbound-method": "off",
|
|
|
|
// force explicit member accessibility modifiers
|
|
"@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }],
|
|
|
|
// enforce return types on module boundaries
|
|
"@typescript-eslint/explicit-module-boundary-types": "error",
|
|
|
|
// allow empty functions
|
|
"@typescript-eslint/no-empty-function": "off",
|
|
},
|
|
},
|
|
|
|
{
|
|
files: ["**/index.ts"],
|
|
rules: {
|
|
// prefer named exports for certain file types
|
|
"import/prefer-default-export": "off",
|
|
"import/no-default-export": "error",
|
|
},
|
|
},
|
|
|
|
{
|
|
files: [
|
|
"**/test/**/*.[jt]s?(x)",
|
|
"**/__tests__/**/*.[jt]s?(x)",
|
|
"**/?(*.)+(spec|test).[jt]s?(x)",
|
|
],
|
|
rules: {
|
|
// allow tests to create multiple classes
|
|
"max-classes-per-file": "off",
|
|
|
|
// allow side effect constructors
|
|
"no-new": "off",
|
|
|
|
// allow import with CommonJS export
|
|
"import/no-import-module-exports": "off",
|
|
|
|
// allow dev dependencies
|
|
"import/no-extraneous-dependencies": [
|
|
"error",
|
|
{ devDependencies: true, optionalDependencies: false, peerDependencies: false },
|
|
],
|
|
|
|
// disallow use of "it" for test blocks
|
|
"jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }],
|
|
|
|
// ensure all tests contain an assertion
|
|
"jest/expect-expect": "error",
|
|
|
|
// no commented out tests
|
|
"jest/no-commented-out-tests": "error",
|
|
|
|
// no duplicate test hooks
|
|
"jest/no-duplicate-hooks": "error",
|
|
|
|
// valid titles
|
|
"jest/valid-title": "error",
|
|
|
|
// no if conditionals in tests
|
|
"jest/no-if": "error",
|
|
|
|
// expect statements in test blocks
|
|
"jest/no-standalone-expect": "error",
|
|
|
|
// disallow returning from test
|
|
"jest/no-test-return-statement": "error",
|
|
|
|
// disallow truthy and falsy in tests
|
|
"jest/no-restricted-matchers": ["error", { toBeFalsy: null, toBeTruthy: null }],
|
|
|
|
// prefer called with
|
|
"jest/prefer-called-with": "error",
|
|
|
|
"jest/no-conditional-expect": "off"
|
|
},
|
|
},
|
|
|
|
{
|
|
files: [
|
|
"**/test/**/*.ts?(x)",
|
|
"**/__tests__/**/*.ts?(x)",
|
|
"**/?(*.)+(spec|test).ts?(x)",
|
|
],
|
|
rules: {
|
|
// allow explicit any in tests
|
|
"@typescript-eslint/no-explicit-any": "off",
|
|
|
|
// allow non-null-assertions
|
|
"@typescript-eslint/no-non-null-assertion": "off",
|
|
|
|
// allow empty arrow functions
|
|
"@typescript-eslint/no-empty-function": ["warn", { allow: ["arrowFunctions"] }],
|
|
},
|
|
},
|
|
|
|
{
|
|
files: ["./.*.js", "./*.js"],
|
|
rules: {
|
|
// allow requires in config files
|
|
"@typescript-eslint/no-var-requires": "off",
|
|
},
|
|
},
|
|
|
|
{
|
|
files: ["**/*.d.ts"],
|
|
rules: {
|
|
// allow tests to create multiple classes
|
|
"max-classes-per-file": "off",
|
|
"@typescript-eslint/naming-convention": "off",
|
|
|
|
"lines-between-class-members": "off",
|
|
"@typescript-eslint/lines-between-class-members": "off",
|
|
"@typescript-eslint/member-ordering": "off",
|
|
"@typescript-eslint/ban-types": "off"
|
|
},
|
|
},
|
|
],
|
|
};
|