eslint.config.mjs•6.1 kB
import perfectionist from 'eslint-plugin-perfectionist';
import js from '@eslint/js';
import typescript from '@typescript-eslint/eslint-plugin';
import typescriptParser from '@typescript-eslint/parser';
import stylistic from '@stylistic/eslint-plugin';
export default [
// Base JavaScript recommended rules
js.configs.recommended,
// TypeScript files configuration
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parser: typescriptParser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: './tsconfig.json',
},
},
plugins: {
'@typescript-eslint': typescript,
'@stylistic': stylistic,
'@perfectionist': perfectionist,
},
rules: {
// TypeScript recommended rules (manual selection to avoid conflicts)
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-var-requires': 'error',
// Console rules
'no-console': ['error', { allow: ['info', 'warn', 'error'] }],
// Perfectionist import ordering
'@perfectionist/sort-imports': ['warn', {
type: 'line-length',
order: 'desc',
groups: [
'builtin',
'external',
'type',
['parent', 'sibling', 'index', 'subpath'],
],
}],
'@perfectionist/sort-named-imports': ['warn', {
type: 'line-length',
order: 'desc',
}],
// Stylistic rules
'@stylistic/max-len': ['warn', {
code: 100,
tabWidth: 2,
ignoreUrls: true,
ignoreStrings: true,
ignoreTemplateLiterals: true,
ignoreComments: true,
}],
'@stylistic/semi': ['error', 'always'],
'@stylistic/indent': ['error', 2, {
SwitchCase: 1,
VariableDeclarator: 1,
outerIIFEBody: 1,
FunctionDeclaration: { parameters: 1, body: 1 },
FunctionExpression: { parameters: 1, body: 1 },
CallExpression: { arguments: 1 },
ArrayExpression: 1,
ObjectExpression: 1,
ImportDeclaration: 1,
flatTernaryExpressions: false,
offsetTernaryExpressions: false,
ignoreComments: false,
}],
'@stylistic/quotes': ['error', 'single', {
avoidEscape: true,
allowTemplateLiterals: 'always',
}],
'@stylistic/brace-style': ['error', '1tbs', {
allowSingleLine: true,
}],
'@stylistic/arrow-parens': ['error', 'always'],
'@stylistic/quote-props': ['error', 'as-needed'],
'@stylistic/comma-dangle': ['error', 'always-multiline'],
// Additional brace and spacing consistency rules
'@stylistic/object-curly-spacing': ['error', 'always'],
'@stylistic/array-bracket-spacing': ['error', 'never'],
'@stylistic/computed-property-spacing': ['error', 'never'],
'@stylistic/space-in-parens': ['error', 'never'],
'@stylistic/space-before-blocks': ['error', 'always'],
'@stylistic/keyword-spacing': ['error', { before: true, after: true }],
'@stylistic/space-infix-ops': 'error',
'@stylistic/space-unary-ops': ['error', { words: true, nonwords: false }],
'@stylistic/no-trailing-spaces': 'error',
'@stylistic/eol-last': ['error', 'always'],
'@stylistic/no-multiple-empty-lines': ['error', { max: 2, maxEOF: 0 }],
'@stylistic/padded-blocks': ['error', 'never'],
'@stylistic/space-before-function-paren': ['error', {
anonymous: 'always',
named: 'never',
asyncArrow: 'always',
}],
// Curly brace rules
curly: ['error', 'all'],
'@stylistic/nonblock-statement-body-position': ['error', 'beside'],
// Additional quality rules
'prefer-const': 'error',
'no-var': 'error',
'no-duplicate-imports': 'error',
'no-unused-expressions': 'error',
'no-unreachable': 'error',
'no-constant-condition': 'error',
'no-empty': 'error',
eqeqeq: ['error', 'always'],
// Override base rules for TypeScript
'no-unused-vars': 'off', // Use TypeScript version instead
'no-undef': 'off', // TypeScript handles this
'no-redeclare': 'off', // TypeScript handles this
},
},
// JavaScript files configuration
{
files: ['**/*.js', '**/*.mjs'],
plugins: {
'@stylistic': stylistic,
},
rules: {
// Console rules
'no-console': ['error', { allow: ['info', 'warn', 'error'] }],
// Stylistic rules for JS files
'@stylistic/max-len': ['warn', {
code: 100,
tabWidth: 2,
ignoreUrls: true,
ignoreStrings: true,
ignoreTemplateLiterals: true,
ignoreComments: true,
}],
'@stylistic/semi': ['error', 'always'],
'@stylistic/indent': ['error', 2],
'@stylistic/quotes': ['error', 'single', {
avoidEscape: true,
allowTemplateLiterals: 'always',
}],
'@stylistic/brace-style': ['error', '1tbs', {
allowSingleLine: true,
}],
'@stylistic/arrow-parens': ['error', 'always'],
'@stylistic/quote-props': ['error', 'as-needed'],
'@stylistic/comma-dangle': ['error', 'always-multiline'],
'@stylistic/object-curly-spacing': ['error', 'always'],
'@stylistic/array-bracket-spacing': ['error', 'never'],
'@stylistic/space-before-blocks': ['error', 'always'],
'@stylistic/keyword-spacing': ['error', { before: true, after: true }],
'@stylistic/space-infix-ops': 'error',
'@stylistic/no-trailing-spaces': 'error',
'@stylistic/eol-last': ['error', 'always'],
curly: ['error', 'all'],
'prefer-const': 'error',
'no-var': 'error',
},
},
// Global ignores
{
ignores: [
'node_modules/**',
'dist/**',
'build/**',
'lambda/**.js*',
'*.min.js',
'coverage/**',
],
},
];