Files
Toju/eslint.config.js
2026-03-03 22:56:12 +01:00

219 lines
8.4 KiB
JavaScript

const eslint = require('@eslint/js');
const tseslint = require('typescript-eslint');
const angular = require('angular-eslint');
const stylisticTs = require('@stylistic/eslint-plugin-ts');
const stylisticJs = require('@stylistic/eslint-plugin-js');
module.exports = tseslint.config(
{
ignores: [
'**/generated/*',
'dist/**',
'dist-electron/**',
'.angular/**',
'**/migrations/**',
'release/**',
'src/index.html',
'server/**'
]
},
{
files: ['src/app/core/services/**/*.ts'],
rules: {
'@typescript-eslint/member-ordering': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-invalid-void-type': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'id-length': 'off',
'max-statements-per-line': 'off'
}
},
{
files: ['**/*.ts'],
plugins: {
'@stylistic/ts': stylisticTs,
'@stylistic/js': stylisticJs
},
extends: [
eslint.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.stylistic,
...angular.configs.tsRecommended,
...tseslint.configs.strict
],
processor: angular.processInlineTemplates,
rules: {
'@typescript-eslint/no-extraneous-class': 'off',
'@angular-eslint/component-class-suffix': ['error', { suffixes: ['Component', 'Page', 'Stub'] }],
'@angular-eslint/directive-class-suffix': 'error',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/explicit-member-accessibility': ['error', { accessibility: 'no-public' }],
'@typescript-eslint/array-type': ['error', { default: 'array' }],
'@typescript-eslint/consistent-type-definitions': 'error',
'@typescript-eslint/dot-notation': 'off',
'@stylistic/ts/indent': [
'error',
2,
{
ignoredNodes: [
'TSTypeParameterInstantiation',
'FunctionExpression > .params[decorators.length > 0]',
'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
'ClassBody.body > PropertyDefinition[decorators.length > 0] > .key'
],
SwitchCase: 1
}
],
'@stylistic/ts/member-delimiter-style': [
'error',
{
multiline: { delimiter: 'semi', requireLast: true },
singleline: { delimiter: 'semi', requireLast: false }
}
],
'@typescript-eslint/member-ordering': [
'error',
{
default: [
'signature',
'call-signature',
'public-static-field',
'protected-static-field',
'private-static-field',
'#private-static-field',
'public-decorated-field',
'protected-decorated-field',
'private-decorated-field',
'public-instance-field',
'protected-instance-field',
'private-instance-field',
'#private-instance-field',
'public-abstract-field',
'protected-abstract-field',
'public-field',
'protected-field',
'private-field',
'#private-field',
'static-field',
'instance-field',
'abstract-field',
'decorated-field',
'field',
'static-initialization',
'public-constructor',
'protected-constructor',
'private-constructor',
'constructor',
'public-static-method',
'protected-static-method',
'private-static-method',
'#private-static-method',
'public-decorated-method',
'protected-decorated-method',
'private-decorated-method',
'public-instance-method',
'protected-instance-method',
'private-instance-method',
'#private-instance-method',
'public-abstract-method',
'protected-abstract-method',
'public-method',
'protected-method',
'private-method',
'#private-method',
'static-method',
'instance-method',
'abstract-method',
'decorated-method',
'method'
]
}
],
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-empty-interface': 'error',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-invalid-this': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', ignoreRestSiblings: true }],
'@typescript-eslint/no-var-requires': 'error',
'@typescript-eslint/prefer-for-of': 'error',
'@typescript-eslint/prefer-function-type': 'error',
'@stylistic/ts/quotes': ['error', 'single', { avoidEscape: true }],
'@stylistic/ts/semi': ['error', 'always'],
'@stylistic/ts/type-annotation-spacing': 'error',
'@typescript-eslint/unified-signatures': 'error',
'@stylistic/js/array-bracket-spacing': 'error',
'@stylistic/ts/comma-dangle': ['error', 'never'],
'@stylistic/ts/comma-spacing': 'error',
'@stylistic/js/comma-style': 'error',
complexity: ['warn', { max: 20 }],
curly: 'off',
'eol-last': 'error',
'id-denylist': ['warn', 'e', 'cb', 'i', 'x', 'c', 'y', 'any', 'string', 'String', 'Undefined', 'undefined', 'callback'],
'max-len': ['error', { code: 150, ignoreComments: true }],
'new-parens': 'error',
'newline-per-chained-call': 'error',
'no-bitwise': 'off',
'no-cond-assign': 'error',
'no-empty': 'off',
'no-eval': 'error',
'@stylistic/js/no-multi-spaces': 'error',
'@stylistic/js/no-multiple-empty-lines': ['error', { max: 1, maxEOF: 1 }],
'no-new-wrappers': 'error',
'no-restricted-imports': ['error', 'rxjs/Rx'],
'no-throw-literal': 'error',
'no-trailing-spaces': 'error',
'no-undef-init': 'error',
'no-unsafe-finally': 'error',
'no-var': 'error',
'one-var': ['error', 'never'],
'prefer-const': 'error',
'@stylistic/ts/space-before-blocks': 'error',
'@stylistic/js/space-before-function-paren': ['error', { anonymous: 'never', asyncArrow: 'always', named: 'never' }],
'@stylistic/ts/space-infix-ops': 'error',
'@stylistic/js/space-in-parens': 'error',
'@stylistic/js/space-unary-ops': 'error',
'@stylistic/js/spaced-comment': ['error', 'always', { markers: ['/'] }],
'@stylistic/js/block-spacing': ['error', 'always'],
'nonblock-statement-body-position': ['error', 'below'],
'max-statements-per-line': ['error', { max: 1 }],
'id-length': ['error', { min: 2, properties: 'never', exceptions: ['_'] }],
'padding-line-between-statements': [
'error',
{ blankLine: 'always', prev: '*', next: 'if' },
{ blankLine: 'always', prev: 'if', next: '*' },
{ blankLine: 'always', prev: '*', next: 'block-like' },
{ blankLine: 'always', prev: 'block-like', next: '*' },
{ blankLine: 'always', prev: 'function', next: '*' },
{ blankLine: 'always', prev: 'class', next: '*' },
{ blankLine: 'always', prev: 'const', next: '*' },
{ blankLine: 'always', prev: 'let', next: '*' },
{ blankLine: 'always', prev: 'var', next: '*' },
{ blankLine: 'never', prev: 'const', next: 'const' },
{ blankLine: 'never', prev: 'let', next: 'let' },
{ blankLine: 'never', prev: 'var', next: 'var' }
]
}
},
{
files: ['src/app/**/*.html'],
extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility],
rules: {
'@angular-eslint/template/button-has-type': 'warn',
'@angular-eslint/template/cyclomatic-complexity': ['warn', { maxComplexity: 10 }],
'@angular-eslint/template/eqeqeq': 'error',
'@angular-eslint/template/prefer-control-flow': 'error',
'@angular-eslint/template/prefer-ngsrc': 'warn',
'@angular-eslint/template/prefer-self-closing-tags': 'warn',
'@angular-eslint/template/use-track-by-function': 'warn',
'@angular-eslint/template/no-negated-async': 'warn',
'@angular-eslint/template/no-call-expression': 'off'
}
}
);
// IMPORTANT: Formatting is handled by Prettier; ESLint validates logic/accessibility.