eslint-config-setup 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -6
- package/dist/configs/0b23ff88.js +6 -23
- package/dist/configs/12c62446.js +5 -22
- package/dist/configs/196d687e.js +33 -48
- package/dist/configs/1c3f743c.js +6 -23
- package/dist/configs/2f6f3a82.js +32 -45
- package/dist/configs/4eb62e57.js +7 -24
- package/dist/configs/52762a42.js +6 -4
- package/dist/configs/532f50a4.js +30 -20
- package/dist/configs/5a302873.js +31 -44
- package/dist/configs/6bc0d588.js +37 -21
- package/dist/configs/91e82988.js +30 -20
- package/dist/configs/c2fecd3d.js +6 -4
- package/dist/configs/cde010b4.js +5 -2
- package/dist/configs/d537b683.js +37 -21
- package/dist/configs/db69ebb6.js +34 -49
- package/dist/configs/e4b137fa.js +5 -2
- package/dist/index.js +24 -4
- package/dist/index.js.map +1 -1
- package/dist/modules.d.ts +9 -7
- package/dist/modules.js +80 -38
- package/dist/modules.js.map +1 -1
- package/dist/oxlint-configs/3047b7d6.json +30 -2
- package/dist/oxlint-configs/58d5e03b.json +31 -3
- package/dist/oxlint-configs/78b40daa.json +35 -5
- package/dist/oxlint-configs/7ff0d87e.json +45 -3
- package/dist/oxlint-configs/85912bf0.json +44 -2
- package/dist/oxlint-configs/9dc42dc3.json +35 -5
- package/dist/oxlint-configs/d46cb9b7.json +57 -6
- package/dist/oxlint-configs/ef643c60.json +57 -6
- package/package.json +37 -35
package/dist/configs/d537b683.js
CHANGED
|
@@ -14,6 +14,8 @@ import packageJsonPlugin from "eslint-plugin-package-json"
|
|
|
14
14
|
import perfectionistPlugin from "eslint-plugin-perfectionist"
|
|
15
15
|
import playwrightPlugin from "eslint-plugin-playwright"
|
|
16
16
|
import reactEffectPlugin from "eslint-plugin-react-you-might-not-need-an-effect"
|
|
17
|
+
import reactHooksPlugin from "eslint-plugin-react-hooks"
|
|
18
|
+
import reactPerfPlugin from "eslint-plugin-react-perf"
|
|
17
19
|
import reactRefreshPlugin from "eslint-plugin-react-refresh"
|
|
18
20
|
import regexpPlugin from "eslint-plugin-regexp"
|
|
19
21
|
import securityPlugin from "eslint-plugin-security"
|
|
@@ -26,7 +28,7 @@ import unicornPlugin from "eslint-plugin-unicorn"
|
|
|
26
28
|
import unusedImportsPlugin from "eslint-plugin-unused-imports"
|
|
27
29
|
import vitestPlugin from "@vitest/eslint-plugin"
|
|
28
30
|
|
|
29
|
-
// React compat plugin —
|
|
31
|
+
// React compat plugin — maps @eslint-react rule families into the `react/` namespace
|
|
30
32
|
// and aliases rules to legacy eslint-plugin-react names for OxLint compatibility.
|
|
31
33
|
const reactCompatPlugin = (() => {
|
|
32
34
|
const core = eslintReactPlugin.rules
|
|
@@ -52,7 +54,6 @@ const reactCompatPlugin = (() => {
|
|
|
52
54
|
"no-unstable-nested-components": [core, "no-nested-component-definitions"],
|
|
53
55
|
"display-name": [core, "no-missing-component-display-name"],
|
|
54
56
|
"forward-ref-uses-ref": [core, "no-forward-ref"],
|
|
55
|
-
"destructuring-assignment": [core, "prefer-destructuring-assignment"],
|
|
56
57
|
"no-did-mount-set-state": [core, "no-set-state-in-component-did-mount"],
|
|
57
58
|
"no-did-update-set-state": [core, "no-set-state-in-component-did-update"],
|
|
58
59
|
"no-will-update-set-state": [core, "no-set-state-in-component-will-update"],
|
|
@@ -74,7 +75,7 @@ const reactCompatPlugin = (() => {
|
|
|
74
75
|
// Identical-name aliases (core rules where legacy name = @eslint-react name)
|
|
75
76
|
const identicalCore = [
|
|
76
77
|
"no-access-state-in-setstate", "no-array-index-key",
|
|
77
|
-
"no-direct-mutation-state",
|
|
78
|
+
"no-direct-mutation-state",
|
|
78
79
|
"no-unused-class-component-members", "no-unused-state",
|
|
79
80
|
]
|
|
80
81
|
for (const n of identicalCore) aliases[n] = [core, n]
|
|
@@ -131,6 +132,8 @@ export default [
|
|
|
131
132
|
"node": nodePlugin,
|
|
132
133
|
"perfectionist": perfectionistPlugin,
|
|
133
134
|
"react": reactCompatPlugin,
|
|
135
|
+
"react-hooks": reactHooksPlugin,
|
|
136
|
+
"react-perf": reactPerfPlugin,
|
|
134
137
|
"react-refresh": reactRefreshPlugin,
|
|
135
138
|
"react-you-might-not-need-an-effect": reactEffectPlugin,
|
|
136
139
|
"regexp": regexpPlugin,
|
|
@@ -929,6 +932,27 @@ export default [
|
|
|
929
932
|
"prefer-template": "error",
|
|
930
933
|
"preserve-caught-error": "error",
|
|
931
934
|
"radix": "error",
|
|
935
|
+
"react-hooks/config": "error",
|
|
936
|
+
"react-hooks/error-boundaries": "error",
|
|
937
|
+
"react-hooks/exhaustive-deps": "warn",
|
|
938
|
+
"react-hooks/gating": "error",
|
|
939
|
+
"react-hooks/globals": "error",
|
|
940
|
+
"react-hooks/immutability": "error",
|
|
941
|
+
"react-hooks/incompatible-library": "warn",
|
|
942
|
+
"react-hooks/preserve-manual-memoization": "error",
|
|
943
|
+
"react-hooks/purity": "error",
|
|
944
|
+
"react-hooks/refs": "error",
|
|
945
|
+
"react-hooks/rules-of-hooks": "error",
|
|
946
|
+
"react-hooks/set-state-in-effect": "error",
|
|
947
|
+
"react-hooks/set-state-in-render": "error",
|
|
948
|
+
"react-hooks/static-components": "error",
|
|
949
|
+
"react-hooks/unsupported-syntax": "warn",
|
|
950
|
+
"react-hooks/use-memo": "error",
|
|
951
|
+
"react-hooks/void-use-memo": "error",
|
|
952
|
+
"react-perf/jsx-no-jsx-as-prop": "error",
|
|
953
|
+
"react-perf/jsx-no-new-array-as-prop": "error",
|
|
954
|
+
"react-perf/jsx-no-new-function-as-prop": "error",
|
|
955
|
+
"react-perf/jsx-no-new-object-as-prop": "error",
|
|
932
956
|
"react-refresh/only-export-components": [
|
|
933
957
|
"warn",
|
|
934
958
|
{
|
|
@@ -938,18 +962,14 @@ export default [
|
|
|
938
962
|
"react-you-might-not-need-an-effect/no-adjust-state-on-prop-change": "warn",
|
|
939
963
|
"react-you-might-not-need-an-effect/no-chain-state-updates": "error",
|
|
940
964
|
"react-you-might-not-need-an-effect/no-derived-state": "error",
|
|
941
|
-
"react-you-might-not-need-an-effect/no-empty-effect": "error",
|
|
942
965
|
"react-you-might-not-need-an-effect/no-event-handler": "error",
|
|
966
|
+
"react-you-might-not-need-an-effect/no-external-store-subscription": "error",
|
|
943
967
|
"react-you-might-not-need-an-effect/no-initialize-state": "error",
|
|
944
968
|
"react-you-might-not-need-an-effect/no-pass-data-to-parent": "error",
|
|
945
969
|
"react-you-might-not-need-an-effect/no-pass-live-state-to-parent": "error",
|
|
946
970
|
"react-you-might-not-need-an-effect/no-reset-all-state-on-prop-change": "error",
|
|
947
971
|
"react/button-has-type": "error",
|
|
948
|
-
"react/component-hook-factories": "error",
|
|
949
972
|
"react/context-name": "warn",
|
|
950
|
-
"react/destructuring-assignment": "warn",
|
|
951
|
-
"react/error-boundaries": "error",
|
|
952
|
-
"react/exhaustive-deps": "warn",
|
|
953
973
|
"react/forward-ref-uses-ref": "error",
|
|
954
974
|
"react/function-definition": "error",
|
|
955
975
|
"react/hook-use-state": "warn",
|
|
@@ -960,6 +980,7 @@ export default [
|
|
|
960
980
|
"react/jsx-no-children-prop-with-children": "error",
|
|
961
981
|
"react/jsx-no-comment-textnodes": "error",
|
|
962
982
|
"react/jsx-no-constructed-context-values": "error",
|
|
983
|
+
"react/jsx-no-leaked-dollar": "warn",
|
|
963
984
|
"react/jsx-no-leaked-render": "error",
|
|
964
985
|
"react/jsx-no-leaked-semicolon": "warn",
|
|
965
986
|
"react/jsx-no-script-url": "warn",
|
|
@@ -991,6 +1012,8 @@ export default [
|
|
|
991
1012
|
"react/no-hydrate": "error",
|
|
992
1013
|
"react/no-implicit-key": "error",
|
|
993
1014
|
"react/no-leaked-event-listener": "error",
|
|
1015
|
+
"react/no-leaked-fetch": "warn",
|
|
1016
|
+
"react/no-leaked-intersection-observer": "warn",
|
|
994
1017
|
"react/no-leaked-interval": "error",
|
|
995
1018
|
"react/no-leaked-resize-observer": "error",
|
|
996
1019
|
"react/no-leaked-timeout": "error",
|
|
@@ -998,12 +1021,9 @@ export default [
|
|
|
998
1021
|
"react/no-namespace": "error",
|
|
999
1022
|
"react/no-nested-lazy-component-declarations": "error",
|
|
1000
1023
|
"react/no-object-type-as-default-prop": "error",
|
|
1001
|
-
"react/no-redundant-should-component-update": "error",
|
|
1002
1024
|
"react/no-render": "error",
|
|
1003
1025
|
"react/no-render-return-value": "error",
|
|
1004
1026
|
"react/no-unknown-property": "error",
|
|
1005
|
-
"react/no-unnecessary-use-callback": "warn",
|
|
1006
|
-
"react/no-unnecessary-use-memo": "warn",
|
|
1007
1027
|
"react/no-unnecessary-use-prefix": "warn",
|
|
1008
1028
|
"react/no-unsafe-component-will-mount": "warn",
|
|
1009
1029
|
"react/no-unsafe-component-will-receive-props": "warn",
|
|
@@ -1016,14 +1036,8 @@ export default [
|
|
|
1016
1036
|
"react/no-use-context": "error",
|
|
1017
1037
|
"react/no-use-form-state": "error",
|
|
1018
1038
|
"react/no-will-update-set-state": "warn",
|
|
1019
|
-
"react/purity": "warn",
|
|
1020
1039
|
"react/ref-name": "warn",
|
|
1021
|
-
"react/rules-of-hooks": "error",
|
|
1022
|
-
"react/set-state-in-effect": "warn",
|
|
1023
|
-
"react/set-state-in-render": "error",
|
|
1024
1040
|
"react/style-prop-object": "error",
|
|
1025
|
-
"react/unsupported-syntax": "error",
|
|
1026
|
-
"react/use-memo": "error",
|
|
1027
1041
|
"react/void-dom-elements-no-children": "error",
|
|
1028
1042
|
"regexp/confusing-quantifier": "warn",
|
|
1029
1043
|
"regexp/control-character-escape": "error",
|
|
@@ -1173,7 +1187,10 @@ export default [
|
|
|
1173
1187
|
"camelCase": true,
|
|
1174
1188
|
"pascalCase": true,
|
|
1175
1189
|
"kebabCase": true
|
|
1176
|
-
}
|
|
1190
|
+
},
|
|
1191
|
+
"ignore": [
|
|
1192
|
+
"__tests__"
|
|
1193
|
+
]
|
|
1177
1194
|
}
|
|
1178
1195
|
],
|
|
1179
1196
|
"unicorn/new-for-builtins": "error",
|
|
@@ -1181,12 +1198,12 @@ export default [
|
|
|
1181
1198
|
"unicorn/no-accessor-recursion": "error",
|
|
1182
1199
|
"unicorn/no-anonymous-default-export": "error",
|
|
1183
1200
|
"unicorn/no-array-callback-reference": "error",
|
|
1184
|
-
"unicorn/no-array-for-each": "error",
|
|
1185
1201
|
"unicorn/no-array-method-this-argument": "error",
|
|
1186
1202
|
"unicorn/no-array-push-push": "error",
|
|
1187
1203
|
"unicorn/no-array-reduce": "error",
|
|
1188
1204
|
"unicorn/no-await-expression-member": "error",
|
|
1189
1205
|
"unicorn/no-await-in-promise-methods": "error",
|
|
1206
|
+
"unicorn/no-for-each": "error",
|
|
1190
1207
|
"unicorn/no-for-loop": "error",
|
|
1191
1208
|
"unicorn/no-instanceof-builtins": "error",
|
|
1192
1209
|
"unicorn/no-invalid-fetch-options": "error",
|
|
@@ -1226,7 +1243,7 @@ export default [
|
|
|
1226
1243
|
"unicorn/prefer-export-from": [
|
|
1227
1244
|
"error",
|
|
1228
1245
|
{
|
|
1229
|
-
"
|
|
1246
|
+
"checkUsedVariables": false
|
|
1230
1247
|
}
|
|
1231
1248
|
],
|
|
1232
1249
|
"unicorn/prefer-global-this": "error",
|
|
@@ -1263,7 +1280,6 @@ export default [
|
|
|
1263
1280
|
],
|
|
1264
1281
|
"unicorn/prefer-top-level-await": "error",
|
|
1265
1282
|
"unicorn/prefer-type-error": "error",
|
|
1266
|
-
"unicorn/prevent-abbreviations": "error",
|
|
1267
1283
|
"unicorn/relative-url-style": "error",
|
|
1268
1284
|
"unicorn/switch-case-braces": "error",
|
|
1269
1285
|
"unicorn/text-encoding-identifier-case": "error",
|
package/dist/configs/db69ebb6.js
CHANGED
|
@@ -8,13 +8,13 @@ import globals from "globals"
|
|
|
8
8
|
import importXPlugin from "eslint-plugin-import-x"
|
|
9
9
|
import jsdocPlugin from "eslint-plugin-jsdoc"
|
|
10
10
|
import jsonPlugin from "@eslint/json"
|
|
11
|
-
import jsxA11yPlugin from "eslint-plugin-jsx-a11y"
|
|
12
11
|
import nodePlugin from "eslint-plugin-n"
|
|
13
12
|
import oxlintPlugin from "eslint-plugin-oxlint"
|
|
14
13
|
import packageJsonPlugin from "eslint-plugin-package-json"
|
|
15
14
|
import perfectionistPlugin from "eslint-plugin-perfectionist"
|
|
16
15
|
import playwrightPlugin from "eslint-plugin-playwright"
|
|
17
16
|
import reactEffectPlugin from "eslint-plugin-react-you-might-not-need-an-effect"
|
|
17
|
+
import reactHooksPlugin from "eslint-plugin-react-hooks"
|
|
18
18
|
import regexpPlugin from "eslint-plugin-regexp"
|
|
19
19
|
import securityPlugin from "eslint-plugin-security"
|
|
20
20
|
import sonarjsPlugin from "eslint-plugin-sonarjs"
|
|
@@ -26,7 +26,7 @@ import unicornPlugin from "eslint-plugin-unicorn"
|
|
|
26
26
|
import unusedImportsPlugin from "eslint-plugin-unused-imports"
|
|
27
27
|
import vitestPlugin from "@vitest/eslint-plugin"
|
|
28
28
|
|
|
29
|
-
// React compat plugin —
|
|
29
|
+
// React compat plugin — maps @eslint-react rule families into the `react/` namespace
|
|
30
30
|
// and aliases rules to legacy eslint-plugin-react names for OxLint compatibility.
|
|
31
31
|
const reactCompatPlugin = (() => {
|
|
32
32
|
const core = eslintReactPlugin.rules
|
|
@@ -52,7 +52,6 @@ const reactCompatPlugin = (() => {
|
|
|
52
52
|
"no-unstable-nested-components": [core, "no-nested-component-definitions"],
|
|
53
53
|
"display-name": [core, "no-missing-component-display-name"],
|
|
54
54
|
"forward-ref-uses-ref": [core, "no-forward-ref"],
|
|
55
|
-
"destructuring-assignment": [core, "prefer-destructuring-assignment"],
|
|
56
55
|
"no-did-mount-set-state": [core, "no-set-state-in-component-did-mount"],
|
|
57
56
|
"no-did-update-set-state": [core, "no-set-state-in-component-did-update"],
|
|
58
57
|
"no-will-update-set-state": [core, "no-set-state-in-component-will-update"],
|
|
@@ -74,7 +73,7 @@ const reactCompatPlugin = (() => {
|
|
|
74
73
|
// Identical-name aliases (core rules where legacy name = @eslint-react name)
|
|
75
74
|
const identicalCore = [
|
|
76
75
|
"no-access-state-in-setstate", "no-array-index-key",
|
|
77
|
-
"no-direct-mutation-state",
|
|
76
|
+
"no-direct-mutation-state",
|
|
78
77
|
"no-unused-class-component-members", "no-unused-state",
|
|
79
78
|
]
|
|
80
79
|
for (const n of identicalCore) aliases[n] = [core, n]
|
|
@@ -127,10 +126,10 @@ export default [
|
|
|
127
126
|
"de-morgan": deMorganPlugin,
|
|
128
127
|
"import": importXPlugin,
|
|
129
128
|
"jsdoc": jsdocPlugin,
|
|
130
|
-
"jsx-a11y": jsxA11yPlugin,
|
|
131
129
|
"node": nodePlugin,
|
|
132
130
|
"perfectionist": perfectionistPlugin,
|
|
133
131
|
"react": reactCompatPlugin,
|
|
132
|
+
"react-hooks": reactHooksPlugin,
|
|
134
133
|
"react-you-might-not-need-an-effect": reactEffectPlugin,
|
|
135
134
|
"regexp": regexpPlugin,
|
|
136
135
|
"security": securityPlugin,
|
|
@@ -234,10 +233,6 @@ export default [
|
|
|
234
233
|
]
|
|
235
234
|
}
|
|
236
235
|
],
|
|
237
|
-
"@typescript-eslint/method-signature-style": [
|
|
238
|
-
"error",
|
|
239
|
-
"property"
|
|
240
|
-
],
|
|
241
236
|
"@typescript-eslint/naming-convention": [
|
|
242
237
|
"error",
|
|
243
238
|
{
|
|
@@ -484,7 +479,6 @@ export default [
|
|
|
484
479
|
"getBeforeSet"
|
|
485
480
|
],
|
|
486
481
|
"guard-for-in": "error",
|
|
487
|
-
"import/newline-after-import": "error",
|
|
488
482
|
"import/no-extraneous-dependencies": [
|
|
489
483
|
"error",
|
|
490
484
|
{
|
|
@@ -506,13 +500,9 @@ export default [
|
|
|
506
500
|
"jsdoc/reject-function-type": "error",
|
|
507
501
|
"jsdoc/require-next-type": "error",
|
|
508
502
|
"jsdoc/require-returns-check": "error",
|
|
509
|
-
"jsdoc/require-throws-type": "error",
|
|
510
503
|
"jsdoc/require-yields-check": "error",
|
|
511
|
-
"jsdoc/require-yields-type": "error",
|
|
512
504
|
"jsdoc/ts-no-empty-object-type": "error",
|
|
513
505
|
"jsdoc/valid-types": "error",
|
|
514
|
-
"jsx-a11y/interactive-supports-focus": "error",
|
|
515
|
-
"jsx-a11y/no-noninteractive-element-interactions": "error",
|
|
516
506
|
"logical-assignment-operators": [
|
|
517
507
|
"error",
|
|
518
508
|
"always",
|
|
@@ -700,24 +690,36 @@ export default [
|
|
|
700
690
|
"prefer-template": "error",
|
|
701
691
|
"preserve-caught-error": "error",
|
|
702
692
|
"radix": "error",
|
|
693
|
+
"react-hooks/config": "error",
|
|
694
|
+
"react-hooks/error-boundaries": "error",
|
|
695
|
+
"react-hooks/gating": "error",
|
|
696
|
+
"react-hooks/globals": "error",
|
|
697
|
+
"react-hooks/immutability": "error",
|
|
698
|
+
"react-hooks/incompatible-library": "warn",
|
|
699
|
+
"react-hooks/preserve-manual-memoization": "error",
|
|
700
|
+
"react-hooks/purity": "error",
|
|
701
|
+
"react-hooks/refs": "error",
|
|
702
|
+
"react-hooks/set-state-in-effect": "error",
|
|
703
|
+
"react-hooks/set-state-in-render": "error",
|
|
704
|
+
"react-hooks/static-components": "error",
|
|
705
|
+
"react-hooks/unsupported-syntax": "warn",
|
|
706
|
+
"react-hooks/use-memo": "error",
|
|
707
|
+
"react-hooks/void-use-memo": "error",
|
|
703
708
|
"react-you-might-not-need-an-effect/no-adjust-state-on-prop-change": "warn",
|
|
704
709
|
"react-you-might-not-need-an-effect/no-chain-state-updates": "error",
|
|
705
710
|
"react-you-might-not-need-an-effect/no-derived-state": "error",
|
|
706
|
-
"react-you-might-not-need-an-effect/no-empty-effect": "error",
|
|
707
711
|
"react-you-might-not-need-an-effect/no-event-handler": "error",
|
|
712
|
+
"react-you-might-not-need-an-effect/no-external-store-subscription": "error",
|
|
708
713
|
"react-you-might-not-need-an-effect/no-initialize-state": "error",
|
|
709
714
|
"react-you-might-not-need-an-effect/no-pass-data-to-parent": "error",
|
|
710
715
|
"react-you-might-not-need-an-effect/no-pass-live-state-to-parent": "error",
|
|
711
716
|
"react-you-might-not-need-an-effect/no-reset-all-state-on-prop-change": "error",
|
|
712
|
-
"react/component-hook-factories": "error",
|
|
713
717
|
"react/context-name": "warn",
|
|
714
|
-
"react/destructuring-assignment": "warn",
|
|
715
|
-
"react/error-boundaries": "error",
|
|
716
|
-
"react/exhaustive-deps": "warn",
|
|
717
718
|
"react/function-definition": "error",
|
|
718
719
|
"react/id-name": "warn",
|
|
719
720
|
"react/jsx-key-before-spread": "error",
|
|
720
721
|
"react/jsx-no-children-prop-with-children": "error",
|
|
722
|
+
"react/jsx-no-leaked-dollar": "warn",
|
|
721
723
|
"react/jsx-no-leaked-render": "error",
|
|
722
724
|
"react/jsx-no-leaked-semicolon": "warn",
|
|
723
725
|
"react/no-access-state-in-setstate": "error",
|
|
@@ -732,39 +734,30 @@ export default [
|
|
|
732
734
|
"react/no-component-will-update": "error",
|
|
733
735
|
"react/no-context-provider": "error",
|
|
734
736
|
"react/no-create-ref": "error",
|
|
735
|
-
"react/no-did-update-set-state": "warn",
|
|
736
737
|
"react/no-duplicate-key": "error",
|
|
737
738
|
"react/no-flush-sync": "error",
|
|
738
739
|
"react/no-hydrate": "error",
|
|
739
740
|
"react/no-implicit-key": "error",
|
|
740
741
|
"react/no-leaked-event-listener": "error",
|
|
742
|
+
"react/no-leaked-fetch": "warn",
|
|
743
|
+
"react/no-leaked-intersection-observer": "warn",
|
|
741
744
|
"react/no-leaked-interval": "error",
|
|
742
745
|
"react/no-leaked-resize-observer": "error",
|
|
743
746
|
"react/no-leaked-timeout": "error",
|
|
744
747
|
"react/no-misused-capture-owner-stack": "error",
|
|
745
748
|
"react/no-nested-lazy-component-declarations": "error",
|
|
746
|
-
"react/no-object-type-as-default-prop": "error",
|
|
747
749
|
"react/no-render": "error",
|
|
748
|
-
"react/no-unnecessary-use-callback": "warn",
|
|
749
|
-
"react/no-unnecessary-use-memo": "warn",
|
|
750
750
|
"react/no-unnecessary-use-prefix": "warn",
|
|
751
751
|
"react/no-unsafe-component-will-mount": "warn",
|
|
752
752
|
"react/no-unsafe-component-will-receive-props": "warn",
|
|
753
753
|
"react/no-unsafe-component-will-update": "warn",
|
|
754
754
|
"react/no-unsafe-iframe-sandbox": "warn",
|
|
755
|
-
"react/no-unstable-nested-components": "error",
|
|
756
755
|
"react/no-unused-class-component-members": "warn",
|
|
757
756
|
"react/no-unused-props": "warn",
|
|
758
757
|
"react/no-unused-state": "error",
|
|
759
758
|
"react/no-use-context": "error",
|
|
760
759
|
"react/no-use-form-state": "error",
|
|
761
|
-
"react/purity": "warn",
|
|
762
760
|
"react/ref-name": "warn",
|
|
763
|
-
"react/rules-of-hooks": "error",
|
|
764
|
-
"react/set-state-in-effect": "warn",
|
|
765
|
-
"react/set-state-in-render": "error",
|
|
766
|
-
"react/unsupported-syntax": "error",
|
|
767
|
-
"react/use-memo": "error",
|
|
768
761
|
"regexp/confusing-quantifier": "warn",
|
|
769
762
|
"regexp/control-character-escape": "error",
|
|
770
763
|
"regexp/match-any": "error",
|
|
@@ -893,20 +886,14 @@ export default [
|
|
|
893
886
|
"sonarjs/reduce-initial-value": "error",
|
|
894
887
|
"symbol-description": "error",
|
|
895
888
|
"unicorn/no-array-push-push": "error",
|
|
889
|
+
"unicorn/no-for-each": "error",
|
|
896
890
|
"unicorn/no-for-loop": "error",
|
|
897
|
-
"unicorn/prefer-export-from": [
|
|
898
|
-
"error",
|
|
899
|
-
{
|
|
900
|
-
"ignoreUsedVariables": true
|
|
901
|
-
}
|
|
902
|
-
],
|
|
903
891
|
"unicorn/prefer-switch": [
|
|
904
892
|
"error",
|
|
905
893
|
{
|
|
906
894
|
"minimumCases": 3
|
|
907
895
|
}
|
|
908
896
|
],
|
|
909
|
-
"unicorn/prevent-abbreviations": "error",
|
|
910
897
|
"unused-imports/no-unused-imports": "error",
|
|
911
898
|
"yoda": "error"
|
|
912
899
|
},
|
|
@@ -922,7 +909,6 @@ export default [
|
|
|
922
909
|
"@typescript-eslint/consistent-type-exports": "off",
|
|
923
910
|
"@typescript-eslint/dot-notation": "off",
|
|
924
911
|
"@typescript-eslint/member-ordering": "off",
|
|
925
|
-
"@typescript-eslint/method-signature-style": "off",
|
|
926
912
|
"@typescript-eslint/naming-convention": "off",
|
|
927
913
|
"@typescript-eslint/no-array-delete": "off",
|
|
928
914
|
"@typescript-eslint/no-base-to-string": "off",
|
|
@@ -981,7 +967,6 @@ export default [
|
|
|
981
967
|
"@typescript-eslint/unbound-method": "off",
|
|
982
968
|
"@typescript-eslint/use-unknown-in-catch-callback-variable": "off",
|
|
983
969
|
"dot-notation": "off",
|
|
984
|
-
"getter-return": "error",
|
|
985
970
|
"no-array-constructor": "off",
|
|
986
971
|
"no-dupe-args": "error",
|
|
987
972
|
"no-empty-function": "off",
|
|
@@ -992,7 +977,6 @@ export default [
|
|
|
992
977
|
"no-shadow": "off",
|
|
993
978
|
"no-throw-literal": "off",
|
|
994
979
|
"no-undef": "error",
|
|
995
|
-
"no-unreachable": "error",
|
|
996
980
|
"no-useless-constructor": "off",
|
|
997
981
|
"prefer-const": [
|
|
998
982
|
"error",
|
|
@@ -1242,7 +1226,6 @@ export default [
|
|
|
1242
1226
|
"@typescript-eslint/consistent-type-exports": "off",
|
|
1243
1227
|
"@typescript-eslint/dot-notation": "off",
|
|
1244
1228
|
"@typescript-eslint/member-ordering": "off",
|
|
1245
|
-
"@typescript-eslint/method-signature-style": "off",
|
|
1246
1229
|
"@typescript-eslint/naming-convention": "off",
|
|
1247
1230
|
"@typescript-eslint/no-array-delete": "off",
|
|
1248
1231
|
"@typescript-eslint/no-base-to-string": "off",
|
|
@@ -1322,13 +1305,15 @@ export default [
|
|
|
1322
1305
|
},
|
|
1323
1306
|
|
|
1324
1307
|
// OxLint integration — disables rules already covered by OxLint
|
|
1325
|
-
...[oxlintPlugin.configs["flat/recommended"]].flat().map((c) => ({ name: "eslint-config-setup/oxlint"
|
|
1326
|
-
...[oxlintPlugin.configs["flat/react"]].flat().map((c) => ({ name: "eslint-config-setup/oxlint-react"
|
|
1327
|
-
...[oxlintPlugin.configs["flat/jsx-a11y"]].flat().map((c) => ({ name: "eslint-config-setup/oxlint-jsx-a11y"
|
|
1328
|
-
...[oxlintPlugin.configs["flat/
|
|
1329
|
-
...[oxlintPlugin.configs["flat/
|
|
1330
|
-
...[oxlintPlugin.configs["flat/
|
|
1331
|
-
...[oxlintPlugin.configs["flat/
|
|
1332
|
-
...[oxlintPlugin.configs["flat/
|
|
1308
|
+
...[oxlintPlugin.configs["flat/recommended"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1309
|
+
...[oxlintPlugin.configs["flat/react"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-react" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1310
|
+
...[oxlintPlugin.configs["flat/jsx-a11y"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-jsx-a11y" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1311
|
+
...[oxlintPlugin.configs["flat/react-hooks"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-react-hooks" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1312
|
+
...[oxlintPlugin.configs["flat/react-perf"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-react-perf" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1313
|
+
...[oxlintPlugin.configs["flat/node"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-node" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1314
|
+
...[oxlintPlugin.configs["flat/typescript"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-typescript" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1315
|
+
...[oxlintPlugin.configs["flat/unicorn"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-unicorn" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1316
|
+
...[oxlintPlugin.configs["flat/import"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-import" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1317
|
+
...[oxlintPlugin.configs["flat/jsdoc"]].flat().map((c, index, array) => ({ ...c, name: "eslint-config-setup/oxlint-jsdoc" + (array.length > 1 ? "-" + (index + 1) : "") })),
|
|
1333
1318
|
|
|
1334
1319
|
]
|
package/dist/configs/e4b137fa.js
CHANGED
|
@@ -621,7 +621,10 @@ export default [
|
|
|
621
621
|
"camelCase": true,
|
|
622
622
|
"pascalCase": true,
|
|
623
623
|
"kebabCase": true
|
|
624
|
-
}
|
|
624
|
+
},
|
|
625
|
+
"ignore": [
|
|
626
|
+
"__tests__"
|
|
627
|
+
]
|
|
625
628
|
}
|
|
626
629
|
],
|
|
627
630
|
"unicorn/new-for-builtins": "error",
|
|
@@ -670,7 +673,7 @@ export default [
|
|
|
670
673
|
"unicorn/prefer-export-from": [
|
|
671
674
|
"error",
|
|
672
675
|
{
|
|
673
|
-
"
|
|
676
|
+
"checkUsedVariables": false
|
|
674
677
|
}
|
|
675
678
|
],
|
|
676
679
|
"unicorn/prefer-global-this": "error",
|
package/dist/index.js
CHANGED
|
@@ -112,21 +112,31 @@ function oxlintOptionsToFilename(opts) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
// src/loader.ts
|
|
115
|
-
import { readFileSync } from "fs";
|
|
115
|
+
import { existsSync, readFileSync } from "fs";
|
|
116
116
|
import path from "path";
|
|
117
|
+
import { pathToFileURL } from "url";
|
|
117
118
|
async function getEslintConfig(opts = {}) {
|
|
118
119
|
const filename = optionsToFilename(opts);
|
|
119
120
|
const dirname = import.meta.dirname;
|
|
120
121
|
const configPath = path.join(dirname, "configs", filename);
|
|
122
|
+
if (!existsSync(configPath)) {
|
|
123
|
+
throwMissingConfigError(opts, filename);
|
|
124
|
+
}
|
|
125
|
+
const configUrl = pathToFileURL(configPath);
|
|
126
|
+
configUrl.search = String(Date.now());
|
|
121
127
|
try {
|
|
122
128
|
const module = await import(
|
|
123
129
|
/* webpackIgnore: true */
|
|
124
|
-
|
|
130
|
+
configUrl.href
|
|
125
131
|
);
|
|
126
132
|
return module.default;
|
|
127
|
-
} catch {
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (!existsSync(configPath)) {
|
|
135
|
+
throwMissingConfigError(opts, filename, error);
|
|
136
|
+
}
|
|
128
137
|
throw new Error(
|
|
129
|
-
`eslint-config-setup:
|
|
138
|
+
`eslint-config-setup: Pre-generated config failed to load for options ${JSON.stringify(opts)}. Expected file: configs/${filename}. Original error: ${getErrorMessage(error)}`,
|
|
139
|
+
{ cause: error }
|
|
130
140
|
);
|
|
131
141
|
}
|
|
132
142
|
}
|
|
@@ -143,6 +153,16 @@ function getOxlintConfig(opts = {}) {
|
|
|
143
153
|
);
|
|
144
154
|
}
|
|
145
155
|
}
|
|
156
|
+
function getErrorMessage(error) {
|
|
157
|
+
return error instanceof Error ? error.message : String(error);
|
|
158
|
+
}
|
|
159
|
+
function throwMissingConfigError(opts, filename, cause) {
|
|
160
|
+
const message = `eslint-config-setup: No pre-generated config found for options ${JSON.stringify(opts)}. Expected file: configs/${filename}. Run "npm run generate" in the package to build configs.`;
|
|
161
|
+
if (cause === void 0) {
|
|
162
|
+
throw new Error(message);
|
|
163
|
+
}
|
|
164
|
+
throw new Error(message, { cause });
|
|
165
|
+
}
|
|
146
166
|
export {
|
|
147
167
|
addRule,
|
|
148
168
|
bitmaskToHash,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/rule-helpers.ts","../src/hash.ts","../src/loader.ts"],"sourcesContent":["/* eslint-disable max-params, complexity -- Public API: config + ruleName + severity + options is the natural signature. Options objects would hurt ergonomics for one-liner calls. */\nimport type { Linter } from \"eslint\"\n\nimport type {\n FlatConfigArray,\n RuleOptions,\n RuleSeverity,\n} from \"../types\"\n\nconst CONFIG_PREFIX = \"eslint-config-setup/\"\n\n/** Maps user-facing scope names to config block name segments. */\nconst SCOPE_TO_BLOCK: Record<string, string> = {\n configs: \"config-files\",\n}\n\n/**\n * Check if a config block matches a given scope.\n * A block matches if its name is `eslint-config-setup/{segment}` or starts with `eslint-config-setup/{segment}-`.\n */\nfunction blockMatchesScope(\n block: Linter.Config,\n scope: string,\n): boolean {\n const name = block.name\n if (name == null) return false\n const segment = SCOPE_TO_BLOCK[scope] ?? scope\n const target = `${CONFIG_PREFIX}${segment}`\n return name === target || name.startsWith(`${target}-`)\n}\n\n/**\n * Change the severity of a rule across all config blocks, preserving options.\n */\nexport function setRuleSeverity(\n config: FlatConfigArray,\n ruleName: string,\n severity: RuleSeverity,\n options?: RuleOptions,\n): void {\n for (const block of config) {\n if (options?.scope !== undefined && !blockMatchesScope(block, options.scope)) continue\n if (block.rules?.[ruleName] == null) continue\n\n const current = block.rules[ruleName]\n if (Array.isArray(current)) {\n block.rules[ruleName] = [severity, ...current.slice(1)] as Linter.RuleEntry\n } else {\n block.rules[ruleName] = severity\n }\n }\n}\n\n/**\n * Update the options of a rule across all config blocks, preserving severity.\n */\nexport function configureRule(\n config: FlatConfigArray,\n ruleName: string,\n options: unknown[],\n ruleOptions?: RuleOptions,\n): void {\n for (const block of config) {\n if (ruleOptions?.scope !== undefined && !blockMatchesScope(block, ruleOptions.scope))\n continue\n if (block.rules?.[ruleName] == null) continue\n\n const current = block.rules[ruleName]\n const severity = Array.isArray(current) ? current[0] : current\n block.rules[ruleName] = [severity, ...options] as Linter.RuleEntry\n }\n}\n\n/**\n * Completely disable a rule across all config blocks.\n * With scope: disables in the first matching block (creates entry if needed).\n */\nexport function disableRule(\n config: FlatConfigArray,\n ruleName: string,\n options?: RuleOptions,\n): void {\n if (options?.scope != null) {\n const { scope } = options\n const block = config.find((b) => blockMatchesScope(b, scope))\n if (!block) return\n block.rules ??= {}\n block.rules[ruleName] = \"off\"\n return\n }\n\n for (const block of config) {\n if (block.rules?.[ruleName] == null) continue\n block.rules[ruleName] = \"off\"\n }\n}\n\n/**\n * Add a new rule to the first (base) config block.\n * With scope: adds to the first matching block instead.\n */\nexport function addRule(\n config: FlatConfigArray,\n ruleName: string,\n severity: RuleSeverity,\n options?: RuleOptions | unknown[],\n ruleOptions?: RuleOptions,\n): void {\n // Handle overloaded signatures: addRule(config, rule, severity, options?, ruleOptions?)\n // When options is a plain object with scope, it's actually ruleOptions\n let ruleOpts: undefined | unknown[]\n let scopeOpts: RuleOptions | undefined\n\n if (Array.isArray(options)) {\n ruleOpts = options\n scopeOpts = ruleOptions\n } else if (options && typeof options === \"object\" && \"scope\" in options) {\n scopeOpts = options\n } else if (options === undefined) {\n scopeOpts = ruleOptions\n }\n\n let target: Linter.Config | undefined\n if (scopeOpts?.scope != null) {\n const { scope } = scopeOpts\n target = config.find((b) => blockMatchesScope(b, scope))\n } else {\n target = config[0]\n }\n\n if (!target) return\n\n target.rules ??= {}\n target.rules[ruleName] = ruleOpts\n ? ([severity, ...ruleOpts] as Linter.RuleEntry)\n : severity\n}\n\n/**\n * Disable all rules except the specified one — useful for debugging.\n */\nexport function disableAllRulesBut(\n config: FlatConfigArray,\n keepRuleName: string,\n): void {\n for (const block of config) {\n if (!block.rules) continue\n for (const ruleName of Object.keys(block.rules)) {\n if (ruleName !== keepRuleName) {\n block.rules[ruleName] = \"off\"\n }\n }\n }\n}\n","import { createHash } from \"node:crypto\"\n\nimport type { ConfigOptions, OxlintConfigOptions } from \"./types\"\n\n/**\n * Converts config options to a deterministic bitmask.\n * Bit order is fixed and must never change (would break published configs).\n */\nexport function optionsToBitmask(opts: ConfigOptions): number {\n let mask = 0\n if (opts.react) mask |= 1 << 0\n if (opts.node) mask |= 1 << 1\n if (opts.ai) mask |= 1 << 2\n if (opts.oxlint) mask |= 1 << 3\n return mask\n}\n\n/**\n * Converts a bitmask to a short deterministic hash (8 hex chars).\n * The same hash is produced at build-time (generate) and run-time (getConfig).\n */\nexport function bitmaskToHash(mask: number): string {\n const input = `effective-eslint-config:${mask}`\n return createHash(\"sha1\").update(input).digest(\"hex\").slice(0, 8)\n}\n\n/** Convenience: options → filename (without path prefix). */\nexport function optionsToFilename(opts: ConfigOptions): string {\n return `${bitmaskToHash(optionsToBitmask(opts))}.js`\n}\n\n/** Total number of permutations (2^4 = 16). */\nexport const TOTAL_PERMUTATIONS = 16\n\n/** Iterate all possible option combinations. */\nexport function* allPermutations(): Generator<ConfigOptions> {\n for (let mask = 0; mask < TOTAL_PERMUTATIONS; mask++) {\n yield {\n react: Boolean(mask & (1 << 0)),\n node: Boolean(mask & (1 << 1)),\n ai: Boolean(mask & (1 << 2)),\n oxlint: Boolean(mask & (1 << 3)),\n }\n }\n}\n\n// --- OxLint config permutations (3 flags → 8 combos) ---\n\n/** Converts OxLint-relevant options to a 3-bit bitmask (react, node, ai). */\nexport function oxlintOptionsToBitmask(opts: OxlintConfigOptions): number {\n let mask = 0\n if (opts.react) mask |= 1 << 0\n if (opts.node) mask |= 1 << 1\n if (opts.ai) mask |= 1 << 2\n return mask\n}\n\n/** Deterministic hash for OxLint configs (different salt to avoid collisions). */\nexport function oxlintBitmaskToHash(mask: number): string {\n const input = `eslint-config-setup-oxlint:${mask}`\n return createHash(\"sha1\").update(input).digest(\"hex\").slice(0, 8)\n}\n\n/** OxLint options → filename (without path prefix). */\nexport function oxlintOptionsToFilename(opts: OxlintConfigOptions): string {\n return `${oxlintBitmaskToHash(oxlintOptionsToBitmask(opts))}.json`\n}\n\n/** Total number of OxLint permutations (2^3 = 8). */\nexport const TOTAL_OXLINT_PERMUTATIONS = 8\n\n/** Iterate all OxLint option combinations. */\nexport function* allOxlintPermutations(): Generator<OxlintConfigOptions> {\n for (let mask = 0; mask < TOTAL_OXLINT_PERMUTATIONS; mask++) {\n yield {\n react: Boolean(mask & (1 << 0)),\n node: Boolean(mask & (1 << 1)),\n ai: Boolean(mask & (1 << 2)),\n }\n }\n}\n","/* eslint-disable security/detect-non-literal-fs-filename, @typescript-eslint/no-unsafe-type-assertion -- Paths are computed from deterministic hashes in dist/, not from user input. */\nimport { readFileSync } from \"node:fs\"\nimport path from \"node:path\"\n\nimport type { ConfigOptions, FlatConfigArray, OxlintConfigOptions, OxlintConfigResult } from \"./types\"\n\nimport { optionsToFilename, oxlintOptionsToFilename } from \"./hash\"\n\n/**\n * Loads a pre-generated ESLint config by dynamically importing the hashed file.\n * The hash is computed from the options using the same algorithm as the build.\n */\nexport async function getEslintConfig(\n opts: ConfigOptions = {},\n): Promise<FlatConfigArray> {\n const filename = optionsToFilename(opts)\n const dirname = import.meta.dirname\n const configPath = path.join(dirname, \"configs\", filename)\n\n try {\n const module = (await import(\n /* webpackIgnore: true */\n `${configPath}?${Date.now()}`\n )) as { default: FlatConfigArray }\n return module.default\n } catch {\n throw new Error(\n `eslint-config-setup: No pre-generated config found for options ${JSON.stringify(opts)}. ` +\n `Expected file: configs/${filename}. Run \"npm run generate\" in the package to build configs.`,\n )\n }\n}\n\n/**\n * Loads a pre-generated OxLint config from the hashed JSON file.\n * Only `react`, `node`, and `ai` flags are relevant — `oxlint` is ignored.\n */\nexport function getOxlintConfig(\n opts: OxlintConfigOptions = {},\n): OxlintConfigResult {\n const filename = oxlintOptionsToFilename(opts)\n const dirname = import.meta.dirname\n const configPath = path.join(dirname, \"oxlint-configs\", filename)\n\n try {\n const content = readFileSync(configPath, \"utf8\")\n return JSON.parse(content) as OxlintConfigResult\n } catch {\n throw new Error(\n `eslint-config-setup: No pre-generated OxLint config found for options ${JSON.stringify(opts)}. ` +\n `Expected file: oxlint-configs/${filename}. Run \"npm run generate\" in the package to build configs.`,\n )\n }\n}\n"],"mappings":";AASA,IAAM,gBAAgB;AAGtB,IAAM,iBAAyC;AAAA,EAC7C,SAAS;AACX;AAMA,SAAS,kBACP,OACA,OACS;AACT,QAAM,OAAO,MAAM;AACnB,MAAI,QAAQ,KAAM,QAAO;AACzB,QAAM,UAAU,eAAe,KAAK,KAAK;AACzC,QAAM,SAAS,GAAG,aAAa,GAAG,OAAO;AACzC,SAAO,SAAS,UAAU,KAAK,WAAW,GAAG,MAAM,GAAG;AACxD;AAKO,SAAS,gBACd,QACA,UACA,UACA,SACM;AACN,aAAW,SAAS,QAAQ;AAC1B,QAAI,SAAS,UAAU,UAAa,CAAC,kBAAkB,OAAO,QAAQ,KAAK,EAAG;AAC9E,QAAI,MAAM,QAAQ,QAAQ,KAAK,KAAM;AAErC,UAAM,UAAU,MAAM,MAAM,QAAQ;AACpC,QAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,YAAM,MAAM,QAAQ,IAAI,CAAC,UAAU,GAAG,QAAQ,MAAM,CAAC,CAAC;AAAA,IACxD,OAAO;AACL,YAAM,MAAM,QAAQ,IAAI;AAAA,IAC1B;AAAA,EACF;AACF;AAKO,SAAS,cACd,QACA,UACA,SACA,aACM;AACN,aAAW,SAAS,QAAQ;AAC1B,QAAI,aAAa,UAAU,UAAa,CAAC,kBAAkB,OAAO,YAAY,KAAK;AACjF;AACF,QAAI,MAAM,QAAQ,QAAQ,KAAK,KAAM;AAErC,UAAM,UAAU,MAAM,MAAM,QAAQ;AACpC,UAAM,WAAW,MAAM,QAAQ,OAAO,IAAI,QAAQ,CAAC,IAAI;AACvD,UAAM,MAAM,QAAQ,IAAI,CAAC,UAAU,GAAG,OAAO;AAAA,EAC/C;AACF;AAMO,SAAS,YACd,QACA,UACA,SACM;AACN,MAAI,SAAS,SAAS,MAAM;AAC1B,UAAM,EAAE,MAAM,IAAI;AAClB,UAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAC5D,QAAI,CAAC,MAAO;AACZ,UAAM,UAAU,CAAC;AACjB,UAAM,MAAM,QAAQ,IAAI;AACxB;AAAA,EACF;AAEA,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,QAAQ,QAAQ,KAAK,KAAM;AACrC,UAAM,MAAM,QAAQ,IAAI;AAAA,EAC1B;AACF;AAMO,SAAS,QACd,QACA,UACA,UACA,SACA,aACM;AAGN,MAAI;AACJ,MAAI;AAEJ,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,eAAW;AACX,gBAAY;AAAA,EACd,WAAW,WAAW,OAAO,YAAY,YAAY,WAAW,SAAS;AACvE,gBAAY;AAAA,EACd,WAAW,YAAY,QAAW;AAChC,gBAAY;AAAA,EACd;AAEA,MAAI;AACJ,MAAI,WAAW,SAAS,MAAM;AAC5B,UAAM,EAAE,MAAM,IAAI;AAClB,aAAS,OAAO,KAAK,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAAA,EACzD,OAAO;AACL,aAAS,OAAO,CAAC;AAAA,EACnB;AAEA,MAAI,CAAC,OAAQ;AAEb,SAAO,UAAU,CAAC;AAClB,SAAO,MAAM,QAAQ,IAAI,WACpB,CAAC,UAAU,GAAG,QAAQ,IACvB;AACN;AAKO,SAAS,mBACd,QACA,cACM;AACN,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,MAAM,MAAO;AAClB,eAAW,YAAY,OAAO,KAAK,MAAM,KAAK,GAAG;AAC/C,UAAI,aAAa,cAAc;AAC7B,cAAM,MAAM,QAAQ,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF;;;ACzJA,SAAS,kBAAkB;AAQpB,SAAS,iBAAiB,MAA6B;AAC5D,MAAI,OAAO;AACX,MAAI,KAAK,MAAO,SAAQ,KAAK;AAC7B,MAAI,KAAK,KAAM,SAAQ,KAAK;AAC5B,MAAI,KAAK,GAAI,SAAQ,KAAK;AAC1B,MAAI,KAAK,OAAQ,SAAQ,KAAK;AAC9B,SAAO;AACT;AAMO,SAAS,cAAc,MAAsB;AAClD,QAAM,QAAQ,2BAA2B,IAAI;AAC7C,SAAO,WAAW,MAAM,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AAClE;AAGO,SAAS,kBAAkB,MAA6B;AAC7D,SAAO,GAAG,cAAc,iBAAiB,IAAI,CAAC,CAAC;AACjD;AAoBO,SAAS,uBAAuB,MAAmC;AACxE,MAAI,OAAO;AACX,MAAI,KAAK,MAAO,SAAQ,KAAK;AAC7B,MAAI,KAAK,KAAM,SAAQ,KAAK;AAC5B,MAAI,KAAK,GAAI,SAAQ,KAAK;AAC1B,SAAO;AACT;AAGO,SAAS,oBAAoB,MAAsB;AACxD,QAAM,QAAQ,8BAA8B,IAAI;AAChD,SAAO,WAAW,MAAM,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AAClE;AAGO,SAAS,wBAAwB,MAAmC;AACzE,SAAO,GAAG,oBAAoB,uBAAuB,IAAI,CAAC,CAAC;AAC7D;;;ACjEA,SAAS,oBAAoB;AAC7B,OAAO,UAAU;AAUjB,eAAsB,gBACpB,OAAsB,CAAC,GACG;AAC1B,QAAM,WAAW,kBAAkB,IAAI;AACvC,QAAM,UAAU,YAAY;AAC5B,QAAM,aAAa,KAAK,KAAK,SAAS,WAAW,QAAQ;AAEzD,MAAI;AACF,UAAM,SAAU,MAAM;AAAA;AAAA,MAEpB,GAAG,UAAU,IAAI,KAAK,IAAI,CAAC;AAAA;AAE7B,WAAO,OAAO;AAAA,EAChB,QAAQ;AACN,UAAM,IAAI;AAAA,MACR,kEAAkE,KAAK,UAAU,IAAI,CAAC,4BAC1D,QAAQ;AAAA,IACtC;AAAA,EACF;AACF;AAMO,SAAS,gBACd,OAA4B,CAAC,GACT;AACpB,QAAM,WAAW,wBAAwB,IAAI;AAC7C,QAAM,UAAU,YAAY;AAC5B,QAAM,aAAa,KAAK,KAAK,SAAS,kBAAkB,QAAQ;AAEhE,MAAI;AACF,UAAM,UAAU,aAAa,YAAY,MAAM;AAC/C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI;AAAA,MACR,yEAAyE,KAAK,UAAU,IAAI,CAAC,mCAC1D,QAAQ;AAAA,IAC7C;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/api/rule-helpers.ts","../src/hash.ts","../src/loader.ts"],"sourcesContent":["/* eslint-disable max-params, complexity -- Public API: config + ruleName + severity + options is the natural signature. Options objects would hurt ergonomics for one-liner calls. */\nimport type { Linter } from \"eslint\"\n\nimport type {\n FlatConfigArray,\n RuleOptions,\n RuleSeverity,\n} from \"../types\"\n\nconst CONFIG_PREFIX = \"eslint-config-setup/\"\n\n/** Maps user-facing scope names to config block name segments. */\nconst SCOPE_TO_BLOCK: Record<string, string> = {\n configs: \"config-files\",\n}\n\n/**\n * Check if a config block matches a given scope.\n * A block matches if its name is `eslint-config-setup/{segment}` or starts with `eslint-config-setup/{segment}-`.\n */\nfunction blockMatchesScope(\n block: Linter.Config,\n scope: string,\n): boolean {\n const name = block.name\n if (name == null) return false\n const segment = SCOPE_TO_BLOCK[scope] ?? scope\n const target = `${CONFIG_PREFIX}${segment}`\n return name === target || name.startsWith(`${target}-`)\n}\n\n/**\n * Change the severity of a rule across all config blocks, preserving options.\n */\nexport function setRuleSeverity(\n config: FlatConfigArray,\n ruleName: string,\n severity: RuleSeverity,\n options?: RuleOptions,\n): void {\n for (const block of config) {\n if (options?.scope !== undefined && !blockMatchesScope(block, options.scope)) continue\n if (block.rules?.[ruleName] == null) continue\n\n const current = block.rules[ruleName]\n if (Array.isArray(current)) {\n block.rules[ruleName] = [severity, ...current.slice(1)] as Linter.RuleEntry\n } else {\n block.rules[ruleName] = severity\n }\n }\n}\n\n/**\n * Update the options of a rule across all config blocks, preserving severity.\n */\nexport function configureRule(\n config: FlatConfigArray,\n ruleName: string,\n options: unknown[],\n ruleOptions?: RuleOptions,\n): void {\n for (const block of config) {\n if (ruleOptions?.scope !== undefined && !blockMatchesScope(block, ruleOptions.scope))\n continue\n if (block.rules?.[ruleName] == null) continue\n\n const current = block.rules[ruleName]\n const severity = Array.isArray(current) ? current[0] : current\n block.rules[ruleName] = [severity, ...options] as Linter.RuleEntry\n }\n}\n\n/**\n * Completely disable a rule across all config blocks.\n * With scope: disables in the first matching block (creates entry if needed).\n */\nexport function disableRule(\n config: FlatConfigArray,\n ruleName: string,\n options?: RuleOptions,\n): void {\n if (options?.scope != null) {\n const { scope } = options\n const block = config.find((b) => blockMatchesScope(b, scope))\n if (!block) return\n block.rules ??= {}\n block.rules[ruleName] = \"off\"\n return\n }\n\n for (const block of config) {\n if (block.rules?.[ruleName] == null) continue\n block.rules[ruleName] = \"off\"\n }\n}\n\n/**\n * Add a new rule to the first (base) config block.\n * With scope: adds to the first matching block instead.\n */\nexport function addRule(\n config: FlatConfigArray,\n ruleName: string,\n severity: RuleSeverity,\n options?: RuleOptions | unknown[],\n ruleOptions?: RuleOptions,\n): void {\n // Handle overloaded signatures: addRule(config, rule, severity, options?, ruleOptions?)\n // When options is a plain object with scope, it's actually ruleOptions\n let ruleOpts: undefined | unknown[]\n let scopeOpts: RuleOptions | undefined\n\n if (Array.isArray(options)) {\n ruleOpts = options\n scopeOpts = ruleOptions\n } else if (options && typeof options === \"object\" && \"scope\" in options) {\n scopeOpts = options\n } else if (options === undefined) {\n scopeOpts = ruleOptions\n }\n\n let target: Linter.Config | undefined\n if (scopeOpts?.scope != null) {\n const { scope } = scopeOpts\n target = config.find((b) => blockMatchesScope(b, scope))\n } else {\n target = config[0]\n }\n\n if (!target) return\n\n target.rules ??= {}\n target.rules[ruleName] = ruleOpts\n ? ([severity, ...ruleOpts] as Linter.RuleEntry)\n : severity\n}\n\n/**\n * Disable all rules except the specified one — useful for debugging.\n */\nexport function disableAllRulesBut(\n config: FlatConfigArray,\n keepRuleName: string,\n): void {\n for (const block of config) {\n if (!block.rules) continue\n for (const ruleName of Object.keys(block.rules)) {\n if (ruleName !== keepRuleName) {\n block.rules[ruleName] = \"off\"\n }\n }\n }\n}\n","import { createHash } from \"node:crypto\"\n\nimport type { ConfigOptions, OxlintConfigOptions } from \"./types\"\n\n/**\n * Converts config options to a deterministic bitmask.\n * Bit order is fixed and must never change (would break published configs).\n */\nexport function optionsToBitmask(opts: ConfigOptions): number {\n let mask = 0\n if (opts.react) mask |= 1 << 0\n if (opts.node) mask |= 1 << 1\n if (opts.ai) mask |= 1 << 2\n if (opts.oxlint) mask |= 1 << 3\n return mask\n}\n\n/**\n * Converts a bitmask to a short deterministic hash (8 hex chars).\n * The same hash is produced at build-time (generate) and run-time (getConfig).\n */\nexport function bitmaskToHash(mask: number): string {\n const input = `effective-eslint-config:${mask}`\n return createHash(\"sha1\").update(input).digest(\"hex\").slice(0, 8)\n}\n\n/** Convenience: options → filename (without path prefix). */\nexport function optionsToFilename(opts: ConfigOptions): string {\n return `${bitmaskToHash(optionsToBitmask(opts))}.js`\n}\n\n/** Total number of permutations (2^4 = 16). */\nexport const TOTAL_PERMUTATIONS = 16\n\n/** Iterate all possible option combinations. */\nexport function* allPermutations(): Generator<ConfigOptions> {\n for (let mask = 0; mask < TOTAL_PERMUTATIONS; mask++) {\n yield {\n react: Boolean(mask & (1 << 0)),\n node: Boolean(mask & (1 << 1)),\n ai: Boolean(mask & (1 << 2)),\n oxlint: Boolean(mask & (1 << 3)),\n }\n }\n}\n\n// --- OxLint config permutations (3 flags → 8 combos) ---\n\n/** Converts OxLint-relevant options to a 3-bit bitmask (react, node, ai). */\nexport function oxlintOptionsToBitmask(opts: OxlintConfigOptions): number {\n let mask = 0\n if (opts.react) mask |= 1 << 0\n if (opts.node) mask |= 1 << 1\n if (opts.ai) mask |= 1 << 2\n return mask\n}\n\n/** Deterministic hash for OxLint configs (different salt to avoid collisions). */\nexport function oxlintBitmaskToHash(mask: number): string {\n const input = `eslint-config-setup-oxlint:${mask}`\n return createHash(\"sha1\").update(input).digest(\"hex\").slice(0, 8)\n}\n\n/** OxLint options → filename (without path prefix). */\nexport function oxlintOptionsToFilename(opts: OxlintConfigOptions): string {\n return `${oxlintBitmaskToHash(oxlintOptionsToBitmask(opts))}.json`\n}\n\n/** Total number of OxLint permutations (2^3 = 8). */\nexport const TOTAL_OXLINT_PERMUTATIONS = 8\n\n/** Iterate all OxLint option combinations. */\nexport function* allOxlintPermutations(): Generator<OxlintConfigOptions> {\n for (let mask = 0; mask < TOTAL_OXLINT_PERMUTATIONS; mask++) {\n yield {\n react: Boolean(mask & (1 << 0)),\n node: Boolean(mask & (1 << 1)),\n ai: Boolean(mask & (1 << 2)),\n }\n }\n}\n","/* eslint-disable security/detect-non-literal-fs-filename, @typescript-eslint/no-unsafe-type-assertion -- Paths are computed from deterministic hashes in dist/, not from user input. */\nimport { existsSync, readFileSync } from \"node:fs\"\nimport path from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\n\nimport type { ConfigOptions, FlatConfigArray, OxlintConfigOptions, OxlintConfigResult } from \"./types\"\n\nimport { optionsToFilename, oxlintOptionsToFilename } from \"./hash\"\n\n/**\n * Loads a pre-generated ESLint config by dynamically importing the hashed file.\n * The hash is computed from the options using the same algorithm as the build.\n */\nexport async function getEslintConfig(\n opts: ConfigOptions = {},\n): Promise<FlatConfigArray> {\n const filename = optionsToFilename(opts)\n const dirname = import.meta.dirname\n const configPath = path.join(dirname, \"configs\", filename)\n\n if (!existsSync(configPath)) {\n throwMissingConfigError(opts, filename)\n }\n\n const configUrl = pathToFileURL(configPath)\n configUrl.search = String(Date.now())\n\n try {\n const module = (await import(\n /* webpackIgnore: true */\n configUrl.href\n )) as { default: FlatConfigArray }\n return module.default\n } catch (error) {\n if (!existsSync(configPath)) {\n throwMissingConfigError(opts, filename, error)\n }\n\n throw new Error(\n `eslint-config-setup: Pre-generated config failed to load for options ${JSON.stringify(opts)}. ` +\n `Expected file: configs/${filename}. Original error: ${getErrorMessage(error)}`,\n { cause: error },\n )\n }\n}\n\n/**\n * Loads a pre-generated OxLint config from the hashed JSON file.\n * Only `react`, `node`, and `ai` flags are relevant — `oxlint` is ignored.\n */\nexport function getOxlintConfig(\n opts: OxlintConfigOptions = {},\n): OxlintConfigResult {\n const filename = oxlintOptionsToFilename(opts)\n const dirname = import.meta.dirname\n const configPath = path.join(dirname, \"oxlint-configs\", filename)\n\n try {\n const content = readFileSync(configPath, \"utf8\")\n return JSON.parse(content) as OxlintConfigResult\n } catch {\n throw new Error(\n `eslint-config-setup: No pre-generated OxLint config found for options ${JSON.stringify(opts)}. ` +\n `Expected file: oxlint-configs/${filename}. Run \"npm run generate\" in the package to build configs.`,\n )\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nfunction throwMissingConfigError(\n opts: ConfigOptions,\n filename: string,\n cause?: unknown,\n): never {\n const message =\n `eslint-config-setup: No pre-generated config found for options ${JSON.stringify(opts)}. ` +\n `Expected file: configs/${filename}. Run \"npm run generate\" in the package to build configs.`\n\n if (cause === undefined) {\n throw new Error(message)\n }\n\n throw new Error(message, { cause })\n}\n"],"mappings":";AASA,IAAM,gBAAgB;AAGtB,IAAM,iBAAyC;AAAA,EAC7C,SAAS;AACX;AAMA,SAAS,kBACP,OACA,OACS;AACT,QAAM,OAAO,MAAM;AACnB,MAAI,QAAQ,KAAM,QAAO;AACzB,QAAM,UAAU,eAAe,KAAK,KAAK;AACzC,QAAM,SAAS,GAAG,aAAa,GAAG,OAAO;AACzC,SAAO,SAAS,UAAU,KAAK,WAAW,GAAG,MAAM,GAAG;AACxD;AAKO,SAAS,gBACd,QACA,UACA,UACA,SACM;AACN,aAAW,SAAS,QAAQ;AAC1B,QAAI,SAAS,UAAU,UAAa,CAAC,kBAAkB,OAAO,QAAQ,KAAK,EAAG;AAC9E,QAAI,MAAM,QAAQ,QAAQ,KAAK,KAAM;AAErC,UAAM,UAAU,MAAM,MAAM,QAAQ;AACpC,QAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,YAAM,MAAM,QAAQ,IAAI,CAAC,UAAU,GAAG,QAAQ,MAAM,CAAC,CAAC;AAAA,IACxD,OAAO;AACL,YAAM,MAAM,QAAQ,IAAI;AAAA,IAC1B;AAAA,EACF;AACF;AAKO,SAAS,cACd,QACA,UACA,SACA,aACM;AACN,aAAW,SAAS,QAAQ;AAC1B,QAAI,aAAa,UAAU,UAAa,CAAC,kBAAkB,OAAO,YAAY,KAAK;AACjF;AACF,QAAI,MAAM,QAAQ,QAAQ,KAAK,KAAM;AAErC,UAAM,UAAU,MAAM,MAAM,QAAQ;AACpC,UAAM,WAAW,MAAM,QAAQ,OAAO,IAAI,QAAQ,CAAC,IAAI;AACvD,UAAM,MAAM,QAAQ,IAAI,CAAC,UAAU,GAAG,OAAO;AAAA,EAC/C;AACF;AAMO,SAAS,YACd,QACA,UACA,SACM;AACN,MAAI,SAAS,SAAS,MAAM;AAC1B,UAAM,EAAE,MAAM,IAAI;AAClB,UAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAC5D,QAAI,CAAC,MAAO;AACZ,UAAM,UAAU,CAAC;AACjB,UAAM,MAAM,QAAQ,IAAI;AACxB;AAAA,EACF;AAEA,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,QAAQ,QAAQ,KAAK,KAAM;AACrC,UAAM,MAAM,QAAQ,IAAI;AAAA,EAC1B;AACF;AAMO,SAAS,QACd,QACA,UACA,UACA,SACA,aACM;AAGN,MAAI;AACJ,MAAI;AAEJ,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,eAAW;AACX,gBAAY;AAAA,EACd,WAAW,WAAW,OAAO,YAAY,YAAY,WAAW,SAAS;AACvE,gBAAY;AAAA,EACd,WAAW,YAAY,QAAW;AAChC,gBAAY;AAAA,EACd;AAEA,MAAI;AACJ,MAAI,WAAW,SAAS,MAAM;AAC5B,UAAM,EAAE,MAAM,IAAI;AAClB,aAAS,OAAO,KAAK,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAAA,EACzD,OAAO;AACL,aAAS,OAAO,CAAC;AAAA,EACnB;AAEA,MAAI,CAAC,OAAQ;AAEb,SAAO,UAAU,CAAC;AAClB,SAAO,MAAM,QAAQ,IAAI,WACpB,CAAC,UAAU,GAAG,QAAQ,IACvB;AACN;AAKO,SAAS,mBACd,QACA,cACM;AACN,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,MAAM,MAAO;AAClB,eAAW,YAAY,OAAO,KAAK,MAAM,KAAK,GAAG;AAC/C,UAAI,aAAa,cAAc;AAC7B,cAAM,MAAM,QAAQ,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF;;;ACzJA,SAAS,kBAAkB;AAQpB,SAAS,iBAAiB,MAA6B;AAC5D,MAAI,OAAO;AACX,MAAI,KAAK,MAAO,SAAQ,KAAK;AAC7B,MAAI,KAAK,KAAM,SAAQ,KAAK;AAC5B,MAAI,KAAK,GAAI,SAAQ,KAAK;AAC1B,MAAI,KAAK,OAAQ,SAAQ,KAAK;AAC9B,SAAO;AACT;AAMO,SAAS,cAAc,MAAsB;AAClD,QAAM,QAAQ,2BAA2B,IAAI;AAC7C,SAAO,WAAW,MAAM,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AAClE;AAGO,SAAS,kBAAkB,MAA6B;AAC7D,SAAO,GAAG,cAAc,iBAAiB,IAAI,CAAC,CAAC;AACjD;AAoBO,SAAS,uBAAuB,MAAmC;AACxE,MAAI,OAAO;AACX,MAAI,KAAK,MAAO,SAAQ,KAAK;AAC7B,MAAI,KAAK,KAAM,SAAQ,KAAK;AAC5B,MAAI,KAAK,GAAI,SAAQ,KAAK;AAC1B,SAAO;AACT;AAGO,SAAS,oBAAoB,MAAsB;AACxD,QAAM,QAAQ,8BAA8B,IAAI;AAChD,SAAO,WAAW,MAAM,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AAClE;AAGO,SAAS,wBAAwB,MAAmC;AACzE,SAAO,GAAG,oBAAoB,uBAAuB,IAAI,CAAC,CAAC;AAC7D;;;ACjEA,SAAS,YAAY,oBAAoB;AACzC,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAU9B,eAAsB,gBACpB,OAAsB,CAAC,GACG;AAC1B,QAAM,WAAW,kBAAkB,IAAI;AACvC,QAAM,UAAU,YAAY;AAC5B,QAAM,aAAa,KAAK,KAAK,SAAS,WAAW,QAAQ;AAEzD,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,4BAAwB,MAAM,QAAQ;AAAA,EACxC;AAEA,QAAM,YAAY,cAAc,UAAU;AAC1C,YAAU,SAAS,OAAO,KAAK,IAAI,CAAC;AAEpC,MAAI;AACF,UAAM,SAAU,MAAM;AAAA;AAAA,MAEpB,UAAU;AAAA;AAEZ,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,QAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,8BAAwB,MAAM,UAAU,KAAK;AAAA,IAC/C;AAEA,UAAM,IAAI;AAAA,MACR,wEAAwE,KAAK,UAAU,IAAI,CAAC,4BAChE,QAAQ,qBAAqB,gBAAgB,KAAK,CAAC;AAAA,MAC/E,EAAE,OAAO,MAAM;AAAA,IACjB;AAAA,EACF;AACF;AAMO,SAAS,gBACd,OAA4B,CAAC,GACT;AACpB,QAAM,WAAW,wBAAwB,IAAI;AAC7C,QAAM,UAAU,YAAY;AAC5B,QAAM,aAAa,KAAK,KAAK,SAAS,kBAAkB,QAAQ;AAEhE,MAAI;AACF,UAAM,UAAU,aAAa,YAAY,MAAM;AAC/C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI;AAAA,MACR,yEAAyE,KAAK,UAAU,IAAI,CAAC,mCAC1D,QAAQ;AAAA,IAC7C;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,wBACP,MACA,UACA,OACO;AACP,QAAM,UACJ,kEAAkE,KAAK,UAAU,IAAI,CAAC,4BAC5D,QAAQ;AAEpC,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AAEA,QAAM,IAAI,MAAM,SAAS,EAAE,MAAM,CAAC;AACpC;","names":[]}
|
package/dist/modules.d.ts
CHANGED
|
@@ -161,16 +161,18 @@ declare function prettierCompatConfig(): FlatConfigArray;
|
|
|
161
161
|
/**
|
|
162
162
|
* React config — React 19+, Hooks, JSX accessibility, and Web API leak detection.
|
|
163
163
|
*
|
|
164
|
-
* Uses `@eslint-react` (eslint-plugin-react-x)
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
164
|
+
* Uses `@eslint-react` (eslint-plugin-react-x) for React, DOM, Web API,
|
|
165
|
+
* naming-convention, and RSC rules under the `react/` compat namespace.
|
|
166
|
+
* Rules of Hooks and React Compiler linting come from Meta's
|
|
167
|
+
* eslint-plugin-react-hooks under the native `react-hooks/` namespace.
|
|
168
168
|
*
|
|
169
|
-
* Base
|
|
170
|
-
*
|
|
171
|
-
*
|
|
169
|
+
* Base React severities come from the `@eslint-react` `strict-type-checked` preset.
|
|
170
|
+
* When `ai: true`, preset "warn" rules that AI should always get right are
|
|
171
|
+
* promoted to "error", and React performance rules are enabled as errors.
|
|
172
172
|
*
|
|
173
173
|
* @see https://eslint-react.xyz/docs/rules/overview
|
|
174
|
+
* @see https://www.npmjs.com/package/eslint-plugin-react-hooks
|
|
175
|
+
* @see https://github.com/cvazac/eslint-plugin-react-perf
|
|
174
176
|
* @see https://github.com/ArnaudBarre/eslint-plugin-react-refresh
|
|
175
177
|
* @see https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules
|
|
176
178
|
*/
|