@codfish/eslint-config 0.0.0-PR-155--2a9a213 → 0.0.0-semantically-released

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,7 +1,7 @@
1
1
  # @codfish/eslint-config
2
2
 
3
3
  > Modern ESLint configuration with TypeScript, React/Next.js, YAML, Testing Library, and testing framework support using
4
- > ESLint v10+ flat config format.
4
+ > ESLint v9+ flat config format.
5
5
 
6
6
  [![version](https://img.shields.io/npm/v/@codfish/eslint-config.svg)](http://npm.im/@codfish/eslint-config)
7
7
  [![downloads](https://img.shields.io/npm/dm/@codfish/eslint-config.svg)](http://npm-stat.com/charts.html?package=@codfish/eslint-config&from=2015-08-01)
@@ -24,10 +24,6 @@
24
24
  - [Use in combination with prettier-plugin-tailwindcss](#use-in-combination-with-prettier-plugin-tailwindcss)
25
25
  - [Example scripts](#example-scripts)
26
26
  - [Commitlint Configuration](#commitlint-configuration)
27
- - [Upgrading to ESLint 10](#upgrading-to-eslint-10)
28
- - [Breaking Changes in ESLint 10](#breaking-changes-in-eslint-10)
29
- - [Migration Steps](#migration-steps)
30
- - [What Changed](#what-changed)
31
27
  - [Migration from Legacy Config](#migration-from-legacy-config)
32
28
 
33
29
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -35,7 +31,7 @@
35
31
 
36
32
  ## Features
37
33
 
38
- - **Modern ESLint v10+ flat config**: Uses the new flat configuration format
34
+ - **Modern ESLint v9+ flat config**: Uses the new flat configuration format
39
35
  - **Dynamic feature detection**: Automatically configures based on your project's dependencies
40
36
  - **TypeScript support**: Full TypeScript linting with modern typescript-eslint parser and rules
41
37
  - **React ecosystem**: React, React Hooks, and JSX accessibility rules when React is detected
@@ -53,7 +49,7 @@
53
49
  Install the package and required peer dependencies:
54
50
 
55
51
  ```sh
56
- npm i -D eslint@10 @codfish/eslint-config
52
+ npm i -D eslint@9 @codfish/eslint-config
57
53
 
58
54
  # Optionally, you can uninstall plugins or presets you don't need to manage anymore,
59
55
  # @codfish/eslint-config includes them all.
@@ -383,7 +379,7 @@ export default {
383
379
  ### Use in combination with prettier-plugin-tailwindcss
384
380
 
385
381
  ```sh
386
- npm i -D eslint@10 @codfish/eslint-config prettier-plugin-tailwindcss
382
+ npm i -D eslint@9 @codfish/eslint-config prettier-plugin-tailwindcss
387
383
  ```
388
384
 
389
385
  ```js
@@ -505,72 +501,11 @@ jobs:
505
501
  --verbose
506
502
  ```
507
503
 
508
- ## Upgrading to ESLint 10
509
-
510
- This package now requires **ESLint 10.0.0 or higher** and **Node.js v20.19.0 or higher**.
511
-
512
- ### Breaking Changes in ESLint 10
513
-
514
- - **ESLint 10 Required**: Minimum ESLint version is now 10.0.0
515
- - **Node.js v20.19.0+**: Minimum Node.js version increased from v20.0.0 to v20.19.0
516
- - **Legacy eslintrc removed**: ESLint 10 completely removes the deprecated eslintrc config system (this package already
517
- uses flat config)
518
- - **Improved JSX tracking**: ESLint 10 properly tracks JSX references in scope analysis, which may surface previously
519
- hidden unused import warnings in React files
520
- - **New recommended rules**: Three new rules enabled in `eslint:recommended`:
521
- - `no-unassigned-vars` - Disallow variables that are assigned but never used
522
- - `no-useless-assignment` - Disallow assignments that don't change the value
523
- - `preserve-caught-error` - Enforce that caught errors are not reassigned
524
-
525
- ### Migration Steps
526
-
527
- 1. **Update Node.js** (if needed):
528
-
529
- ```sh
530
- node --version # Ensure you're on v20.19.0+ or v22.13.0+
531
- ```
532
-
533
- 2. **Update ESLint and this config**:
534
-
535
- ```sh
536
- npm install --save-dev eslint@10 @codfish/eslint-config@latest
537
- ```
538
-
539
- 3. **Install dependencies with legacy peer deps** (required until all plugins update):
540
-
541
- ```sh
542
- npm install --legacy-peer-deps
543
- ```
544
-
545
- This is necessary because some ESLint plugins haven't updated their `peerDependencies` to include ESLint 10 yet. The
546
- plugins still work correctly with ESLint 10.
547
-
548
- 4. **Run linting** and check for new violations:
549
-
550
- ```sh
551
- npm run lint
552
- ```
553
-
554
- 5. **Review React files** for newly reported unused imports. ESLint 10's improved JSX tracking may flag imports that
555
- were previously ignored but are actually used in JSX.
556
-
557
- ### What Changed
558
-
559
- Since this package already uses ESLint's flat config format (the biggest change in ESLint 9), the upgrade to ESLint 10
560
- is relatively smooth. The main changes are:
561
-
562
- - ✅ Flat config format (already implemented)
563
- - ✅ Plugin configurations updated to ESLint 10-compatible versions
564
- - ✅ All tests passing with ESLint 10
565
- - ⚠️ Some plugins show peer dependency warnings but work correctly (ecosystem is catching up)
566
-
567
- For more details, see the [ESLint 10 Migration Guide](https://eslint.org/docs/latest/use/migrate-to-10.0.0).
568
-
569
504
  ## Migration from Legacy Config
570
505
 
571
506
  If you're upgrading from an older version that used Airbnb presets:
572
507
 
573
- 1. **Update to ESLint v10+**: `npm install --save-dev eslint@10`
508
+ 1. **Update to ESLint v9+**: `npm install --save-dev eslint@9`
574
509
  2. **Switch to flat config**: Replace `.eslintrc.js` with `eslint.config.js`
575
510
  3. **Use import syntax**: Change from `require()` to `import` statements
576
511
  4. **Remove explicit React config**: React support is now automatically detected
package/dist/utils.d.ts CHANGED
@@ -1,8 +1,3 @@
1
- /**
2
- * Get the version of a dependency from the consumer's package.json.
3
- * Returns the major version as a string (e.g. '18', '19'), or null if not found.
4
- */
5
- export function getDepVersion(dep: any): string | null;
6
1
  export function hasLocalConfig(moduleName: any, searchOptions?: {}): boolean;
7
2
  export function hasDep(props: any): boolean;
8
3
  export function hasDevDep(props: any): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../utils.js"],"names":[],"mappings":"AAyBA;;;GAGG;AACH,uDAKC;AAED,6EAKC;AA1BgC,4CAA+D;AAA/D,+CAA+D;AAA/D,gDAA+D;AAMzF,8CAA8E;AAE9E,yDAAmE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../utils.js"],"names":[],"mappings":"AAyBA,6EAKC;AAfgC,4CAA+D;AAA/D,+CAA+D;AAA/D,gDAA+D;AAMzF,8CAA8E;AAE9E,yDAAmE"}
package/index.js CHANGED
@@ -8,13 +8,14 @@ import prettierConfig from 'eslint-plugin-prettier/recommended';
8
8
  import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
9
9
  import ymlPlugin from 'eslint-plugin-yml';
10
10
  import globals from 'globals';
11
+ import tseslint from 'typescript-eslint';
11
12
 
12
13
  import prettierBuiltInConfig from './prettier.js';
13
14
  import configFilesConfig from './rules/config-files.js';
14
15
  import reactConfig from './rules/react.js';
15
16
  import testConfig from './rules/tests.js';
16
- import tseslintConfig, { rules as tsRules } from './rules/typescript.js';
17
17
  import { hasLocalConfig, ifAnyDep } from './utils.js';
18
+
18
19
  const useBuiltinPrettierConfig = !hasLocalConfig('prettier');
19
20
 
20
21
  /**
@@ -33,7 +34,7 @@ export default defineConfig([
33
34
 
34
35
  files: ['**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}'],
35
36
 
36
- extends: [js.configs.recommended, ...tseslintConfig],
37
+ extends: [js.configs.recommended, tseslint.configs.recommended],
37
38
 
38
39
  plugins: {
39
40
  'simple-import-sort': simpleImportSortPlugin,
@@ -42,9 +43,6 @@ export default defineConfig([
42
43
  languageOptions: {
43
44
  ecmaVersion: 'latest',
44
45
  sourceType: 'module',
45
- parserOptions: {
46
- ecmaFeatures: { jsx: true },
47
- },
48
46
  globals: {
49
47
  ...globals.browser,
50
48
  ...globals.node,
@@ -56,10 +54,8 @@ export default defineConfig([
56
54
  // Error handling rules to enforce using the Error object
57
55
  'no-throw-literal': 'error',
58
56
  'prefer-promise-reject-errors': 'error',
59
- 'no-unused-vars': ['error', { ignoreRestSiblings: true }],
60
- 'no-empty-function': 'off',
61
57
 
62
- // Asynchronous functions that don't use await might not need to be asynchronous functions
58
+ // Asynchronous functions that dont use await might not need to be asynchronous functions
63
59
  // Usually result of refactoring, leads to misunderstanding/misusage
64
60
  'require-await': 'error',
65
61
 
@@ -89,6 +85,44 @@ export default defineConfig([
89
85
  'simple-import-sort/exports': 'error',
90
86
  'sort-imports': 'off',
91
87
 
88
+ // Allows destructuring of rest properties even if they are unused
89
+ '@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true }],
90
+ '@typescript-eslint/no-empty-function': 'off',
91
+ '@typescript-eslint/naming-convention': [
92
+ 'error',
93
+ {
94
+ selector: ['interface', 'typeAlias'],
95
+ format: ['PascalCase'],
96
+ custom: {
97
+ regex: '^I[A-Z]', // prevent prefixing interfaces and type alias declarations with "I"
98
+ match: false,
99
+ },
100
+ },
101
+ ],
102
+ '@typescript-eslint/ban-ts-comment': [
103
+ 'error',
104
+ {
105
+ // If you need to use a ts comment, make sure you have a description.
106
+ 'ts-ignore': 'allow-with-description',
107
+ 'ts-expect-error': 'allow-with-description',
108
+ 'ts-nocheck': 'allow-with-description',
109
+ },
110
+ ],
111
+
112
+ '@typescript-eslint/no-restricted-types': [
113
+ 'error',
114
+ {
115
+ types: {
116
+ 'React.FC': {
117
+ message: 'Useless and has some drawbacks, see https://github.com/facebook/create-react-app/pull/8177',
118
+ },
119
+ 'React.FunctionComponent': {
120
+ message: 'Useless and has some drawbacks, see https://github.com/facebook/create-react-app/pull/8177',
121
+ },
122
+ },
123
+ },
124
+ ],
125
+
92
126
  // 1. Encouraging `lodash-es` imports per file
93
127
  // lodash imports should use `lodash-es` package and should be imported per file.
94
128
  // E.G: `import get from "lodash-es/get"`
@@ -136,9 +170,6 @@ export default defineConfig([
136
170
  ],
137
171
  },
138
172
  ],
139
-
140
- // TypeScript rules (empty object when typescript is not installed)
141
- ...tsRules,
142
173
  },
143
174
  },
144
175
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codfish/eslint-config",
3
- "version": "0.0.0-PR-155--2a9a213",
3
+ "version": "0.0.0-semantically-released",
4
4
  "description": "Modern ESLint configuration with TypeScript, React, and testing framework support.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -54,45 +54,44 @@
54
54
  "prepare": "husky"
55
55
  },
56
56
  "dependencies": {
57
- "@commitlint/cli": "^20.4.2",
58
- "@commitlint/config-conventional": "^20.4.2",
59
- "@eslint/js": "^10.0.0",
60
- "@eslint/json": "^1.0.1",
61
- "@eslint/markdown": "^8.0.0",
62
- "@html-eslint/eslint-plugin": "^0.58.0",
63
- "@html-eslint/parser": "^0.58.0",
57
+ "@commitlint/cli": "^20.4.0",
58
+ "@commitlint/config-conventional": "^20.4.0",
59
+ "@eslint/js": "^9.35.0",
60
+ "@eslint/json": "^1.0.0",
61
+ "@eslint/markdown": "^7.5.1",
62
+ "@html-eslint/eslint-plugin": "^0.54.2",
63
+ "@html-eslint/parser": "^0.54.0",
64
64
  "@next/eslint-plugin-next": "^16.1.6",
65
65
  "@tanstack/eslint-plugin-query": "^5.91.4",
66
- "@vitest/eslint-plugin": "^1.6.9",
66
+ "@vitest/eslint-plugin": "^1.3.10",
67
67
  "cosmiconfig": "^9.0.0",
68
68
  "eslint-config-prettier": "^10.1.8",
69
- "eslint-plugin-jest": "^29.15.0",
69
+ "eslint-plugin-jest": "^29.0.1",
70
70
  "eslint-plugin-jsx-a11y": "^6.10.2",
71
- "eslint-plugin-prettier": "^5.5.5",
71
+ "eslint-plugin-prettier": "^5.5.4",
72
72
  "eslint-plugin-react": "^7.37.5",
73
73
  "eslint-plugin-react-hooks": "^7.0.1",
74
- "eslint-plugin-react-refresh": "^0.5.2",
74
+ "eslint-plugin-react-refresh": "^0.5.0",
75
75
  "eslint-plugin-simple-import-sort": "^12.1.1",
76
- "eslint-plugin-testing-library": "^7.16.0",
77
- "eslint-plugin-yml": "^3.3.0",
76
+ "eslint-plugin-testing-library": "^7.1.0",
77
+ "eslint-plugin-yml": "^3.0.0",
78
78
  "globals": "^17.3.0",
79
79
  "lodash.has": "^4.5.2",
80
80
  "prettier": ">= 3",
81
81
  "read-package-up": "^12.0.0",
82
- "typescript-eslint": "^8.56.1"
82
+ "typescript-eslint": "^8.44.0"
83
83
  },
84
84
  "devDependencies": {
85
- "@types/node": "^25.3.3",
86
85
  "@vitest/coverage-v8": "^4.0.18",
87
- "doctoc": "^2.3.0",
88
- "eslint": "^10.0.2",
86
+ "doctoc": "^2.2.1",
87
+ "eslint": "^9.35.0",
89
88
  "husky": "^9.1.7",
90
- "lint-staged": "^17.0.0",
91
- "typescript": "^6.0.0",
89
+ "lint-staged": "^16.1.6",
90
+ "typescript": "^5.9.2",
92
91
  "vitest": "^4.0.18"
93
92
  },
94
93
  "engines": {
95
- "node": ">=20.19.0"
94
+ "node": ">=20.0.0"
96
95
  },
97
96
  "files": [
98
97
  "dist",
@@ -105,7 +104,7 @@
105
104
  "commitlint.js"
106
105
  ],
107
106
  "peerDependencies": {
108
- "eslint": ">= 10",
107
+ "eslint": ">= 9",
109
108
  "prettier": ">= 3"
110
109
  },
111
110
  "peerDependenciesMeta": {
@@ -128,6 +127,6 @@
128
127
  ]
129
128
  },
130
129
  "volta": {
131
- "node": "24.14.1"
130
+ "node": "24.8.0"
132
131
  }
133
132
  }
package/rules/react.js CHANGED
@@ -7,7 +7,7 @@ import reactHooks from 'eslint-plugin-react-hooks';
7
7
  import reactRefresh from 'eslint-plugin-react-refresh';
8
8
  import globals from 'globals';
9
9
 
10
- import { getDepVersion, ifAnyDep } from '../utils.js';
10
+ import { ifAnyDep } from '../utils.js';
11
11
 
12
12
  /**
13
13
  * React ESLint configuration. Includes React, React Hooks, and JSX accessibility rules.
@@ -41,9 +41,7 @@ export default defineConfig([
41
41
 
42
42
  settings: {
43
43
  react: {
44
- // Avoid 'detect' — it uses context.getFilename() which was removed in ESLint 10.
45
- // Read the major version from the consumer's package.json instead.
46
- version: getDepVersion('react') || 'detect',
44
+ version: 'detect',
47
45
  },
48
46
  },
49
47
 
package/utils.js CHANGED
@@ -23,17 +23,6 @@ export const hasAnyDep = args => [hasDep, hasDevDep, hasPeerDep].some(fn => fn(a
23
23
 
24
24
  export const ifAnyDep = (deps, t, f) => (hasAnyDep([deps].flat()) ? t : f);
25
25
 
26
- /**
27
- * Get the version of a dependency from the consumer's package.json.
28
- * Returns the major version as a string (e.g. '18', '19'), or null if not found.
29
- */
30
- export function getDepVersion(dep) {
31
- const spec = pkg?.dependencies?.[dep] || pkg?.devDependencies?.[dep] || pkg?.peerDependencies?.[dep];
32
- if (!spec) return null;
33
- const match = spec.match(/\d+/);
34
- return match ? match[0] : null;
35
- }
36
-
37
26
  export function hasLocalConfig(moduleName, searchOptions = {}) {
38
27
  const explorerSync = cosmiconfigSync(moduleName, searchOptions);
39
28
  const result = explorerSync.search(pkgPath || './');
@@ -1,38 +0,0 @@
1
- export default tseslintConfig;
2
- export const rules: {
3
- '@typescript-eslint/no-unused-vars': (string | {
4
- ignoreRestSiblings: boolean;
5
- })[];
6
- '@typescript-eslint/no-empty-function': string;
7
- '@typescript-eslint/naming-convention': (string | {
8
- selector: string[];
9
- format: string[];
10
- custom: {
11
- regex: string;
12
- match: boolean;
13
- };
14
- })[];
15
- '@typescript-eslint/ban-ts-comment': (string | {
16
- 'ts-ignore': string;
17
- 'ts-expect-error': string;
18
- 'ts-nocheck': string;
19
- })[];
20
- '@typescript-eslint/no-restricted-types': (string | {
21
- types: {
22
- 'React.FC': {
23
- message: string;
24
- };
25
- 'React.FunctionComponent': {
26
- message: string;
27
- };
28
- };
29
- })[];
30
- } | {
31
- '@typescript-eslint/no-unused-vars'?: never;
32
- '@typescript-eslint/no-empty-function'?: never;
33
- '@typescript-eslint/naming-convention'?: never;
34
- '@typescript-eslint/ban-ts-comment'?: never;
35
- '@typescript-eslint/no-restricted-types'?: never;
36
- };
37
- declare const tseslintConfig: import("eslint").Linter.Config[];
38
- //# sourceMappingURL=typescript.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../rules/typescript.js"],"names":[],"mappings":";AAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCO;AA9CP,8BACa,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CACsC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=react-integration.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"react-integration.spec.d.ts","sourceRoot":"","sources":["../../../tests/integration/react-integration.spec.js"],"names":[],"mappings":""}
@@ -1,56 +0,0 @@
1
- import { hasAnyDep } from '../utils.js';
2
-
3
- /**
4
- * TypeScript ESLint configuration. Dynamically loads typescript-eslint
5
- * only when typescript is installed in the consuming project.
6
- *
7
- * - https://typescript-eslint.io/
8
- */
9
- const hasTypeScript = hasAnyDep('typescript');
10
- const tseslintConfig =
11
- /** @type {import('eslint').Linter.Config[]} */
12
- (hasTypeScript ? [(await import('typescript-eslint')).configs.recommended] : []);
13
-
14
- export default tseslintConfig;
15
-
16
- export const rules = hasTypeScript
17
- ? {
18
- // Allows destructuring of rest properties even if they are unused
19
- '@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true }],
20
- '@typescript-eslint/no-empty-function': 'off',
21
- '@typescript-eslint/naming-convention': [
22
- 'error',
23
- {
24
- selector: ['interface', 'typeAlias'],
25
- format: ['PascalCase'],
26
- custom: {
27
- regex: '^I[A-Z]', // prevent prefixing interfaces and type alias declarations with "I"
28
- match: false,
29
- },
30
- },
31
- ],
32
- '@typescript-eslint/ban-ts-comment': [
33
- 'error',
34
- {
35
- // If you need to use a ts comment, make sure you have a description.
36
- 'ts-ignore': 'allow-with-description',
37
- 'ts-expect-error': 'allow-with-description',
38
- 'ts-nocheck': 'allow-with-description',
39
- },
40
- ],
41
-
42
- '@typescript-eslint/no-restricted-types': [
43
- 'error',
44
- {
45
- types: {
46
- 'React.FC': {
47
- message: 'Useless and has some drawbacks, see https://github.com/facebook/create-react-app/pull/8177',
48
- },
49
- 'React.FunctionComponent': {
50
- message: 'Useless and has some drawbacks, see https://github.com/facebook/create-react-app/pull/8177',
51
- },
52
- },
53
- },
54
- ],
55
- }
56
- : {};