1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import stylistic from '@stylistic/eslint-plugin'; 17import _import from 'eslint-plugin-import'; 18import n from 'eslint-plugin-n'; 19import { fixupPluginRules } from '@eslint/compat'; 20import eslint from '@eslint/js'; 21import tseslint from 'typescript-eslint'; 22 23export default tseslint.config( 24 { 25 // config with just ignores is the replacement for `.eslintignore` 26 ignores: [ 27 'bin/**/*', 28 'build/**/*', 29 'bundle/**/*', 30 'dist/**/*', 31 'docs/**/*', 32 'node_modules/**/*', 33 'scripts/**/*', 34 'third_party/**/*', 35 'test/**/*', 36 '**/**.json', 37 '**/**.js' 38 ] 39 }, 40 { 41 files: ['**/*.ts'], 42 extends: [eslint.configs.recommended, tseslint.configs.recommended], 43 plugins: { 44 '@typescript-eslint': tseslint.plugin, 45 '@stylistic': stylistic, 46 import: fixupPluginRules(_import), 47 n 48 }, 49 languageOptions: { 50 parser: tseslint.parser, 51 ecmaVersion: 'latest', 52 sourceType: 'module', 53 parserOptions: { 54 project: true 55 } 56 }, 57 rules: { 58 // suggestions 59 'accessor-pairs': 'error', 60 'arrow-body-style': ['error', 'always'], 61 camelcase: 'off', // we use naming-convention rule to enforce naming scheme 62 'class-methods-use-this': ['error', { exceptMethods: [], enforceForClassFields: true }], 63 complexity: ['error', { max: 15 }], 64 'consistent-return': ['error', { treatUndefinedAsUnspecified: false }], 65 curly: ['error', 'all'], 66 'default-case': 'error', 67 'default-param-last': 'warn', 68 'dot-notation': 'error', 69 eqeqeq: ['error', 'smart'], 70 'func-style': ['error', 'declaration', { allowArrowFunctions: true }], 71 'max-depth': ['error', { max: 4 }], 72 'max-lines-per-function': ['error', { max: 50 }], 73 'max-params': ['error', 5], 74 'multiline-comment-style': ['error', 'starred-block'], 75 'no-else-return': ['error', { allowElseIf: true }], 76 'no-eval': ['error', { allowIndirect: false }], 77 'no-extra-bind': 'error', 78 'no-implied-eval': 'error', 79 'no-lonely-if': 'error', 80 'no-nested-ternary': 'warn', 81 'no-param-reassign': 'warn', 82 'no-prototype-builtins': 'error', 83 'no-regex-spaces': 'error', 84 'no-return-await': 'error', 85 'no-throw-literal': 'error', 86 'no-undef-init': 'error', 87 'no-unneeded-ternary': 'error', 88 'no-useless-return': 'error', 89 'no-var': 'error', 90 'one-var': ['error', 'never'], 91 'one-var-declaration-per-line': 'error', 92 'prefer-const': 'error', 93 'prefer-named-capture-group': 'warn', 94 'prefer-rest-params': 'error', 95 strict: 'error', 96 'spaced-comment': ['error', 'always'], 97 'vars-on-top': 'error', 98 99 // imports 100 'import/no-absolute-path': 'error', 101 'n/file-extension-in-import': ['error', 'never'], 102 103 // style 104 '@stylistic/array-bracket-newline': ['error', 'consistent'], 105 '@stylistic/array-bracket-spacing': ['error', 'never'], 106 '@stylistic/array-element-newline': ['error', 'consistent'], 107 '@stylistic/arrow-parens': ['error', 'always'], 108 '@stylistic/arrow-spacing': ['error', { before: true, after: true }], 109 '@stylistic/block-spacing': ['error', 'always'], 110 '@stylistic/brace-style': ['error', '1tbs', { allowSingleLine: true }], 111 '@stylistic/comma-dangle': [ 112 'error', 113 { 114 arrays: 'never', 115 objects: 'never', 116 imports: 'never', 117 exports: 'never', 118 functions: 'never' 119 } 120 ], 121 '@stylistic/comma-spacing': ['error', { before: false, after: true }], 122 '@stylistic/comma-style': ['error', 'last'], 123 '@stylistic/computed-property-spacing': ['error', 'never', { enforceForClassMembers: true }], 124 '@stylistic/dot-location': ['error', 'object'], 125 '@stylistic/eol-last': ['error', 'always'], 126 '@stylistic/no-confusing-arrow': 'error', 127 '@stylistic/no-floating-decimal': 'error', 128 '@stylistic/func-call-spacing': ['error', 'never'], 129 '@stylistic/function-call-argument-newline': ['error', 'consistent'], 130 '@stylistic/function-paren-newline': ['error', 'consistent'], 131 '@stylistic/generator-star-spacing': ['error', { before: true, after: false }], 132 '@stylistic/implicit-arrow-linebreak': ['error', 'beside'], 133 '@stylistic/indent': [ 134 'error', 135 2, 136 { 137 ignoredNodes: [], 138 SwitchCase: 1, 139 VariableDeclarator: 1, 140 outerIIFEBody: 1, 141 MemberExpression: 1, 142 FunctionDeclaration: { 143 parameters: 1, 144 body: 1 145 }, 146 FunctionExpression: { 147 parameters: 1, 148 body: 1 149 }, 150 CallExpression: { 151 arguments: 1 152 }, 153 ArrayExpression: 1, 154 ObjectExpression: 1, 155 ImportDeclaration: 1, 156 flatTernaryExpressions: true, 157 offsetTernaryExpressions: false, 158 ignoreComments: false 159 } 160 ], 161 '@stylistic/jsx-quotes': ['error', 'prefer-double'], 162 '@stylistic/keyword-spacing': ['error', { before: true, after: true }], 163 'line-comment-position': ['error', { position: 'above' }], 164 '@stylistic/linebreak-style': ['error', 'unix'], 165 '@stylistic/lines-around-comment': ['error', { beforeBlockComment: true }], 166 '@stylistic/lines-between-class-members': [ 167 'error', 168 { 169 enforce: [ 170 { blankLine: 'always', prev: '*', next: 'method' }, 171 { blankLine: 'always', prev: 'method', next: '*' } 172 ] 173 } 174 ], 175 '@stylistic/max-len': [ 176 'error', 177 { 178 code: 120, 179 tabWidth: 2, 180 ignoreComments: true, 181 ignoreStrings: true 182 } 183 ], 184 '@stylistic/max-statements-per-line': ['error', { max: 1 }], 185 '@stylistic/multiline-ternary': ['error', 'always-multiline'], 186 '@stylistic/new-parens': ['error', 'always'], 187 '@stylistic/newline-per-chained-call': ['error', { ignoreChainWithDepth: 2 }], 188 '@stylistic/no-extra-parens': ['error', 'all'], 189 '@stylistic/no-mixed-spaces-and-tabs': 'error', 190 '@stylistic/no-multi-spaces': 'error', 191 '@stylistic/no-multiple-empty-lines': ['error', { max: 2, maxEOF: 1 }], 192 '@stylistic/no-tabs': 'error', 193 '@stylistic/no-trailing-spaces': ['error', { skipBlankLines: false, ignoreComments: false }], 194 '@stylistic/no-whitespace-before-property': 'error', 195 '@stylistic/nonblock-statement-body-position': ['error', 'beside'], 196 '@stylistic/object-curly-newline': ['error', { consistent: true }], 197 '@stylistic/object-curly-spacing': ['error', 'always'], 198 '@stylistic/operator-linebreak': ['error', 'after'], 199 // disable due to conflict with required rule 'lines-around-comment' 200 '@stylistic/padded-blocks': 'off', 201 '@stylistic/quotes': ['error', 'single'], 202 '@stylistic/rest-spread-spacing': ['error', 'never'], 203 '@stylistic/semi': ['error', 'always'], 204 '@stylistic/semi-spacing': ['error', { before: false, after: true }], 205 '@stylistic/semi-style': ['error', 'last'], 206 '@stylistic/space-before-blocks': ['error', 'always'], 207 '@stylistic/space-before-function-paren': ['error', 'never'], 208 '@stylistic/space-in-parens': ['error', 'never'], 209 '@stylistic/space-infix-ops': ['error'], 210 '@stylistic/space-unary-ops': ['error', { words: true, nonwords: false, overrides: {} }], 211 '@stylistic/switch-colon-spacing': ['error', { after: true, before: false }], 212 '@stylistic/template-curly-spacing': ['error', 'never'], 213 '@stylistic/template-tag-spacing': ['error', 'never'], 214 'unicode-bom': ['error', 'never'], 215 '@stylistic/wrap-iife': ['error', 'outside'], 216 '@stylistic/wrap-regex': 'error', 217 '@stylistic/yield-star-spacing': ['error', { before: true, after: false }], 218 219 // typescript 220 '@typescript-eslint/explicit-function-return-type': 'error', 221 '@typescript-eslint/adjacent-overload-signatures': 'error', 222 '@typescript-eslint/consistent-type-exports': 'error', 223 '@typescript-eslint/await-thenable': 'error', 224 '@typescript-eslint/no-dynamic-delete': 'error', 225 '@typescript-eslint/no-this-alias': 'error', 226 '@typescript-eslint/explicit-member-accessibility': [ 227 'error', 228 { 229 accessibility: 'no-public' 230 } 231 ], 232 '@typescript-eslint/method-signature-style': 'error', 233 '@typescript-eslint/no-confusing-non-null-assertion': 'error', 234 '@typescript-eslint/no-confusing-void-expression': 'error', 235 // FIXME(knazarov) 236 // need to do something about this 237 '@typescript-eslint/no-explicit-any': 'warn', 238 // Produce too many warning caused by 'any' usage 239 // "@typescript-eslint/no-unsafe-member-access": "warn", 240 // "@typescript-eslint/no-unsafe-assignment": "warn", 241 '@typescript-eslint/no-unsafe-call': 'warn', 242 '@typescript-eslint/no-unsafe-argument': 'warn', 243 '@typescript-eslint/no-unsafe-return': 'warn', 244 'no-unsafe-finally': 'error', 245 '@typescript-eslint/no-extra-non-null-assertion': 'error', 246 '@typescript-eslint/no-meaningless-void-operator': 'error', 247 '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error', 248 // FIXME(knazarov) 249 // disabled due to many cases, where typescript deduces non-undefined value, but we can receive one from the api 250 '@typescript-eslint/no-unnecessary-condition': 'off', 251 '@typescript-eslint/no-unnecessary-type-assertion': 'error', 252 '@typescript-eslint/prefer-as-const': 'error', 253 '@typescript-eslint/prefer-optional-chain': 'error', 254 '@typescript-eslint/prefer-readonly': 'error', 255 '@typescript-eslint/consistent-type-imports': 'error', 256 // FIXME(knazarov) 257 // need to change metadata in cookbook accordingly. so do it later 258 '@typescript-eslint/naming-convention': [ 259 'off', 260 { 261 selector: 'default', 262 format: ['camelCase'] 263 }, 264 { 265 selector: 'enumMember', 266 format: ['UPPER_CASE'] 267 }, 268 { 269 selector: 'variable', 270 format: ['camelCase', 'UPPER_CASE'] 271 }, 272 { 273 selector: 'typeLike', 274 format: ['PascalCase'] 275 }, 276 { 277 selector: 'memberLike', 278 format: ['camelCase'] 279 } 280 ] 281 } 282 } 283); 284