eslint-plugin-code-style 1.0.17 → 1.0.37
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/AGENTS.md +245 -0
- package/README.md +1336 -466
- package/index.d.ts +5 -5
- package/index.js +655 -407
- package/package.json +2 -1
package/AGENTS.md
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Instructions for AI coding agents working with this codebase.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**eslint-plugin-code-style** is an ESLint plugin providing 47 custom auto-fixable formatting rules for React/JSX projects. It's designed for ESLint v9+ flat config system.
|
|
8
|
+
|
|
9
|
+
- **Main entry:** `index.js` - Contains all 47 rules in a single file
|
|
10
|
+
- **Type definitions:** `index.d.ts` - TypeScript declarations for IDE support
|
|
11
|
+
- **Recommended configs:** `recommended-configs/` - Ready-to-use ESLint configurations
|
|
12
|
+
- **Test apps:** `_tests_/` - Sample apps for testing rules
|
|
13
|
+
|
|
14
|
+
### Available Configurations
|
|
15
|
+
|
|
16
|
+
| Config | Folder | Status |
|
|
17
|
+
|--------|--------|--------|
|
|
18
|
+
| React (JS) | `react/` | Available |
|
|
19
|
+
| React + TypeScript | `react-ts/` | Coming Soon |
|
|
20
|
+
| React + TS + Tailwind | `react-ts-tw/` | Coming Soon |
|
|
21
|
+
|
|
22
|
+
## Build & Test Commands
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# No build step required - plain JavaScript ES modules
|
|
26
|
+
|
|
27
|
+
# Test rules against a test app (e.g., react, react-ts, react-ts-tw)
|
|
28
|
+
cd _tests_/<config-name>
|
|
29
|
+
npm install
|
|
30
|
+
npm run lint # Check for errors
|
|
31
|
+
npm run lint:fix # Auto-fix issues
|
|
32
|
+
|
|
33
|
+
# Publish (from root folder only)
|
|
34
|
+
npm publish
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Code Structure
|
|
38
|
+
|
|
39
|
+
All rules are defined in `index.js` with this structure:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
index.js
|
|
43
|
+
├── imports (fs, path, url)
|
|
44
|
+
├── Rule 1 definition (const ruleName = { create(), meta: {} })
|
|
45
|
+
├── Rule 2 definition
|
|
46
|
+
├── ... (47 rules total)
|
|
47
|
+
└── export default { meta: {}, rules: {} }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Rule Implementation Pattern
|
|
51
|
+
|
|
52
|
+
Every rule follows this exact structure:
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
/**
|
|
56
|
+
* ───────────────────────────────────────────────────────────────
|
|
57
|
+
* Rule: Rule Name Here
|
|
58
|
+
* ───────────────────────────────────────────────────────────────
|
|
59
|
+
*
|
|
60
|
+
* Description:
|
|
61
|
+
* Brief description of what the rule does.
|
|
62
|
+
*
|
|
63
|
+
* Options:
|
|
64
|
+
* { optionName: defaultValue } - Description of option
|
|
65
|
+
*
|
|
66
|
+
* ✓ Good:
|
|
67
|
+
* // Example of correct code
|
|
68
|
+
*
|
|
69
|
+
* ✗ Bad:
|
|
70
|
+
* // Example of incorrect code
|
|
71
|
+
*/
|
|
72
|
+
const ruleName = {
|
|
73
|
+
create(context) {
|
|
74
|
+
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
75
|
+
const options = context.options[0] || {};
|
|
76
|
+
const optionName = options.optionName !== undefined ? options.optionName : defaultValue;
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
NodeType(node) {
|
|
80
|
+
// Rule logic here
|
|
81
|
+
|
|
82
|
+
// Report issues with auto-fix
|
|
83
|
+
context.report({
|
|
84
|
+
fix: (fixer) => fixer.replaceText(node, "fixed code"),
|
|
85
|
+
message: "Error message describing the issue",
|
|
86
|
+
node,
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
meta: {
|
|
92
|
+
docs: { description: "Short description for documentation" },
|
|
93
|
+
fixable: "code", // Required for auto-fix rules
|
|
94
|
+
schema: [
|
|
95
|
+
{
|
|
96
|
+
additionalProperties: false,
|
|
97
|
+
properties: {
|
|
98
|
+
optionName: {
|
|
99
|
+
default: 3,
|
|
100
|
+
description: "Option description",
|
|
101
|
+
minimum: 1,
|
|
102
|
+
type: "integer",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
type: "object",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
type: "layout", // "layout" for formatting, "suggestion" for conventions
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Adding a New Rule
|
|
114
|
+
|
|
115
|
+
1. Add the rule definition (const) following the pattern above
|
|
116
|
+
2. Add to the `rules` object in the default export (keep alphabetical within categories)
|
|
117
|
+
3. Update `index.d.ts` to add the rule name to the `RuleNames` type
|
|
118
|
+
4. Update `README.md`:
|
|
119
|
+
- Add to the Rules Summary table
|
|
120
|
+
- Add detailed description with examples
|
|
121
|
+
5. Add to relevant recommended configs in `recommended-configs/`
|
|
122
|
+
|
|
123
|
+
## Key Patterns & Conventions
|
|
124
|
+
|
|
125
|
+
### Source Code Access
|
|
126
|
+
```javascript
|
|
127
|
+
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Options with Defaults
|
|
131
|
+
```javascript
|
|
132
|
+
const options = context.options[0] || {};
|
|
133
|
+
const maxItems = options.maxItems !== undefined ? options.maxItems : 3;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Getting Tokens
|
|
137
|
+
```javascript
|
|
138
|
+
const openBracket = sourceCode.getFirstToken(node);
|
|
139
|
+
const closeBracket = sourceCode.getLastToken(node);
|
|
140
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
|
141
|
+
const tokenAfter = sourceCode.getTokenAfter(node);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Getting Text
|
|
145
|
+
```javascript
|
|
146
|
+
const text = sourceCode.getText(node);
|
|
147
|
+
const lines = sourceCode.lines; // Array of all lines
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Indentation Calculation
|
|
151
|
+
```javascript
|
|
152
|
+
const lineText = sourceCode.lines[node.loc.start.line - 1];
|
|
153
|
+
const baseIndent = lineText.match(/^\s*/)[0];
|
|
154
|
+
const itemIndent = baseIndent + " "; // 4 spaces
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Fixer Methods
|
|
158
|
+
```javascript
|
|
159
|
+
fixer.replaceText(node, "new text")
|
|
160
|
+
fixer.replaceTextRange([start, end], "new text")
|
|
161
|
+
fixer.insertTextBefore(node, "text")
|
|
162
|
+
fixer.insertTextAfter(node, "text")
|
|
163
|
+
fixer.remove(node)
|
|
164
|
+
fixer.removeRange([start, end])
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Common Node Type Checks
|
|
168
|
+
```javascript
|
|
169
|
+
// Check parent type
|
|
170
|
+
if (node.parent && node.parent.type === "Property") { }
|
|
171
|
+
|
|
172
|
+
// Check for specific patterns
|
|
173
|
+
if (node.type === "ArrowFunctionExpression") { }
|
|
174
|
+
if (node.type === "JSXElement") { }
|
|
175
|
+
if (node.type === "ObjectExpression") { }
|
|
176
|
+
|
|
177
|
+
// React hooks detection
|
|
178
|
+
if (/^use[A-Z]/.test(node.callee.name)) { }
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Skip Conditions (Common Patterns)
|
|
182
|
+
```javascript
|
|
183
|
+
// Skip empty structures
|
|
184
|
+
if (elements.length === 0) return;
|
|
185
|
+
|
|
186
|
+
// Skip complex elements
|
|
187
|
+
const hasComplexElement = elements.some((el) =>
|
|
188
|
+
el.type === "SpreadElement" ||
|
|
189
|
+
el.type === "ObjectExpression" ||
|
|
190
|
+
el.type === "ArrowFunctionExpression"
|
|
191
|
+
);
|
|
192
|
+
if (hasComplexElement) return;
|
|
193
|
+
|
|
194
|
+
// Skip specific parent contexts
|
|
195
|
+
if (node.parent?.type === "CallExpression") return;
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Rule Categories
|
|
199
|
+
|
|
200
|
+
Rules are organized in these categories (see default export):
|
|
201
|
+
|
|
202
|
+
- **Array rules:** `array-*`
|
|
203
|
+
- **Arrow function rules:** `arrow-function-*`, `curried-arrow-*`
|
|
204
|
+
- **Assignment rules:** `assignment-*`
|
|
205
|
+
- **Block statement rules:** `block-statement-*`
|
|
206
|
+
- **Comment rules:** `comment-*`
|
|
207
|
+
- **Function rules:** `function-*`
|
|
208
|
+
- **Hook rules:** `hook-*`
|
|
209
|
+
- **If statement rules:** `if-statement-*`, `multiline-if-*`
|
|
210
|
+
- **Import/Export rules:** `absolute-imports-*`, `export-*`, `import-*`, `index-export-*`, `module-index-*`
|
|
211
|
+
- **JSX rules:** `jsx-*`
|
|
212
|
+
- **Member expression rules:** `member-expression-*`
|
|
213
|
+
- **Nested call rules:** `nested-call-*`
|
|
214
|
+
- **No empty lines rules:** `no-empty-lines-*`
|
|
215
|
+
- **Object property rules:** `object-property-*`
|
|
216
|
+
- **Opening brackets rules:** `opening-brackets-*`
|
|
217
|
+
- **Simple call rules:** `simple-call-*`, `single-argument-*`
|
|
218
|
+
- **String property rules:** `string-property-*`
|
|
219
|
+
- **Variable rules:** `variable-*`
|
|
220
|
+
|
|
221
|
+
## Naming Conventions
|
|
222
|
+
|
|
223
|
+
- **Rule names:** kebab-case (e.g., `array-items-per-line`)
|
|
224
|
+
- **Internal variables:** camelCase (e.g., `arrayItemsPerLine`)
|
|
225
|
+
- **Handler functions:** end with `Handler` (e.g., `checkPatternHandler`)
|
|
226
|
+
- **Options:** camelCase (e.g., `maxItems`, `minProperties`)
|
|
227
|
+
|
|
228
|
+
## Meta Types
|
|
229
|
+
|
|
230
|
+
- `type: "layout"` - Formatting/whitespace rules (most rules)
|
|
231
|
+
- `type: "suggestion"` - Code convention rules (naming conventions)
|
|
232
|
+
|
|
233
|
+
## Documentation Files
|
|
234
|
+
|
|
235
|
+
- `README.md` - Main documentation with all 47 rules
|
|
236
|
+
- `recommended-configs/<config-name>/README.md` - Config-specific documentation (references main README for rule details)
|
|
237
|
+
- `index.d.ts` - TypeScript types for IDE autocomplete
|
|
238
|
+
|
|
239
|
+
## Important Notes
|
|
240
|
+
|
|
241
|
+
- All rules must be auto-fixable (`fixable: "code"` in meta)
|
|
242
|
+
- Use 4-space indentation throughout
|
|
243
|
+
- Object properties in `context.report()` must be alphabetically sorted
|
|
244
|
+
- Keep rules self-sufficient (no dependencies on other ESLint rules)
|
|
245
|
+
- Test with relevant test app in `_tests_/` before publishing
|