@tb-dev/eslint-config 6.0.7 → 6.1.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 CHANGED
@@ -1,6 +1,3 @@
1
1
  # @tb-dev/eslint-config
2
2
 
3
3
  Opinionated config for ESLint.
4
-
5
- - TypeScript only.
6
- - Optional Vue support.
package/dist/index.cjs CHANGED
@@ -41,6 +41,10 @@ function isEnabled(config, feature) {
41
41
  return config?.perfectionist ?? true;
42
42
  case "react":
43
43
  return config?.react ?? false;
44
+ case "reactCompiler":
45
+ return config?.reactCompiler ?? config?.react ?? false;
46
+ case "reactHooks":
47
+ return config?.reactHooks ?? config?.react ?? false;
44
48
  case "svelte":
45
49
  return config?.svelte ?? false;
46
50
  case "tailwind":
@@ -289,6 +293,55 @@ async function vue(options) {
289
293
  ];
290
294
  }
291
295
 
296
+ async function react(options) {
297
+ if (!isEnabled(options.features, "react")) return {};
298
+ const plugin = await interopDefault(import('eslint-plugin-react'));
299
+ return {
300
+ plugins: { react: plugin },
301
+ rules: {
302
+ "react/button-has-type": "error",
303
+ "react/function-component-definition": [
304
+ "error",
305
+ {
306
+ namedComponents: "function-expression",
307
+ unnamedComponents: "function-expression"
308
+ }
309
+ ],
310
+ "react/hook-use-state": ["error", { allowDestructuredState: true }],
311
+ "react/jsx-boolean-value": ["error", "never", { assumeUndefinedIsFalse: true }],
312
+ "react/jsx-key": [
313
+ "error",
314
+ {
315
+ checkFragmentShorthand: true,
316
+ checkKeyMustBeforeSpread: false,
317
+ warnOnDuplicates: true
318
+ }
319
+ ],
320
+ "react/jsx-no-script-url": "error",
321
+ "react/jsx-no-useless-fragment": "error",
322
+ "react/jsx-pascal-case": [
323
+ "error",
324
+ {
325
+ allowAllCaps: false,
326
+ allowNamespace: true,
327
+ allowLeadingUnderscore: false
328
+ }
329
+ ],
330
+ "react/jsx-props-no-spread-multi": "error",
331
+ "react/no-access-state-in-setstate": "error",
332
+ "react/no-array-index-key": "error",
333
+ "react/no-danger": "error",
334
+ "react/no-deprecated": "error",
335
+ "react/no-direct-mutation-state": "error",
336
+ "react/no-find-dom-node": "error",
337
+ "react/no-is-mounted": "error",
338
+ "react/no-render-return-value": "error",
339
+ "react/no-unsafe": "error",
340
+ ...options.overrides?.react
341
+ }
342
+ };
343
+ }
344
+
292
345
  async function svelte(options) {
293
346
  if (!isEnabled(options.features, "svelte")) return [];
294
347
  const [sveltePlugin, svelteParser, tsParser] = await Promise.all([
@@ -868,6 +921,19 @@ async function typescript(options) {
868
921
  };
869
922
  }
870
923
 
924
+ async function reactHooks(options) {
925
+ if (!isEnabled(options.features, "react")) return {};
926
+ const plugin = await interopDefault(import('eslint-plugin-react-hooks'));
927
+ return {
928
+ plugins: { "react-hooks": plugin },
929
+ rules: {
930
+ "react-hooks/rules-of-hooks": "error",
931
+ "react-hooks/exhaustive-deps": "error",
932
+ ...options.overrides?.reactHooks
933
+ }
934
+ };
935
+ }
936
+
871
937
  async function perfectionist(options) {
872
938
  if (!isEnabled(options.features, "perfectionist")) return {};
873
939
  const plugin = await interopDefault(import('eslint-plugin-perfectionist'));
@@ -968,6 +1034,18 @@ async function perfectionist(options) {
968
1034
  };
969
1035
  }
970
1036
 
1037
+ async function reactCompiler(options) {
1038
+ if (!isEnabled(options.features, "react")) return {};
1039
+ const plugin = await interopDefault(import('eslint-plugin-react-compiler'));
1040
+ return {
1041
+ plugins: { "react-compiler": plugin },
1042
+ rules: {
1043
+ "react-compiler/react-compiler": "error",
1044
+ ...options.overrides?.reactCompiler
1045
+ }
1046
+ };
1047
+ }
1048
+
971
1049
  async function defineConfig(options) {
972
1050
  const ignores = {
973
1051
  ignores: [...getIgnores(), ...options.ignores ?? []]
@@ -977,6 +1055,9 @@ async function defineConfig(options) {
977
1055
  typescript(options),
978
1056
  ...await vue(options),
979
1057
  ...await svelte(options),
1058
+ react(options),
1059
+ reactHooks(options),
1060
+ reactCompiler(options),
980
1061
  perfectionist(options),
981
1062
  unicorn(options),
982
1063
  tailwind(options),
package/dist/index.d.ts CHANGED
@@ -22,6 +22,9 @@ declare interface ConfigOptions {
22
22
  overrides?: {
23
23
  javascript?: Rules;
24
24
  perfectionist?: Rules;
25
+ react?: Rules;
26
+ reactCompiler?: Rules;
27
+ reactHooks?: Rules;
25
28
  svelte?: Rules;
26
29
  tailwind?: Rules;
27
30
  typescript?: Rules;
@@ -40,6 +43,10 @@ declare interface FeaturesObject {
40
43
  /** @default false */
41
44
  react?: boolean;
42
45
  /** @default false */
46
+ reactCompiler?: boolean;
47
+ /** @default false */
48
+ reactHooks?: boolean;
49
+ /** @default false */
43
50
  svelte?: boolean;
44
51
  /** @default false */
45
52
  tailwind?: boolean;
package/dist/index.js CHANGED
@@ -37,6 +37,10 @@ function isEnabled(config, feature) {
37
37
  return config?.perfectionist ?? true;
38
38
  case "react":
39
39
  return config?.react ?? false;
40
+ case "reactCompiler":
41
+ return config?.reactCompiler ?? config?.react ?? false;
42
+ case "reactHooks":
43
+ return config?.reactHooks ?? config?.react ?? false;
40
44
  case "svelte":
41
45
  return config?.svelte ?? false;
42
46
  case "tailwind":
@@ -285,6 +289,55 @@ async function vue(options) {
285
289
  ];
286
290
  }
287
291
 
292
+ async function react(options) {
293
+ if (!isEnabled(options.features, "react")) return {};
294
+ const plugin = await interopDefault(import('eslint-plugin-react'));
295
+ return {
296
+ plugins: { react: plugin },
297
+ rules: {
298
+ "react/button-has-type": "error",
299
+ "react/function-component-definition": [
300
+ "error",
301
+ {
302
+ namedComponents: "function-expression",
303
+ unnamedComponents: "function-expression"
304
+ }
305
+ ],
306
+ "react/hook-use-state": ["error", { allowDestructuredState: true }],
307
+ "react/jsx-boolean-value": ["error", "never", { assumeUndefinedIsFalse: true }],
308
+ "react/jsx-key": [
309
+ "error",
310
+ {
311
+ checkFragmentShorthand: true,
312
+ checkKeyMustBeforeSpread: false,
313
+ warnOnDuplicates: true
314
+ }
315
+ ],
316
+ "react/jsx-no-script-url": "error",
317
+ "react/jsx-no-useless-fragment": "error",
318
+ "react/jsx-pascal-case": [
319
+ "error",
320
+ {
321
+ allowAllCaps: false,
322
+ allowNamespace: true,
323
+ allowLeadingUnderscore: false
324
+ }
325
+ ],
326
+ "react/jsx-props-no-spread-multi": "error",
327
+ "react/no-access-state-in-setstate": "error",
328
+ "react/no-array-index-key": "error",
329
+ "react/no-danger": "error",
330
+ "react/no-deprecated": "error",
331
+ "react/no-direct-mutation-state": "error",
332
+ "react/no-find-dom-node": "error",
333
+ "react/no-is-mounted": "error",
334
+ "react/no-render-return-value": "error",
335
+ "react/no-unsafe": "error",
336
+ ...options.overrides?.react
337
+ }
338
+ };
339
+ }
340
+
288
341
  async function svelte(options) {
289
342
  if (!isEnabled(options.features, "svelte")) return [];
290
343
  const [sveltePlugin, svelteParser, tsParser] = await Promise.all([
@@ -864,6 +917,19 @@ async function typescript(options) {
864
917
  };
865
918
  }
866
919
 
920
+ async function reactHooks(options) {
921
+ if (!isEnabled(options.features, "react")) return {};
922
+ const plugin = await interopDefault(import('eslint-plugin-react-hooks'));
923
+ return {
924
+ plugins: { "react-hooks": plugin },
925
+ rules: {
926
+ "react-hooks/rules-of-hooks": "error",
927
+ "react-hooks/exhaustive-deps": "error",
928
+ ...options.overrides?.reactHooks
929
+ }
930
+ };
931
+ }
932
+
867
933
  async function perfectionist(options) {
868
934
  if (!isEnabled(options.features, "perfectionist")) return {};
869
935
  const plugin = await interopDefault(import('eslint-plugin-perfectionist'));
@@ -964,6 +1030,18 @@ async function perfectionist(options) {
964
1030
  };
965
1031
  }
966
1032
 
1033
+ async function reactCompiler(options) {
1034
+ if (!isEnabled(options.features, "react")) return {};
1035
+ const plugin = await interopDefault(import('eslint-plugin-react-compiler'));
1036
+ return {
1037
+ plugins: { "react-compiler": plugin },
1038
+ rules: {
1039
+ "react-compiler/react-compiler": "error",
1040
+ ...options.overrides?.reactCompiler
1041
+ }
1042
+ };
1043
+ }
1044
+
967
1045
  async function defineConfig(options) {
968
1046
  const ignores = {
969
1047
  ignores: [...getIgnores(), ...options.ignores ?? []]
@@ -973,6 +1051,9 @@ async function defineConfig(options) {
973
1051
  typescript(options),
974
1052
  ...await vue(options),
975
1053
  ...await svelte(options),
1054
+ react(options),
1055
+ reactHooks(options),
1056
+ reactCompiler(options),
976
1057
  perfectionist(options),
977
1058
  unicorn(options),
978
1059
  tailwind(options),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tb-dev/eslint-config",
3
- "version": "6.0.7",
3
+ "version": "6.1.1",
4
4
  "description": "ESLint config",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,18 +17,23 @@
17
17
  "eslint",
18
18
  "eslint-config",
19
19
  "typescript",
20
+ "react",
21
+ "svelte",
20
22
  "vue"
21
23
  ],
22
24
  "dependencies": {
23
25
  "@typescript-eslint/eslint-plugin": "^8.19.1",
24
26
  "@typescript-eslint/parser": "^8.19.1",
25
27
  "eslint-plugin-perfectionist": "^4.6.0",
28
+ "eslint-plugin-react": "^7.37.3",
29
+ "eslint-plugin-react-compiler": "19.0.0-beta-63e3235-20250105",
30
+ "eslint-plugin-react-hooks": "^5.1.0",
26
31
  "eslint-plugin-svelte": "^3.0.0-next.10",
27
32
  "eslint-plugin-tailwindcss": "^3.17.5",
28
33
  "eslint-plugin-unicorn": "^56.0.1",
29
34
  "eslint-plugin-vue": "^9.32.0",
30
35
  "globals": "^15.14.0",
31
- "svelte": "^5.16.4",
36
+ "svelte": "^5.16.5",
32
37
  "svelte-eslint-parser": "^1.0.0-next.6",
33
38
  "vue-eslint-parser": "^9.4.3"
34
39
  },