11import { coreInternalDirs , createImportBoundaries } from '@codexo/exojs-config/eslint' ;
2+ import eslintReact from '@eslint-react/eslint-plugin' ;
23import js from '@eslint/js' ;
34import { defineConfig } from 'eslint/config' ;
45import prettier from 'eslint-config-prettier' ;
6+ import reactHooks from 'eslint-plugin-react-hooks' ;
57import security from 'eslint-plugin-security' ;
68import simpleImportSort from 'eslint-plugin-simple-import-sort' ;
79import unicorn from 'eslint-plugin-unicorn' ;
@@ -11,17 +13,7 @@ import tseslint from 'typescript-eslint';
1113
1214export default defineConfig ( [
1315 {
14- ignores : [
15- 'dist/**' ,
16- 'node_modules/**' ,
17- 'src/vendor/**' ,
18- 'site/dist/**' ,
19- 'site/node_modules/**' ,
20- 'site/public/vendor/**' ,
21- 'site/src/**' ,
22- 'coverage/**' ,
23- '**/*.min.*' ,
24- ] ,
16+ ignores : [ 'dist/**' , 'node_modules/**' , 'src/vendor/**' , 'site/dist/**' , 'site/node_modules/**' , 'site/public/vendor/**' , 'coverage/**' , '**/*.min.*' ] ,
2517 } ,
2618
2719 // Base JavaScript recommendations
@@ -590,6 +582,110 @@ export default defineConfig([
590582 } ,
591583 } ,
592584
585+ // Site React components. Astro files are type-checked by `astro check`; this
586+ // block covers the TypeScript/TSX islands that ship browser interactivity.
587+ {
588+ files : [ 'site/src/**/*.{ts,tsx}' ] ,
589+ languageOptions : {
590+ ecmaVersion : 'latest' ,
591+ sourceType : 'module' ,
592+ parserOptions : {
593+ projectService : true ,
594+ tsconfigRootDir : import . meta. dirname ,
595+ } ,
596+ globals : {
597+ ...globals . browser ,
598+ ...globals . es2024 ,
599+ } ,
600+ } ,
601+ plugins : {
602+ '@eslint-react' : eslintReact ,
603+ 'react-hooks' : reactHooks ,
604+ 'simple-import-sort' : simpleImportSort ,
605+ 'unused-imports' : unusedImports ,
606+ } ,
607+ rules : {
608+ ...eslintReact . configs [ 'recommended-typescript' ] . rules ,
609+ ...eslintReact . configs [ 'disable-conflict-eslint-plugin-react-hooks' ] . rules ,
610+ ...reactHooks . configs . recommended . rules ,
611+
612+ 'simple-import-sort/imports' : 'error' ,
613+ 'simple-import-sort/exports' : 'error' ,
614+ 'unused-imports/no-unused-imports' : 'error' ,
615+ 'unused-imports/no-unused-vars' : [
616+ 'warn' ,
617+ {
618+ argsIgnorePattern : '^_' ,
619+ caughtErrorsIgnorePattern : '^_' ,
620+ destructuredArrayIgnorePattern : '^_' ,
621+ varsIgnorePattern : '^_' ,
622+ ignoreRestSiblings : true ,
623+ } ,
624+ ] ,
625+
626+ '@typescript-eslint/consistent-type-imports' : [ 'error' , { prefer : 'type-imports' , disallowTypeAnnotations : false , fixStyle : 'inline-type-imports' } ] ,
627+ '@typescript-eslint/array-type' : 'off' ,
628+ '@typescript-eslint/consistent-indexed-object-style' : 'off' ,
629+ '@typescript-eslint/consistent-type-definitions' : 'off' ,
630+ '@typescript-eslint/no-floating-promises' : 'error' ,
631+ '@typescript-eslint/no-misused-promises' : [
632+ 'error' ,
633+ {
634+ checksVoidReturn : {
635+ arguments : false ,
636+ attributes : false ,
637+ } ,
638+ } ,
639+ ] ,
640+ '@typescript-eslint/no-unsafe-argument' : 'off' ,
641+ '@typescript-eslint/no-unsafe-assignment' : 'off' ,
642+ '@typescript-eslint/no-unsafe-call' : 'off' ,
643+ '@typescript-eslint/no-unsafe-member-access' : 'off' ,
644+ '@typescript-eslint/no-unsafe-return' : 'off' ,
645+ '@typescript-eslint/no-unused-vars' : 'off' ,
646+ '@typescript-eslint/prefer-regexp-exec' : 'off' ,
647+ '@typescript-eslint/prefer-nullish-coalescing' : 'warn' ,
648+ '@typescript-eslint/prefer-optional-chain' : 'warn' ,
649+ '@typescript-eslint/restrict-template-expressions' : [
650+ 'error' ,
651+ {
652+ allowNumber : true ,
653+ allowBoolean : false ,
654+ allowAny : false ,
655+ allowNullish : false ,
656+ allowRegExp : false ,
657+ } ,
658+ ] ,
659+ // Disabled for site/src to match the engine: `strict-boolean-expressions`
660+ // is turned off across every practical src/ directory (core, input, math,
661+ // rendering, audio, resources, …). The site's URL/version/runtime helpers
662+ // are the same class of nullable-string code, so holding only site code to
663+ // it would be an inconsistent double standard.
664+ '@typescript-eslint/strict-boolean-expressions' : 'off' ,
665+ '@typescript-eslint/unbound-method' : 'off' ,
666+
667+ '@eslint-react/dom-no-unsafe-iframe-sandbox' : 'error' ,
668+ '@eslint-react/no-array-index-key' : 'warn' ,
669+ '@eslint-react/no-nested-component-definitions' : 'error' ,
670+ '@eslint-react/no-unstable-default-props' : 'error' ,
671+ 'react-hooks/exhaustive-deps' : 'warn' ,
672+ 'react-hooks/immutability' : 'warn' ,
673+ 'react-hooks/preserve-manual-memoization' : 'warn' ,
674+ 'react-hooks/set-state-in-effect' : 'warn' ,
675+
676+ curly : 'error' ,
677+ eqeqeq : [ 'error' , 'always' ] ,
678+ // Allow console.error/console.warn for intentional diagnostics (e.g. the
679+ // fetch/parse error logging in request-manager.ts); only console.log/debug warn.
680+ 'no-console' : [ 'warn' , { allow : [ 'warn' , 'error' ] } ] ,
681+ 'no-nested-ternary' : 'warn' ,
682+ 'object-shorthand' : 'error' ,
683+ 'prefer-object-spread' : 'error' ,
684+ 'prefer-template' : 'error' ,
685+ radix : 'error' ,
686+ } ,
687+ } ,
688+
593689 // ---------------------------------------------------------------------------
594690 // Per-subsystem overrides for src/. Scoped narrowly because these directories
595691 // either have hot-path lifecycle invariants, browser-API variance, or typed-
0 commit comments