eslint-config-agent 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/configs/overrides.js +0 -9
- package/index.js +9 -1
- package/package.json +2 -1
- package/plugins/index.js +0 -2
- package/rules/index.js +0 -3
- package/rules/jsx-classname-required/index.js +0 -95
package/configs/overrides.js
CHANGED
|
@@ -86,15 +86,6 @@ export const overridesConfig = (
|
|
|
86
86
|
},
|
|
87
87
|
},
|
|
88
88
|
|
|
89
|
-
// className requirement for JSX files
|
|
90
|
-
{
|
|
91
|
-
files: ['**/*.{tsx,jsx}'],
|
|
92
|
-
ignores: ['**/*.stories.{js,jsx,ts,tsx}'],
|
|
93
|
-
rules: {
|
|
94
|
-
'custom/jsx-classname-required': 'error',
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
|
|
98
89
|
// Function and file length rules - strict error thresholds
|
|
99
90
|
{
|
|
100
91
|
files: ['**/*.{ts,tsx,js,jsx}'],
|
package/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import js from '@eslint/js'
|
|
2
2
|
import earlyReturn from 'eslint-plugin-early-return'
|
|
3
|
+
import jsxClassname from 'eslint-plugin-jsx-classname'
|
|
3
4
|
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
5
|
import { defineConfig } from 'eslint/config'
|
|
5
6
|
import tseslint from 'typescript-eslint'
|
|
@@ -141,7 +142,14 @@ const config = defineConfig([
|
|
|
141
142
|
// Examples files configuration
|
|
142
143
|
...examplesConfig,
|
|
143
144
|
|
|
144
|
-
//
|
|
145
|
+
// className requirement for JSX files (strict: errors + rejects Tailwind-only classNames)
|
|
146
|
+
{
|
|
147
|
+
...jsxClassname.configs.strict,
|
|
148
|
+
files: ['**/*.{tsx,jsx}'],
|
|
149
|
+
ignores: ['**/*.stories.{js,jsx,ts,tsx}'],
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
// Final overrides (index files, switch case, length rules)
|
|
145
153
|
...overridesConfig(sharedRestrictedSyntax, tsOnlyRestrictedSyntax),
|
|
146
154
|
])
|
|
147
155
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-config-agent",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "ESLint configuration package with TypeScript support",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -110,6 +110,7 @@
|
|
|
110
110
|
"eslint-plugin-early-return": "^1.0.0",
|
|
111
111
|
"eslint-plugin-error": "^1.3.0",
|
|
112
112
|
"eslint-plugin-import": "^2.32.0",
|
|
113
|
+
"eslint-plugin-jsx-classname": "^1.0.1",
|
|
113
114
|
"eslint-plugin-n": "^17.21.3",
|
|
114
115
|
"eslint-plugin-no-optional-chaining": "^1.0.0",
|
|
115
116
|
"eslint-plugin-preact": "^0.1.0",
|
package/plugins/index.js
CHANGED
|
@@ -18,7 +18,6 @@ import defaultPlugin from 'eslint-plugin-default'
|
|
|
18
18
|
import noOptionalChainingPlugin from 'eslint-plugin-no-optional-chaining'
|
|
19
19
|
import dddPlugin from 'eslint-plugin-ddd'
|
|
20
20
|
import preactPlugin from 'eslint-plugin-preact'
|
|
21
|
-
import allRules from '../rules/index.js'
|
|
22
21
|
import { noDefaultClassExportRule } from '../rules/no-default-class-export/index.js'
|
|
23
22
|
|
|
24
23
|
// Centralized plugin configuration
|
|
@@ -39,7 +38,6 @@ export const plugins = {
|
|
|
39
38
|
custom: {
|
|
40
39
|
rules: {
|
|
41
40
|
'no-default-class-export': noDefaultClassExportRule,
|
|
42
|
-
'jsx-classname-required': allRules.jsxClassNameRequiredRule,
|
|
43
41
|
},
|
|
44
42
|
},
|
|
45
43
|
}
|
package/rules/index.js
CHANGED
|
@@ -22,7 +22,6 @@ import { noTypeAssertionsConfig } from './no-type-assertions/index.js'
|
|
|
22
22
|
import { noExportSpecifiersConfig } from './no-empty-exports/index.js'
|
|
23
23
|
import { noClassPropertyDefaultsConfig } from './no-class-property-defaults/index.js'
|
|
24
24
|
import { noDefaultClassExportRules } from './no-default-class-export/index.js'
|
|
25
|
-
import { jsxClassNameRequiredRule } from './jsx-classname-required/index.js'
|
|
26
25
|
import { noNullishCoalescingConfig } from './nullish-coalescing/index.js'
|
|
27
26
|
import { switchStatementsReturnTypeConfigs } from './switch-statements-return-type/index.js'
|
|
28
27
|
import { switchCaseFunctionsReturnTypeConfigs } from './switch-case-functions-return-type/index.js'
|
|
@@ -49,7 +48,6 @@ const allRules = {
|
|
|
49
48
|
noExportSpecifiersConfig,
|
|
50
49
|
noClassPropertyDefaultsConfig,
|
|
51
50
|
noDefaultClassExportRules,
|
|
52
|
-
jsxClassNameRequiredRule,
|
|
53
51
|
noNullishCoalescingConfig,
|
|
54
52
|
switchStatementsReturnTypeConfigs,
|
|
55
53
|
switchCaseFunctionsReturnTypeConfigs,
|
|
@@ -79,7 +77,6 @@ export {
|
|
|
79
77
|
noExportSpecifiersConfig,
|
|
80
78
|
noClassPropertyDefaultsConfig,
|
|
81
79
|
noDefaultClassExportRules,
|
|
82
|
-
jsxClassNameRequiredRule,
|
|
83
80
|
noNullishCoalescingConfig,
|
|
84
81
|
switchStatementsReturnTypeConfigs,
|
|
85
82
|
switchCaseFunctionsReturnTypeConfigs,
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule to require className attribute on HTML elements in JSX
|
|
3
|
-
*
|
|
4
|
-
* This rule enforces that all HTML elements in JSX must have a non-empty className attribute.
|
|
5
|
-
* It excludes React components (starting with capital letters), fragments, and title elements.
|
|
6
|
-
*
|
|
7
|
-
* Examples:
|
|
8
|
-
* - ❌ <div>Content</div>
|
|
9
|
-
* - ❌ <div className="">Content</div>
|
|
10
|
-
* - ✅ <div className="container">Content</div>
|
|
11
|
-
* - ✅ <MyComponent>Content</MyComponent> (ignored - React component)
|
|
12
|
-
* - ✅ <Fragment>Content</Fragment> (ignored - fragment)
|
|
13
|
-
* - ✅ <React.Fragment>Content</React.Fragment> (ignored - React fragment)
|
|
14
|
-
* - ✅ <React.StrictMode>Content</React.StrictMode> (ignored - React component)
|
|
15
|
-
* - ✅ <title>Page Title</title> (ignored - title element)
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
const jsxClassNameRequiredRule = {
|
|
19
|
-
meta: {
|
|
20
|
-
type: 'layout',
|
|
21
|
-
docs: {
|
|
22
|
-
description:
|
|
23
|
-
'Require non-empty className attribute on HTML elements in JSX',
|
|
24
|
-
category: 'Stylistic Issues',
|
|
25
|
-
recommended: false,
|
|
26
|
-
},
|
|
27
|
-
fixable: null,
|
|
28
|
-
schema: [],
|
|
29
|
-
messages: {
|
|
30
|
-
missingClassName: 'HTML elements must have a className attribute.',
|
|
31
|
-
emptyClassName:
|
|
32
|
-
'HTML elements must have a non-empty className attribute.',
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
create(context) {
|
|
37
|
-
return {
|
|
38
|
-
JSXOpeningElement(node) {
|
|
39
|
-
// Skip if this is a React component (starts with capital letter)
|
|
40
|
-
if (
|
|
41
|
-
node.name.type === 'JSXIdentifier' &&
|
|
42
|
-
/^[A-Z]/.test(node.name.name)
|
|
43
|
-
) {
|
|
44
|
-
return
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Skip if this is Fragment
|
|
48
|
-
if (
|
|
49
|
-
node.name.type === 'JSXIdentifier' &&
|
|
50
|
-
node.name.name === 'Fragment'
|
|
51
|
-
) {
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Skip if this is React.Something (like React.Fragment, React.StrictMode, etc.)
|
|
56
|
-
if (
|
|
57
|
-
node.name.type === 'JSXMemberExpression' &&
|
|
58
|
-
node.name.object.name === 'React' &&
|
|
59
|
-
/^[A-Z]/.test(node.name.property.name)
|
|
60
|
-
) {
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Skip if this is a title element (used in document head)
|
|
65
|
-
if (node.name.type === 'JSXIdentifier' && node.name.name === 'title') {
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Find className attribute
|
|
70
|
-
const classNameAttr = node.attributes.find(
|
|
71
|
-
attr => attr.type === 'JSXAttribute' && attr.name.name === 'className'
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
if (!classNameAttr) {
|
|
75
|
-
context.report({
|
|
76
|
-
node,
|
|
77
|
-
messageId: 'missingClassName',
|
|
78
|
-
})
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Check if className is an empty string
|
|
83
|
-
const value = classNameAttr.value
|
|
84
|
-
if (value && value.type === 'Literal' && value.value === '') {
|
|
85
|
-
context.report({
|
|
86
|
-
node,
|
|
87
|
-
messageId: 'emptyClassName',
|
|
88
|
-
})
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export { jsxClassNameRequiredRule }
|