@codfish/eslint-config 0.0.0-PR-155--2a9a213 → 0.0.0-PR-124--5ec5040

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 (40) hide show
  1. package/README.md +23 -158
  2. package/dist/dapp.d.ts +1 -1
  3. package/dist/docker.d.ts +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/rules/config-files.d.ts +1 -1
  6. package/dist/rules/jest.d.ts +3 -0
  7. package/dist/rules/jest.d.ts.map +1 -0
  8. package/dist/rules/react.d.ts +1 -1
  9. package/dist/rules/vitest.d.ts +3 -0
  10. package/dist/rules/vitest.d.ts.map +1 -0
  11. package/dist/utils.d.ts +0 -5
  12. package/dist/utils.d.ts.map +1 -1
  13. package/index.js +31 -153
  14. package/package.json +26 -38
  15. package/rules/jest.js +34 -0
  16. package/rules/react.js +17 -49
  17. package/rules/vitest.js +39 -0
  18. package/utils.js +5 -13
  19. package/dist/rules/tests.d.ts +0 -3
  20. package/dist/rules/tests.d.ts.map +0 -1
  21. package/dist/rules/typescript.d.ts +0 -38
  22. package/dist/rules/typescript.d.ts.map +0 -1
  23. package/dist/tests/integration/eslint-execution.spec.d.ts +0 -2
  24. package/dist/tests/integration/eslint-execution.spec.d.ts.map +0 -1
  25. package/dist/tests/integration/react-integration.spec.d.ts +0 -2
  26. package/dist/tests/integration/react-integration.spec.d.ts.map +0 -1
  27. package/dist/tests/integration/rule-application.spec.d.ts +0 -2
  28. package/dist/tests/integration/rule-application.spec.d.ts.map +0 -1
  29. package/dist/tests/scenarios/edge-cases.spec.d.ts +0 -2
  30. package/dist/tests/scenarios/edge-cases.spec.d.ts.map +0 -1
  31. package/dist/tests/unit/config-loading.spec.d.ts +0 -2
  32. package/dist/tests/unit/config-loading.spec.d.ts.map +0 -1
  33. package/dist/tests/unit/dynamic-detection.spec.d.ts +0 -2
  34. package/dist/tests/unit/dynamic-detection.spec.d.ts.map +0 -1
  35. package/dist/tests/unit/utils.spec.d.ts +0 -2
  36. package/dist/tests/unit/utils.spec.d.ts.map +0 -1
  37. package/dist/vitest.config.d.ts +0 -3
  38. package/dist/vitest.config.d.ts.map +0 -1
  39. package/rules/tests.js +0 -52
  40. package/rules/typescript.js +0 -56
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)
@@ -18,16 +18,10 @@
18
18
  - [Installation](#installation)
19
19
  - [Usage](#usage)
20
20
  - [Opinionated Highlights](#opinionated-highlights)
21
- - [IDE Setup](#ide-setup)
22
- - [VS Code / Cursor](#vs-code--cursor)
23
21
  - [Prettier Configuration](#prettier-configuration)
24
22
  - [Use in combination with prettier-plugin-tailwindcss](#use-in-combination-with-prettier-plugin-tailwindcss)
25
23
  - [Example scripts](#example-scripts)
26
24
  - [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
25
  - [Migration from Legacy Config](#migration-from-legacy-config)
32
26
 
33
27
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -35,14 +29,14 @@
35
29
 
36
30
  ## Features
37
31
 
38
- - **Modern ESLint v10+ flat config**: Uses the new flat configuration format
32
+ - **Modern ESLint v9+ flat config**: Uses the new flat configuration format
39
33
  - **Dynamic feature detection**: Automatically configures based on your project's dependencies
40
34
  - **TypeScript support**: Full TypeScript linting with modern typescript-eslint parser and rules
41
35
  - **React ecosystem**: React, React Hooks, and JSX accessibility rules when React is detected
42
36
  - **Next.js support**: Automatically configures Next.js official plugin linting rules when detected
43
37
  - **Test framework agnostic**: Supports Jest and Vitest with automatic detection
44
38
  - **Testing Library integration**: Automatically includes Testing Library rules for test files
45
- - **Multi-format support**: Built-in linting and formatting for Markdown, HTML, JSON, YAML/YML files
39
+ - **YAML/YML support**: Built-in linting for YAML configuration files
46
40
  - **Prettier integration**: Built-in Prettier configuration with conflict resolution via eslint-config-prettier
47
41
  - **ESM architecture**: Built with ECMAScript modules and full TypeScript typing
48
42
  - **Docker support**: Optional configuration for dockerized applications
@@ -53,35 +47,9 @@
53
47
  Install the package and required peer dependencies:
54
48
 
55
49
  ```sh
56
- npm i -D eslint@10 @codfish/eslint-config
57
-
58
- # Optionally, you can uninstall plugins or presets you don't need to manage anymore,
59
- # @codfish/eslint-config includes them all.
60
- npm uninstall typescript-eslint \
61
- eslint-config-prettier \
62
- eslint-plugin-jest \
63
- eslint-plugin-jsx-a11y \
64
- eslint-plugin-prettier \
65
- eslint-plugin-react \
66
- eslint-plugin-react-hooks \
67
- @tanstack/eslint-plugin-query \
68
- eslint-plugin-simple-import-sort \
69
- eslint-plugin-testing-library \
70
- eslint-plugin-yml \
71
- @next/eslint-plugin-next \
72
- eslint-plugin-next \
73
- commitlint \
74
- @commitlint/cli \
75
- @commitlint/config-conventional \
76
- prettier # optional, see note
50
+ npm i -D eslint@9 @codfish/eslint-config
77
51
  ```
78
52
 
79
- > [!NOTE]
80
- >
81
- > ESLint now handles linting and formatting for JavaScript, TypeScript, Markdown, HTML, JSON, and YAML files
82
- > automatically. If you want to format additional file types (like CSS, SCSS, etc.), you can leave Prettier installed as
83
- > a dev dependency in your project.
84
-
85
53
  ## Usage
86
54
 
87
55
  Create an `eslint.config.js` file in your project root:
@@ -177,11 +145,6 @@ import codfish from '@codfish/eslint-config';
177
145
  export default defineConfig(
178
146
  codfish,
179
147
 
180
- // Custom ignores
181
- {
182
- ignores: ['some-directory'],
183
- },
184
-
185
148
  {
186
149
  files: ['**/*.spec.{js,ts,jsx,tsx}'],
187
150
  rules: {
@@ -287,49 +250,19 @@ This configuration includes some opinionated settings that you might want to cus
287
250
  See the [configuration examples below](#usage) for instructions on overriding these settings to match your team's
288
251
  preferences.
289
252
 
290
- ## IDE Setup
291
-
292
- ### VS Code / Cursor
253
+ ## Prettier Configuration
293
254
 
294
- For the best development experience with VS Code or Cursor (or any VS Code-based IDE), install the
295
- [ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and configure it to
296
- auto-fix on save:
255
+ **Prettier is included and runs automatically** through ESLint for JavaScript, TypeScript, JSX, and TSX files using the
256
+ [built-in configuration](./prettier.js). **You don't need to install or configure Prettier separately** for basic usage.
297
257
 
298
- Add these settings to your `.vscode/settings.json` or user settings:
258
+ However, if you want to format other file types (like Markdown, JSON, CSS, or YAML) or run Prettier directly, you can
259
+ install it as a dev dependency:
299
260
 
300
- ```json
301
- {
302
- "editor.codeActionsOnSave": {
303
- "source.fixAll": "explicit"
304
- },
305
- "eslint.validate": [
306
- "javascript",
307
- "javascriptreact",
308
- "typescript",
309
- "typescriptreact",
310
- "markdown",
311
- "json",
312
- "jsonc",
313
- "html",
314
- "yml",
315
- "yaml"
316
- ]
317
- }
261
+ ```sh
262
+ npm i -D prettier
318
263
  ```
319
264
 
320
- This configuration enables:
321
-
322
- - Automatic linting and formatting on save for all supported file types
323
- - ESLint validation for Markdown, JSON, YAML, and HTML files
324
- - A unified development experience across your entire codebase
325
-
326
- ## Prettier Configuration
327
-
328
- **Prettier is included and runs automatically** through ESLint for JavaScript, TypeScript, JSX, TSX, Markdown, HTML,
329
- JSON, and YAML files using the [built-in configuration](./prettier.js). **You don't need to install or configure
330
- Prettier separately** for these file types.
331
-
332
- You can then override the default config by creating your own Prettier config file, or extend the built-in config:
265
+ You can then override the defaults by creating your own Prettier config file, or extend the built-in config:
333
266
 
334
267
  **Option 1: Extend the built-in config (Recommended)**
335
268
 
@@ -383,17 +316,18 @@ export default {
383
316
  ### Use in combination with prettier-plugin-tailwindcss
384
317
 
385
318
  ```sh
386
- npm i -D eslint@10 @codfish/eslint-config prettier-plugin-tailwindcss
319
+ npm i -D eslint@9 @codfish/eslint-config prettier-plugin-tailwindcss
387
320
  ```
388
321
 
389
322
  ```js
390
323
  // prettier.config.js
391
324
 
392
- import codfish from '@codfish/eslint-config/prettier';
325
+ import codfishPrettier from '@codfish/eslint-config/prettier';
326
+ import tailwindcss from 'prettier-plugin-tailwindcss';
393
327
 
394
328
  /** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
395
329
  export default {
396
- ...codfish,
330
+ ...codfishPrettier,
397
331
  plugins: ['prettier-plugin-tailwindcss'],
398
332
  tailwindStylesheet: './src/styles/app.css',
399
333
  tailwindFunctions: ['clsx'], // optional
@@ -404,7 +338,7 @@ export default {
404
338
 
405
339
  Optionally, you can add these scripts to your `package.json` for common linting workflows:
406
340
 
407
- **Recommended scripts:**
341
+ **Basic scripts (no separate Prettier installation needed):**
408
342
 
409
343
  ```json
410
344
  {
@@ -413,32 +347,24 @@ Optionally, you can add these scripts to your `package.json` for common linting
413
347
  "fix": "eslint . --fix"
414
348
  },
415
349
  "lint-staged": {
416
- "*.{js,jsx,ts,tsx,md,json,yml,yaml,html}": ["eslint --fix"]
350
+ "*.{js,jsx,ts,tsx}": ["eslint --fix"]
417
351
  }
418
352
  }
419
353
  ```
420
354
 
421
- > [!NOTE]
422
- >
423
- > ESLint now handles linting and formatting for JavaScript, TypeScript, Markdown, HTML, JSON, and YAML files. You don't
424
- > need to run Prettier separately for these file types.
425
-
426
- **With Prettier for other file types (CSS, SCSS, etc.):**
427
-
428
- If you want to format additional file types not covered by ESLint (like CSS, SCSS), you can install Prettier and add
429
- these scripts:
355
+ **With Prettier installed separately (for formatting non-JS files):**
430
356
 
431
357
  ```json
432
358
  {
433
359
  "scripts": {
434
360
  "lint": "eslint .",
435
361
  "fix": "eslint . --fix",
436
- "format": "prettier --write \"**/*.{css,scss}\"",
362
+ "format": "prettier --config ./node_modules/@codfish/eslint-config/prettier.js --write \"**/*.{json,css,md}\"",
437
363
  "check": "npm run lint && npm run format -- --check --no-write"
438
364
  },
439
365
  "lint-staged": {
440
- "*.{js,jsx,ts,tsx,md,json,yml,yaml,html}": ["eslint --fix"],
441
- "*.{css,scss}": ["prettier --write"]
366
+ "*.{js,jsx,ts,tsx}": ["eslint --fix"],
367
+ "*.{json,css,md}": ["prettier --write --config ./node_modules/@codfish/eslint-config/prettier.js"]
442
368
  }
443
369
  }
444
370
  ```
@@ -505,72 +431,11 @@ jobs:
505
431
  --verbose
506
432
  ```
507
433
 
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
434
  ## Migration from Legacy Config
570
435
 
571
436
  If you're upgrading from an older version that used Airbnb presets:
572
437
 
573
- 1. **Update to ESLint v10+**: `npm install --save-dev eslint@10`
438
+ 1. **Update to ESLint v9+**: `npm install --save-dev eslint@9`
574
439
  2. **Switch to flat config**: Replace `.eslintrc.js` with `eslint.config.js`
575
440
  3. **Use import syntax**: Change from `require()` to `import` statements
576
441
  4. **Remove explicit React config**: React support is now automatically detected
package/dist/dapp.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- declare const _default: import("eslint/config").Config[];
1
+ declare const _default: import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
2
2
  export default _default;
3
3
  //# sourceMappingURL=dapp.d.ts.map
package/dist/docker.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- declare const _default: import("eslint/config").Config[];
1
+ declare const _default: import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
2
2
  export default _default;
3
3
  //# sourceMappingURL=docker.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- declare const _default: import("eslint/config").Config[];
1
+ declare const _default: import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
2
2
  export default _default;
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,3 @@
1
- declare const _default: import("eslint/config").Config[];
1
+ declare const _default: import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
2
2
  export default _default;
3
3
  //# sourceMappingURL=config-files.d.ts.map
@@ -0,0 +1,3 @@
1
+ declare const _default: import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
2
+ export default _default;
3
+ //# sourceMappingURL=jest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jest.d.ts","sourceRoot":"","sources":["../../rules/jest.js"],"names":[],"mappings":""}
@@ -1,3 +1,3 @@
1
- declare const _default: import("eslint/config").Config[];
1
+ declare const _default: import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
2
2
  export default _default;
3
3
  //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1,3 @@
1
+ declare const _default: import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
2
+ export default _default;
3
+ //# sourceMappingURL=vitest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../rules/vitest.js"],"names":[],"mappings":""}
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":"AA4BA,6EAKC;AAfgC,4CAA+D;AAA/D,+CAA+D;AAA/D,gDAA+D;AAMzF,8CAA8E;AAE9E,yDAAmE"}
package/index.js CHANGED
@@ -1,39 +1,33 @@
1
1
  import js from '@eslint/js';
2
- import json from '@eslint/json';
3
- import markdown from '@eslint/markdown';
4
- import html from '@html-eslint/eslint-plugin';
5
- import htmlParser from '@html-eslint/parser';
6
2
  import { defineConfig } from 'eslint/config';
7
- import prettierConfig from 'eslint-plugin-prettier/recommended';
3
+ import prettier from 'eslint-plugin-prettier/recommended';
8
4
  import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
9
5
  import ymlPlugin from 'eslint-plugin-yml';
10
6
  import globals from 'globals';
7
+ import tseslint from 'typescript-eslint';
11
8
 
12
9
  import prettierBuiltInConfig from './prettier.js';
13
10
  import configFilesConfig from './rules/config-files.js';
11
+ import jestConfig from './rules/jest.js';
14
12
  import reactConfig from './rules/react.js';
15
- import testConfig from './rules/tests.js';
16
- import tseslintConfig, { rules as tsRules } from './rules/typescript.js';
13
+ import vitestConfig from './rules/vitest.js';
17
14
  import { hasLocalConfig, ifAnyDep } from './utils.js';
15
+
18
16
  const useBuiltinPrettierConfig = !hasLocalConfig('prettier');
19
17
 
20
18
  /**
21
- * Modern ESLint configuration with dynamic feature detection.
22
- * Supports TypeScript, React, Vitest, Prettier, YAML, and more.
23
- *
24
- * React ESLint configuration. Includes React, React Hooks, and JSX accessibility rules.
25
- * - https://github.com/jsx-eslint/eslint-plugin-react
26
- * - https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks
27
- * - https://github.com/jsx-eslint/eslint-plugin-jsx-a11y
19
+ * Modern ESLint configuration with dynamic feature detection
20
+ * Supports TypeScript, React, Jest, Vitest, Prettier, YAML, and Next.js
28
21
  */
29
22
  export default defineConfig([
30
- // Base opinionated rules
31
- {
32
- name: 'codfish/base',
23
+ // Base JavaScript configuration
24
+ js.configs.recommended,
33
25
 
34
- files: ['**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}'],
26
+ tseslint.configs.recommended,
35
27
 
36
- extends: [js.configs.recommended, ...tseslintConfig],
28
+ // Base configuration for all files
29
+ {
30
+ name: 'codfish/base',
37
31
 
38
32
  plugins: {
39
33
  'simple-import-sort': simpleImportSortPlugin,
@@ -42,9 +36,6 @@ export default defineConfig([
42
36
  languageOptions: {
43
37
  ecmaVersion: 'latest',
44
38
  sourceType: 'module',
45
- parserOptions: {
46
- ecmaFeatures: { jsx: true },
47
- },
48
39
  globals: {
49
40
  ...globals.browser,
50
41
  ...globals.node,
@@ -53,22 +44,6 @@ export default defineConfig([
53
44
  },
54
45
 
55
46
  rules: {
56
- // Error handling rules to enforce using the Error object
57
- 'no-throw-literal': 'error',
58
- 'prefer-promise-reject-errors': 'error',
59
- 'no-unused-vars': ['error', { ignoreRestSiblings: true }],
60
- 'no-empty-function': 'off',
61
-
62
- // Asynchronous functions that don't use await might not need to be asynchronous functions
63
- // Usually result of refactoring, leads to misunderstanding/misusage
64
- 'require-await': 'error',
65
-
66
- // Disallow console statements in regular code (only allowed in test files)
67
- 'no-console': 'error',
68
-
69
- // Consolidate your imports
70
- 'no-duplicate-imports': ['error', { includeExports: false }],
71
-
72
47
  // Custom Grouping: https://github.com/lydell/eslint-plugin-simple-import-sort#custom-grouping
73
48
  // Examples: https://github.com/lydell/eslint-plugin-simple-import-sort/blob/main/examples/.eslintrc.js
74
49
  'simple-import-sort/imports': [
@@ -87,58 +62,32 @@ export default defineConfig([
87
62
  },
88
63
  ],
89
64
  'simple-import-sort/exports': 'error',
90
- 'sort-imports': 'off',
91
65
 
92
- // 1. Encouraging `lodash-es` imports per file
66
+ // 2. Encouraging `lodash-es` imports per file
93
67
  // lodash imports should use `lodash-es` package and should be imported per file.
94
- // E.G: `import get from "lodash-es/get"`
68
+ // E.G: `import get from 'lodash-es/get'`
95
69
  // More details in https://stackoverflow.com/questions/35250500/correct-way-to-import-lodash#answer-35251059
96
- // 2. Prevent relative imports - use path aliases instead
97
- // Use `@/` for src imports and `@tests/` for test imports
98
- // 3. Prevent vitest globals imports - these are available globally
99
70
  'no-restricted-imports': [
100
71
  'error',
101
72
  {
102
73
  paths: [
103
74
  {
104
75
  name: 'lodash',
105
- message: 'Please use lodash-es direct import E.G: `import get from "lodash-es/get"`',
76
+ message: "Please use lodash-es direct import E.G: `import get from 'lodash-es/get'`",
106
77
  },
107
78
  {
108
79
  name: 'lodash-es',
109
- message: 'Please use lodash-es direct import E.G: `import get from "lodash-es/get"`',
110
- },
111
- {
112
- name: 'jest',
113
- importNames: ['describe', 'expect', 'test', 'it', 'jest'],
114
- message:
115
- 'These jest globals (describe, expect, test, it, jest) are available globally and should not be imported. Remove this import statement.',
116
- },
117
- {
118
- name: 'vitest',
119
- importNames: ['describe', 'expect', 'test', 'it', 'vi'],
120
- message:
121
- 'These vitest globals (describe, expect, test, it, vi) are available globally and should not be imported. Remove this import statement.',
80
+ message: "Please use lodash-es direct import E.G: `import get from 'lodash-es/get'`",
122
81
  },
123
82
  ],
124
83
  patterns: [
125
84
  {
126
85
  group: ['lodash/*'],
127
- message: 'Please use lodash-es direct import E.G: `import get from "lodash-es/get"`',
128
- },
129
- {
130
- // Prevent relative imports going back 1+ directories. Use @/ or @tests/ aliases instead.
131
- // Ensures consistent and cleaner import paths, and avoids confusing import hell with deeply nested files.
132
- group: ['../*', '../../*', '../../../*', '../../../../*'],
133
- message:
134
- 'Relative imports going back 1+ directories are not allowed. Use path aliases: @/ for src/*, @tests/ for tests/* imports. For example, instead of `import x from "../components/*"`, use `import x from "@/components/*"`',
86
+ message: "Please use lodash-es direct import E.G: `import get from 'lodash-es/get'`",
135
87
  },
136
88
  ],
137
89
  },
138
90
  ],
139
-
140
- // TypeScript rules (empty object when typescript is not installed)
141
- ...tsRules,
142
91
  },
143
92
  },
144
93
 
@@ -153,6 +102,7 @@ export default defineConfig([
153
102
  'coverage',
154
103
  '.vercel',
155
104
  '**/logs/',
105
+ 'bin/*',
156
106
  '**/dist/',
157
107
  '**/dist-ssr/',
158
108
  '**/cache/',
@@ -183,109 +133,37 @@ export default defineConfig([
183
133
  '.expo',
184
134
  '**/tmp/',
185
135
  '**/temp/',
186
- '**/.tmp',
187
- '.nx',
188
- '**/.eslintcache',
136
+ '.tmp',
137
+ '.eslintcache',
189
138
  '*.tsbuildinfo',
190
- 'node_modules',
191
- '**/node_modules/',
192
- '**/pnpm-lock.yaml',
193
- '**/pnpm-lock.*.yaml',
194
- '.history',
195
- '**/.yarn',
196
- '**/yarn.lock',
197
- '**/package-lock.json',
198
- '**/.yarnrc.yml',
199
- 'pacts',
200
- '.claude',
201
- '.__mf__temp',
202
139
  ],
203
140
  },
204
141
 
205
142
  // Configuration files (eslint, prettier, etc.)
206
143
  configFilesConfig,
207
144
 
208
- // React configuration (dynamic)
209
- ifAnyDep('react', reactConfig, []),
210
-
211
- // Jest OR Vitest configuration (dynamic)
212
- ifAnyDep(['jest', 'vitest'], testConfig, []),
213
-
214
145
  // YML files
215
146
  ymlPlugin.configs['flat/standard'],
216
147
  ymlPlugin.configs['flat/prettier'], // handles conflicting rules with the yml plugin
217
148
 
218
- {
219
- name: 'codfish/github-yml-overrides',
220
-
221
- files: ['.github/**/*.yml', '.github/**/*.yaml'],
222
-
223
- rules: {
224
- 'yml/no-empty-mapping-value': 'off', // somewhat common in github workflows
225
- },
226
- },
227
-
228
- // JSON files
229
- {
230
- name: 'codfish/json',
231
- files: ['**/*.json'],
232
- ignores: ['**/tsconfig*.json', '**/package-lock.json'],
233
- plugins: { json },
234
- language: 'json/json',
235
- extends: ['json/recommended'],
236
- },
237
-
238
- // JSONC files (JSON with Comments) - for files that allow comments
239
- {
240
- name: 'codfish/jsonc',
241
- files: ['**/*.jsonc'],
242
- plugins: { json },
243
- language: 'json/jsonc',
244
- extends: ['json/recommended'],
245
- },
246
-
247
- // JSON5 files - for TypeScript configs (supports comments AND trailing commas)
248
- {
249
- name: 'codfish/json5',
250
- files: ['**/tsconfig*.json', '**/*.json5'],
251
- plugins: { json },
252
- language: 'json/json5',
253
- extends: ['json/recommended'],
254
- },
149
+ // React configuration (dynamic)
150
+ ifAnyDep('react', reactConfig, []),
255
151
 
256
- // Markdown files
257
- {
258
- name: 'codfish/markdown',
259
- files: ['**/*.md'],
260
- plugins: { markdown },
261
- extends: ['markdown/recommended'],
262
- rules: {
263
- // Allow GitHub-style alerts and checkbox syntax (task lists)
264
- 'markdown/no-missing-label-refs': [
265
- 'error',
266
- { allowLabels: ['!NOTE', '!WARNING', '!IMPORTANT', '!TIP', '!CAUTION', '', 'x', 'X'] },
267
- ],
268
- },
269
- },
152
+ // Jest OR Vitest configuration (dynamic)
153
+ ifAnyDep('jest', jestConfig, []),
270
154
 
271
- // HTML files
272
- {
273
- name: 'codfish/html',
274
- files: ['**/*.html'],
275
- plugins: { html },
276
- languageOptions: { parser: htmlParser },
277
- },
155
+ // Vitest configuration (dynamic)
156
+ ifAnyDep('vitest', vitestConfig, []),
278
157
 
279
158
  // Prettier plugin is responsible for running prettier as an ESLint
280
159
  // rule and turning off ESLint rules that might conflict.
281
160
  // IMPORTANT: KEEP THIS LAST TO OVERRIDE ESLINT!
282
- {
283
- files: ['**/*.{js,ts,jsx,tsx,md,yml,yaml,html,json,jsonc,json5}'],
284
-
285
- extends: [prettierConfig],
161
+ prettier,
286
162
 
163
+ {
287
164
  rules: {
288
- // Reset prettier rule passing in custom prettier config.
165
+ // Reset prettier rule passing in codfish's prettier config.
166
+ // IMPORTANT: KEEP THIS LAST TO OVERRIDE PRETTIER PLUGIN!
289
167
  'prettier/prettier': useBuiltinPrettierConfig ? ['error', prettierBuiltInConfig] : 'error',
290
168
  },
291
169
  },
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-PR-124--5ec5040",
4
4
  "description": "Modern ESLint configuration with TypeScript, React, and testing framework support.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -45,54 +45,43 @@
45
45
  "scripts": {
46
46
  "build": "tsc --emitDeclarationOnly",
47
47
  "dev": "tsc --watch",
48
- "typecheck": "tsc --noEmit",
49
- "lint": "eslint",
50
- "format": "eslint --fix",
51
- "test": "vitest",
52
- "test:coverage": "vitest --coverage",
48
+ "type-check": "tsc --noEmit",
49
+ "lint": "eslint .",
50
+ "fix": "prettier --write \"**/*.{json,css,scss,md}\" --config ./prettier.js && npm run lint -- --fix",
53
51
  "prepublishOnly": "npm run build",
54
52
  "prepare": "husky"
55
53
  },
56
54
  "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",
64
- "@next/eslint-plugin-next": "^16.1.6",
65
- "@tanstack/eslint-plugin-query": "^5.91.4",
66
- "@vitest/eslint-plugin": "^1.6.9",
55
+ "@commitlint/cli": "^19.8.1",
56
+ "@commitlint/config-conventional": "^19.8.1",
57
+ "@eslint/js": "^9.35.0",
58
+ "@vitest/eslint-plugin": "^1.3.10",
67
59
  "cosmiconfig": "^9.0.0",
68
60
  "eslint-config-prettier": "^10.1.8",
69
- "eslint-plugin-jest": "^29.15.0",
61
+ "eslint-plugin-jest": "^29.0.1",
70
62
  "eslint-plugin-jsx-a11y": "^6.10.2",
71
- "eslint-plugin-prettier": "^5.5.5",
63
+ "eslint-plugin-prettier": "^5.5.4",
72
64
  "eslint-plugin-react": "^7.37.5",
73
- "eslint-plugin-react-hooks": "^7.0.1",
74
- "eslint-plugin-react-refresh": "^0.5.2",
65
+ "eslint-plugin-react-hooks": "^5.2.0",
75
66
  "eslint-plugin-simple-import-sort": "^12.1.1",
76
- "eslint-plugin-testing-library": "^7.16.0",
77
- "eslint-plugin-yml": "^3.3.0",
78
- "globals": "^17.3.0",
67
+ "eslint-plugin-testing-library": "^7.1.0",
68
+ "eslint-plugin-yml": "^1.16.0",
69
+ "@next/eslint-plugin-next": "^15.1.6",
70
+ "globals": "^16.4.0",
79
71
  "lodash.has": "^4.5.2",
80
- "prettier": ">= 3",
81
- "read-package-up": "^12.0.0",
82
- "typescript-eslint": "^8.56.1"
72
+ "prettier": "^3.6.2",
73
+ "read-package-up": "^11.0.0",
74
+ "typescript-eslint": "^8.44.0"
83
75
  },
84
76
  "devDependencies": {
85
- "@types/node": "^25.3.3",
86
- "@vitest/coverage-v8": "^4.0.18",
87
- "doctoc": "^2.3.0",
88
- "eslint": "^10.0.2",
77
+ "doctoc": "^2.2.1",
78
+ "eslint": "^9.35.0",
89
79
  "husky": "^9.1.7",
90
- "lint-staged": "^17.0.0",
91
- "typescript": "^6.0.0",
92
- "vitest": "^4.0.18"
80
+ "lint-staged": "^16.1.6",
81
+ "typescript": "^5.9.2"
93
82
  },
94
83
  "engines": {
95
- "node": ">=20.19.0"
84
+ "node": ">=20.0.0"
96
85
  },
97
86
  "files": [
98
87
  "dist",
@@ -105,11 +94,10 @@
105
94
  "commitlint.js"
106
95
  ],
107
96
  "peerDependencies": {
108
- "eslint": ">= 10",
109
- "prettier": ">= 3"
97
+ "eslint": ">= 9"
110
98
  },
111
99
  "peerDependenciesMeta": {
112
- "prettier": {
100
+ "typescript": {
113
101
  "optional": true
114
102
  }
115
103
  },
@@ -128,6 +116,6 @@
128
116
  ]
129
117
  },
130
118
  "volta": {
131
- "node": "24.14.1"
119
+ "node": "24.8.0"
132
120
  }
133
121
  }
package/rules/jest.js ADDED
@@ -0,0 +1,34 @@
1
+ import { defineConfig } from 'eslint/config';
2
+ import jest from 'eslint-plugin-jest';
3
+ import testingLibrary from 'eslint-plugin-testing-library';
4
+
5
+ import { ifAnyDep } from '../utils.js';
6
+
7
+ /**
8
+ * Jest ESLint configuration for flat config format
9
+ * Includes Jest-specific rules, globals, and Testing Library rules for test files
10
+ */
11
+ export default defineConfig([
12
+ {
13
+ name: 'codfish/jest',
14
+
15
+ files: [
16
+ '**/__tests__/**/*.{js,ts,jsx,tsx}',
17
+ '**/*.{test,spec}.{js,ts,jsx,tsx}',
18
+ '**/jest.config.{js,ts}',
19
+ '**/jest.setup.{js,ts}',
20
+ '**/setupTests.{js,ts}',
21
+ '**/testUtils.{js,ts}',
22
+ 'tests/**/*.{js,ts,jsx,tsx}',
23
+ ],
24
+
25
+ ...jest.configs['flat/recommended'],
26
+
27
+ ...ifAnyDep('react-testing-library', testingLibrary.configs['flat/react'], {}),
28
+ ...ifAnyDep('vue-testing-library', testingLibrary.configs['flat/vue'], {}),
29
+
30
+ rules: {
31
+ 'no-console': 'off',
32
+ },
33
+ },
34
+ ]);
package/rules/react.js CHANGED
@@ -1,13 +1,11 @@
1
1
  import nextPlugin from '@next/eslint-plugin-next';
2
- import tanstackQuery from '@tanstack/eslint-plugin-query';
3
2
  import { defineConfig } from 'eslint/config';
4
3
  import jsxA11y from 'eslint-plugin-jsx-a11y';
5
4
  import react from 'eslint-plugin-react';
6
5
  import reactHooks from 'eslint-plugin-react-hooks';
7
- import reactRefresh from 'eslint-plugin-react-refresh';
8
6
  import globals from 'globals';
9
7
 
10
- import { getDepVersion, ifAnyDep } from '../utils.js';
8
+ import { ifAnyDep } from '../utils.js';
11
9
 
12
10
  /**
13
11
  * React ESLint configuration. Includes React, React Hooks, and JSX accessibility rules.
@@ -20,17 +18,10 @@ export default defineConfig([
20
18
  {
21
19
  name: 'codfish/react',
22
20
 
23
- files: ['**/*.jsx', '**/*.tsx', '**/*.mjsx', '**/*.mtsx'],
21
+ files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
24
22
 
25
- extends: [
26
- react.configs.flat.recommended,
27
- reactHooks.configs.flat['recommended-latest'],
28
- reactRefresh.configs.recommended,
29
- jsxA11y.flatConfigs.recommended,
30
- ifAnyDep('@tanstack/react-query', tanstackQuery.configs['flat/recommended']),
31
- ifAnyDep('next', nextPlugin.configs.recommended),
32
- ifAnyDep('next', nextPlugin.configs['core-web-vitals']),
33
- ].filter(Boolean),
23
+ ...react.configs.flat.recommended,
24
+ ...jsxA11y.flatConfigs.recommended,
34
25
 
35
26
  languageOptions: {
36
27
  globals: {
@@ -38,49 +29,26 @@ export default defineConfig([
38
29
  ...globals.browser,
39
30
  },
40
31
  },
32
+ },
41
33
 
42
- settings: {
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',
47
- },
48
- },
49
-
50
- rules: {
51
- // React 17+ uses automatic JSX runtime, no need to import React
52
- 'react/react-in-jsx-scope': 'off',
53
- 'react/jsx-uses-react': 'off',
54
-
55
- // TypeScript provides type checking, no need for PropTypes
56
- 'react/prop-types': 'off',
57
-
58
- // this rule is too noisey and doesn't account for certain valid use cases
59
- 'react-hooks/exhaustive-deps': 'off',
60
-
61
- // sometimes autoFocus is needed for better UX. @todo - revisit later?
62
- 'jsx-a11y/no-autofocus': 'off',
63
-
64
- 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
34
+ // React Hooks configuration
35
+ reactHooks.configs['recommended-latest'],
65
36
 
66
- ...ifAnyDep('@tanstack/react-query', { '@tanstack/query/exhaustive-deps': 'error' }, {}),
37
+ // Next.js configuration (dynamic)
38
+ ifAnyDep(
39
+ 'next',
40
+ {
41
+ ...nextPlugin.flatConfig.recommended,
42
+ ...nextPlugin.flatConfig.coreWebVitals,
67
43
 
68
- ...ifAnyDep(
69
- 'next',
70
- {
71
- // annoying cause this is common in Next.js, i.e. generateMetadata()
72
- 'react-refresh/only-export-components': ['off'],
73
- },
74
- {},
75
- ),
44
+ name: 'codfish/next',
76
45
  },
77
- },
46
+ {},
47
+ ),
78
48
 
79
49
  {
80
- name: 'codfish/react-next-config',
81
- files: ['next.config.js', 'next.config.ts'],
82
50
  rules: {
83
- 'require-await': 'off',
51
+ 'react-hooks/exhaustive-deps': 'off',
84
52
  },
85
53
  },
86
54
  ]);
@@ -0,0 +1,39 @@
1
+ import vitest from '@vitest/eslint-plugin';
2
+ import { defineConfig } from 'eslint/config';
3
+ import testingLibrary from 'eslint-plugin-testing-library';
4
+ import globals from 'globals';
5
+
6
+ import { ifAnyDep } from '../utils.js';
7
+
8
+ /**
9
+ * Vitest ESLint configuration for flat config format
10
+ * Includes Vitest-specific rules, globals, and Testing Library rules for test files
11
+ */
12
+ export default defineConfig([
13
+ {
14
+ files: [
15
+ '**/*.{spec,test}.{js,ts,jsx,tsx}',
16
+ '**/tests/**/*.{js,ts,jsx,tsx}',
17
+ '**/__mocks__/**/*.{js,ts,jsx,tsx}',
18
+ '**/__tests__/**/*.{js,ts,jsx,tsx}',
19
+ ],
20
+
21
+ ...vitest.configs.recommended,
22
+
23
+ ...ifAnyDep('react-testing-library', testingLibrary.configs['flat/react'], {}),
24
+ ...ifAnyDep('vue-testing-library', testingLibrary.configs['flat/vue'], {}),
25
+
26
+ name: 'codfish/vitest',
27
+
28
+ languageOptions: {
29
+ globals: {
30
+ ...vitest.environments.env.globals,
31
+ ...globals.node,
32
+ },
33
+ },
34
+
35
+ rules: {
36
+ 'no-console': 'off',
37
+ },
38
+ },
39
+ ]);
package/utils.js CHANGED
@@ -8,9 +8,12 @@
8
8
  import fs from 'node:fs';
9
9
  import { cosmiconfigSync } from 'cosmiconfig';
10
10
  import has from 'lodash.has';
11
- import { readPackageUpSync } from 'read-package-up';
11
+ import { readPackageUp } from 'read-package-up';
12
12
 
13
- const { packageJson: pkg, path: pkgPath } = readPackageUpSync({ cwd: fs.realpathSync(process.cwd()) }) || {};
13
+ const { packageJson: pkg, path: pkgPath } =
14
+ (await readPackageUp({
15
+ cwd: fs.realpathSync(process.cwd()),
16
+ })) || {};
14
17
 
15
18
  const hasPkgProp = props => [props].flat().some(prop => has(pkg, prop));
16
19
  const hasPkgSubProp = pkgProp => props => hasPkgProp([props].flat().map(p => `${pkgProp}.${p}`));
@@ -23,17 +26,6 @@ export const hasAnyDep = args => [hasDep, hasDevDep, hasPeerDep].some(fn => fn(a
23
26
 
24
27
  export const ifAnyDep = (deps, t, f) => (hasAnyDep([deps].flat()) ? t : f);
25
28
 
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
29
  export function hasLocalConfig(moduleName, searchOptions = {}) {
38
30
  const explorerSync = cosmiconfigSync(moduleName, searchOptions);
39
31
  const result = explorerSync.search(pkgPath || './');
@@ -1,3 +0,0 @@
1
- declare const _default: import("eslint/config").Config[];
2
- export default _default;
3
- //# sourceMappingURL=tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../rules/tests.js"],"names":[],"mappings":""}
@@ -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=eslint-execution.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eslint-execution.spec.d.ts","sourceRoot":"","sources":["../../../tests/integration/eslint-execution.spec.js"],"names":[],"mappings":""}
@@ -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,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=rule-application.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rule-application.spec.d.ts","sourceRoot":"","sources":["../../../tests/integration/rule-application.spec.js"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=edge-cases.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"edge-cases.spec.d.ts","sourceRoot":"","sources":["../../../tests/scenarios/edge-cases.spec.js"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=config-loading.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-loading.spec.d.ts","sourceRoot":"","sources":["../../../tests/unit/config-loading.spec.js"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=dynamic-detection.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dynamic-detection.spec.d.ts","sourceRoot":"","sources":["../../../tests/unit/dynamic-detection.spec.js"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=utils.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.spec.d.ts","sourceRoot":"","sources":["../../../tests/unit/utils.spec.js"],"names":[],"mappings":""}
@@ -1,3 +0,0 @@
1
- declare const _default: import("vite").UserConfig;
2
- export default _default;
3
- //# sourceMappingURL=vitest.config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["../vitest.config.js"],"names":[],"mappings":""}
package/rules/tests.js DELETED
@@ -1,52 +0,0 @@
1
- import vitest from '@vitest/eslint-plugin';
2
- import { defineConfig } from 'eslint/config';
3
- import jest from 'eslint-plugin-jest';
4
- import testingLibrary from 'eslint-plugin-testing-library';
5
- import globals from 'globals';
6
-
7
- import { ifAnyDep } from '../utils.js';
8
-
9
- /**
10
- * Jest ESLint configuration for flat config format
11
- * Includes Jest-specific rules, globals, and Testing Library rules for test files
12
- */
13
- export default defineConfig({
14
- name: 'codfish/tests',
15
-
16
- files: [
17
- '**/*.{spec,test}.{js,ts,jsx,tsx}',
18
- '**/tests/**/*.{js,ts,jsx,tsx}',
19
- '**/__mocks__/**/*.{js,ts,jsx,tsx}',
20
- '**/__tests__/**/*.{js,ts,jsx,tsx}',
21
- '**/jest.config.{js,ts}',
22
- '**/jest.setup.{js,ts}',
23
- '**/vitest.config.{js,ts}',
24
- '**/vitest.setup.{js,ts}',
25
- '**/setupTests.{js,ts}',
26
- '**/testUtils.{js,ts}',
27
- 'tests/**/*.{js,ts,jsx,tsx}',
28
- ],
29
-
30
- extends: [
31
- ifAnyDep('jest', jest.configs['flat/recommended'], false),
32
- ifAnyDep('vitest', vitest.configs.recommended, false),
33
- ifAnyDep('@testing-library/dom', testingLibrary.configs['flat/dom'], false),
34
- ifAnyDep('@testing-library/react', testingLibrary.configs['flat/react'], false),
35
- ifAnyDep('@testing-library/vue', testingLibrary.configs['flat/vue'], false),
36
- ifAnyDep('@testing-library/svelte', testingLibrary.configs['flat/svelte'], false),
37
- ifAnyDep('@testing-library/angular', testingLibrary.configs['flat/angular'], false),
38
- ifAnyDep('@testing-library/marko', testingLibrary.configs['flat/marko'], false),
39
- ].filter(Boolean),
40
-
41
- languageOptions: {
42
- globals: {
43
- ...globals.node,
44
- ...ifAnyDep('jest', globals.jest, {}),
45
- ...ifAnyDep('vitest', globals.vitest, {}),
46
- },
47
- },
48
-
49
- rules: {
50
- 'no-console': 'off',
51
- },
52
- });
@@ -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
- : {};