eslint-plugin-code-style 1.0.34 → 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 +11 -8
- package/index.d.ts +5 -5
- package/index.js +44 -6
- 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
|
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
**A powerful ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects.**
|
|
19
19
|
|
|
20
|
-
*
|
|
20
|
+
*47 auto-fixable rules to keep your codebase clean and consistent*
|
|
21
21
|
|
|
22
22
|
</div>
|
|
23
23
|
|
|
@@ -25,15 +25,18 @@
|
|
|
25
25
|
|
|
26
26
|
## 🎯 Why This Plugin?
|
|
27
27
|
|
|
28
|
-
This plugin provides **
|
|
28
|
+
This plugin provides **47 custom auto-fixable rules** for code formatting. Built for **ESLint v9 flat configs**.
|
|
29
29
|
|
|
30
30
|
> **Note:** ESLint [deprecated 79 formatting rules](https://eslint.org/blog/2023/10/deprecating-formatting-rules/) in v8.53.0. Our recommended configs use `@stylistic/eslint-plugin` as the replacement for these deprecated rules.
|
|
31
31
|
|
|
32
32
|
**Key Benefits:**
|
|
33
33
|
- **Fills the gaps** — Provides formatting rules not available in other plugins
|
|
34
|
+
- **Works alongside existing tools** — Complements ESLint's built-in rules and packages like eslint-plugin-react, eslint-plugin-import, etc
|
|
34
35
|
- **Self-sufficient rules** — Each rule handles complete formatting independently
|
|
35
|
-
- **Consistency at scale** — Reduces code-style differences between team members by
|
|
36
|
-
- **Fully automated** — All
|
|
36
|
+
- **Consistency at scale** — Reduces code-style differences between team members by enforcing uniform formatting across your projects
|
|
37
|
+
- **Fully automated** — All 47 rules support auto-fix, eliminating manual style reviews
|
|
38
|
+
|
|
39
|
+
When combined with ESLint's native rules and other popular plugins, this package helps create a complete code style solution that keeps your codebase clean and consistent.
|
|
37
40
|
|
|
38
41
|
<div align="center">
|
|
39
42
|
|
|
@@ -55,7 +58,7 @@ We provide **ready-to-use ESLint flat configuration files** that combine `eslint
|
|
|
55
58
|
|
|
56
59
|
### 💡 Why Use These Configs?
|
|
57
60
|
|
|
58
|
-
- **Complete Coverage** — Combines ESLint built-in rules, third-party plugins, and all
|
|
61
|
+
- **Complete Coverage** — Combines ESLint built-in rules, third-party plugins, and all 47 code-style rules
|
|
59
62
|
- **Ready-to-Use** — Copy the config file and start linting immediately
|
|
60
63
|
- **Battle-Tested** — These configurations have been refined through real-world usage
|
|
61
64
|
- **Fully Documented** — Each config includes detailed instructions and explanations
|
|
@@ -65,8 +68,8 @@ We provide **ready-to-use ESLint flat configuration files** that combine `eslint
|
|
|
65
68
|
| Configuration | Description | Link |
|
|
66
69
|
|---------------|-------------|------|
|
|
67
70
|
| **React** | React.js projects (JavaScript, JSX) | [View Config](./recommended-configs/react/) |
|
|
71
|
+
| **React + TypeScript** | React + TypeScript | *Coming Soon* |
|
|
68
72
|
| **React + TS + Tailwind** | React + TypeScript + Tailwind CSS | *Coming Soon* |
|
|
69
|
-
| **Next.js + TS + Tailwind** | Next.js + TypeScript + Tailwind CSS | *Coming Soon* |
|
|
70
73
|
|
|
71
74
|
### ⚡ Quick Start with Recommended Config
|
|
72
75
|
|
|
@@ -91,7 +94,7 @@ We provide **ready-to-use ESLint flat configuration files** that combine `eslint
|
|
|
91
94
|
<td width="50%">
|
|
92
95
|
|
|
93
96
|
### 🔧 Auto-Fixable Rules
|
|
94
|
-
All **
|
|
97
|
+
All **47 rules** support automatic fixing with `eslint --fix`. No manual code changes needed.
|
|
95
98
|
|
|
96
99
|
</td>
|
|
97
100
|
<td width="50%">
|
|
@@ -231,7 +234,7 @@ rules: {
|
|
|
231
234
|
|
|
232
235
|
## 📖 Rules Summary
|
|
233
236
|
|
|
234
|
-
> All **
|
|
237
|
+
> All **47 rules** are auto-fixable. See detailed examples for each rule in the [Rules Reference](#-rules-reference) section below.
|
|
235
238
|
>
|
|
236
239
|
> Rules marked with ⚙️ support customization options (e.g., extending default folder lists).
|
|
237
240
|
|
package/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type RuleNames =
|
|
|
15
15
|
| "code-style/comment-spacing"
|
|
16
16
|
| "code-style/curried-arrow-same-line"
|
|
17
17
|
| "code-style/export-format"
|
|
18
|
+
| "code-style/function-arguments-format"
|
|
18
19
|
| "code-style/function-call-spacing"
|
|
19
20
|
| "code-style/function-naming-convention"
|
|
20
21
|
| "code-style/function-params-per-line"
|
|
@@ -23,6 +24,7 @@ export type RuleNames =
|
|
|
23
24
|
| "code-style/if-statement-format"
|
|
24
25
|
| "code-style/import-format"
|
|
25
26
|
| "code-style/import-source-spacing"
|
|
27
|
+
| "code-style/index-export-style"
|
|
26
28
|
| "code-style/jsx-children-on-new-line"
|
|
27
29
|
| "code-style/jsx-closing-bracket-spacing"
|
|
28
30
|
| "code-style/jsx-element-child-new-line"
|
|
@@ -34,9 +36,7 @@ export type RuleNames =
|
|
|
34
36
|
| "code-style/jsx-ternary-format"
|
|
35
37
|
| "code-style/member-expression-bracket-spacing"
|
|
36
38
|
| "code-style/module-index-exports"
|
|
37
|
-
| "code-style/multiline-argument-newline"
|
|
38
39
|
| "code-style/multiline-if-conditions"
|
|
39
|
-
| "code-style/multiple-arguments-per-line"
|
|
40
40
|
| "code-style/nested-call-closing-brackets"
|
|
41
41
|
| "code-style/no-empty-lines-in-function-calls"
|
|
42
42
|
| "code-style/no-empty-lines-in-function-params"
|
|
@@ -84,6 +84,7 @@ interface PluginRules {
|
|
|
84
84
|
"comment-spacing": Rule.RuleModule;
|
|
85
85
|
"curried-arrow-same-line": Rule.RuleModule;
|
|
86
86
|
"export-format": Rule.RuleModule;
|
|
87
|
+
"function-arguments-format": Rule.RuleModule;
|
|
87
88
|
"function-call-spacing": Rule.RuleModule;
|
|
88
89
|
"function-naming-convention": Rule.RuleModule;
|
|
89
90
|
"function-params-per-line": Rule.RuleModule;
|
|
@@ -92,6 +93,7 @@ interface PluginRules {
|
|
|
92
93
|
"if-statement-format": Rule.RuleModule;
|
|
93
94
|
"import-format": Rule.RuleModule;
|
|
94
95
|
"import-source-spacing": Rule.RuleModule;
|
|
96
|
+
"index-export-style": Rule.RuleModule;
|
|
95
97
|
"jsx-children-on-new-line": Rule.RuleModule;
|
|
96
98
|
"jsx-closing-bracket-spacing": Rule.RuleModule;
|
|
97
99
|
"jsx-element-child-new-line": Rule.RuleModule;
|
|
@@ -103,9 +105,7 @@ interface PluginRules {
|
|
|
103
105
|
"jsx-ternary-format": Rule.RuleModule;
|
|
104
106
|
"member-expression-bracket-spacing": Rule.RuleModule;
|
|
105
107
|
"module-index-exports": Rule.RuleModule;
|
|
106
|
-
"multiline-argument-newline": Rule.RuleModule;
|
|
107
108
|
"multiline-if-conditions": Rule.RuleModule;
|
|
108
|
-
"multiple-arguments-per-line": Rule.RuleModule;
|
|
109
109
|
"nested-call-closing-brackets": Rule.RuleModule;
|
|
110
110
|
"no-empty-lines-in-function-calls": Rule.RuleModule;
|
|
111
111
|
"no-empty-lines-in-function-params": Rule.RuleModule;
|
|
@@ -117,7 +117,7 @@ interface PluginRules {
|
|
|
117
117
|
"object-property-value-format": Rule.RuleModule;
|
|
118
118
|
"opening-brackets-same-line": Rule.RuleModule;
|
|
119
119
|
"simple-call-single-line": Rule.RuleModule;
|
|
120
|
-
"single-argument-on-line": Rule.RuleModule;
|
|
120
|
+
"single-argument-on-one-line": Rule.RuleModule;
|
|
121
121
|
"string-property-spacing": Rule.RuleModule;
|
|
122
122
|
"variable-naming-convention": Rule.RuleModule;
|
|
123
123
|
}
|
package/index.js
CHANGED
|
@@ -6446,10 +6446,30 @@ const objectPropertyPerLine = {
|
|
|
6446
6446
|
if (!valueNode) return true;
|
|
6447
6447
|
|
|
6448
6448
|
// Simple values can always be collapsed
|
|
6449
|
-
if (["Literal", "Identifier", "
|
|
6449
|
+
if (["Literal", "Identifier", "MemberExpression", "UnaryExpression"].includes(valueNode.type)) {
|
|
6450
6450
|
return true;
|
|
6451
6451
|
}
|
|
6452
6452
|
|
|
6453
|
+
// Template literals: can only collapse if single-line (multi-line templates would break)
|
|
6454
|
+
if (valueNode.type === "TemplateLiteral") {
|
|
6455
|
+
return valueNode.loc.start.line === valueNode.loc.end.line;
|
|
6456
|
+
}
|
|
6457
|
+
|
|
6458
|
+
// Call expressions: can only collapse if already on single line
|
|
6459
|
+
if (valueNode.type === "CallExpression") {
|
|
6460
|
+
return valueNode.loc.start.line === valueNode.loc.end.line;
|
|
6461
|
+
}
|
|
6462
|
+
|
|
6463
|
+
// Arrow functions: can only collapse if already on single line
|
|
6464
|
+
if (valueNode.type === "ArrowFunctionExpression") {
|
|
6465
|
+
return valueNode.loc.start.line === valueNode.loc.end.line;
|
|
6466
|
+
}
|
|
6467
|
+
|
|
6468
|
+
// Spread elements: check if the argument can be collapsed
|
|
6469
|
+
if (valueNode.type === "SpreadElement") {
|
|
6470
|
+
return canCollapse(valueNode.argument);
|
|
6471
|
+
}
|
|
6472
|
+
|
|
6453
6473
|
// Arrays: can collapse only if already on single line (let array-items-per-line handle it)
|
|
6454
6474
|
if (valueNode.type === "ArrayExpression") {
|
|
6455
6475
|
const isAlreadySingleLine = valueNode.loc.start.line === valueNode.loc.end.line;
|
|
@@ -6465,11 +6485,15 @@ const objectPropertyPerLine = {
|
|
|
6465
6485
|
|
|
6466
6486
|
if (properties.length >= minProperties) return false;
|
|
6467
6487
|
|
|
6468
|
-
// Check all property values can be collapsed
|
|
6469
|
-
return properties.every((prop) =>
|
|
6488
|
+
// Check all property values can be collapsed (handle SpreadElement)
|
|
6489
|
+
return properties.every((prop) => {
|
|
6490
|
+
if (prop.type === "SpreadElement") return canCollapse(prop.argument);
|
|
6491
|
+
|
|
6492
|
+
return canCollapse(prop.value);
|
|
6493
|
+
});
|
|
6470
6494
|
}
|
|
6471
6495
|
|
|
6472
|
-
// Other complex types (functions,
|
|
6496
|
+
// Other complex types (functions, etc.) cannot be collapsed
|
|
6473
6497
|
return false;
|
|
6474
6498
|
};
|
|
6475
6499
|
|
|
@@ -6488,6 +6512,11 @@ const objectPropertyPerLine = {
|
|
|
6488
6512
|
if (properties.length === 0) return "{}";
|
|
6489
6513
|
|
|
6490
6514
|
const propsText = properties.map((prop) => {
|
|
6515
|
+
// Handle SpreadElement (e.g., ...obj)
|
|
6516
|
+
if (prop.type === "SpreadElement") {
|
|
6517
|
+
return `...${getCollapsedText(prop.argument)}`;
|
|
6518
|
+
}
|
|
6519
|
+
|
|
6491
6520
|
const keyText = prop.computed ? `[${sourceCode.getText(prop.key)}]` : sourceCode.getText(prop.key);
|
|
6492
6521
|
const valueText = getCollapsedText(prop.value);
|
|
6493
6522
|
|
|
@@ -6517,12 +6546,21 @@ const objectPropertyPerLine = {
|
|
|
6517
6546
|
if (properties.length < minProperties) {
|
|
6518
6547
|
const isMultiline = openBrace.loc.start.line !== closeBrace.loc.end.line;
|
|
6519
6548
|
|
|
6520
|
-
// Check if all property values can be collapsed
|
|
6521
|
-
const allCanCollapse = properties.every((prop) =>
|
|
6549
|
+
// Check if all property values can be collapsed (handle SpreadElement)
|
|
6550
|
+
const allCanCollapse = properties.every((prop) => {
|
|
6551
|
+
if (prop.type === "SpreadElement") return canCollapse(prop.argument);
|
|
6552
|
+
|
|
6553
|
+
return canCollapse(prop.value);
|
|
6554
|
+
});
|
|
6522
6555
|
|
|
6523
6556
|
if (isMultiline && allCanCollapse) {
|
|
6524
6557
|
// Generate collapsed text for all properties
|
|
6525
6558
|
const propertiesText = properties.map((prop) => {
|
|
6559
|
+
// Handle SpreadElement (e.g., ...obj)
|
|
6560
|
+
if (prop.type === "SpreadElement") {
|
|
6561
|
+
return `...${getCollapsedText(prop.argument)}`;
|
|
6562
|
+
}
|
|
6563
|
+
|
|
6526
6564
|
const keyText = prop.computed ? `[${sourceCode.getText(prop.key)}]` : sourceCode.getText(prop.key);
|
|
6527
6565
|
const valueText = getCollapsedText(prop.value);
|
|
6528
6566
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-code-style",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.37",
|
|
4
4
|
"description": "A custom ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"files": [
|
|
16
16
|
"index.js",
|
|
17
17
|
"index.d.ts",
|
|
18
|
+
"AGENTS.md",
|
|
18
19
|
"README.md",
|
|
19
20
|
"LICENSE"
|
|
20
21
|
],
|