|
| 1 | +import { fixupConfigRules, fixupPluginRules } from '@eslint/compat' |
| 2 | +import { FlatCompat } from '@eslint/eslintrc' |
| 3 | +import path from 'node:path' |
| 4 | +import { fileURLToPath } from 'node:url' |
| 5 | + |
| 6 | +const filename = fileURLToPath(import.meta.url) |
| 7 | +const dirname = path.dirname(filename) |
| 8 | + |
| 9 | +const compat = new FlatCompat({ |
| 10 | + baseDirectory: dirname, |
| 11 | +}) |
| 12 | + |
| 13 | +const config = compat.extends('airbnb-base') |
| 14 | + |
| 15 | +const defaultAirBnbRules = [...fixupPluginRules(config)].reduce( |
| 16 | + (acc, currentConfig) => ({ |
| 17 | + ...acc, |
| 18 | + ...currentConfig.rules, |
| 19 | + }), |
| 20 | + {}, |
| 21 | +) |
| 22 | + |
| 23 | +export default [ |
| 24 | + ...fixupConfigRules(compat.extends('airbnb-base')), |
| 25 | + { |
| 26 | + rules: { |
| 27 | + // Replace Airbnb 'camelcase' rule with '@typescript-eslint/naming-convention' |
| 28 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/naming-convention.md |
| 29 | + camelcase: 'off', |
| 30 | + // The `@typescript-eslint/naming-convention` rule allows `leadingUnderscore` and `trailingUnderscore` settings. However, the existing `no-underscore-dangle` rule already takes care of this. |
| 31 | + '@typescript-eslint/naming-convention': [ |
| 32 | + 'error', |
| 33 | + // Allow camelCase variables (23.2), PascalCase variables (23.8), and UPPER_CASE variables (23.10) |
| 34 | + { |
| 35 | + selector: 'variable', |
| 36 | + format: ['camelCase', 'PascalCase', 'UPPER_CASE'], |
| 37 | + }, |
| 38 | + // Allow camelCase functions (23.2), and PascalCase functions (23.8) |
| 39 | + { |
| 40 | + selector: 'function', |
| 41 | + format: ['camelCase', 'PascalCase'], |
| 42 | + }, |
| 43 | + // Airbnb recommends PascalCase for classes (23.3), and although Airbnb does not make TypeScript recommendations, we are assuming this rule would similarly apply to anything "type like", including interfaces, type aliases, and enums |
| 44 | + { |
| 45 | + selector: 'typeLike', |
| 46 | + format: ['PascalCase'], |
| 47 | + }, |
| 48 | + ], |
| 49 | + |
| 50 | + // Replace Airbnb 'default-param-last' rule with '@typescript-eslint' version |
| 51 | + // https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/default-param-last.md |
| 52 | + 'default-param-last': 'off', |
| 53 | + '@typescript-eslint/default-param-last': |
| 54 | + defaultAirBnbRules['default-param-last'], |
| 55 | + |
| 56 | + // Replace Airbnb 'dot-notation' rule with '@typescript-eslint' version |
| 57 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/dot-notation.md |
| 58 | + 'dot-notation': 'off', |
| 59 | + '@typescript-eslint/dot-notation': defaultAirBnbRules['dot-notation'], |
| 60 | + |
| 61 | + // Replace Airbnb 'no-array-constructor' rule with '@typescript-eslint' version |
| 62 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-array-constructor.md |
| 63 | + 'no-array-constructor': 'off', |
| 64 | + '@typescript-eslint/no-array-constructor': |
| 65 | + defaultAirBnbRules['no-array-constructor'], |
| 66 | + |
| 67 | + // Replace Airbnb 'no-dupe-class-members' rule with '@typescript-eslint' version |
| 68 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-dupe-class-members.md |
| 69 | + 'no-dupe-class-members': 'off', |
| 70 | + '@typescript-eslint/no-dupe-class-members': |
| 71 | + defaultAirBnbRules['no-dupe-class-members'], |
| 72 | + |
| 73 | + // Replace Airbnb 'no-empty-function' rule with '@typescript-eslint' version |
| 74 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-empty-function.md |
| 75 | + 'no-empty-function': 'off', |
| 76 | + '@typescript-eslint/no-empty-function': |
| 77 | + defaultAirBnbRules['no-empty-function'], |
| 78 | + |
| 79 | + // Replace Airbnb 'no-extra-parens' rule with '@typescript-eslint' version |
| 80 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-extra-parens.md |
| 81 | + 'no-extra-parens': 'off', |
| 82 | + '@typescript-eslint/no-extra-parens': |
| 83 | + defaultAirBnbRules['no-extra-parens'], |
| 84 | + |
| 85 | + // Replace Airbnb 'no-implied-eval' and 'no-new-func' rules with '@typescript-eslint' version |
| 86 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-implied-eval.md |
| 87 | + 'no-implied-eval': 'off', |
| 88 | + 'no-new-func': 'off', |
| 89 | + '@typescript-eslint/no-implied-eval': |
| 90 | + defaultAirBnbRules['no-implied-eval'], |
| 91 | + |
| 92 | + // Replace Airbnb 'no-loss-of-precision' rule with '@typescript-eslint' version |
| 93 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-loss-of-precision.md |
| 94 | + 'no-loss-of-precision': 'off', |
| 95 | + '@typescript-eslint/no-loss-of-precision': |
| 96 | + defaultAirBnbRules['no-loss-of-precision'], |
| 97 | + |
| 98 | + // Replace Airbnb 'no-loop-func' rule with '@typescript-eslint' version |
| 99 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-loop-func.md |
| 100 | + 'no-loop-func': 'off', |
| 101 | + '@typescript-eslint/no-loop-func': defaultAirBnbRules['no-loop-func'], |
| 102 | + |
| 103 | + // Replace Airbnb 'no-magic-numbers' rule with '@typescript-eslint' version |
| 104 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-magic-numbers.md |
| 105 | + 'no-magic-numbers': 'off', |
| 106 | + '@typescript-eslint/no-magic-numbers': |
| 107 | + defaultAirBnbRules['no-magic-numbers'], |
| 108 | + |
| 109 | + // Replace Airbnb 'no-redeclare' rule with '@typescript-eslint' version |
| 110 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-redeclare.md |
| 111 | + 'no-redeclare': 'off', |
| 112 | + '@typescript-eslint/no-redeclare': defaultAirBnbRules['no-redeclare'], |
| 113 | + |
| 114 | + // Replace Airbnb 'no-shadow' rule with '@typescript-eslint' version |
| 115 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-shadow.md |
| 116 | + 'no-shadow': 'off', |
| 117 | + '@typescript-eslint/no-shadow': defaultAirBnbRules['no-shadow'], |
| 118 | + |
| 119 | + // Replace Airbnb 'no-unused-expressions' rule with '@typescript-eslint' version |
| 120 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unused-expressions.md |
| 121 | + 'no-unused-expressions': 'off', |
| 122 | + '@typescript-eslint/no-unused-expressions': |
| 123 | + defaultAirBnbRules['no-unused-expressions'], |
| 124 | + |
| 125 | + // Replace Airbnb 'no-unused-vars' rule with '@typescript-eslint' version |
| 126 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unused-vars.md |
| 127 | + 'no-unused-vars': 'off', |
| 128 | + '@typescript-eslint/no-unused-vars': defaultAirBnbRules['no-unused-vars'], |
| 129 | + |
| 130 | + // Replace Airbnb 'no-use-before-define' rule with '@typescript-eslint' version |
| 131 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md |
| 132 | + 'no-use-before-define': 'off', |
| 133 | + '@typescript-eslint/no-use-before-define': |
| 134 | + defaultAirBnbRules['no-use-before-define'], |
| 135 | + |
| 136 | + // Replace Airbnb 'no-useless-constructor' rule with '@typescript-eslint' version |
| 137 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-useless-constructor.md |
| 138 | + 'no-useless-constructor': 'off', |
| 139 | + '@typescript-eslint/no-useless-constructor': |
| 140 | + defaultAirBnbRules['no-useless-constructor'], |
| 141 | + |
| 142 | + // Replace Airbnb 'quotes' rule with '@typescript-eslint' version |
| 143 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/quotes.md |
| 144 | + quotes: 'off', |
| 145 | + // '@typescript-eslint/quotes': defaultAirBnbRules.quotes, |
| 146 | + |
| 147 | + // Replace Airbnb 'require-await' rule with '@typescript-eslint' version |
| 148 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/require-await.md |
| 149 | + 'require-await': 'off', |
| 150 | + '@typescript-eslint/require-await': defaultAirBnbRules['require-await'], |
| 151 | + |
| 152 | + // Replace Airbnb 'no-return-await' rule with '@typescript-eslint' version |
| 153 | + // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/return-await.md |
| 154 | + 'no-return-await': 'off', |
| 155 | + '@typescript-eslint/return-await': [ |
| 156 | + defaultAirBnbRules['no-return-await'], |
| 157 | + 'in-try-catch', |
| 158 | + ], |
| 159 | + |
| 160 | + // Append 'ts' and 'tsx' to Airbnb 'import/extensions' rule |
| 161 | + // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md |
| 162 | + 'import/extensions': [ |
| 163 | + defaultAirBnbRules['import/extensions'][0], |
| 164 | + defaultAirBnbRules['import/extensions'][1], |
| 165 | + { |
| 166 | + ...defaultAirBnbRules['import/extensions'][2], |
| 167 | + ts: 'never', |
| 168 | + tsx: 'never', |
| 169 | + }, |
| 170 | + ], |
| 171 | + |
| 172 | + // Append 'ts' and 'tsx' extensions to Airbnb 'import/no-extraneous-dependencies' rule |
| 173 | + // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md |
| 174 | + 'import/no-extraneous-dependencies': [ |
| 175 | + defaultAirBnbRules['import/no-extraneous-dependencies'][0], |
| 176 | + { |
| 177 | + ...defaultAirBnbRules['import/no-extraneous-dependencies'][1], |
| 178 | + devDependencies: defaultAirBnbRules[ |
| 179 | + 'import/no-extraneous-dependencies' |
| 180 | + ][1].devDependencies.reduce((result, devDep) => { |
| 181 | + const toAppend = [devDep] |
| 182 | + const devDepWithTs = devDep.replace(/\bjs(x?)\b/g, 'ts$1') |
| 183 | + if (devDepWithTs !== devDep) { |
| 184 | + toAppend.push(devDepWithTs) |
| 185 | + } |
| 186 | + return [...result, ...toAppend] |
| 187 | + }, []), |
| 188 | + }, |
| 189 | + ], |
| 190 | + }, |
| 191 | + }, |
| 192 | +] |
0 commit comments