eslint-config-agent 3.0.4 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +158 -0
  2. package/README.md +592 -26
  3. package/configs/base-plugins.js +32 -0
  4. package/configs/config-files.js +19 -3
  5. package/configs/examples.js +12 -1
  6. package/configs/javascript.js +12 -4
  7. package/configs/length-rule-scope.js +27 -0
  8. package/configs/overrides.js +3 -14
  9. package/configs/test-files.js +40 -1
  10. package/configs/tsx.js +10 -0
  11. package/configs/typescript.js +44 -2
  12. package/exports/ddd.d.ts +10 -0
  13. package/exports/ddd.js +1 -3
  14. package/exports/incremental.d.ts +11 -0
  15. package/exports/incremental.js +39 -0
  16. package/exports/recommended-incremental.d.ts +11 -0
  17. package/exports/recommended-incremental.js +46 -0
  18. package/exports/recommended.d.ts +14 -0
  19. package/exports/recommended.js +110 -0
  20. package/exports/to-warnings.d.ts +20 -0
  21. package/exports/to-warnings.js +41 -0
  22. package/index.d.ts +18 -0
  23. package/index.js +883 -7
  24. package/package.json +46 -17
  25. package/plugins/index.js +6 -0
  26. package/rules/index.js +20 -22
  27. package/rules/no-inline-union-types/index.js +8 -6
  28. package/rules/no-process-env-properties/index.js +4 -4
  29. package/rules/no-record-literal-types/index.js +3 -3
  30. package/rules/plugin/import/index.js +41 -0
  31. package/rules/plugin/index.js +0 -2
  32. package/rules/plugin/n/index.js +16 -2
  33. package/rules/plugin/n/no-process-env/index.js +4 -4
  34. package/rules/plugin/react/index.js +150 -2
  35. package/rules/plugin/typescript-eslint/index.js +406 -0
  36. package/rules/require-spec-file-tsx/README.md +57 -0
  37. package/rules/require-spec-file-tsx/helpers.js +93 -0
  38. package/rules/require-spec-file-tsx/index.js +109 -0
  39. package/rules/plugin/jsx-a11y/index.js +0 -3
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Custom ESLint rule: require-spec-file-tsx
3
+ *
4
+ * Require a sibling spec/test file next to every `.tsx`/`.jsx` source file
5
+ * that contains logic (a component, hook, or any function/class with a body).
6
+ *
7
+ * Why this rule exists: the shared config already enforces
8
+ * `ddd/require-spec-file`, but the upstream `eslint-plugin-ddd` rule only
9
+ * inspects `.js`/`.ts` files — it bails out on any other extension. That
10
+ * silently exempts `.tsx`/`.jsx` files, i.e. the React/Preact components this
11
+ * config primarily targets. This rule covers the JSX extensions with the same
12
+ * heuristic, leaving `.js`/`.ts` to the `ddd` plugin.
13
+ *
14
+ * A file satisfies the rule when a sibling `<name>.spec.<ext>` exists in the
15
+ * same directory. As with `ddd/require-spec-file`, only the `.spec.*` name
16
+ * counts; a `.test.*` sibling is still skipped from needing its own spec but
17
+ * does not satisfy the requirement for the source file.
18
+ */
19
+
20
+ import { existsSync } from 'node:fs'
21
+ import { parse as parsePath, join as joinPath } from 'node:path'
22
+ import {
23
+ JSX_EXTENSIONS,
24
+ hasLogicInNode,
25
+ checkExcludePatterns,
26
+ DEFAULT_EXCLUDE_PATTERNS,
27
+ } from './helpers.js'
28
+
29
+ export const requireSpecFileTsxRule = {
30
+ meta: {
31
+ type: 'problem',
32
+ docs: {
33
+ description:
34
+ 'Require a sibling spec/test file for .tsx/.jsx files with logic',
35
+ category: 'Best Practices',
36
+ },
37
+ messages: {
38
+ missingSpecFile:
39
+ 'Missing spec file: "{{specFile}}" should exist alongside this file.',
40
+ },
41
+ schema: [
42
+ {
43
+ type: 'object',
44
+ properties: {
45
+ excludePatterns: {
46
+ type: 'array',
47
+ items: { type: 'string' },
48
+ description:
49
+ 'Glob patterns to exclude from the spec-file requirement',
50
+ },
51
+ },
52
+ additionalProperties: false,
53
+ },
54
+ ],
55
+ },
56
+
57
+ create(context) {
58
+ const options = context.options[0] || {}
59
+ const excludePatterns = options.excludePatterns || DEFAULT_EXCLUDE_PATTERNS
60
+
61
+ let hasLogic = false
62
+ const markLogic = node => {
63
+ if (hasLogicInNode(node)) {
64
+ hasLogic = true
65
+ }
66
+ }
67
+
68
+ return {
69
+ FunctionDeclaration: markLogic,
70
+ FunctionExpression: markLogic,
71
+ ArrowFunctionExpression: markLogic,
72
+ ClassDeclaration: markLogic,
73
+ ClassExpression: markLogic,
74
+
75
+ 'Program:exit'(node) {
76
+ const filename = context.filename || context.getFilename()
77
+ const normalized = filename.replaceAll('\\', '/')
78
+ const parsed = parsePath(normalized)
79
+ const extension = JSX_EXTENSIONS.find(candidate =>
80
+ normalized.endsWith(candidate)
81
+ )
82
+
83
+ if (!extension) {
84
+ return
85
+ }
86
+ // A spec/test file never needs its own spec.
87
+ if (parsed.name.endsWith('.spec') || parsed.name.endsWith('.test')) {
88
+ return
89
+ }
90
+ if (!hasLogic || checkExcludePatterns(normalized, excludePatterns)) {
91
+ return
92
+ }
93
+
94
+ const specFileName = `${parsed.name}.spec${extension}`
95
+ const hasSibling = existsSync(joinPath(parsed.dir, specFileName))
96
+
97
+ if (!hasSibling) {
98
+ context.report({
99
+ node,
100
+ messageId: 'missingSpecFile',
101
+ data: { specFile: specFileName },
102
+ })
103
+ }
104
+ },
105
+ }
106
+ },
107
+ }
108
+
109
+ export default requireSpecFileTsxRule
@@ -1,3 +0,0 @@
1
- export const jsxA11yRules = {
2
- 'jsx-a11y/label-has-associated-control': 'off',
3
- }