11import eslintReact from '@eslint-react/eslint-plugin' ;
22import markdown from '@eslint/markdown' ;
33import vitest from '@vitest/eslint-plugin' ;
4- import jestDom from 'eslint-plugin-jest-dom' ;
5- import reactDom from 'eslint-plugin-react-dom' ;
64import reactHooks from 'eslint-plugin-react-hooks' ;
7- import reactNamingConvention from 'eslint-plugin-react-naming-convention' ;
8- import reactRsc from 'eslint-plugin-react-rsc' ;
9- import reactWebApi from 'eslint-plugin-react-web-api' ;
105import sonarjs from 'eslint-plugin-sonarjs' ;
11- import testingLibrary from 'eslint-plugin-testing-library' ;
126import { defineConfig , globalIgnores } from 'eslint/config' ;
137import tseslint from 'typescript-eslint' ;
148
@@ -29,10 +23,6 @@ export default defineConfig([
2923 // @ts -expect-error
3024 'react-hooks' : reactHooks ,
3125 '@eslint-react' : eslintReact ,
32- '@eslint-react/rsc' : reactRsc ,
33- '@eslint-react/dom' : reactDom ,
34- '@eslint-react/web-api' : reactWebApi ,
35- '@eslint-react/naming-convention' : reactNamingConvention ,
3626 sonarjs,
3727 '@typescript-eslint' : tseslint . plugin
3828 } ,
@@ -288,7 +278,7 @@ export default defineConfig([
288278 // https://www.eslint-react.xyz/docs/rules/overview
289279 /*
290280// copy all the rules from the rules table for easy pasting
291- function getRules(id, prefix ) {
281+ function getRules(id) {
292282 return (
293283 Iterator.from(
294284 document
@@ -298,38 +288,33 @@ function getRules(id, prefix) {
298288 .querySelectorAll('tr a')
299289 )
300290 // map link to rule declaration
301- .map((a) => `'@eslint-react/${prefix}${a.textContent }': 1,`)
291+ .map((a) => `'@eslint-react/${a.getAttribute('href') }': 1,`)
302292 );
303293}
304294copy(
305295 Iterator.from([
306- getRules('x-rules', ''),
307- getRules('rsc-rules', 'rsc/'),
308- getRules('dom-rules', 'dom/'),
309- getRules('web-api-rules', 'web-api/'),
310- getRules('naming-convention-rules', 'naming-convention/'),
296+ getRules('x-rules'),
297+ getRules('jsx-rules'),
298+ getRules('rsc-rules'),
299+ getRules('dom-rules'),
300+ getRules('web-api-rules'),
301+ getRules('naming-convention-rules'),
311302 ])
312303 .flatMap((x) => x)
313304 .toArray()
314305 .join('\n')
315306);
316307 */
317- '@eslint-react/jsx-dollar' : 1 ,
318- '@eslint-react/jsx-key-before-spread' : 1 ,
319- '@eslint-react/jsx-no-comment-textnodes' : 1 ,
320- '@eslint-react/jsx-shorthand-boolean' : 1 ,
321- '@eslint-react/jsx-shorthand-fragment' : 1 ,
322308 '@eslint-react/component-hook-factories' : 1 ,
323309 '@eslint-react/error-boundaries' : 1 ,
324310 '@eslint-react/exhaustive-deps' : 1 ,
325- '@eslint-react/immutability' : 0 ,
311+ '@eslint-react/immutability' : 1 ,
326312 '@eslint-react/no-access-state-in-setstate' : 1 ,
327313 '@eslint-react/no-array-index-key' : 0 ,
328314 '@eslint-react/no-children-count' : 1 ,
329315 '@eslint-react/no-children-for-each' : 1 ,
330316 '@eslint-react/no-children-map' : 1 ,
331317 '@eslint-react/no-children-only' : 1 ,
332- '@eslint-react/no-children-prop' : 1 ,
333318 '@eslint-react/no-children-to-array' : 1 ,
334319 '@eslint-react/no-class-component' : 1 ,
335320 '@eslint-react/no-clone-element' : 1 ,
@@ -367,7 +352,6 @@ copy(
367352 '@eslint-react/no-unused-props' : 1 ,
368353 '@eslint-react/no-unused-state' : 1 ,
369354 '@eslint-react/no-use-context' : 1 ,
370- '@eslint-react/no-useless-fragment' : [ 1 , { allowExpressions : false } ] ,
371355 '@eslint-react/prefer-destructuring-assignment' : 1 ,
372356 '@eslint-react/prefer-namespace-import' : 1 ,
373357 '@eslint-react/purity' : 1 ,
@@ -378,32 +362,37 @@ copy(
378362 '@eslint-react/unsupported-syntax' : 1 ,
379363 '@eslint-react/use-memo' : 1 ,
380364 '@eslint-react/use-state' : 1 ,
381- '@eslint-react/rsc/function-definition' : 1 ,
382- '@eslint-react/dom/no-dangerously-set-innerhtml' : 1 ,
383- '@eslint-react/dom/no-dangerously-set-innerhtml-with-children' : 1 ,
384- '@eslint-react/dom/no-find-dom-node' : 1 ,
385- '@eslint-react/dom/no-flush-sync' : 0 ,
386- '@eslint-react/dom/no-hydrate' : 1 ,
387- '@eslint-react/dom/no-missing-button-type' : 1 ,
388- '@eslint-react/dom/no-missing-iframe-sandbox' : 1 ,
389- '@eslint-react/dom/no-namespace' : 1 ,
390- '@eslint-react/dom/no-render' : 1 ,
391- '@eslint-react/dom/no-render-return-value' : 1 ,
392- '@eslint-react/dom/no-script-url' : 1 ,
393- '@eslint-react/dom/no-string-style-prop' : 1 ,
394- '@eslint-react/dom/no-unknown-property' : 0 ,
395- '@eslint-react/dom/no-unsafe-iframe-sandbox' : 1 ,
396- '@eslint-react/dom/no-unsafe-target-blank' : 1 ,
397- '@eslint-react/dom/no-use-form-state' : 1 ,
398- '@eslint-react/dom/no-void-elements-with-children' : 1 ,
399- '@eslint-react/dom/prefer-namespace-import' : 1 ,
400- '@eslint-react/web-api/no-leaked-event-listener' : 1 ,
401- '@eslint-react/web-api/no-leaked-interval' : 1 ,
402- '@eslint-react/web-api/no-leaked-resize-observer' : 1 ,
403- '@eslint-react/web-api/no-leaked-timeout' : 1 ,
404- '@eslint-react/naming-convention/context-name' : 1 ,
405- '@eslint-react/naming-convention/id-name' : 1 ,
406- '@eslint-react/naming-convention/ref-name' : 1 ,
365+ '@eslint-react/jsx-no-children-prop' : 1 ,
366+ '@eslint-react/jsx-no-children-prop-with-children' : 1 ,
367+ '@eslint-react/jsx-no-comment-textnodes' : 1 ,
368+ '@eslint-react/jsx-no-useless-fragment' : [ 1 , { allowExpressions : false } ] ,
369+ '@eslint-react/jsx-no-key-after-spread' : 1 ,
370+ '@eslint-react/jsx-no-namespace' : 1 ,
371+ '@eslint-react/rsc-function-definition' : 1 ,
372+ '@eslint-react/dom-no-dangerously-set-innerhtml' : 1 ,
373+ '@eslint-react/dom-no-dangerously-set-innerhtml-with-children' : 1 ,
374+ '@eslint-react/dom-no-find-dom-node' : 1 ,
375+ '@eslint-react/dom-no-flush-sync' : 0 ,
376+ '@eslint-react/dom-no-hydrate' : 1 ,
377+ '@eslint-react/dom-no-missing-button-type' : 1 ,
378+ '@eslint-react/dom-no-missing-iframe-sandbox' : 1 ,
379+ '@eslint-react/dom-no-render' : 1 ,
380+ '@eslint-react/dom-no-render-return-value' : 1 ,
381+ '@eslint-react/dom-no-script-url' : 1 ,
382+ '@eslint-react/dom-no-string-style-prop' : 1 ,
383+ '@eslint-react/dom-no-unknown-property' : 1 ,
384+ '@eslint-react/dom-no-unsafe-iframe-sandbox' : 1 ,
385+ '@eslint-react/dom-no-unsafe-target-blank' : 1 ,
386+ '@eslint-react/dom-no-use-form-state' : 1 ,
387+ '@eslint-react/dom-no-void-elements-with-children' : 1 ,
388+ '@eslint-react/dom-prefer-namespace-import' : 1 ,
389+ '@eslint-react/web-api-no-leaked-event-listener' : 1 ,
390+ '@eslint-react/web-api-no-leaked-interval' : 1 ,
391+ '@eslint-react/web-api-no-leaked-resize-observer' : 1 ,
392+ '@eslint-react/web-api-no-leaked-timeout' : 1 ,
393+ '@eslint-react/naming-convention-context-name' : 1 ,
394+ '@eslint-react/naming-convention-id-name' : 1 ,
395+ '@eslint-react/naming-convention-ref-name' : 1 ,
407396
408397 // SonarJS rules
409398 // https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md#rules
@@ -893,7 +882,7 @@ copy(
893882 1 ,
894883 { path : 'never' , types : 'never' , lib : 'never' }
895884 ] ,
896- '@typescript-eslint/unbound-method' : 0 ,
885+ '@typescript-eslint/unbound-method' : 0 , // replaced by vitest/unbound-method
897886 '@typescript-eslint/unified-signatures' : 0 ,
898887 '@typescript-eslint/use-unknown-in-catch-callback-variable' : 1
899888 }
@@ -905,9 +894,7 @@ copy(
905894 files : [ 'test/**/*' ] ,
906895
907896 plugins : {
908- vitest,
909- 'jest-dom' : jestDom ,
910- 'testing-library' : testingLibrary
897+ vitest
911898 } ,
912899
913900 rules : {
@@ -1022,55 +1009,12 @@ copy(
10221009 'vitest/require-test-timeout' : 0 ,
10231010 'vitest/require-to-throw-message' : 1 ,
10241011 'vitest/require-top-level-describe' : 0 ,
1012+ 'vitest/unbound-method' : 0 ,
10251013 'vitest/valid-describe-callback' : 1 ,
10261014 'vitest/valid-expect' : [ 1 , { alwaysAwait : true } ] ,
10271015 'vitest/valid-expect-in-promise' : 1 ,
10281016 'vitest/valid-title' : 1 ,
1029- 'vitest/warn-todo' : 1 ,
1030-
1031- // https://github.com/testing-library/eslint-plugin-jest-dom#supported-rules
1032- 'jest-dom/prefer-checked' : 1 ,
1033- 'jest-dom/prefer-empty' : 1 ,
1034- 'jest-dom/prefer-enabled-disabled' : 1 ,
1035- 'jest-dom/prefer-focus' : 1 ,
1036- 'jest-dom/prefer-in-document' : 1 ,
1037- 'jest-dom/prefer-required' : 1 ,
1038- 'jest-dom/prefer-to-have-attribute' : 1 ,
1039- 'jest-dom/prefer-to-have-class' : 1 ,
1040- 'jest-dom/prefer-to-have-style' : 1 ,
1041- 'jest-dom/prefer-to-have-text-content' : 1 ,
1042- 'jest-dom/prefer-to-have-value' : 1 ,
1043-
1044- // eslint-plugin-testing-library Rules
1045- // https://github.com/testing-library/eslint-plugin-testing-library#supported-rules
1046- 'testing-library/await-async-events' : 0 ,
1047- 'testing-library/await-async-queries' : 0 ,
1048- 'testing-library/await-async-utils' : 0 ,
1049- 'testing-library/consistent-data-testid' : 0 ,
1050- 'testing-library/no-await-sync-events' : 0 ,
1051- 'testing-library/no-await-sync-queries' : 0 ,
1052- 'testing-library/no-container' : 1 ,
1053- 'testing-library/no-debugging-utils' : 1 ,
1054- 'testing-library/no-dom-import' : 1 ,
1055- 'testing-library/no-global-regexp-flag-in-query' : 1 ,
1056- 'testing-library/no-manual-cleanup' : 0 ,
1057- 'testing-library/no-node-access' : 0 ,
1058- 'testing-library/no-promise-in-fire-event' : 0 ,
1059- 'testing-library/no-render-in-lifecycle' : 0 ,
1060- 'testing-library/no-test-id-queries' : 0 ,
1061- 'testing-library/no-unnecessary-act' : 1 ,
1062- 'testing-library/no-wait-for-multiple-assertions' : 1 ,
1063- 'testing-library/no-wait-for-side-effects' : 1 ,
1064- 'testing-library/no-wait-for-snapshot' : 0 ,
1065- 'testing-library/prefer-explicit-assert' : 1 ,
1066- 'testing-library/prefer-find-by' : 1 ,
1067- 'testing-library/prefer-implicit-assert' : 0 ,
1068- 'testing-library/prefer-presence-queries' : 0 ,
1069- 'testing-library/prefer-query-by-disappearance' : 1 ,
1070- 'testing-library/prefer-query-matchers' : 0 ,
1071- 'testing-library/prefer-screen-queries' : 0 ,
1072- 'testing-library/prefer-user-event' : 1 ,
1073- 'testing-library/render-result-naming-convention' : 0
1017+ 'vitest/warn-todo' : 1
10741018 }
10751019 } ,
10761020
@@ -1103,20 +1047,38 @@ copy(
11031047 name : 'markdown' ,
11041048 files : [ '**/*.md' ] ,
11051049 plugins : {
1106- // @ts -expect-error
11071050 markdown
11081051 } ,
1109- language : 'markdown/commonmark ' ,
1052+ language : 'markdown/gfm ' ,
11101053 rules : {
1054+ // `@eslint/markdown` rules
1055+ // https://github.com/eslint/markdown/blob/main/README.md#rules
1056+ /*
1057+ // copy all the rules from the rules table for easy pasting
1058+ copy(
1059+ Iterator.from(
1060+ document
1061+ // select rules table
1062+ .querySelector('.markdown-heading:has(> a[href="#rules"]) ~ markdown-accessiblity-table tbody')
1063+ // select all rule links
1064+ .querySelectorAll(':any-link')
1065+ )
1066+ // map link to rule declaration
1067+ .map((link) => `'markdown/${link.textContent}': 1,`)
1068+ .toArray()
1069+ .join('\n')
1070+ );
1071+ */
11111072 'markdown/fenced-code-language' : 1 ,
1073+ 'markdown/fenced-code-meta' : 0 ,
11121074 'markdown/heading-increment' : 1 ,
11131075 'markdown/no-bare-urls' : 1 ,
11141076 'markdown/no-duplicate-definitions' : 1 ,
1115- 'markdown/no-duplicate-headings' : 0 ,
1077+ 'markdown/no-duplicate-headings' : [ 1 , { checkSiblingsOnly : true } ] ,
11161078 'markdown/no-empty-definitions' : 1 ,
11171079 'markdown/no-empty-images' : 1 ,
11181080 'markdown/no-empty-links' : 1 ,
1119- 'markdown/no-html' : 0 ,
1081+ 'markdown/no-html' : [ 1 , { allowed : [ 'br' , 'kbd' ] } ] ,
11201082 'markdown/no-invalid-label-refs' : 1 ,
11211083 'markdown/no-missing-atx-heading-space' : 1 ,
11221084 'markdown/no-missing-label-refs' : 1 ,
0 commit comments