import js from '@eslint/js'; import typescript from '@typescript-eslint/eslint-plugin'; import typescriptParser from '@typescript-eslint/parser'; import react from 'eslint-plugin-react'; import reactHooks from 'eslint-plugin-react-hooks'; import reactRefresh from 'eslint-plugin-react-refresh'; import jsxA11y from 'eslint-plugin-jsx-a11y'; export default [ js.configs.recommended, { files: ['**/*.{ts,tsx,js,jsx}'], languageOptions: { parser: typescriptParser, parserOptions: { ecmaFeatures: { jsx: true, }, ecmaVersion: 2022, sourceType: 'module', }, globals: { // Browser globals window: 'readonly', document: 'readonly', localStorage: 'readonly', sessionStorage: 'readonly', console: 'readonly', setTimeout: 'readonly', clearTimeout: 'readonly', setInterval: 'readonly', clearInterval: 'readonly', fetch: 'readonly', WebSocket: 'readonly', File: 'readonly', FormData: 'readonly', CustomEvent: 'readonly', Event: 'readonly', CloseEvent: 'readonly', MessageEvent: 'readonly', KeyboardEvent: 'readonly', HTMLElement: 'readonly', HTMLDivElement: 'readonly', HTMLInputElement: 'readonly', HTMLButtonElement: 'readonly', HTMLAnchorElement: 'readonly', HTMLParagraphElement: 'readonly', HTMLHeadingElement: 'readonly', HTMLTextAreaElement: 'readonly', HTMLSelectElement: 'readonly', HTMLImageElement: 'readonly', HTMLAudioElement: 'readonly', Element: 'readonly', Node: 'readonly', MouseEvent: 'readonly', Blob: 'readonly', FileReader: 'readonly', Image: 'readonly', global: 'readonly', NodeJS: 'readonly', Buffer: 'readonly', crypto: 'readonly', performance: 'readonly', require: 'readonly', process: 'readonly', // URL API globals URL: 'readonly', URLSearchParams: 'readonly', // DOM API globals DOMRect: 'readonly', DOMRectReadOnly: 'readonly', Headers: 'readonly', navigator: 'readonly', WindowEventMap: 'readonly', requestAnimationFrame: 'readonly', cancelAnimationFrame: 'readonly', Notification: 'readonly', NotificationOptions: 'readonly', NotificationPermission: 'readonly', IntersectionObserver: 'readonly', IntersectionObserverInit: 'readonly', MessageChannel: 'readonly', confirm: 'readonly', // Service Worker globals self: 'readonly', caches: 'readonly', ServiceWorkerRegistration: 'readonly', Cache: 'readonly', CacheStorage: 'readonly', Response: 'readonly', Request: 'readonly', clients: 'readonly', // React globals React: 'readonly', // Test globals beforeAll: 'readonly', afterAll: 'readonly', afterEach: 'readonly', beforeEach: 'readonly', describe: 'readonly', it: 'readonly', test: 'readonly', expect: 'readonly', vi: 'readonly', vitest: 'readonly', waitFor: 'readonly', jest: 'readonly', AbortController: 'readonly', AbortSignal: 'readonly', BroadcastChannel: 'readonly', DOMException: 'readonly', atob: 'readonly', PerformanceNavigationTiming: 'readonly', PerformanceObserver: 'readonly', HTMLFormElement: 'readonly', HTMLTableElement: 'readonly', HTMLTableSectionElement: 'readonly', HTMLTableRowElement: 'readonly', HTMLTableCellElement: 'readonly', HTMLTableCaptionElement: 'readonly', HTMLSpanElement: 'readonly', HTMLCanvasElement: 'readonly', HTMLLabelElement: 'readonly', FileList: 'readonly', MediaQueryListEvent: 'readonly', IntersectionObserver: 'readonly', IntersectionObserverEntry: 'readonly', IntersectionObserverCallback: 'readonly', ResizeObserver: 'readonly', ResizeObserverEntry: 'readonly', HeadersInit: 'readonly', EventListener: 'readonly', }, }, plugins: { '@typescript-eslint': typescript, 'react': react, 'react-hooks': reactHooks, 'react-refresh': reactRefresh, 'jsx-a11y': jsxA11y, }, rules: { // TypeScript '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-non-null-assertion': 'warn', // React 'react/react-in-jsx-scope': 'off', 'react/prop-types': 'off', 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn', 'react-refresh/only-export-components': [ 'warn', { allowConstantExport: true } ], // General 'no-console': 'off', 'no-debugger': 'error', 'prefer-const': 'error', 'no-var': 'error', 'object-shorthand': 'error', 'prefer-template': 'error', 'no-unused-vars': 'off', // Handled by @typescript-eslint/no-unused-vars 'no-useless-escape': 'error', 'no-prototype-builtins': 'warn', }, settings: { react: { version: 'detect', }, }, }, { ignores: [ 'node_modules/', 'dist/', 'build/', 'target/', '_archive/', 'archive/', '*.config.js', '*.config.ts', '*.config.cjs', '**/ui.backup/**', ], }, ];