eslint-config-setup 0.2.7 → 0.3.0

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/dist/modules.js CHANGED
@@ -128,7 +128,7 @@ function aiConfig() {
128
128
  allowExpressions: true,
129
129
  allowTypedFunctionExpressions: true,
130
130
  allowHigherOrderFunctions: true,
131
- allowIIFE: true
131
+ allowIIFEs: true
132
132
  }
133
133
  ],
134
134
  // Enforce consistent naming: camelCase for values, PascalCase for types,
@@ -294,9 +294,6 @@ function aiConfig() {
294
294
  name: "eslint-config-setup/ai-unicorn",
295
295
  rules: {
296
296
  // ── D. Unicorn — modern, idiomatic patterns ───────────────────
297
- // Prefer early return over deeply nested if/else — flattens logic
298
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-early-return.md
299
- "unicorn/prefer-early-return": "error",
300
297
  // Move functions to the smallest scope where they're used
301
298
  // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-function-scoping.md
302
299
  "unicorn/consistent-function-scoping": "error",
@@ -392,7 +389,7 @@ function aiConfig() {
392
389
  "sonarjs/no-nested-template-literals": "error",
393
390
  // Limit union type size — too many members signals missing abstraction
394
391
  // https://sonarsource.github.io/rspec/#/rspec/S4622/javascript
395
- "sonarjs/max-union-size": ["error", { max: 5 }],
392
+ "sonarjs/max-union-size": ["error", { threshold: 5 }],
396
393
  // Prefer type predicates for type narrowing — safer than assertions
397
394
  // https://sonarsource.github.io/rspec/#/rspec/S4322/javascript
398
395
  "sonarjs/prefer-type-guard": "error",
@@ -446,12 +443,6 @@ function aiConfig() {
446
443
  {
447
444
  name: "eslint-config-setup/ai-react",
448
445
  rules: {
449
- // Max one component per file — clear module boundaries
450
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md
451
- "react/no-multi-comp": "error",
452
- // No inline function creation in JSX props — extract to variable or useCallback
453
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
454
- "react/jsx-no-bind": "error",
455
446
  // No click handlers on static elements without role — use semantic HTML
456
447
  // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-static-element-interactions.md
457
448
  "jsx-a11y/no-static-element-interactions": "error",
@@ -1127,12 +1118,15 @@ function prettierCompatConfig() {
1127
1118
  }
1128
1119
 
1129
1120
  // src/configs/react.ts
1121
+ import eslintReactPlugin from "@eslint-react/eslint-plugin";
1122
+ import stylisticPlugin from "@stylistic/eslint-plugin";
1130
1123
  import jsxA11yPlugin from "eslint-plugin-jsx-a11y";
1131
- import reactPlugin from "eslint-plugin-react";
1132
1124
  import reactHooksPlugin from "eslint-plugin-react-hooks";
1133
1125
  import reactRefreshPlugin from "eslint-plugin-react-refresh";
1134
1126
  import globals2 from "globals";
1135
1127
  function reactConfig() {
1128
+ const reactDomPlugin = eslintReactPlugin.configs.dom.plugins;
1129
+ const reactWebApiPlugin = eslintReactPlugin.configs["web-api"].plugins;
1136
1130
  return [
1137
1131
  {
1138
1132
  name: "eslint-config-setup/react",
@@ -1147,133 +1141,127 @@ function reactConfig() {
1147
1141
  }
1148
1142
  },
1149
1143
  plugins: {
1150
- react: reactPlugin,
1144
+ // @eslint-react core → registered as "react" (like import-x → "import")
1145
+ react: eslintReactPlugin,
1146
+ // @eslint-react/dom → registered as "react-dom"
1147
+ "react-dom": reactDomPlugin["@eslint-react/dom"],
1148
+ // @eslint-react/web-api → registered as "react-web-api"
1149
+ "react-web-api": reactWebApiPlugin["@eslint-react/web-api"],
1150
+ // eslint-plugin-react-hooks stays as-is
1151
1151
  "react-hooks": reactHooksPlugin,
1152
+ "@stylistic": stylisticPlugin,
1152
1153
  "react-refresh": reactRefreshPlugin,
1153
1154
  "jsx-a11y": jsxA11yPlugin
1154
1155
  },
1155
- settings: {
1156
- react: {
1157
- version: "detect"
1158
- }
1159
- },
1160
1156
  rules: {
1161
- // ── React core ────────────────────────────────────────────────
1162
- // Prevent unsafe target="_blank" linksrequires rel="noreferrer"
1163
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md
1164
- "react/jsx-no-target-blank": "error",
1165
- // Prevent usage of undefined JSX components — catches typos
1166
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md
1167
- "react/jsx-no-undef": "error",
1168
- // OFF: Not needed with React 17+ automatic JSX transform
1169
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
1170
- "react/jsx-uses-react": "off",
1171
- // OFF: Not needed with React 17+ automatic JSX transform
1172
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md
1173
- "react/react-in-jsx-scope": "off",
1174
- // Warn on dangerouslySetInnerHTML — XSS risk, should be reviewed
1175
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger.md
1176
- "react/no-danger": "warn",
1177
- // Prevent usage of deprecated React APIs — stay current
1178
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-deprecated.md
1179
- "react/no-deprecated": "error",
1157
+ // ── React core (react/) ─────────────────────────────────────────
1158
+ // Prevent passing children as a prop use JSX children syntax instead
1159
+ // https://eslint-react.xyz/docs/rules/no-children-prop
1160
+ "react/no-children-prop": "error",
1180
1161
  // Prevent direct mutation of this.state — use setState instead
1181
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md
1162
+ // https://eslint-react.xyz/docs/rules/no-direct-mutation-state
1182
1163
  "react/no-direct-mutation-state": "error",
1183
- // Prevent unknown DOM properties (e.g., class → className)
1184
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md
1185
- "react/no-unknown-property": "error",
1186
1164
  // Prevent unstable nested component definitions — causes remounts
1187
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unstable-nested-components.md
1188
- "react/no-unstable-nested-components": "error",
1189
- // Prevent passing children as a prop use JSX children syntax instead
1190
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-children-prop.md
1191
- "react/no-children-prop": "error",
1192
- // Enforce self-closing tags for components without children — <Foo />
1193
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md
1194
- "react/self-closing-comp": "error",
1195
- // Prevent void DOM elements (br, img, hr) from having children
1196
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/void-dom-elements-no-children.md
1197
- "react/void-dom-elements-no-children": "error",
1198
- // OFF: TypeScript handles prop validation
1199
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prop-types.md
1200
- "react/prop-types": "off",
1201
- // Require key prop in iterators — including fragment shorthand
1202
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-key.md
1203
- "react/jsx-key": ["error", { checkFragmentShorthand: true }],
1165
+ // https://eslint-react.xyz/docs/rules/no-nested-component-definitions
1166
+ "react/no-nested-component-definitions": "error",
1167
+ // Require key prop in iteratorsprevent reconciliation bugs
1168
+ // https://eslint-react.xyz/docs/rules/no-missing-key
1169
+ "react/no-missing-key": "error",
1170
+ // Prevent duplicate key props in iterators
1171
+ // https://eslint-react.xyz/docs/rules/no-duplicate-key
1172
+ "react/no-duplicate-key": "error",
1204
1173
  // Prevent comments from being inserted as text nodes in JSX
1205
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-comment-textnodes.md
1174
+ // https://eslint-react.xyz/docs/rules/jsx-no-comment-textnodes
1206
1175
  "react/jsx-no-comment-textnodes": "error",
1207
- // Prevent duplicate props — always a bug
1208
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-duplicate-props.md
1209
- "react/jsx-no-duplicate-props": "error",
1210
1176
  // Remove unnecessary JSX fragments — <>{x}</> → {x}
1211
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-useless-fragment.md
1212
- "react/jsx-no-useless-fragment": ["error", { allowExpressions: true }],
1213
- // Enforce PascalCase for component names — React convention
1214
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md
1215
- "react/jsx-pascal-case": "error",
1177
+ // https://eslint-react.xyz/docs/rules/no-useless-fragment
1178
+ "react/no-useless-fragment": "error",
1216
1179
  // Prefer <Foo active /> over <Foo active={true} /> — concise
1217
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md
1218
- "react/jsx-boolean-value": ["error", "never"],
1219
- // Prevent unnecessary string curly braces: title={"foo"} → title="foo"
1220
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-brace-presence.md
1221
- "react/jsx-curly-brace-presence": [
1222
- "error",
1223
- { props: "never", children: "never" }
1224
- ],
1225
- // Enforce function declarations for named components, arrows for unnamed
1226
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/function-component-definition.md
1227
- "react/function-component-definition": [
1228
- "error",
1229
- {
1230
- namedComponents: "function-declaration",
1231
- unnamedComponents: "arrow-function"
1232
- }
1233
- ],
1234
- // Enforce destructured useState naming: const [foo, setFoo] = useState()
1235
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/hook-use-state.md
1236
- "react/hook-use-state": "error",
1237
- // Require sandbox attribute on iframes — security best practice
1238
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/iframe-missing-sandbox.md
1239
- "react/iframe-missing-sandbox": "error",
1180
+ // https://eslint-react.xyz/docs/rules/jsx-shorthand-boolean
1181
+ "react/jsx-shorthand-boolean": "error",
1240
1182
  // Prevent using array index as key — breaks reconciliation on reorder
1241
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md
1183
+ // https://eslint-react.xyz/docs/rules/no-array-index-key
1242
1184
  "react/no-array-index-key": "error",
1243
1185
  // Prevent object/array literals as default props — creates new reference every render
1244
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-object-type-as-default-prop.md
1245
- "react/no-object-type-as-default-prop": "error",
1186
+ // https://eslint-react.xyz/docs/rules/no-unstable-default-props
1187
+ "react/no-unstable-default-props": "error",
1246
1188
  // Prevent `{count && <Foo />}` — renders "0" when count is 0
1247
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-leaked-render.md
1248
- "react/jsx-no-leaked-render": "error",
1189
+ // https://eslint-react.xyz/docs/rules/no-leaked-conditional-rendering
1190
+ "react/no-leaked-conditional-rendering": "error",
1249
1191
  // Prevent inline object creation in context providers — causes re-renders
1250
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-constructed-context-values.md
1251
- "react/jsx-no-constructed-context-values": "error",
1192
+ // https://eslint-react.xyz/docs/rules/no-unstable-context-value
1193
+ "react/no-unstable-context-value": "error",
1252
1194
  // Prevent `this.setState({ count: this.state.count + 1 })` — race condition
1253
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-access-state-in-setstate.md
1195
+ // https://eslint-react.xyz/docs/rules/no-access-state-in-setstate
1254
1196
  "react/no-access-state-in-setstate": "error",
1255
1197
  // Detect state properties that are set but never read — dead code
1256
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-state.md
1198
+ // https://eslint-react.xyz/docs/rules/no-unused-state
1257
1199
  "react/no-unused-state": "error",
1200
+ // ── React 19 migration rules ────────────────────────────────────
1201
+ // React 19: Use <Context> instead of <Context.Provider>
1202
+ // https://eslint-react.xyz/docs/rules/no-context-provider
1203
+ "react/no-context-provider": "error",
1204
+ // React 19: Use ref as prop instead of forwardRef
1205
+ // https://eslint-react.xyz/docs/rules/no-forward-ref
1206
+ "react/no-forward-ref": "error",
1207
+ // React 19: Use use() instead of useContext()
1208
+ // https://eslint-react.xyz/docs/rules/no-use-context
1209
+ "react/no-use-context": "error",
1210
+ // ── React DOM (react-dom/) ──────────────────────────────────────
1211
+ // Prevent unsafe target="_blank" links — requires rel="noreferrer"
1212
+ // https://eslint-react.xyz/docs/rules/dom-no-unsafe-target-blank
1213
+ "react-dom/no-unsafe-target-blank": "error",
1214
+ // Prevent unknown DOM properties (e.g., class → className)
1215
+ // https://eslint-react.xyz/docs/rules/dom-no-unknown-property
1216
+ "react-dom/no-unknown-property": "error",
1217
+ // Prevent void DOM elements (br, img, hr) from having children
1218
+ // https://eslint-react.xyz/docs/rules/dom-no-void-elements-with-children
1219
+ "react-dom/no-void-elements-with-children": "error",
1220
+ // Require sandbox attribute on iframes — security best practice
1221
+ // https://eslint-react.xyz/docs/rules/dom-no-missing-iframe-sandbox
1222
+ "react-dom/no-missing-iframe-sandbox": "error",
1258
1223
  // Prevent `style="color: red"` — must be an object in React
1259
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/style-prop-object.md
1260
- "react/style-prop-object": "error",
1261
- // No string refs — deprecated since React 16.3, use useRef
1262
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md
1263
- "react/no-string-refs": "error",
1224
+ // https://eslint-react.xyz/docs/rules/dom-no-string-style-prop
1225
+ "react-dom/no-string-style-prop": "error",
1264
1226
  // Require explicit type on <button> — prevents unintended form submits
1265
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/button-has-type.md
1266
- "react/button-has-type": "error",
1227
+ // https://eslint-react.xyz/docs/rules/dom-no-missing-button-type
1228
+ "react-dom/no-missing-button-type": "error",
1267
1229
  // Prevent dangerouslySetInnerHTML + children at the same time — conflict
1268
- // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger-with-children.md
1269
- "react/no-danger-with-children": "error",
1270
- // ── React Hooks ───────────────────────────────────────────────
1230
+ // https://eslint-react.xyz/docs/rules/dom-no-dangerously-set-innerhtml-with-children
1231
+ "react-dom/no-dangerously-set-innerhtml-with-children": "error",
1232
+ // Warn on dangerouslySetInnerHTML — XSS risk, should be reviewed
1233
+ // https://eslint-react.xyz/docs/rules/dom-no-dangerously-set-innerhtml
1234
+ "react-dom/no-dangerously-set-innerhtml": "warn",
1235
+ // ── React Web API (react-web-api/) — cleanup leak detection ─────
1236
+ // Require cleanup for addEventListener in effects
1237
+ // https://eslint-react.xyz/docs/rules/web-api-no-leaked-event-listener
1238
+ "react-web-api/no-leaked-event-listener": "error",
1239
+ // Require cleanup for setInterval in effects
1240
+ // https://eslint-react.xyz/docs/rules/web-api-no-leaked-interval
1241
+ "react-web-api/no-leaked-interval": "error",
1242
+ // Require cleanup for setTimeout in effects
1243
+ // https://eslint-react.xyz/docs/rules/web-api-no-leaked-timeout
1244
+ "react-web-api/no-leaked-timeout": "error",
1245
+ // Require cleanup for ResizeObserver in effects
1246
+ // https://eslint-react.xyz/docs/rules/web-api-no-leaked-resize-observer
1247
+ "react-web-api/no-leaked-resize-observer": "error",
1248
+ // ── React Hooks (react-hooks/) — eslint-plugin-react-hooks ──────
1271
1249
  // Enforce Rules of Hooks — hooks must be called at the top level
1272
1250
  // https://react.dev/reference/rules/rules-of-hooks
1273
1251
  "react-hooks/rules-of-hooks": "error",
1274
1252
  // Verify dependency arrays in useEffect/useMemo/useCallback
1275
1253
  // https://react.dev/reference/react/useEffect#specifying-reactive-dependencies
1276
1254
  "react-hooks/exhaustive-deps": "error",
1255
+ // ── @stylistic — JSX formatting rules ───────────────────────────
1256
+ // Enforce self-closing tags for components without children — <Foo />
1257
+ // https://eslint.style/rules/jsx/jsx-self-closing-comp
1258
+ "@stylistic/jsx-self-closing-comp": "error",
1259
+ // Prevent unnecessary string curly braces: title={"foo"} → title="foo"
1260
+ // https://eslint.style/rules/jsx/jsx-curly-brace-presence
1261
+ "@stylistic/jsx-curly-brace-presence": [
1262
+ "error",
1263
+ { props: "never", children: "never" }
1264
+ ],
1277
1265
  // ── React Refresh (Fast Refresh / HMR) ────────────────────────
1278
1266
  // Ensure components are exported in a way that supports Fast Refresh.
1279
1267
  // Mixed exports (component + constants) break HMR state preservation.
@@ -1283,11 +1271,6 @@ function reactConfig() {
1283
1271
  "warn",
1284
1272
  { allowConstantExport: true }
1285
1273
  ],
1286
- // ── React Compiler (via react-hooks >= 7.0) ─────────────────────
1287
- // Validates code is compatible with React Compiler's auto-memoization
1288
- // Merged into react-hooks since React Compiler v1.0 (Oct 2025)
1289
- // https://react.dev/learn/react-compiler
1290
- "react-hooks/react-compiler": "error",
1291
1274
  // ── JSX Accessibility (a11y) ──────────────────────────────────
1292
1275
  // Require alt text on img, area, input[type="image"], object
1293
1276
  // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/alt-text.md