UNPKG

eslint-config-xaxa

Version:

The ultimate ESLint config - successor to Airbnb Config. Built on Anthony Fu's ESLint config, Airbnb, ESLint Stylistic, Perfectionist, React, TypeScript, Astro, JSDocs, Prettier, Node.js, Unicorns, Promises, and more.

994 lines (993 loc) 24.7 kB
import { GLOB_SRC } from "@antfu/eslint-config"; import confusingBrowserGlobals from "confusing-browser-globals"; import globals from "globals"; import { pluginImport, pluginNode, pluginStylistic } from "../plugins.js"; export const airbnbBestPractices = { name: "airbnb/best-practices", plugins: { node: pluginNode, style: pluginStylistic }, rules: { "accessor-pairs": "off", "array-callback-return": ["error", { allowImplicit: true }], "block-scoped-var": "error", "class-methods-use-this": ["error", { exceptMethods: [] }], "complexity": ["error", 40], "consistent-return": "error", "curly": ["error", "multi-line"], "default-case": ["error", { commentPattern: "^no default$" }], "default-case-last": "error", "default-param-last": "error", "dot-notation": ["error", { allowKeywords: true }], "eqeqeq": [ "error", "always", { null: "ignore" } ], "grouped-accessor-pairs": "error", "guard-for-in": "error", "max-classes-per-file": ["error", 1], "no-alert": "warn", "no-caller": "error", "no-case-declarations": "error", "no-constructor-return": "error", "no-div-regex": "off", "no-else-return": ["error", { allowElseIf: false }], "no-empty": ["error", { allowEmptyCatch: true }], "no-empty-pattern": "error", "no-empty-static-block": "off", "no-eq-null": "off", "no-eval": "error", "no-extend-native": "error", "no-extra-bind": "error", "no-extra-label": "error", "no-fallthrough": "error", "no-global-assign": ["error", { exceptions: [] }], "no-implicit-coercion": ["off", { allow: [], boolean: false, number: true, string: true }], "no-implicit-globals": "off", "no-implied-eval": "error", "no-import-assign": "error", "no-invalid-this": "off", "no-iterator": "error", "no-labels": ["error", { allowLoop: false, allowSwitch: false }], "no-lone-blocks": "error", "no-loop-func": "error", "no-magic-numbers": ["off", { detectObjects: false, enforceConst: true, ignore: [], ignoreArrayIndexes: true }], "no-multi-str": "error", "no-new": "error", "no-new-func": "error", "no-new-wrappers": "error", "no-nonoctal-decimal-escape": "error", "no-object-constructor": "off", "no-octal": "error", "no-octal-escape": "error", "no-param-reassign": ["error", { ignorePropertyModificationsFor: [ "err", "x", "_", "opts", "flags", "options", "settings", "config", "cfg", "acc", "accumulator", "e", "ctx", "context", "req", "request", "res", "response", "$scope", "staticContext" ], props: true }], "no-proto": "error", "no-redeclare": "error", "no-restricted-properties": [ "error", { message: "arguments.callee is deprecated", object: "arguments", property: "callee" }, { message: "Please use Number.isFinite instead", object: "global", property: "isFinite" }, { message: "Please use Number.isFinite instead", object: "self", property: "isFinite" }, { message: "Please use Number.isFinite instead", object: "window", property: "isFinite" }, { message: "Please use Number.isNaN instead", object: "global", property: "isNaN" }, { message: "Please use Number.isNaN instead", object: "self", property: "isNaN" }, { message: "Please use Number.isNaN instead", object: "window", property: "isNaN" }, { message: "Please use Object.defineProperty instead.", property: "__defineGetter__" }, { message: "Please use Object.defineProperty instead.", property: "__defineSetter__" }, { message: "Use the exponentiation operator (**) instead.", object: "Math", property: "pow" } ], "no-return-assign": ["error", "always"], "no-return-await": "error", "no-script-url": "error", "no-self-assign": ["error", { props: true }], "no-self-compare": "error", "no-sequences": "error", "no-throw-literal": "error", "no-unmodified-loop-condition": "off", "no-unsafe-optional-chaining": ["error", { disallowArithmeticOperators: true }], "no-unused-expressions": ["error", { allowShortCircuit: false, allowTaggedTemplates: false, allowTernary: false }], "no-unused-labels": "error", "no-useless-call": "off", "no-useless-catch": "error", "no-useless-concat": "error", "no-useless-escape": "error", "no-useless-return": "error", "no-void": "off", "no-warning-comments": ["off", { location: "start", terms: [ "todo", "fixme", "xxx" ] }], "no-with": "error", "prefer-named-capture-group": "error", "prefer-object-has-own": "error", "prefer-promise-reject-errors": ["error", { allowEmptyReject: true }], "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }], "radix": "off", "require-await": "off", "require-unicode-regexp": "error", "style/dot-location": ["error", "property"], "style/function-call-argument-newline": ["error", "consistent"], "style/no-floating-decimal": "error", "style/no-multi-spaces": ["error", { ignoreEOLComments: false }], "style/no-native-reassign": "off", "style/wrap-iife": [ "error", "outside", { functionPrototypeMethods: false } ], "vars-on-top": "error", "yoda": "error" } }; export const airbnbErrors = { name: "airbnb/errors", plugins: { style: pluginStylistic }, rules: { "for-direction": "error", "getter-return": ["error", { allowImplicit: true }], "no-async-promise-executor": "error", "no-await-in-loop": "error", "no-compare-neg-zero": "error", "no-cond-assign": ["error", "always"], "no-console": "warn", "no-constant-binary-expression": "off", "no-constant-condition": "warn", "no-control-regex": "error", "no-debugger": "error", "no-dupe-args": "error", "no-dupe-else-if": "error", "no-dupe-keys": "error", "no-duplicate-case": "error", "no-empty": "error", "no-empty-character-class": "error", "no-ex-assign": "error", "no-extra-boolean-cast": "error", "no-func-assign": "error", "no-import-assign": "error", "no-inner-declarations": "error", "no-invalid-regexp": "error", "no-irregular-whitespace": "error", "no-loss-of-precision": "error", "no-misleading-character-class": "error", "no-new-native-nonconstructor": "error", "no-obj-calls": "error", "no-promise-executor-return": "error", "no-prototype-builtins": "error", "no-regex-spaces": "error", "no-setter-return": "error", "no-sparse-arrays": "error", "no-template-curly-in-string": "error", "no-unexpected-multiline": "error", "no-unreachable": "error", "no-unreachable-loop": ["error", { ignore: [] }], "no-unsafe-finally": "error", "no-unsafe-negation": "error", "no-unsafe-optional-chaining": ["error", { disallowArithmeticOperators: true }], "no-unused-private-class-members": "warn", "no-useless-backreference": "error", "require-atomic-updates": "off", "style/no-extra-parens": [ "error", "all", { conditionalAssign: true, enforceForArrowConditionals: false, ignoreJSX: "all", nestedBinaryExpressions: false, returnAssign: false } ], "style/no-extra-semi": "error", "use-isnan": ["error", { enforceForIndexOf: true, enforceForSwitchCase: true }], "valid-jsdoc": "off", "valid-typeof": ["error", { requireStringLiterals: true }] } }; export const airbnbES6Style = { name: "airbnb/es6-style", plugins: { style: pluginStylistic }, rules: { "arrow-body-style": [ "error", "as-needed", { requireReturnForObjectLiteral: false } ], "constructor-super": "error", "no-class-assign": "error", "no-const-assign": "error", "no-dupe-class-members": "error", "no-duplicate-imports": "off", "no-new-native-nonconstructor": "error", "no-restricted-exports": ["error", { restrictedNamedExports: [ "default", "then", "catch" ] }], "no-restricted-imports": ["off", { paths: [], patterns: [] }], "no-this-before-super": "error", "no-useless-computed-key": "error", "no-useless-constructor": "error", "no-useless-rename": ["error", { ignoreDestructuring: false, ignoreExport: true, ignoreImport: true }], "no-var": "error", "object-shorthand": [ "error", "always", { avoidQuotes: true, ignoreConstructors: false } ], "prefer-arrow-callback": ["error", { allowNamedFunctions: false, allowUnboundThis: true }], "prefer-const": ["error", { destructuring: "any", ignoreReadBeforeAssign: true }], "prefer-destructuring": [ "error", { AssignmentExpression: { array: true, object: false }, VariableDeclarator: { array: false, object: true } }, { enforceForRenamedProperties: false } ], "prefer-numeric-literals": "error", "prefer-reflect": "error", "prefer-rest-params": "error", "prefer-spread": "error", "prefer-template": "error", "require-yield": "error", "sort-imports": ["off", { ignoreCase: false, ignoreDeclarationSort: false, ignoreMemberSort: false, memberSyntaxSortOrder: [ "none", "all", "multiple", "single" ] }], "style/arrow-parens": ["error", "always"], "style/arrow-spacing": ["error", { after: true, before: true }], "style/generator-star-spacing": ["error", { after: true, before: false }], "style/no-confusing-arrow": ["error", { allowParens: true }], "style/rest-spread-spacing": ["error", "never"], "style/template-curly-spacing": "error", "style/yield-star-spacing": ["error", "after"], "symbol-description": "error" } }; export const airbnbNodejsSpecifics = { name: "airbnb/specific-to-nodejs", plugins: { node: pluginNode, style: pluginStylistic }, rules: { "node/callback-return": ["error", [ "callback", "cb", "next", "done" ]], "node/global-require": "error", "node/handle-callback-err": "off", "node/no-new-require": "error", "node/no-path-concat": "error", "node/no-process-env": "off", "node/no-process-exit": "off", "node/no-sync": "off", "style/no-mixed-requires": ["off", false], "style/no-restricted-modules": "off" } }; export const airbnbGeneralStyling = { name: "airbnb/general-styling", plugins: { style: pluginStylistic }, rules: { "camelcase": ["error", { ignoreDestructuring: false, properties: "never" }], "capitalized-comments": [ "off", "never", { block: { ignoreConsecutiveComments: true, ignoreInlineComments: true, ignorePattern: ".*" }, line: { ignoreConsecutiveComments: true, ignoreInlineComments: true, ignorePattern: ".*" } } ], "consistent-this": "off", "func-name-matching": [ "off", "always", { considerPropertyDescriptor: true, includeCommonJSModuleExports: false } ], "func-names": "warn", "func-style": ["off", "expression"], "id-denylist": "off", "id-length": "off", "id-match": "off", "logical-assignment-operators": [ "off", "always", { enforceForIfStatements: true } ], "max-depth": ["off", 4], "max-params": ["error", 5], "new-cap": ["error", { capIsNew: false, capIsNewExceptions: [ "Immutable.Map", "Immutable.Set", "Immutable.List" ], newIsCap: true, newIsCapExceptions: [] }], "no-array-constructor": "error", "no-bitwise": "error", "no-continue": "error", "no-inline-comments": "off", "no-lonely-if": "error", "no-multi-assign": ["error"], "no-negated-condition": "off", "no-nested-ternary": "error", "no-object-constructor": "error", "no-plusplus": "error", "no-restricted-syntax": [ "error", { 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: "ForInStatement" }, { message: `iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.`, selector: "ForOfStatement" }, { message: `Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.`, selector: "LabeledStatement" }, { message: `the "with" is disallowed in strict mode because it makes code impossible to predict and optimize.`, selector: "WithStatement" } ], "no-underscore-dangle": ["error", { allow: [], allowAfterSuper: false, allowAfterThis: false, enforceInMethodNames: true }], "no-unneeded-ternary": ["error", { defaultAssignment: false }], "one-var": ["error", "never"], "operator-assignment": ["error", "always"], "prefer-exponentiation-operator": "error", "prefer-object-spread": "error", "require-jsdoc": "off", "style/array-bracket-spacing": ["error", "never"], "style/block-spacing": ["error", "always"], "style/brace-style": [ "error", "1tbs", { allowSingleLine: true } ], "style/comma-dangle": ["error", { arrays: "always-multiline", exports: "always-multiline", functions: "always-multiline", imports: "always-multiline", objects: "always-multiline" }], "style/comma-spacing": ["error", { after: true, before: false }], "style/comma-style": [ "error", "last", { exceptions: { ArrayExpression: false, ArrayPattern: false, ArrowFunctionExpression: false, CallExpression: false, FunctionDeclaration: false, FunctionExpression: false, ImportDeclaration: false, NewExpression: false, ObjectExpression: false, ObjectPattern: false, VariableDeclaration: false } } ], "style/computed-property-spacing": ["error", "never"], "style/eol-last": ["error", "always"], "style/function-call-spacing": ["error", "never"], "style/function-paren-newline": ["error", "multiline-arguments"], "style/implicit-arrow-linebreak": ["error", "beside"], "style/indent": [ "error", 2, { ArrayExpression: 1, CallExpression: { arguments: 1 }, flatTernaryExpressions: false, FunctionDeclaration: { body: 1, parameters: 1 }, FunctionExpression: { body: 1, parameters: 1 }, ignoreComments: false, ignoredNodes: [ "JSXElement", "JSXElement > *", "JSXAttribute", "JSXIdentifier", "JSXNamespacedName", "JSXMemberExpression", "JSXSpreadAttribute", "JSXExpressionContainer", "JSXOpeningElement", "JSXClosingElement", "JSXFragment", "JSXOpeningFragment", "JSXClosingFragment", "JSXText", "JSXEmptyExpression", "JSXSpreadChild" ], ImportDeclaration: 1, ObjectExpression: 1, outerIIFEBody: 1, SwitchCase: 1, VariableDeclarator: 1 } ], "style/jsx-quotes": ["error", "prefer-double"], "style/key-spacing": ["error", { afterColon: true, beforeColon: false }], "style/keyword-spacing": ["error", { after: true, before: true, overrides: { case: { after: true }, return: { after: true }, throw: { after: true } } }], "style/line-comment-position": ["off", { applyDefaultPatterns: true, ignorePattern: "", position: "above" }], "style/linebreak-style": ["error", "unix"], "style/lines-around-comment": "off", "style/lines-between-class-members": [ "error", "always", { exceptAfterSingleLine: false } ], "style/max-len": [ "error", 120, 2, { ignoreComments: true, ignoreRegExpLiterals: true, ignoreStrings: true, ignoreTemplateLiterals: true, ignoreUrls: true } ], "style/max-lines": ["off", { max: 300, skipBlankLines: true, skipComments: true }], "style/max-lines-per-function": ["off", { IIFEs: true, max: 50, skipBlankLines: true, skipComments: true }], "style/max-nested-callbacks": "off", "style/max-statements": ["off", 40], "style/max-statements-per-line": ["error", { max: 1 }], "style/multiline-comment-style": ["off", "starred-block"], "style/multiline-ternary": ["error", "always-multiline"], "style/new-parens": "error", "style/newline-per-chained-call": ["error", { ignoreChainWithDepth: 4 }], "style/no-mixed-operators": ["error", { allowSamePrecedence: false, groups: [ ["%", "**"], ["%", "+"], ["%", "-"], ["%", "*"], ["%", "/"], ["/", "*"], [ "&", "|", "<<", ">>", ">>>" ], [ "==", "!=", "===", "!==" ], ["&&", "||"] ] }], "style/no-mixed-spaces-and-tabs": "error", "style/no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }], "style/no-spaced-func": "off", "style/no-tabs": "error", "style/no-ternary": "off", "style/no-trailing-spaces": ["error", { ignoreComments: false, skipBlankLines: false }], "style/no-whitespace-before-property": "error", "style/nonblock-statement-body-position": [ "error", "beside", { overrides: {} } ], "style/object-curly-newline": ["error", { ExportDeclaration: { consistent: true, minProperties: 4, multiline: true }, ImportDeclaration: { consistent: true, minProperties: 4, multiline: true }, ObjectExpression: { consistent: true, minProperties: 4, multiline: true }, ObjectPattern: { consistent: true, minProperties: 4, multiline: true } }], "style/object-curly-spacing": ["error", "always"], "style/object-property-newline": ["error", { allowAllPropertiesOnSameLine: true }], "style/one-var-declaration-per-line": ["error", "always"], "style/operator-linebreak": [ "error", "before", { overrides: { "=": "none" } } ], "style/padded-blocks": [ "error", { blocks: "never", classes: "never", switches: "never" }, { allowSingleLineBlocks: true } ], "style/padding-line-between-statements": ["error", { blankLine: "always", next: "return", prev: [ "const", "let", "var" ] }], "style/quote-props": [ "error", "as-needed", { keywords: false, numbers: false, unnecessary: true } ], "style/quotes": [ "error", "single", { allowTemplateLiterals: true, avoidEscape: true } ], "style/semi": ["error", "always"], "style/semi-spacing": ["error", { after: true, before: false }], "style/semi-style": ["error", "last"], "style/sort-keys": [ "off", "asc", { caseSensitive: false, natural: true } ], "style/sort-vars": "off", "style/space-before-blocks": "error", "style/space-before-function-paren": ["error", { anonymous: "always", asyncArrow: "always", named: "never" }], "style/space-in-parens": ["error", "never"], "style/space-infix-ops": "error", "style/space-unary-ops": ["error", { nonwords: false, overrides: {}, words: true }], "style/spaced-comment": [ "error", "always", { block: { balanced: true, exceptions: ["-", "+"], markers: [ "=", "!", ":", "::" ] }, line: { exceptions: ["-", "+"], markers: [ "=", "!", "/" ] } } ], "style/switch-colon-spacing": ["error", { after: true, before: false }], "style/template-tag-spacing": ["error", "never"], "style/wrap-regex": "off", "unicode-bom": ["error", "never"] } }; export const airbnbVariables = { name: "airbnb/variables", rules: { "init-declarations": "off", "no-delete-var": "error", "no-label-var": "error", "no-restricted-globals": [ "error", { message: `Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite`, name: "isFinite" }, { message: `Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan`, name: "isNaN" } ].concat(confusingBrowserGlobals.map((g) => ({ message: `Use window.${g} instead. https://github.com/facebook/create-react-app/blob/HEAD/packages/confusing-browser-globals/README.md`, name: g }))), "no-shadow": "error", "no-shadow-restricted-names": "error", "no-undef": "error", "no-undef-init": "error", "no-undefined": "error", "no-unused-vars": ["error", { args: "after-used", argsIgnorePattern: "^_", ignoreRestSiblings: true, vars: "all", varsIgnorePattern: "^_" }], "no-use-before-define": ["off", { classes: true, functions: true, variables: true }] } }; export const airbnbImportPluginRules = { name: "airbnb/import-rules", plugins: { import: pluginImport }, rules: { "import/consistent-type-specifier-style": ["off", "prefer-inline"], "import/default": "off", "import/dynamic-import-chunkname": ["off", { importFunctions: [], webpackChunknameFormat: "[0-9a-zA-Z-_/.]+" }], "import/export": "error", "import/exports-last": "error", "import/extensions": [ "error", "always", { ignorePackages: true, js: "always", jsx: "always", mjs: "always", ts: "always", tsx: "always" } ], "import/first": "error", "import/group-exports": "off", "import/imports-first": "error", "import/max-dependencies": ["warn", { max: 50 }], "import/named": "error", "import/namespace": ["error", { allowComputed: true }], "import/newline-after-import": "error", "import/no-absolute-path": "error", "import/no-amd": "error", "import/no-anonymous-default-export": ["off", { allowAnonymousClass: false, allowAnonymousFunction: false, allowArray: false, allowArrowFunction: false, allowLiteral: false, allowObject: false }], "import/no-commonjs": "error", "import/no-cycle": ["error", { maxDepth: "∞" }], "import/no-default-export": "off", "import/no-deprecated": "error", "import/no-duplicates": "error", "import/no-dynamic-require": "error", "import/no-empty-named-blocks": "off", "import/no-extraneous-dependencies": ["error", { devDependencies: [ "test/**", "tests/**", "spec/**", "**/__tests__/**", "**/__mocks__/**", "test.{js,jsx,ts,tsx}", "test-*.{js,jsx}", "**/*{.,_}{test,spec}.{js,jsx,ts,tsx}", "**/jest.config.js", "**/jest.setup.js", "**/vue.config.js", "**/webpack.config.js", "**/webpack.config.*.js", "**/rollup.config.js", "**/rollup.config.*.js", "**/gulpfile.js", "**/gulpfile.*.js", "**/Gruntfile{,.js}", "**/protractor.conf.js", "**/protractor.conf.*.js", "**/karma.conf.js", "**/.eslintrc.js", "**/eslint.config.{js,ts,mjs}" ], optionalDependencies: false }], "import/no-import-module-exports": ["error", { exceptions: [] }], "import/no-internal-modules": ["off", { allow: [] }], "import/no-mutable-exports": "error", "import/no-named-as-default": "off", "import/no-named-as-default-member": "error", "import/no-named-default": "error", "import/no-named-export": "off", "import/no-namespace": "off", "import/no-nodejs-modules": "off", "import/no-relative-packages": "off", "import/no-relative-parent-imports": "off", "import/no-restricted-paths": "off", "import/no-self-import": "error", "import/no-unassigned-import": "off", "import/no-unresolved": ["error", { caseSensitive: true, commonjs: false, ignore: [ "^astro:*", "^bun:*", "^bun$", "^npm:*", "^jsr:*", "^cloudflare:*" ] }], "import/no-useless-path-segments": ["error", { commonjs: false, noUselessIndex: false }], "import/no-webpack-loader-syntax": "error", "import/order": "off", "import/prefer-default-export": "off", "import/unambiguous": "off" } }; export async function airbnb(options = {}) { const { imports = true,...opts } = { ...options }; return [ { files: [GLOB_SRC], languageOptions: { ecmaVersion: 2022, globals: { ...globals.builtin, ...globals.browser, ...globals.es2021, ...globals.node, ...globals.nodeBuiltin, ...globals["shared-node-browser"], document: "readonly", navigator: "readonly", window: "readonly", ...opts.globals || {} }, parserOptions: { ecmaFeatures: { jsx: true }, ecmaVersion: 2022, sourceType: "module" }, sourceType: "module" }, linterOptions: { reportUnusedDisableDirectives: false, ...opts?.linterOptions || {} }, ...opts?.setup || {}, name: "xaxa/airbnb/setup" }, airbnbBestPractices, airbnbErrors, airbnbES6Style, airbnbNodejsSpecifics, airbnbGeneralStyling, airbnbVariables, imports && airbnbImportPluginRules, { name: "xaxa/airbnb/user-overrides", rules: { ...opts?.overrides || {} } } ].flat().filter(Boolean); }