eslint-plugin-nextfriday 1.3.0 → 1.4.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.
- package/CHANGELOG.md +6 -0
- package/README.md +20 -14
- package/docs/rules/NO_COMPLEX_INLINE_RETURN.md +136 -0
- package/docs/rules/NO_LOGIC_IN_PARAMS.md +122 -0
- package/lib/index.cjs +190 -74
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +28 -0
- package/lib/index.d.ts +28 -0
- package/lib/index.js +190 -74
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# eslint-plugin-nextfriday
|
|
2
2
|
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#26](https://github.com/next-friday/eslint-plugin-nextfriday/pull/26) [`e90935a`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/e90935a56129ff84efc9df5de3f43e8e4a61af16) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Add two new rules to improve code readability and debugging: `no-complex-inline-return` disallows complex inline expressions (such as ternary operators, logical expressions, or `new` expressions) directly in return statements, requiring extraction to a `const` variable instead; and `no-logic-in-params` prohibits using logic or conditions (e.g., ternary, logical, comparison, or negation operators) within function parameters, enforcing the use of intermediate `const` variables to enhance clarity and allow inspection of values.
|
|
8
|
+
|
|
3
9
|
## 1.3.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -67,6 +67,8 @@ export default [
|
|
|
67
67
|
"nextfriday/prefer-import-type": "error",
|
|
68
68
|
"nextfriday/prefer-named-param-types": "error",
|
|
69
69
|
"nextfriday/prefer-react-import-types": "error",
|
|
70
|
+
"nextfriday/no-complex-inline-return": "error",
|
|
71
|
+
"nextfriday/no-logic-in-params": "error",
|
|
70
72
|
"nextfriday/jsx-pascal-case": "error",
|
|
71
73
|
"nextfriday/prefer-interface-over-inline-types": "error",
|
|
72
74
|
"nextfriday/react-props-destructure": "error",
|
|
@@ -107,20 +109,22 @@ module.exports = {
|
|
|
107
109
|
|
|
108
110
|
## Rules
|
|
109
111
|
|
|
110
|
-
| Rule | Description
|
|
111
|
-
| -------------------------------------------------------------------------------------- |
|
|
112
|
-
| [no-emoji](docs/rules/NO_EMOJI.md) | Disallow emojis in code
|
|
113
|
-
| [file-kebab-case](docs/rules/FILE_KEBAB_CASE.md) | Enforce kebab-case filenames for .ts and .js files
|
|
114
|
-
| [jsx-pascal-case](docs/rules/JSX_PASCAL_CASE.md) | Enforce PascalCase filenames for .jsx and .tsx files
|
|
115
|
-
| [md-filename-case-restriction](docs/rules/MD_FILENAME_CASE_RESTRICTION.md) | Enforce SNAKE_CASE filenames for .md files
|
|
116
|
-
| [prefer-destructuring-params](docs/rules/PREFER_DESTRUCTURING_PARAMS.md) | Enforce destructuring for functions with multiple parameters
|
|
117
|
-
| [no-explicit-return-type](docs/rules/NO_EXPLICIT_RETURN_TYPE.md) | Disallow explicit return types on functions
|
|
118
|
-
| [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports
|
|
119
|
-
| [prefer-named-param-types](docs/rules/PREFER_NAMED_PARAM_TYPES.md) | Enforce named types for function parameters with object types
|
|
120
|
-
| [prefer-interface-over-inline-types](docs/rules/PREFER_INTERFACE_OVER_INLINE_TYPES.md) | Enforce interface declarations over inline types for React props
|
|
121
|
-
| [prefer-react-import-types](docs/rules/PREFER_REACT_IMPORT_TYPES.md) | Enforce direct imports from 'react' instead of React.X
|
|
122
|
-
| [react-props-destructure](docs/rules/REACT_PROPS_DESTRUCTURE.md) | Enforce destructuring props inside React component body
|
|
123
|
-
| [enforce-readonly-component-props](docs/rules/ENFORCE_READONLY_COMPONENT_PROPS.md) | Enforce Readonly wrapper for React component props
|
|
112
|
+
| Rule | Description | Fixable |
|
|
113
|
+
| -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------- |
|
|
114
|
+
| [no-emoji](docs/rules/NO_EMOJI.md) | Disallow emojis in code | ❌ |
|
|
115
|
+
| [file-kebab-case](docs/rules/FILE_KEBAB_CASE.md) | Enforce kebab-case filenames for .ts and .js files | ❌ |
|
|
116
|
+
| [jsx-pascal-case](docs/rules/JSX_PASCAL_CASE.md) | Enforce PascalCase filenames for .jsx and .tsx files | ❌ |
|
|
117
|
+
| [md-filename-case-restriction](docs/rules/MD_FILENAME_CASE_RESTRICTION.md) | Enforce SNAKE_CASE filenames for .md files | ❌ |
|
|
118
|
+
| [prefer-destructuring-params](docs/rules/PREFER_DESTRUCTURING_PARAMS.md) | Enforce destructuring for functions with multiple parameters | ❌ |
|
|
119
|
+
| [no-explicit-return-type](docs/rules/NO_EXPLICIT_RETURN_TYPE.md) | Disallow explicit return types on functions | ✅ |
|
|
120
|
+
| [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports | ✅ |
|
|
121
|
+
| [prefer-named-param-types](docs/rules/PREFER_NAMED_PARAM_TYPES.md) | Enforce named types for function parameters with object types | ❌ |
|
|
122
|
+
| [prefer-interface-over-inline-types](docs/rules/PREFER_INTERFACE_OVER_INLINE_TYPES.md) | Enforce interface declarations over inline types for React props | ❌ |
|
|
123
|
+
| [prefer-react-import-types](docs/rules/PREFER_REACT_IMPORT_TYPES.md) | Enforce direct imports from 'react' instead of React.X | ✅ |
|
|
124
|
+
| [react-props-destructure](docs/rules/REACT_PROPS_DESTRUCTURE.md) | Enforce destructuring props inside React component body | ❌ |
|
|
125
|
+
| [enforce-readonly-component-props](docs/rules/ENFORCE_READONLY_COMPONENT_PROPS.md) | Enforce Readonly wrapper for React component props | ✅ |
|
|
126
|
+
| [no-complex-inline-return](docs/rules/NO_COMPLEX_INLINE_RETURN.md) | Disallow complex inline expressions in return statements - prefer const first | ❌ |
|
|
127
|
+
| [no-logic-in-params](docs/rules/NO_LOGIC_IN_PARAMS.md) | Disallow logic or conditions in function parameters - extract to const first | ❌ |
|
|
124
128
|
|
|
125
129
|
## Configurations
|
|
126
130
|
|
|
@@ -138,6 +142,8 @@ Basic configuration without JSX-specific rules:
|
|
|
138
142
|
- `nextfriday/prefer-import-type`: `"error"`
|
|
139
143
|
- `nextfriday/prefer-named-param-types`: `"error"`
|
|
140
144
|
- `nextfriday/prefer-react-import-types`: `"error"`
|
|
145
|
+
- `nextfriday/no-complex-inline-return`: `"error"`
|
|
146
|
+
- `nextfriday/no-logic-in-params`: `"error"`
|
|
141
147
|
|
|
142
148
|
#### `base/recommended`
|
|
143
149
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# no-complex-inline-return
|
|
2
|
+
|
|
3
|
+
Disallow complex inline expressions in return statements - prefer extracting to a const first.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule enforces a pattern where complex expressions (ternary operators, logical expressions, new expressions) are extracted to a const variable before being returned. This improves code readability and makes debugging easier by allowing you to inspect intermediate values.
|
|
8
|
+
|
|
9
|
+
**Incorrect** code for this rule:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
function waitForLoad(targetWindow: Window) {
|
|
13
|
+
return targetWindow.document.readyState === "complete"
|
|
14
|
+
? Promise.resolve()
|
|
15
|
+
: new Promise<void>((resolve) => {
|
|
16
|
+
targetWindow.addEventListener(
|
|
17
|
+
"load",
|
|
18
|
+
() => {
|
|
19
|
+
resolve();
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
once: true,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getValue(condition: boolean) {
|
|
29
|
+
return condition ? "yes" : "no";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getUser(user: User | null) {
|
|
33
|
+
return user || defaultUser;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function createInstance() {
|
|
37
|
+
return new MyClass();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function checkStatus(a: boolean, b: boolean) {
|
|
41
|
+
return a && b;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Correct** code for this rule:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
function waitForLoad(targetWindow: Window) {
|
|
49
|
+
const loadPromise =
|
|
50
|
+
targetWindow.document.readyState === "complete"
|
|
51
|
+
? Promise.resolve()
|
|
52
|
+
: new Promise<void>((resolve) => {
|
|
53
|
+
targetWindow.addEventListener(
|
|
54
|
+
"load",
|
|
55
|
+
() => {
|
|
56
|
+
resolve();
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
once: true,
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return loadPromise;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function getValue(condition: boolean) {
|
|
68
|
+
const value = condition ? "yes" : "no";
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getUser(user: User | null) {
|
|
73
|
+
const activeUser = user || defaultUser;
|
|
74
|
+
return activeUser;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function createInstance() {
|
|
78
|
+
const instance = new MyClass();
|
|
79
|
+
return instance;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function checkStatus(a: boolean, b: boolean) {
|
|
83
|
+
const isValid = a && b;
|
|
84
|
+
return isValid;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Simple returns are still allowed
|
|
88
|
+
function getName() {
|
|
89
|
+
return "John Doe";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function getAge() {
|
|
93
|
+
return 42;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function callFunction() {
|
|
97
|
+
return someFunction();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getMath() {
|
|
101
|
+
return a + b;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Benefits
|
|
106
|
+
|
|
107
|
+
- **Better readability**: Complex logic is separated from the return statement
|
|
108
|
+
- **Easier debugging**: Intermediate values can be inspected in debuggers
|
|
109
|
+
- **Self-documenting**: Variable names can describe what the complex expression represents
|
|
110
|
+
- **Consistent style**: Enforces a uniform approach to handling complex return values
|
|
111
|
+
|
|
112
|
+
## When Not To Use
|
|
113
|
+
|
|
114
|
+
- For very simple projects where inline expressions are preferred
|
|
115
|
+
- When you prefer a more compact coding style
|
|
116
|
+
- In cases where the expression is trivial and doesn't benefit from extraction
|
|
117
|
+
|
|
118
|
+
## What This Rule Checks
|
|
119
|
+
|
|
120
|
+
This rule flags the following patterns when used directly in return statements:
|
|
121
|
+
|
|
122
|
+
- **Ternary expressions** (conditional operators): `condition ? value1 : value2`
|
|
123
|
+
- **Logical expressions**: `a && b`, `a || b`, `a ?? b`
|
|
124
|
+
- **New expressions**: `new MyClass()`
|
|
125
|
+
|
|
126
|
+
The following are allowed in return statements:
|
|
127
|
+
|
|
128
|
+
- Simple values (literals, variables)
|
|
129
|
+
- Function calls
|
|
130
|
+
- Binary expressions (math operations like `a + b`)
|
|
131
|
+
- Object/array literals
|
|
132
|
+
- Member expressions (`obj.prop`)
|
|
133
|
+
|
|
134
|
+
## Related Rules
|
|
135
|
+
|
|
136
|
+
- No related rules
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# no-logic-in-params
|
|
2
|
+
|
|
3
|
+
Disallow logic or conditions in function parameters - extract to a const variable first.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule enforces a pattern where complex expressions (logical operators, ternary operators, comparison operators) are extracted to a const variable before being passed as function arguments. This improves code readability, makes debugging easier, and helps maintain cleaner function calls.
|
|
8
|
+
|
|
9
|
+
**Incorrect** code for this rule:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// Nullish coalescing
|
|
13
|
+
functionFoo(bar ?? baz);
|
|
14
|
+
|
|
15
|
+
// Ternary operator
|
|
16
|
+
handleUser(isActive ? activeUser : inactiveUser);
|
|
17
|
+
|
|
18
|
+
// Logical AND
|
|
19
|
+
processData(hasPermission && isValid);
|
|
20
|
+
|
|
21
|
+
// Logical OR
|
|
22
|
+
setConfig(customConfig || defaultConfig);
|
|
23
|
+
|
|
24
|
+
// Comparison operators
|
|
25
|
+
validateInput(value > 100);
|
|
26
|
+
checkEquality(a === b);
|
|
27
|
+
|
|
28
|
+
// Negation
|
|
29
|
+
toggleFeature(!isEnabled);
|
|
30
|
+
|
|
31
|
+
// Multiple parameters with logic
|
|
32
|
+
createUser(username, age >= 18, status === "active");
|
|
33
|
+
|
|
34
|
+
// New expression with logic
|
|
35
|
+
new MyClass(a || b);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Correct** code for this rule:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// Extract logic to a variable first
|
|
42
|
+
const value = bar ?? baz;
|
|
43
|
+
functionFoo(value);
|
|
44
|
+
|
|
45
|
+
const user = isActive ? activeUser : inactiveUser;
|
|
46
|
+
handleUser(user);
|
|
47
|
+
|
|
48
|
+
const canProcess = hasPermission && isValid;
|
|
49
|
+
processData(canProcess);
|
|
50
|
+
|
|
51
|
+
const config = customConfig || defaultConfig;
|
|
52
|
+
setConfig(config);
|
|
53
|
+
|
|
54
|
+
const isValid = value > 100;
|
|
55
|
+
validateInput(isValid);
|
|
56
|
+
|
|
57
|
+
const areEqual = a === b;
|
|
58
|
+
checkEquality(areEqual);
|
|
59
|
+
|
|
60
|
+
const shouldDisable = !isEnabled;
|
|
61
|
+
toggleFeature(shouldDisable);
|
|
62
|
+
|
|
63
|
+
const isAdult = age >= 18;
|
|
64
|
+
const isActive = status === "active";
|
|
65
|
+
createUser(username, isAdult, isActive);
|
|
66
|
+
|
|
67
|
+
const param = a || b;
|
|
68
|
+
new MyClass(param);
|
|
69
|
+
|
|
70
|
+
// Simple values are still allowed
|
|
71
|
+
functionFoo(bar);
|
|
72
|
+
functionFoo(42);
|
|
73
|
+
functionFoo("string");
|
|
74
|
+
functionFoo(obj.property);
|
|
75
|
+
functionFoo(getValue());
|
|
76
|
+
|
|
77
|
+
// Arithmetic operations are allowed
|
|
78
|
+
calculate(a + b);
|
|
79
|
+
multiply(x * y);
|
|
80
|
+
|
|
81
|
+
// Object/array literals are allowed
|
|
82
|
+
configure({ key: "value" });
|
|
83
|
+
process([1, 2, 3]);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Benefits
|
|
87
|
+
|
|
88
|
+
- **Better readability**: Logic is separated from function calls, making code easier to scan
|
|
89
|
+
- **Easier debugging**: Intermediate values can be inspected in debuggers before being passed to functions
|
|
90
|
+
- **Self-documenting**: Variable names describe what the complex expression represents
|
|
91
|
+
- **Consistent style**: Enforces a uniform approach to handling complex function arguments
|
|
92
|
+
- **Reduced cognitive load**: Readers don't need to mentally evaluate expressions while also understanding function calls
|
|
93
|
+
|
|
94
|
+
## When Not To Use
|
|
95
|
+
|
|
96
|
+
- For very simple projects where inline expressions are preferred
|
|
97
|
+
- When you prefer a more compact coding style
|
|
98
|
+
- In cases where the expression is trivial and doesn't benefit from extraction
|
|
99
|
+
|
|
100
|
+
## What This Rule Checks
|
|
101
|
+
|
|
102
|
+
This rule flags the following patterns when used as function arguments:
|
|
103
|
+
|
|
104
|
+
- **Ternary expressions** (conditional operators): `condition ? value1 : value2`
|
|
105
|
+
- **Logical expressions**: `a && b`, `a || b`, `a ?? b`
|
|
106
|
+
- **Comparison operators**: `===`, `!==`, `==`, `!=`, `>`, `<`, `>=`, `<=`
|
|
107
|
+
- **Type checking operators**: `in`, `instanceof`
|
|
108
|
+
- **Negation operator**: `!value`
|
|
109
|
+
|
|
110
|
+
The following are allowed as function arguments:
|
|
111
|
+
|
|
112
|
+
- Simple values (literals, variables)
|
|
113
|
+
- Function calls
|
|
114
|
+
- Member expressions (`obj.prop`)
|
|
115
|
+
- Arithmetic operations (`a + b`, `a * b`, etc.)
|
|
116
|
+
- Object/array literals
|
|
117
|
+
- Template literals
|
|
118
|
+
- Spread operators (`...args`)
|
|
119
|
+
|
|
120
|
+
## Related Rules
|
|
121
|
+
|
|
122
|
+
- [no-complex-inline-return](./NO_COMPLEX_INLINE_RETURN.md) - Similar rule but for return statements
|