@kasoa/eslint-config 0.0.12 → 0.0.13

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.
Files changed (49) hide show
  1. package/dist/base/eslint.d.ts.map +1 -1
  2. package/dist/base/eslint.js +14 -1
  3. package/dist/base/index.d.ts.map +1 -1
  4. package/dist/base/index.js +3 -1
  5. package/dist/base/json.d.ts.map +1 -1
  6. package/dist/base/json.js +1 -4
  7. package/dist/base/perfectionist.d.ts +1 -0
  8. package/dist/base/perfectionist.d.ts.map +1 -1
  9. package/dist/base/perfectionist.js +98 -19
  10. package/dist/base/regexp.d.ts +2 -0
  11. package/dist/base/regexp.d.ts.map +1 -0
  12. package/dist/base/regexp.js +3 -0
  13. package/dist/base/sonarjs.d.ts +2 -0
  14. package/dist/base/sonarjs.d.ts.map +1 -0
  15. package/dist/base/sonarjs.js +8 -0
  16. package/dist/base/typescript-eslint.d.ts.map +1 -1
  17. package/dist/base/typescript-eslint.js +86 -16
  18. package/dist/base/unicorn-x.js +1 -1
  19. package/dist/base/unused-imports.js +1 -1
  20. package/dist/base/vitest.js +1 -1
  21. package/dist/node/n.js +1 -1
  22. package/dist/react/eslint-react.d.ts.map +1 -1
  23. package/dist/react/eslint-react.js +3 -2
  24. package/dist/react/index.d.ts.map +1 -1
  25. package/dist/react/index.js +2 -1
  26. package/dist/react/jsx-a11y.js +1 -1
  27. package/dist/react/react-compiler.js +1 -1
  28. package/dist/react/react-hooks.js +1 -1
  29. package/dist/react/react-refresh.js +1 -1
  30. package/dist/react/react-you-might-not-need-an-effect.js +1 -1
  31. package/package.json +13 -11
  32. package/src/base/eslint.ts +14 -1
  33. package/src/base/index.ts +4 -0
  34. package/src/base/json.ts +3 -4
  35. package/src/base/perfectionist.ts +102 -19
  36. package/src/base/regexp.ts +6 -0
  37. package/src/base/sonarjs.ts +10 -0
  38. package/src/base/typescript-eslint.ts +92 -20
  39. package/src/base/unicorn-x.ts +1 -1
  40. package/src/base/unused-imports.ts +1 -1
  41. package/src/base/vitest.ts +1 -1
  42. package/src/node/n.ts +1 -1
  43. package/src/react/eslint-react.ts +3 -2
  44. package/src/react/index.ts +2 -0
  45. package/src/react/jsx-a11y.ts +1 -1
  46. package/src/react/react-compiler.ts +1 -1
  47. package/src/react/react-hooks.ts +1 -1
  48. package/src/react/react-refresh.ts +1 -1
  49. package/src/react/react-you-might-not-need-an-effect.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../../src/base/eslint.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,kCAMvB,CAAC"}
1
+ {"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../../src/base/eslint.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,kCAmBvB,CAAC"}
@@ -2,8 +2,21 @@ import eslint from "@eslint/js";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const eslintConfig = defineConfig(eslint.configs.recommended, {
4
4
  rules: {
5
- eqeqeq: "error",
6
5
  curly: ["error", "multi-line", "consistent"],
6
+ "default-case-last": "error",
7
+ eqeqeq: "error",
8
+ "grouped-accessor-pairs": ["error", "getBeforeSet"],
9
+ "logical-assignment-operators": ["error", "always"],
10
+ "max-params": "warn",
11
+ "no-alert": "error",
12
+ "no-console": ["warn", { allow: ["warn", "error"] }],
13
+ "no-constructor-return": "error",
14
+ "no-else-return": ["error", { allowElseIf: false }],
15
+ "no-param-reassign": ["error", { props: false }],
16
+ "no-shadow": "off",
17
+ "no-unneeded-ternary": "error",
18
+ "no-useless-return": "error",
7
19
  "object-shorthand": "error",
20
+ "prefer-template": "error",
8
21
  },
9
22
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/base/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,IAAI,kCAYhB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/base/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,IAAI,kCAchB,CAAC"}
@@ -5,8 +5,10 @@ import { eslintConfig } from "./eslint.js";
5
5
  import { importLiteConfig } from "./import-lite.js";
6
6
  import { jsonConfig } from "./json.js";
7
7
  import { perfectionistConfig } from "./perfectionist.js";
8
+ import { regexpConfig } from "./regexp.js";
9
+ import { sonarjsConfig } from "./sonarjs.js";
8
10
  import { typescriptEslintConfig } from "./typescript-eslint.js";
9
11
  import { unicornXConfig } from "./unicorn-x.js";
10
12
  import { unusedImportsConfig } from "./unused-imports.js";
11
13
  import { vitestConfig } from "./vitest.js";
12
- export const base = defineConfig(gitignore(), globalIgnores(["**/*.d.ts"]), jsonConfig, eslintConfig, typescriptEslintConfig, unicornXConfig, vitestConfig, importLiteConfig, unusedImportsConfig, perfectionistConfig, eslintConfigPrettier);
14
+ export const base = defineConfig(gitignore(), globalIgnores(["**/*.d.ts"]), jsonConfig, eslintConfig, typescriptEslintConfig, unicornXConfig, vitestConfig, importLiteConfig, unusedImportsConfig, perfectionistConfig, sonarjsConfig, regexpConfig, eslintConfigPrettier);
@@ -1 +1 @@
1
- {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/base/json.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,kCAGrB,CAAC"}
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/base/json.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,kCAEtB,CAAC"}
package/dist/base/json.js CHANGED
@@ -1,6 +1,3 @@
1
1
  import jsonSchemaValidator from "eslint-plugin-json-schema-validator";
2
2
  import { defineConfig } from "eslint/config";
3
- export const jsonConfig = defineConfig({
4
- files: ["**/*.json", "**/*.jsonc", "**/*.json5"],
5
- extends: [jsonSchemaValidator.configs["flat/recommended"]],
6
- });
3
+ export const jsonConfig = defineConfig(...jsonSchemaValidator.configs["flat/recommended"]);
@@ -1,2 +1,3 @@
1
1
  export declare const perfectionistConfig: import("eslint/config").Config[];
2
+ export declare const perfectionistJsxConfig: import("eslint/config").Config[];
2
3
  //# sourceMappingURL=perfectionist.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"perfectionist.d.ts","sourceRoot":"","sources":["../../src/base/perfectionist.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,kCA8C9B,CAAC"}
1
+ {"version":3,"file":"perfectionist.d.ts","sourceRoot":"","sources":["../../src/base/perfectionist.ts"],"names":[],"mappings":"AA+CA,eAAO,MAAM,mBAAmB,kCAqE9B,CAAC;AAEH,eAAO,MAAM,sBAAsB,kCAcjC,CAAC"}
@@ -1,48 +1,127 @@
1
1
  import perfectionist from "eslint-plugin-perfectionist";
2
2
  import { defineConfig } from "eslint/config";
3
+ const unifiedCustomGroups = [
4
+ {
5
+ elementNamePattern: "(?:^id$|^_id$|^key$|^uuid$|Id$)",
6
+ groupName: "id",
7
+ },
8
+ {
9
+ elementNamePattern: "(?:At$|_at$)",
10
+ groupName: "timestamp",
11
+ },
12
+ {
13
+ elementNamePattern: "(?:^ref$|Ref$)",
14
+ groupName: "ref",
15
+ },
16
+ {
17
+ elementNamePattern: "^on[A-Z]",
18
+ groupName: "callback",
19
+ },
20
+ {
21
+ elementNamePattern: "(?:^style$|Style$)",
22
+ groupName: "style",
23
+ },
24
+ {
25
+ elementNamePattern: "(?:^className$|ClassName$)",
26
+ groupName: "className",
27
+ },
28
+ ];
29
+ const unifiedGroups = [
30
+ "id",
31
+ "unknown",
32
+ "multiline-member",
33
+ "timestamp",
34
+ "ref",
35
+ "method",
36
+ "callback",
37
+ "style",
38
+ "className",
39
+ ];
40
+ const baseConfig = {
41
+ order: "asc",
42
+ type: "natural",
43
+ };
3
44
  export const perfectionistConfig = defineConfig({
4
45
  plugins: {
5
46
  perfectionist,
6
47
  },
7
48
  rules: {
49
+ "perfectionist/sort-enums": ["error", baseConfig],
50
+ "perfectionist/sort-export-attributes": ["error", baseConfig],
51
+ "perfectionist/sort-import-attributes": ["error", baseConfig],
52
+ "perfectionist/sort-intersection-types": ["error", baseConfig],
53
+ "perfectionist/sort-named-exports": ["error", baseConfig],
54
+ "perfectionist/sort-named-imports": ["error", baseConfig],
55
+ "perfectionist/sort-switch-case": ["error", baseConfig],
56
+ "perfectionist/sort-union-types": ["error", baseConfig],
57
+ "perfectionist/sort-classes": [
58
+ "error",
59
+ {
60
+ ...baseConfig,
61
+ newlinesBetween: 1,
62
+ },
63
+ ],
8
64
  "perfectionist/sort-exports": [
9
65
  "error",
10
66
  {
11
- order: "asc",
12
- type: "natural",
67
+ ...baseConfig,
68
+ groups: ["type-export", "wildcard-export", "value-export"],
13
69
  },
14
70
  ],
15
71
  "perfectionist/sort-imports": [
16
72
  "error",
17
73
  {
74
+ ...baseConfig,
75
+ newlinesBetween: 0,
18
76
  groups: [
19
- "type",
20
- ["parent-type", "sibling-type", "index-type", "internal-type"],
21
- "builtin",
22
- "external",
23
- "internal",
24
- ["parent", "sibling", "index"],
25
- "side-effect",
26
- "object",
77
+ "type-import",
78
+ ["type-parent", "type-sibling", "type-index", "type-internal"],
79
+ "value-builtin",
80
+ "value-external",
81
+ "value-internal",
82
+ ["value-parent", "value-sibling", "value-index"],
83
+ "value-side-effect",
27
84
  "unknown",
28
85
  ],
29
- newlinesBetween: 0,
30
- order: "asc",
31
- type: "natural",
32
86
  },
33
87
  ],
34
- "perfectionist/sort-named-exports": [
88
+ "perfectionist/sort-interfaces": [
89
+ "error",
90
+ {
91
+ ...baseConfig,
92
+ customGroups: unifiedCustomGroups,
93
+ groups: unifiedGroups,
94
+ },
95
+ ],
96
+ "perfectionist/sort-object-types": [
97
+ "error",
98
+ {
99
+ ...baseConfig,
100
+ customGroups: unifiedCustomGroups,
101
+ groups: unifiedGroups,
102
+ },
103
+ ],
104
+ "perfectionist/sort-objects": [
35
105
  "error",
36
106
  {
37
- order: "asc",
38
- type: "natural",
107
+ ...baseConfig,
108
+ customGroups: unifiedCustomGroups,
109
+ groups: unifiedGroups,
39
110
  },
40
111
  ],
41
- "perfectionist/sort-named-imports": [
112
+ },
113
+ });
114
+ export const perfectionistJsxConfig = defineConfig({
115
+ plugins: {
116
+ perfectionist,
117
+ },
118
+ rules: {
119
+ "perfectionist/sort-jsx-props": [
42
120
  "error",
43
121
  {
44
- order: "asc",
45
- type: "natural",
122
+ ...baseConfig,
123
+ customGroups: unifiedCustomGroups,
124
+ groups: unifiedGroups,
46
125
  },
47
126
  ],
48
127
  },
@@ -0,0 +1,2 @@
1
+ export declare const regexpConfig: import("eslint/config").Config[];
2
+ //# sourceMappingURL=regexp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regexp.d.ts","sourceRoot":"","sources":["../../src/base/regexp.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,kCAExB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import * as regexpPlugin from "eslint-plugin-regexp";
2
+ import { defineConfig } from "eslint/config";
3
+ export const regexpConfig = defineConfig(regexpPlugin.configs["flat/recommended"]);
@@ -0,0 +1,2 @@
1
+ export declare const sonarjsConfig: import("eslint/config").Config[];
2
+ //# sourceMappingURL=sonarjs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonarjs.d.ts","sourceRoot":"","sources":["../../src/base/sonarjs.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa,kCAIxB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import sonarjs from "eslint-plugin-sonarjs";
2
+ import { defineConfig } from "eslint/config";
3
+ const COGNITIVE_COMPLEXITY_THRESHOLD = 15;
4
+ export const sonarjsConfig = defineConfig(sonarjs.configs.recommended, {
5
+ rules: {
6
+ "sonarjs/cognitive-complexity": ["warn", COGNITIVE_COMPLEXITY_THRESHOLD],
7
+ },
8
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"typescript-eslint.d.ts","sourceRoot":"","sources":["../../src/base/typescript-eslint.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,sBAAsB,kCAsClC,CAAC"}
1
+ {"version":3,"file":"typescript-eslint.d.ts","sourceRoot":"","sources":["../../src/base/typescript-eslint.ts"],"names":[],"mappings":"AA0FA,eAAO,MAAM,sBAAsB,kCAwBlC,CAAC"}
@@ -1,39 +1,109 @@
1
1
  import { defineConfig } from "eslint/config";
2
2
  import globals from "globals";
3
3
  import typescriptEslint from "typescript-eslint";
4
- export const typescriptEslintConfig = defineConfig({
5
- files: ["**/*.{js,jsx,mjs,ts,tsx,mts}"],
4
+ const sharedConfig = {
6
5
  extends: [
7
6
  typescriptEslint.configs.strictTypeChecked,
8
7
  typescriptEslint.configs.stylisticTypeChecked,
9
8
  ],
10
- languageOptions: {
11
- parserOptions: {
12
- projectService: true,
13
- },
9
+ parserOptions: {
10
+ projectService: true,
14
11
  },
15
12
  rules: {
16
- "@typescript-eslint/no-unused-vars": "off",
17
13
  "@typescript-eslint/consistent-type-imports": "error",
14
+ "@typescript-eslint/method-signature-style": ["error", "property"],
15
+ "@typescript-eslint/no-shadow": "error",
16
+ "@typescript-eslint/no-unused-vars": "off",
17
+ "@typescript-eslint/prefer-readonly": "error",
18
+ "@typescript-eslint/require-array-sort-compare": "error",
19
+ "@typescript-eslint/switch-exhaustiveness-check": "error",
20
+ "no-shadow": "off",
21
+ "@typescript-eslint/consistent-type-exports": [
22
+ "error",
23
+ { fixMixedExportsWithInlineTypeSpecifier: true },
24
+ ],
25
+ "@typescript-eslint/naming-convention": [
26
+ "warn",
27
+ {
28
+ format: ["camelCase"],
29
+ leadingUnderscore: "allow",
30
+ selector: "default",
31
+ trailingUnderscore: "allow",
32
+ },
33
+ {
34
+ format: ["camelCase", "UPPER_CASE", "PascalCase"],
35
+ selector: "variable",
36
+ },
37
+ {
38
+ format: ["camelCase", "PascalCase"],
39
+ selector: "function",
40
+ },
41
+ {
42
+ format: ["camelCase"],
43
+ leadingUnderscore: "allow",
44
+ selector: "parameter",
45
+ },
46
+ {
47
+ format: ["PascalCase"],
48
+ selector: "typeLike",
49
+ },
50
+ {
51
+ format: ["PascalCase", "UPPER_CASE"],
52
+ selector: "enumMember",
53
+ },
54
+ {
55
+ format: ["camelCase", "UPPER_CASE"],
56
+ leadingUnderscore: "allow",
57
+ selector: "property",
58
+ },
59
+ {
60
+ format: ["camelCase", "UPPER_CASE"],
61
+ selector: "classProperty",
62
+ },
63
+ {
64
+ format: ["camelCase"],
65
+ selector: "classMethod",
66
+ },
67
+ {
68
+ // eslint-disable-next-line unicorn-x/no-null -- format: null is required by @typescript-eslint/naming-convention to disable format checking
69
+ format: null,
70
+ modifiers: ["requiresQuotes"],
71
+ selector: "objectLiteralProperty",
72
+ },
73
+ ],
74
+ "@typescript-eslint/no-magic-numbers": [
75
+ "warn",
76
+ {
77
+ ignore: [-1, 0, 1, 2],
78
+ ignoreArrayIndexes: true,
79
+ ignoreDefaultValues: true,
80
+ ignoreEnums: true,
81
+ ignoreNumericLiteralTypes: true,
82
+ ignoreReadonlyClassProperties: true,
83
+ ignoreTypeIndexes: true,
84
+ },
85
+ ],
86
+ },
87
+ };
88
+ export const typescriptEslintConfig = defineConfig({
89
+ extends: sharedConfig.extends,
90
+ files: ["**/*.{js,jsx,mjs,ts,tsx,mts}"],
91
+ rules: sharedConfig.rules,
92
+ languageOptions: {
93
+ parserOptions: sharedConfig.parserOptions,
18
94
  },
19
95
  }, {
96
+ extends: sharedConfig.extends,
20
97
  files: ["**/*.{cjs,cts}"],
21
- extends: [
22
- typescriptEslint.configs.strictTypeChecked,
23
- typescriptEslint.configs.stylisticTypeChecked,
24
- ],
25
98
  languageOptions: {
99
+ parserOptions: sharedConfig.parserOptions,
26
100
  sourceType: "commonjs",
27
- parserOptions: {
28
- projectService: true,
29
- },
30
101
  globals: {
31
102
  ...globals.node,
32
103
  },
33
104
  },
34
105
  rules: {
35
- "@typescript-eslint/no-unused-vars": "off",
36
- "@typescript-eslint/consistent-type-imports": "error",
106
+ ...sharedConfig.rules,
37
107
  "@typescript-eslint/no-require-imports": "off",
38
108
  },
39
109
  });
@@ -2,8 +2,8 @@ import unicornX from "eslint-plugin-unicorn-x";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const unicornXConfig = defineConfig(unicornX.configs.recommended, {
4
4
  rules: {
5
- "unicorn-x/prevent-abbreviations": "off",
6
5
  "unicorn-x/better-regex": "error",
7
6
  "unicorn-x/prefer-import-meta-properties": "error",
7
+ "unicorn-x/prevent-abbreviations": "off",
8
8
  },
9
9
  });
@@ -5,7 +5,7 @@ export const unusedImportsConfig = defineConfig({
5
5
  "unused-imports": unusedImports,
6
6
  },
7
7
  rules: {
8
- "unused-imports/no-unused-vars": "off",
9
8
  "unused-imports/no-unused-imports": "error",
9
+ "unused-imports/no-unused-vars": "off",
10
10
  },
11
11
  });
@@ -1,6 +1,6 @@
1
1
  import vitest from "@vitest/eslint-plugin";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const vitestConfig = defineConfig({
4
+ ...vitest.configs.all,
4
5
  files: ["**/tests/**", "**/*.test.ts", "**/*.test.tsx"],
5
- extends: [vitest.configs.all],
6
6
  });
package/dist/node/n.js CHANGED
@@ -2,7 +2,7 @@ import nodePlugin from "eslint-plugin-n";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const nodeConfig = defineConfig(nodePlugin.configs["flat/recommended-module"], {
4
4
  rules: {
5
- "n/no-unpublished-import": "off",
6
5
  "n/no-missing-import": "off",
6
+ "n/no-unpublished-import": "off",
7
7
  },
8
8
  });
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-react.d.ts","sourceRoot":"","sources":["../../src/react/eslint-react.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,kCAO5B,CAAC"}
1
+ {"version":3,"file":"eslint-react.d.ts","sourceRoot":"","sources":["../../src/react/eslint-react.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,kCAQ5B,CAAC"}
@@ -1,10 +1,11 @@
1
1
  import eslintReact from "@eslint-react/eslint-plugin";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const eslintReactConfig = defineConfig({
4
+ ...eslintReact.configs["strict-type-checked"],
4
5
  files: ["**/*.{js,jsx,ts,tsx}"],
5
- extends: [eslintReact.configs["strict-type-checked"]],
6
6
  rules: {
7
- "@eslint-react/prefer-namespace-import": "error",
7
+ ...eslintReact.configs["strict-type-checked"].rules,
8
8
  "@eslint-react/no-unstable-context-value": "off",
9
+ "@eslint-react/prefer-namespace-import": "error",
9
10
  },
10
11
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,KAAK,kCAQjB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,KAAK,kCASjB,CAAC"}
@@ -1,9 +1,10 @@
1
1
  import { defineConfig } from "eslint/config";
2
2
  import { base } from "../base/index.js";
3
+ import { perfectionistJsxConfig } from "../base/perfectionist.js";
3
4
  import { eslintReactConfig } from "./eslint-react.js";
4
5
  import { jsxA11yConfig } from "./jsx-a11y.js";
5
6
  import { reactCompilerConfig } from "./react-compiler.js";
6
7
  import { reactHooksConfig } from "./react-hooks.js";
7
8
  import { reactRefreshConfig } from "./react-refresh.js";
8
9
  import { reactYouMightNotNeedAnEffectConfig } from "./react-you-might-not-need-an-effect.js";
9
- export const react = defineConfig(base, eslintReactConfig, jsxA11yConfig, reactHooksConfig, reactRefreshConfig, reactCompilerConfig, reactYouMightNotNeedAnEffectConfig);
10
+ export const react = defineConfig(base, eslintReactConfig, jsxA11yConfig, reactHooksConfig, reactRefreshConfig, reactCompilerConfig, reactYouMightNotNeedAnEffectConfig, perfectionistJsxConfig);
@@ -1,6 +1,6 @@
1
1
  import jsxA11y from "eslint-plugin-jsx-a11y";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const jsxA11yConfig = defineConfig({
4
+ ...jsxA11y.flatConfigs.strict,
4
5
  files: ["**/*.{js,jsx,ts,tsx}"],
5
- extends: [jsxA11y.flatConfigs.strict],
6
6
  });
@@ -1,6 +1,6 @@
1
1
  import reactCompiler from "eslint-plugin-react-compiler";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const reactCompilerConfig = defineConfig({
4
+ ...reactCompiler.configs.recommended,
4
5
  files: ["**/*.{js,jsx,ts,tsx}"],
5
- extends: [reactCompiler.configs.recommended],
6
6
  });
@@ -1,6 +1,6 @@
1
1
  import reactHooks from "eslint-plugin-react-hooks";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const reactHooksConfig = defineConfig({
4
+ ...reactHooks.configs.flat["recommended-latest"],
4
5
  files: ["**/*.{js,jsx,ts,tsx}"],
5
- extends: [reactHooks.configs.flat["recommended-latest"]],
6
6
  });
@@ -1,6 +1,6 @@
1
1
  import reactRefresh from "eslint-plugin-react-refresh";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const reactRefreshConfig = defineConfig({
4
+ ...reactRefresh.configs.recommended,
4
5
  files: ["**/*.{js,jsx,ts,tsx}"],
5
- extends: [reactRefresh.configs.recommended],
6
6
  });
@@ -1,6 +1,6 @@
1
1
  import reactYouMightNotNeedAnEffect from "eslint-plugin-react-you-might-not-need-an-effect";
2
2
  import { defineConfig } from "eslint/config";
3
3
  export const reactYouMightNotNeedAnEffectConfig = defineConfig({
4
+ ...reactYouMightNotNeedAnEffect.configs.recommended,
4
5
  files: ["**/*.{js,jsx,ts,tsx}"],
5
- extends: [reactYouMightNotNeedAnEffect.configs.recommended],
6
6
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kasoa/eslint-config",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Kasoa's ESLint config",
@@ -36,31 +36,33 @@
36
36
  "access": "public"
37
37
  },
38
38
  "dependencies": {
39
- "@eslint-react/eslint-plugin": "^2.3.13",
39
+ "@eslint-react/eslint-plugin": "^2.5.5",
40
40
  "@eslint/js": "latest",
41
- "@vitest/eslint-plugin": "^1.5.2",
41
+ "@vitest/eslint-plugin": "^1.6.6",
42
42
  "eslint": "^9.39.2",
43
43
  "eslint-config-flat-gitignore": "^2.1.0",
44
44
  "eslint-config-prettier": "^10.1.8",
45
- "eslint-plugin-import-lite": "^0.3.0",
45
+ "eslint-plugin-import-lite": "^0.5.0",
46
+ "eslint-plugin-json-schema-validator": "^5.5.1",
46
47
  "eslint-plugin-jsx-a11y": "^6.10.2",
47
48
  "eslint-plugin-jsx-a11y-x": "^0.1.1",
48
- "eslint-plugin-json-schema-validator": "^5.5.0",
49
49
  "eslint-plugin-n": "^17.23.1",
50
- "eslint-plugin-perfectionist": "^4.15.1",
50
+ "eslint-plugin-perfectionist": "^5.3.1",
51
51
  "eslint-plugin-react-compiler": "19.1.0-rc.2",
52
52
  "eslint-plugin-react-hooks": "^7.0.1",
53
53
  "eslint-plugin-react-refresh": "^0.4.26",
54
- "eslint-plugin-react-you-might-not-need-an-effect": "^0.7.0",
54
+ "eslint-plugin-react-you-might-not-need-an-effect": "^0.8.5",
55
+ "eslint-plugin-regexp": "^2.10.0",
56
+ "eslint-plugin-sonarjs": "^3.0.5",
55
57
  "eslint-plugin-unicorn-x": "^3.2.1",
56
58
  "eslint-plugin-unused-imports": "^4.3.0",
57
- "globals": "^16.5.0",
58
- "typescript-eslint": "^8.50.0"
59
+ "globals": "^17.0.0",
60
+ "typescript-eslint": "^8.52.0"
59
61
  },
60
62
  "devDependencies": {
61
63
  "@types/eslint-plugin-jsx-a11y": "^6.10.1",
62
- "@types/node": "^25.0.3",
63
- "@typescript/native-preview": "^7.0.0-dev.20251216.1",
64
+ "@types/node": "^25.0.6",
65
+ "@typescript/native-preview": "^7.0.0-dev.20260111.1",
64
66
  "prettier": "^3.7.4",
65
67
  "@kasoa/tsconfig": "0.0.0"
66
68
  },
@@ -3,8 +3,21 @@ import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const eslintConfig = defineConfig(eslint.configs.recommended, {
5
5
  rules: {
6
- eqeqeq: "error",
7
6
  curly: ["error", "multi-line", "consistent"],
7
+ "default-case-last": "error",
8
+ eqeqeq: "error",
9
+ "grouped-accessor-pairs": ["error", "getBeforeSet"],
10
+ "logical-assignment-operators": ["error", "always"],
11
+ "max-params": "warn",
12
+ "no-alert": "error",
13
+ "no-console": ["warn", { allow: ["warn", "error"] }],
14
+ "no-constructor-return": "error",
15
+ "no-else-return": ["error", { allowElseIf: false }],
16
+ "no-param-reassign": ["error", { props: false }],
17
+ "no-shadow": "off",
18
+ "no-unneeded-ternary": "error",
19
+ "no-useless-return": "error",
8
20
  "object-shorthand": "error",
21
+ "prefer-template": "error",
9
22
  },
10
23
  });
package/src/base/index.ts CHANGED
@@ -5,6 +5,8 @@ import { eslintConfig } from "./eslint.js";
5
5
  import { importLiteConfig } from "./import-lite.js";
6
6
  import { jsonConfig } from "./json.js";
7
7
  import { perfectionistConfig } from "./perfectionist.js";
8
+ import { regexpConfig } from "./regexp.js";
9
+ import { sonarjsConfig } from "./sonarjs.js";
8
10
  import { typescriptEslintConfig } from "./typescript-eslint.js";
9
11
  import { unicornXConfig } from "./unicorn-x.js";
10
12
  import { unusedImportsConfig } from "./unused-imports.js";
@@ -21,5 +23,7 @@ export const base = defineConfig(
21
23
  importLiteConfig,
22
24
  unusedImportsConfig,
23
25
  perfectionistConfig,
26
+ sonarjsConfig,
27
+ regexpConfig,
24
28
  eslintConfigPrettier,
25
29
  );
package/src/base/json.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import jsonSchemaValidator from "eslint-plugin-json-schema-validator";
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
- export const jsonConfig = defineConfig({
5
- files: ["**/*.json", "**/*.jsonc", "**/*.json5"],
6
- extends: [jsonSchemaValidator.configs["flat/recommended"]],
7
- });
4
+ export const jsonConfig = defineConfig(
5
+ ...jsonSchemaValidator.configs["flat/recommended"],
6
+ );
@@ -1,49 +1,132 @@
1
1
  import perfectionist from "eslint-plugin-perfectionist";
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
+ const unifiedCustomGroups = [
5
+ {
6
+ elementNamePattern: "(?:^id$|^_id$|^key$|^uuid$|Id$)",
7
+ groupName: "id",
8
+ },
9
+ {
10
+ elementNamePattern: "(?:At$|_at$)",
11
+ groupName: "timestamp",
12
+ },
13
+ {
14
+ elementNamePattern: "(?:^ref$|Ref$)",
15
+ groupName: "ref",
16
+ },
17
+ {
18
+ elementNamePattern: "^on[A-Z]",
19
+ groupName: "callback",
20
+ },
21
+ {
22
+ elementNamePattern: "(?:^style$|Style$)",
23
+ groupName: "style",
24
+ },
25
+ {
26
+ elementNamePattern: "(?:^className$|ClassName$)",
27
+ groupName: "className",
28
+ },
29
+ ];
30
+
31
+ const unifiedGroups = [
32
+ "id",
33
+ "unknown",
34
+ "multiline-member",
35
+ "timestamp",
36
+ "ref",
37
+ "method",
38
+ "callback",
39
+ "style",
40
+ "className",
41
+ ];
42
+
43
+ const baseConfig = {
44
+ order: "asc" as const,
45
+ type: "natural" as const,
46
+ };
47
+
4
48
  export const perfectionistConfig = defineConfig({
5
49
  plugins: {
6
50
  perfectionist,
7
51
  },
8
52
  rules: {
53
+ "perfectionist/sort-enums": ["error", baseConfig],
54
+ "perfectionist/sort-export-attributes": ["error", baseConfig],
55
+ "perfectionist/sort-import-attributes": ["error", baseConfig],
56
+ "perfectionist/sort-intersection-types": ["error", baseConfig],
57
+ "perfectionist/sort-named-exports": ["error", baseConfig],
58
+ "perfectionist/sort-named-imports": ["error", baseConfig],
59
+ "perfectionist/sort-switch-case": ["error", baseConfig],
60
+ "perfectionist/sort-union-types": ["error", baseConfig],
61
+ "perfectionist/sort-classes": [
62
+ "error",
63
+ {
64
+ ...baseConfig,
65
+ newlinesBetween: 1,
66
+ },
67
+ ],
9
68
  "perfectionist/sort-exports": [
10
69
  "error",
11
70
  {
12
- order: "asc",
13
- type: "natural",
71
+ ...baseConfig,
72
+ groups: ["type-export", "wildcard-export", "value-export"],
14
73
  },
15
74
  ],
16
75
  "perfectionist/sort-imports": [
17
76
  "error",
18
77
  {
78
+ ...baseConfig,
79
+ newlinesBetween: 0,
19
80
  groups: [
20
- "type",
21
- ["parent-type", "sibling-type", "index-type", "internal-type"],
22
- "builtin",
23
- "external",
24
- "internal",
25
- ["parent", "sibling", "index"],
26
- "side-effect",
27
- "object",
81
+ "type-import",
82
+ ["type-parent", "type-sibling", "type-index", "type-internal"],
83
+ "value-builtin",
84
+ "value-external",
85
+ "value-internal",
86
+ ["value-parent", "value-sibling", "value-index"],
87
+ "value-side-effect",
28
88
  "unknown",
29
89
  ],
30
- newlinesBetween: 0,
31
- order: "asc",
32
- type: "natural",
33
90
  },
34
91
  ],
35
- "perfectionist/sort-named-exports": [
92
+ "perfectionist/sort-interfaces": [
36
93
  "error",
37
94
  {
38
- order: "asc",
39
- type: "natural",
95
+ ...baseConfig,
96
+ customGroups: unifiedCustomGroups,
97
+ groups: unifiedGroups,
40
98
  },
41
99
  ],
42
- "perfectionist/sort-named-imports": [
100
+ "perfectionist/sort-object-types": [
101
+ "error",
102
+ {
103
+ ...baseConfig,
104
+ customGroups: unifiedCustomGroups,
105
+ groups: unifiedGroups,
106
+ },
107
+ ],
108
+ "perfectionist/sort-objects": [
109
+ "error",
110
+ {
111
+ ...baseConfig,
112
+ customGroups: unifiedCustomGroups,
113
+ groups: unifiedGroups,
114
+ },
115
+ ],
116
+ },
117
+ });
118
+
119
+ export const perfectionistJsxConfig = defineConfig({
120
+ plugins: {
121
+ perfectionist,
122
+ },
123
+ rules: {
124
+ "perfectionist/sort-jsx-props": [
43
125
  "error",
44
126
  {
45
- order: "asc",
46
- type: "natural",
127
+ ...baseConfig,
128
+ customGroups: unifiedCustomGroups,
129
+ groups: unifiedGroups,
47
130
  },
48
131
  ],
49
132
  },
@@ -0,0 +1,6 @@
1
+ import * as regexpPlugin from "eslint-plugin-regexp";
2
+ import { defineConfig } from "eslint/config";
3
+
4
+ export const regexpConfig = defineConfig(
5
+ regexpPlugin.configs["flat/recommended"],
6
+ );
@@ -0,0 +1,10 @@
1
+ import sonarjs from "eslint-plugin-sonarjs";
2
+ import { defineConfig } from "eslint/config";
3
+
4
+ const COGNITIVE_COMPLEXITY_THRESHOLD = 15;
5
+
6
+ export const sonarjsConfig = defineConfig(sonarjs.configs.recommended, {
7
+ rules: {
8
+ "sonarjs/cognitive-complexity": ["warn", COGNITIVE_COMPLEXITY_THRESHOLD],
9
+ },
10
+ });
@@ -1,42 +1,114 @@
1
+ import type { Linter } from "eslint";
1
2
  import { defineConfig } from "eslint/config";
2
3
  import globals from "globals";
3
4
  import typescriptEslint from "typescript-eslint";
4
5
 
6
+ const sharedConfig = {
7
+ extends: [
8
+ typescriptEslint.configs.strictTypeChecked,
9
+ typescriptEslint.configs.stylisticTypeChecked,
10
+ ],
11
+ parserOptions: {
12
+ projectService: true,
13
+ },
14
+ rules: {
15
+ "@typescript-eslint/consistent-type-imports": "error",
16
+ "@typescript-eslint/method-signature-style": ["error", "property"],
17
+ "@typescript-eslint/no-shadow": "error",
18
+ "@typescript-eslint/no-unused-vars": "off",
19
+ "@typescript-eslint/prefer-readonly": "error",
20
+ "@typescript-eslint/require-array-sort-compare": "error",
21
+ "@typescript-eslint/switch-exhaustiveness-check": "error",
22
+ "no-shadow": "off",
23
+ "@typescript-eslint/consistent-type-exports": [
24
+ "error",
25
+ { fixMixedExportsWithInlineTypeSpecifier: true },
26
+ ],
27
+ "@typescript-eslint/naming-convention": [
28
+ "warn",
29
+ {
30
+ format: ["camelCase"],
31
+ leadingUnderscore: "allow",
32
+ selector: "default",
33
+ trailingUnderscore: "allow",
34
+ },
35
+ {
36
+ format: ["camelCase", "UPPER_CASE", "PascalCase"],
37
+ selector: "variable",
38
+ },
39
+ {
40
+ format: ["camelCase", "PascalCase"],
41
+ selector: "function",
42
+ },
43
+ {
44
+ format: ["camelCase"],
45
+ leadingUnderscore: "allow",
46
+ selector: "parameter",
47
+ },
48
+ {
49
+ format: ["PascalCase"],
50
+ selector: "typeLike",
51
+ },
52
+ {
53
+ format: ["PascalCase", "UPPER_CASE"],
54
+ selector: "enumMember",
55
+ },
56
+ {
57
+ format: ["camelCase", "UPPER_CASE"],
58
+ leadingUnderscore: "allow",
59
+ selector: "property",
60
+ },
61
+ {
62
+ format: ["camelCase", "UPPER_CASE"],
63
+ selector: "classProperty",
64
+ },
65
+ {
66
+ format: ["camelCase"],
67
+ selector: "classMethod",
68
+ },
69
+ {
70
+ // eslint-disable-next-line unicorn-x/no-null -- format: null is required by @typescript-eslint/naming-convention to disable format checking
71
+ format: null,
72
+ modifiers: ["requiresQuotes"],
73
+ selector: "objectLiteralProperty",
74
+ },
75
+ ],
76
+ "@typescript-eslint/no-magic-numbers": [
77
+ "warn",
78
+ {
79
+ ignore: [-1, 0, 1, 2],
80
+ ignoreArrayIndexes: true,
81
+ ignoreDefaultValues: true,
82
+ ignoreEnums: true,
83
+ ignoreNumericLiteralTypes: true,
84
+ ignoreReadonlyClassProperties: true,
85
+ ignoreTypeIndexes: true,
86
+ },
87
+ ],
88
+ } satisfies Linter.RulesRecord,
89
+ };
90
+
5
91
  export const typescriptEslintConfig = defineConfig(
6
92
  {
93
+ extends: sharedConfig.extends,
7
94
  files: ["**/*.{js,jsx,mjs,ts,tsx,mts}"],
8
- extends: [
9
- typescriptEslint.configs.strictTypeChecked,
10
- typescriptEslint.configs.stylisticTypeChecked,
11
- ],
95
+ rules: sharedConfig.rules,
12
96
  languageOptions: {
13
- parserOptions: {
14
- projectService: true,
15
- },
16
- },
17
- rules: {
18
- "@typescript-eslint/no-unused-vars": "off",
19
- "@typescript-eslint/consistent-type-imports": "error",
97
+ parserOptions: sharedConfig.parserOptions,
20
98
  },
21
99
  },
22
100
  {
101
+ extends: sharedConfig.extends,
23
102
  files: ["**/*.{cjs,cts}"],
24
- extends: [
25
- typescriptEslint.configs.strictTypeChecked,
26
- typescriptEslint.configs.stylisticTypeChecked,
27
- ],
28
103
  languageOptions: {
104
+ parserOptions: sharedConfig.parserOptions,
29
105
  sourceType: "commonjs",
30
- parserOptions: {
31
- projectService: true,
32
- },
33
106
  globals: {
34
107
  ...globals.node,
35
108
  },
36
109
  },
37
110
  rules: {
38
- "@typescript-eslint/no-unused-vars": "off",
39
- "@typescript-eslint/consistent-type-imports": "error",
111
+ ...sharedConfig.rules,
40
112
  "@typescript-eslint/no-require-imports": "off",
41
113
  },
42
114
  },
@@ -3,8 +3,8 @@ import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const unicornXConfig = defineConfig(unicornX.configs.recommended, {
5
5
  rules: {
6
- "unicorn-x/prevent-abbreviations": "off",
7
6
  "unicorn-x/better-regex": "error",
8
7
  "unicorn-x/prefer-import-meta-properties": "error",
8
+ "unicorn-x/prevent-abbreviations": "off",
9
9
  },
10
10
  });
@@ -6,7 +6,7 @@ export const unusedImportsConfig = defineConfig({
6
6
  "unused-imports": unusedImports,
7
7
  },
8
8
  rules: {
9
- "unused-imports/no-unused-vars": "off",
10
9
  "unused-imports/no-unused-imports": "error",
10
+ "unused-imports/no-unused-vars": "off",
11
11
  },
12
12
  });
@@ -2,6 +2,6 @@ import vitest from "@vitest/eslint-plugin";
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const vitestConfig = defineConfig({
5
+ ...vitest.configs.all,
5
6
  files: ["**/tests/**", "**/*.test.ts", "**/*.test.tsx"],
6
- extends: [vitest.configs.all],
7
7
  });
package/src/node/n.ts CHANGED
@@ -5,8 +5,8 @@ export const nodeConfig = defineConfig(
5
5
  nodePlugin.configs["flat/recommended-module"],
6
6
  {
7
7
  rules: {
8
- "n/no-unpublished-import": "off",
9
8
  "n/no-missing-import": "off",
9
+ "n/no-unpublished-import": "off",
10
10
  },
11
11
  },
12
12
  );
@@ -2,10 +2,11 @@ import eslintReact from "@eslint-react/eslint-plugin";
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const eslintReactConfig = defineConfig({
5
+ ...eslintReact.configs["strict-type-checked"],
5
6
  files: ["**/*.{js,jsx,ts,tsx}"],
6
- extends: [eslintReact.configs["strict-type-checked"]],
7
7
  rules: {
8
- "@eslint-react/prefer-namespace-import": "error",
8
+ ...eslintReact.configs["strict-type-checked"].rules,
9
9
  "@eslint-react/no-unstable-context-value": "off",
10
+ "@eslint-react/prefer-namespace-import": "error",
10
11
  },
11
12
  });
@@ -1,5 +1,6 @@
1
1
  import { defineConfig } from "eslint/config";
2
2
  import { base } from "../base/index.js";
3
+ import { perfectionistJsxConfig } from "../base/perfectionist.js";
3
4
  import { eslintReactConfig } from "./eslint-react.js";
4
5
  import { jsxA11yConfig } from "./jsx-a11y.js";
5
6
  import { reactCompilerConfig } from "./react-compiler.js";
@@ -15,4 +16,5 @@ export const react = defineConfig(
15
16
  reactRefreshConfig,
16
17
  reactCompilerConfig,
17
18
  reactYouMightNotNeedAnEffectConfig,
19
+ perfectionistJsxConfig,
18
20
  );
@@ -2,6 +2,6 @@ import jsxA11y from "eslint-plugin-jsx-a11y";
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const jsxA11yConfig = defineConfig({
5
+ ...jsxA11y.flatConfigs.strict,
5
6
  files: ["**/*.{js,jsx,ts,tsx}"],
6
- extends: [jsxA11y.flatConfigs.strict],
7
7
  });
@@ -2,6 +2,6 @@ import reactCompiler from "eslint-plugin-react-compiler";
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const reactCompilerConfig = defineConfig({
5
+ ...reactCompiler.configs.recommended,
5
6
  files: ["**/*.{js,jsx,ts,tsx}"],
6
- extends: [reactCompiler.configs.recommended],
7
7
  });
@@ -2,6 +2,6 @@ import reactHooks from "eslint-plugin-react-hooks";
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const reactHooksConfig = defineConfig({
5
+ ...reactHooks.configs.flat["recommended-latest"],
5
6
  files: ["**/*.{js,jsx,ts,tsx}"],
6
- extends: [reactHooks.configs.flat["recommended-latest"]],
7
7
  });
@@ -2,6 +2,6 @@ import reactRefresh from "eslint-plugin-react-refresh";
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const reactRefreshConfig = defineConfig({
5
+ ...reactRefresh.configs.recommended,
5
6
  files: ["**/*.{js,jsx,ts,tsx}"],
6
- extends: [reactRefresh.configs.recommended],
7
7
  });
@@ -2,6 +2,6 @@ import reactYouMightNotNeedAnEffect from "eslint-plugin-react-you-might-not-need
2
2
  import { defineConfig } from "eslint/config";
3
3
 
4
4
  export const reactYouMightNotNeedAnEffectConfig = defineConfig({
5
+ ...reactYouMightNotNeedAnEffect.configs.recommended,
5
6
  files: ["**/*.{js,jsx,ts,tsx}"],
6
- extends: [reactYouMightNotNeedAnEffect.configs.recommended],
7
7
  });