const js = require('@eslint/js'); const tseslint = require('@typescript-eslint/eslint-plugin'); const tsparser = require('@typescript-eslint/parser'); const prettierConfig = require('eslint-config-prettier'); module.exports = [ js.configs.recommended, prettierConfig, // Disable all formatting rules that conflict with Prettier { languageOptions: { ecmaVersion: 'latest', sourceType: 'commonjs', globals: { console: 'readonly', process: 'readonly', Buffer: 'readonly', __dirname: 'readonly', __filename: 'readonly', module: 'readonly', require: 'readonly', exports: 'readonly', global: 'readonly', setImmediate: 'readonly', clearImmediate: 'readonly', setTimeout: 'readonly', clearTimeout: 'readonly', setInterval: 'readonly', clearInterval: 'readonly', fetch: 'readonly', URL: 'readonly' } }, rules: { // Error prevention 'no-unused-vars': ['error', { 'argsIgnorePattern': '^_', 'varsIgnorePattern': '^_', 'caughtErrorsIgnorePattern': '^_' }], 'no-console': 'warn', 'no-debugger': 'error', // Removed all formatting rules - let Prettier handle them // Best practices 'eqeqeq': 'error', 'no-eval': 'error', 'no-implied-eval': 'error', 'no-new-func': 'error', 'no-return-assign': 'error', 'no-self-compare': 'error', 'no-sequences': 'error', 'no-throw-literal': 'error', 'no-unmodified-loop-condition': 'error', 'no-unused-expressions': 'error', 'no-useless-call': 'error', 'no-useless-concat': 'error', 'no-useless-return': 'error', 'no-void': 'error', 'radix': 'error', 'wrap-iife': 'error', 'yoda': 'error', // Node.js specific 'no-process-exit': 'error', 'no-sync': 'warn', // Security 'no-buffer-constructor': 'error' } }, // TypeScript files configuration { files: ['**/*.ts', '**/*.tsx'], languageOptions: { parser: tsparser, parserOptions: { ecmaVersion: 'latest', sourceType: 'commonjs', project: './tsconfig.json' } }, plugins: { '@typescript-eslint': tseslint }, rules: { // Disable base rules that are covered by TypeScript equivalents 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_', 'varsIgnorePattern': '^_', 'caughtErrorsIgnorePattern': '^_' }], // TypeScript specific rules '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/no-non-null-assertion': 'warn', '@typescript-eslint/prefer-nullish-coalescing': 'error', '@typescript-eslint/prefer-optional-chain': 'error', '@typescript-eslint/no-unnecessary-type-assertion': 'error', '@typescript-eslint/no-floating-promises': 'error', '@typescript-eslint/await-thenable': 'error', '@typescript-eslint/no-misused-promises': 'error', '@typescript-eslint/require-await': 'error', '@typescript-eslint/prefer-as-const': 'error', '@typescript-eslint/no-inferrable-types': 'error', '@typescript-eslint/no-unnecessary-condition': 'warn', // Style rules '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], '@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports' }] } }, // Test files (JavaScript) { files: ['test/**/*.js', '**/*.test.js'], languageOptions: { ecmaVersion: 'latest', sourceType: 'commonjs', globals: { jest: 'readonly', describe: 'readonly', test: 'readonly', it: 'readonly', expect: 'readonly', beforeEach: 'readonly', afterEach: 'readonly', beforeAll: 'readonly', afterAll: 'readonly' } }, rules: { 'no-console': 'off' } }, // Test files (TypeScript) { files: ['test/**/*.ts', '**/*.test.ts'], languageOptions: { parser: tsparser, parserOptions: { ecmaVersion: 'latest', sourceType: 'commonjs', project: './tsconfig.test.json' }, globals: { jest: 'readonly', describe: 'readonly', test: 'readonly', it: 'readonly', expect: 'readonly', beforeEach: 'readonly', afterEach: 'readonly', beforeAll: 'readonly', afterAll: 'readonly' } }, plugins: { '@typescript-eslint': tseslint }, rules: { 'no-console': 'off', '@typescript-eslint/no-explicit-any': 'off' // Allow any in tests for mocking } } ];