import { defineConfig } from 'oxlint'; export default defineConfig({ ignorePatterns: ['app/vendor/**', '**/__mocks__/**', 'stubs/**'], plugins: ['react', 'import'], env: { browser: true, es2024: true, }, categories: { correctness: 'error', pedantic: 'off', style: 'warn', suspicious: 'warn', perf: 'off', restriction: 'off', }, rules: { 'eslint/capitalized-comments': 'off', 'eslint/curly': 'off', 'eslint/func-names': 'off', 'eslint/func-style': 'off', 'eslint/id-length': 'off', 'eslint/max-params': 'off', 'eslint/max-statements': 'off', 'eslint/new-cap': 'off', 'eslint/no-continue': 'off', 'eslint/no-magic-numbers': 'off', 'eslint/no-nested-ternary': 'off', 'eslint/no-ternary': 'off', 'eslint/no-underscore-dangle': 'off', 'eslint/one-var': 'off', 'eslint/prefer-destructuring': 'off', // 23 findings from two files of dense parsing regexes; naming every group is churn for little gain. 'eslint/prefer-named-capture-group': 'off', // Sort the names inside `import { ... }` alphabetically (auto-fixable). Statement order is // left alone (ignoreDeclarationSort) - the "React, then libs, then app/*" grouping is // deliberate and sort-imports can't model it. 'eslint/sort-imports': ['warn', { ignoreDeclarationSort: true, ignoreCase: true }], 'eslint/sort-keys': 'off', 'import/exports-last': 'off', 'import/group-exports': 'off', 'import/no-named-as-default': 'off', 'import/no-named-export': 'off', 'import/no-namespace': 'off', 'import/no-unassigned-import': 'off', // `export default new FooStore()` is the established store-singleton convention here. 'import/no-anonymous-default-export': 'off', 'import/prefer-default-export': 'off', // Rules of Hooks - a violation is a real bug, not a style nit. 'react/hooks': 'error', // Hook dependency arrays. Historically noisy, so keep it advisory rather than blocking. 'react/exhaustive-deps': 'warn', 'react/exhaustive-effect-dependencies': 'off', 'react/jsx-max-depth': 'off', 'react/jsx-props-no-spreading': 'off', // Misfires when a component forwards native on* handlers (e.g. map/mapViewport.tsx). 'react/jsx-handler-names': 'off', 'react/memo-dependencies': 'off', // Class components still exist during the YUI -> React migration. 'react/no-set-state': 'off', 'react/no-unstable-nested-components': 'off', // Seeding local draft state from a query and re-syncing on change is a sanctioned pattern // in several windows; keep it visible as a warning rather than a build failure for now. 'react/set-state-in-effect': 'warn', 'react/style-prop-object': 'off', 'unicorn/prefer-global-this': 'off', 'unicorn/filename-case': [ 'error', { case: 'camelCase', }, ], 'react/function-component-definition': [ 'error', { namedComponents: 'arrow-function', unnamedComponents: 'arrow-function' }, ], }, overrides: [ { // Test files used to be ignored wholesale. Lint them with the Jest plugin, keeping its // bug-catching rules (no-focused-tests, no-identical-title, valid-expect, ...) but turning // off the house-style opinions that would otherwise flood a suite this size. files: ['**/*.test.{ts,tsx}', '**/*.test.js'], plugins: ['jest'], env: { jest: true, }, rules: { // Test ergonomics. 'eslint/no-unused-vars': 'off', // `let mockedView; beforeEach(() => { mockedView = ... })` is the standard mock pattern. 'eslint/init-declarations': 'off', 'typescript/no-explicit-any': 'off', 'typescript/no-non-null-assertion': 'off', // Data-driven tests legitimately assert inside a loop/guard; keep it visible, don't block. 'jest/no-conditional-expect': 'warn', // Jest house-style opinions we are not adopting. 'jest/require-top-level-describe': 'off', 'jest/prefer-expect-assertions': 'off', 'jest/prefer-importing-jest-globals': 'off', 'jest/prefer-jest-mocked': 'off', 'jest/prefer-called-with': 'off', 'jest/prefer-ending-with-an-expect': 'off', 'jest/prefer-lowercase-title': 'off', 'jest/prefer-to-be': 'off', 'jest/consistent-test-it': 'off', 'jest/max-expects': 'off', 'jest/no-hooks': 'off', }, }, ], });