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.

254 lines (219 loc) 8.56 kB
import { GLOB_MARKDOWN_CODE, type TypedFlatConfigItem } from '@antfu/eslint-config'; import { pluginNoUseExtendNative, pluginUnusedImports } from '../plugins.ts'; export interface OptionsWgw { /** * Enable TypeScript support */ isTypescript?: boolean; /** * Enable editor specific rules */ isInEditor?: boolean; /** * User overrides */ overrides?: TypedFlatConfigItem['rules']; /** * Enable Astro patches */ isAstro?: boolean; } export async function wgw(options?: OptionsWgw): Promise<TypedFlatConfigItem[]> { const { isAstro = false, isInEditor, isTypescript = true, overrides = {}, } = { ...options } as OptionsWgw; const tsRules = { 'ts/no-explicit-any': 'off', 'ts/no-unnecessary-template-expression': 'off', 'ts/no-unused-vars': 'off', // F off, we have properly configured `no-unused-vars` & `unused-imports` plugin 'ts/triple-slash-reference': 'off', } as any; return [{ name: 'xaxa/wgw/rules-and-overrides', plugins: { 'no-use-extend-native': pluginNoUseExtendNative, 'unused-imports': pluginUnusedImports, }, rules: { ...(isAstro ? { 'astro/sort-attributes': ['error', { ignoreCase: true, order: 'asc', type: 'alphabetical', }], } : {}), ...(isTypescript ? tsRules : {}), // enforces no braces where they can be omitted // https://eslint.org/docs/rules/arrow-body-style // Never enable for object literal. 'arrow-body-style': ['error', 'as-needed', { requireReturnForObjectLiteral: false }], 'camelcase': 'off', 'class-methods-use-this': 'off', 'consistent-return': 'off', // https://eslint.org/docs/rules/default-param-last 'default-param-last': 'error', // Enforce using named functions when regular function is used, // otherwise use arrow functions 'func-names': ['error', 'always'], // ?NOTE: buggy ones 'import/no-extraneous-dependencies': 'off', 'import/no-unresolved': 'off', 'max-classes-per-file': 'off', // http://eslint.org/docs/rules/max-depth 'max-depth': ['error', { max: 4 }], // http://eslint.org/docs/rules/max-nested-callbacks 'max-nested-callbacks': ['error', { max: 4 }], // http://eslint.org/docs/rules/max-params 'max-params': ['error', { max: 6 }], // http://eslint.org/docs/rules/max-statements 'max-statements': ['error', 40, { ignoreTopLevelFunctions: true }], 'no-await-in-loop': 'off', 'no-console': 'off', // why? 'no-continue': 'warn', 'no-empty': ['error', { allowEmptyCatch: true }], 'no-extend-native': 'error', 'no-import-assign': 'error', 'no-nested-ternary': 'off', // 'no-explicit-any': 'warn', 'no-param-reassign': 'off', 'no-plusplus': 'off', 'no-restricted-exports': 'off', // Default as Airbnb's except we allow `for of` & `for await of` and disallow `TSEnumDeclaration` & `TSExportAssignment` // https://eslint.org/docs/rules/no-restricted-syntax 'no-restricted-syntax': [ 'error', 'TSEnumDeclaration[const=true]', 'TSExportAssignment', { 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', }, // { // selector: 'ForOfStatement', // 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.', // }, { 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', }, ], // yes, we know that it's just a convention, allow me Airbnb. 'no-underscore-dangle': 'off', 'no-unnecessary-template-expression': 'off', // Off in Airbnb, until `eslint v7.15 is required` // disallow use of optional chaining in contexts where the undefined value is not allowed // https://eslint.org/docs/rules/no-unsafe-optional-chaining 'no-unsafe-optional-chaining': ['error', { disallowArithmeticOperators: true, }], // Allow functions to be use before define because: // 1) they are hoisted, // 2) because ensure read flow is from top to bottom // 3) logically order of the code. // 4) the only addition is 'typedefs' option, see overrides for TS files 'no-use-before-define': ['error', { allowNamedExports: true, classes: true, functions: false, variables: true, }], 'no-use-extend-native/no-use-extend-native': 'error', 'no-useless-template-literals': 'off', // ?NOTE: buggy 'node/no-missing-import': 'warn', 'node/no-unpublished-import': 'warn', 'prefer-arrow-callback': ['error', { allowNamedFunctions: true, allowUnboundThis: true, }], 'prefer-const': [isInEditor ? 'warn' : 'error', { ignoreReadBeforeAssign: true }, ], // bruh 'prefer-destructuring': 'off', // Prefer Object.hasOwn() over Object.prototype.hasOwnProperty.call() // https://eslint.org/docs/rules/prefer-object-has-own 'prefer-object-has-own': 'error', 'prefer-regex-literals': 'error', 'sort-keys': 'off', // we use es modules 'strict': ['off', 'global'], // Always use parens (for consistency). // https://eslint.org/docs/rules/arrow-parens 'style/arrow-parens': ['error', 'always'], 'style/brace-style': ['error', '1tbs', { allowSingleLine: false }], 'style/lines-between-class-members': ['error', { enforce: [ { blankLine: 'never', next: '*', prev: 'field' }, { blankLine: 'always', next: 'method', prev: 'field' }, { blankLine: 'always', next: 'method', prev: 'method' }, ], }], // http://eslint.org/docs/rules/max-statements-per-line 'style/max-statements-per-line': ['error', { max: 1 }], 'style/quote-props': 'error', 'unused-imports/no-unused-imports': isInEditor ? 'warn' : 'error', // disallow declaration of variables that are not used in the code 'unused-imports/no-unused-vars': ['error', { args: 'after-used', // airbnb's default argsIgnorePattern: '^(?:$$|xx|_|__|[iI]gnor(?:e|ing|ed))', // catch blocks are handled by Unicorns caughtErrors: 'none', ignoreRestSiblings: true, // airbnb's default vars: 'all', // airbnb's default // caughtErrorsIgnorePattern: '^(?:$$|xx|_|__|[iI]gnor(?:e|ing|ed))', varsIgnorePattern: '^(?:$$|xx|_|__|[iI]gnor(?:e|ing|ed))', }], }, }, { // ensure antfu/markdown/disables are last (because WGW is set as last, so we need to redefine these here again) files: [GLOB_MARKDOWN_CODE], name: 'xaxa/markdown/disables', rules: { 'antfu/no-top-level-await': 'off', // ?NOTE: buggy ones 'import/no-extraneous-dependencies': 'off', 'import/no-unresolved': 'off', 'no-alert': 'off', 'no-console': 'off', 'no-labels': 'off', 'no-lone-blocks': 'off', 'no-restricted-syntax': 'off', 'no-undef': 'off', 'no-unused-expressions': 'off', 'no-unused-labels': 'off', 'no-unused-vars': 'off', // ?NOTE: buggy 'node/no-missing-import': 'off', 'node/no-unpublished-import': 'off', 'node/prefer-global/process': 'off', 'style/comma-dangle': 'off', 'style/eol-last': 'off', 'ts/consistent-type-imports': 'off', 'ts/explicit-function-return-type': 'off', 'ts/no-namespace': 'off', 'ts/no-redeclare': 'off', 'ts/no-require-imports': 'off', 'ts/no-unused-expressions': 'off', 'ts/no-unused-vars': 'off', 'ts/no-use-before-define': 'off', 'unicode-bom': 'off', 'unused-imports/no-unused-imports': 'off', 'unused-imports/no-unused-vars': 'off', }, }, { name: 'xaxa/wgw/user-overrides', rules: { ...overrides, }, }]; }