eslint-plugin-nextfriday 5.0.0 → 5.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/CHANGELOG.md +6 -0
- package/docs/rules/NO_INLINE_NESTED_OBJECT.md +49 -49
- package/lib/index.cjs +42 -23
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +42 -23
- 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
|
+
## 5.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#138](https://github.com/next-friday/eslint-plugin-nextfriday/pull/138) [`28c600d`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/28c600d4746de76f7587e2fb5eab97ec5bdc6658) Thanks [@joetakara](https://github.com/joetakara)! - fix `no-inline-nested-object` scope — the rule now applies only to function-like contexts (call arguments, `new` expressions, `return` statements, arrow implicit returns, and JSX expressions) instead of every object property; module-level data declarations such as route tables, dependency rule arrays, and configuration objects are no longer flagged, eliminating false positives in patterns where Prettier already controls the layout
|
|
8
|
+
|
|
3
9
|
## 5.0.0
|
|
4
10
|
|
|
5
11
|
### Major Changes
|
|
@@ -1,96 +1,96 @@
|
|
|
1
1
|
# no-inline-nested-object
|
|
2
2
|
|
|
3
|
-
Require object or array values
|
|
3
|
+
Require object or array values passed to functions, returned from functions, or used as JSX attributes to span multiple lines when they contain nested objects or arrays.
|
|
4
|
+
|
|
5
|
+
> This rule is auto-fixable using `--fix`.
|
|
4
6
|
|
|
5
7
|
## Rule Details
|
|
6
8
|
|
|
7
|
-
This rule
|
|
9
|
+
This rule applies **only to function-like contexts**:
|
|
10
|
+
|
|
11
|
+
- Arguments to function calls (`CallExpression`) and constructor calls (`NewExpression`)
|
|
12
|
+
- Values returned from functions (`return` statements)
|
|
13
|
+
- Implicit returns from arrow functions
|
|
14
|
+
- Expressions inside JSX braces (props, children)
|
|
15
|
+
|
|
16
|
+
When the value passed/returned in one of those contexts is an inline object or array that contains another object or array as a property value or element, the rule requires it to span multiple lines. Flat collections — objects of primitive properties or arrays of simple references — are allowed inline because Prettier already controls their wrapping via `printWidth`.
|
|
8
17
|
|
|
9
|
-
|
|
18
|
+
The rule deliberately **does not apply to module-level data declarations** (e.g., `const config = { ... }`, route tables, dependency rule arrays). These are static configuration data, not function calls — Prettier handles their layout, and forcing them multiline produces noisy diffs without aiding readability.
|
|
10
19
|
|
|
11
20
|
### Why?
|
|
12
21
|
|
|
13
|
-
Truly nested structures are easy to misread when collapsed onto a single line, and adding or removing an inner element produces noisy diffs.
|
|
22
|
+
Truly nested structures passed at a call site are easy to misread when collapsed onto a single line, and adding or removing an inner element produces noisy diffs at the call site. The rule does not target data declarations because forcing static configuration arrays/objects onto multiple lines fights Prettier and bloats config files without aiding readability.
|
|
14
23
|
|
|
15
24
|
## Examples
|
|
16
25
|
|
|
17
26
|
### Incorrect
|
|
18
27
|
|
|
19
|
-
<!-- prettier-ignore -->
|
|
20
28
|
```ts
|
|
21
|
-
|
|
22
|
-
items: [{ a: 1 }, { b: 2 }],
|
|
23
|
-
};
|
|
29
|
+
useState({ a: { b: 1 } });
|
|
24
30
|
```
|
|
25
31
|
|
|
26
|
-
<!-- prettier-ignore -->
|
|
27
32
|
```ts
|
|
28
|
-
|
|
29
|
-
matrix: [[1, 2], [3, 4]],
|
|
30
|
-
};
|
|
33
|
+
doThing([{ a: 1 }, { b: 2 }]);
|
|
31
34
|
```
|
|
32
35
|
|
|
33
36
|
```ts
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
+
function build() {
|
|
38
|
+
return { user: { id: 1 } };
|
|
39
|
+
}
|
|
37
40
|
```
|
|
38
41
|
|
|
39
42
|
```ts
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
const factory = () => ({ a: { b: 1 } });
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
const el = <Comp prop={{ a: { b: 1 } }} />;
|
|
43
48
|
```
|
|
44
49
|
|
|
45
50
|
### Correct
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
Function-context calls expanded onto multiple lines:
|
|
53
|
+
|
|
48
54
|
```ts
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
{ b: 2 },
|
|
53
|
-
],
|
|
54
|
-
};
|
|
55
|
+
useState({
|
|
56
|
+
a: { b: 1 },
|
|
57
|
+
});
|
|
55
58
|
```
|
|
56
59
|
|
|
57
60
|
```ts
|
|
58
|
-
|
|
59
|
-
layer: {
|
|
60
|
-
inner: { leaf: 1 },
|
|
61
|
-
},
|
|
62
|
-
};
|
|
61
|
+
doThing([{ a: 1 }, { b: 2 }]);
|
|
63
62
|
```
|
|
64
63
|
|
|
65
|
-
Flat values stay inline:
|
|
66
|
-
|
|
67
64
|
```ts
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
};
|
|
65
|
+
function build() {
|
|
66
|
+
return {
|
|
67
|
+
user: { id: 1 },
|
|
68
|
+
};
|
|
69
|
+
}
|
|
72
70
|
```
|
|
73
71
|
|
|
72
|
+
Flat values stay inline:
|
|
73
|
+
|
|
74
74
|
```ts
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
allow: [target.utils, target.types, target.constants],
|
|
78
|
-
};
|
|
75
|
+
useState({ enabled: true, timeout: 5000 });
|
|
76
|
+
useState([1, 2, 3]);
|
|
79
77
|
```
|
|
80
78
|
|
|
81
|
-
|
|
79
|
+
Module-level data declarations are not checked:
|
|
82
80
|
|
|
81
|
+
<!-- prettier-ignore -->
|
|
83
82
|
```ts
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
const dependencyRules = [
|
|
84
|
+
{ from: source.modules, allow: [{ to: { type: "templates" } }] },
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const obj = {
|
|
88
|
+
items: [{ a: 1 }, { b: 2 }],
|
|
89
|
+
matrix: [[1, 2], [3, 4]],
|
|
90
|
+
layer: { inner: { leaf: 1 } },
|
|
87
91
|
};
|
|
88
92
|
```
|
|
89
93
|
|
|
90
94
|
## When Not To Use It
|
|
91
95
|
|
|
92
|
-
If your team prefers compact single-line nested structures regardless of
|
|
93
|
-
|
|
94
|
-
## Fixable
|
|
95
|
-
|
|
96
|
-
This rule is auto-fixable. Running ESLint with the `--fix` flag will expand inline collections that contain nested structures onto multiple lines.
|
|
96
|
+
If your team prefers compact single-line nested structures at call sites regardless of nesting, or if your project has different formatting preferences.
|
package/lib/index.cjs
CHANGED
|
@@ -32,7 +32,7 @@ let emoji_regex = require("emoji-regex");
|
|
|
32
32
|
emoji_regex = __toESM(emoji_regex, 1);
|
|
33
33
|
//#region package.json
|
|
34
34
|
var name = "eslint-plugin-nextfriday";
|
|
35
|
-
var version = "5.0.
|
|
35
|
+
var version = "5.0.1";
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/rules/boolean-naming-prefix.ts
|
|
38
38
|
const createRule$26 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
@@ -1778,9 +1778,6 @@ const noHelperFunctionInTest = _typescript_eslint_utils.ESLintUtils.RuleCreator(
|
|
|
1778
1778
|
//#endregion
|
|
1779
1779
|
//#region src/rules/no-inline-nested-object.ts
|
|
1780
1780
|
const createRule$11 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
1781
|
-
function isObjectOrArray(node) {
|
|
1782
|
-
return node.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression || node.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrayExpression || node.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression;
|
|
1783
|
-
}
|
|
1784
1781
|
function getInnerExpression(node) {
|
|
1785
1782
|
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression) return getInnerExpression(node.expression);
|
|
1786
1783
|
return node;
|
|
@@ -1803,7 +1800,7 @@ const noInlineNestedObject = createRule$11({
|
|
|
1803
1800
|
name: "no-inline-nested-object",
|
|
1804
1801
|
meta: {
|
|
1805
1802
|
type: "layout",
|
|
1806
|
-
docs: { description: "Require object or array values
|
|
1803
|
+
docs: { description: "Require object or array values passed to functions, returned, or used as JSX attributes to span multiple lines when they contain nested objects or arrays" },
|
|
1807
1804
|
fixable: "whitespace",
|
|
1808
1805
|
messages: { requireMultiline: "Inline collections containing nested objects or arrays should span multiple lines" },
|
|
1809
1806
|
schema: []
|
|
@@ -1811,32 +1808,54 @@ const noInlineNestedObject = createRule$11({
|
|
|
1811
1808
|
defaultOptions: [],
|
|
1812
1809
|
create(context) {
|
|
1813
1810
|
const { sourceCode } = context;
|
|
1814
|
-
|
|
1815
|
-
if (!node
|
|
1816
|
-
const
|
|
1817
|
-
if (
|
|
1818
|
-
if (!
|
|
1819
|
-
if (
|
|
1820
|
-
if (!containsNestedStructure(
|
|
1821
|
-
const elements =
|
|
1811
|
+
function checkValue(node) {
|
|
1812
|
+
if (!node) return;
|
|
1813
|
+
const inner = getInnerExpression(node);
|
|
1814
|
+
if (inner.type !== _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression && inner.type !== _typescript_eslint_utils.AST_NODE_TYPES.ArrayExpression) return;
|
|
1815
|
+
if (!inner.loc) return;
|
|
1816
|
+
if (inner.loc.start.line !== inner.loc.end.line) return;
|
|
1817
|
+
if (!containsNestedStructure(inner)) return;
|
|
1818
|
+
const elements = inner.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression ? inner.properties : inner.elements;
|
|
1822
1819
|
context.report({
|
|
1823
|
-
node:
|
|
1820
|
+
node: inner,
|
|
1824
1821
|
messageId: "requireMultiline",
|
|
1825
1822
|
fix(fixer) {
|
|
1826
|
-
const
|
|
1827
|
-
const
|
|
1828
|
-
|
|
1829
|
-
const indent = " ".repeat(node.loc?.start.column ?? 0);
|
|
1830
|
-
const innerIndent = `${indent} `;
|
|
1823
|
+
const lineIndentMatch = (sourceCode.lines[inner.loc.start.line - 1] ?? "").match(/^(\s*)/);
|
|
1824
|
+
const lineIndent = lineIndentMatch ? lineIndentMatch[1] : "";
|
|
1825
|
+
const innerIndent = `${lineIndent} `;
|
|
1831
1826
|
const elementTexts = elements.filter((el) => el !== null).map((el) => sourceCode.getText(el));
|
|
1832
|
-
const isObject =
|
|
1827
|
+
const isObject = inner.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression;
|
|
1833
1828
|
const openChar = isObject ? "{" : "[";
|
|
1834
1829
|
const closeChar = isObject ? "}" : "]";
|
|
1835
|
-
const newContent = `${openChar}\n${elementTexts.map((text) => `${innerIndent}${text},`).join("\n")}\n${
|
|
1836
|
-
return fixer.replaceText(
|
|
1830
|
+
const newContent = `${openChar}\n${elementTexts.map((text) => `${innerIndent}${text},`).join("\n")}\n${lineIndent}${closeChar}`;
|
|
1831
|
+
return fixer.replaceText(inner, newContent);
|
|
1837
1832
|
}
|
|
1838
1833
|
});
|
|
1839
|
-
}
|
|
1834
|
+
}
|
|
1835
|
+
function checkArguments(args) {
|
|
1836
|
+
args.forEach((arg) => {
|
|
1837
|
+
if (arg.type === _typescript_eslint_utils.AST_NODE_TYPES.SpreadElement) return;
|
|
1838
|
+
checkValue(arg);
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
return {
|
|
1842
|
+
CallExpression(node) {
|
|
1843
|
+
checkArguments(node.arguments);
|
|
1844
|
+
},
|
|
1845
|
+
NewExpression(node) {
|
|
1846
|
+
checkArguments(node.arguments);
|
|
1847
|
+
},
|
|
1848
|
+
ReturnStatement(node) {
|
|
1849
|
+
checkValue(node.argument);
|
|
1850
|
+
},
|
|
1851
|
+
ArrowFunctionExpression(node) {
|
|
1852
|
+
if (node.body.type !== _typescript_eslint_utils.AST_NODE_TYPES.BlockStatement) checkValue(node.body);
|
|
1853
|
+
},
|
|
1854
|
+
JSXExpressionContainer(node) {
|
|
1855
|
+
if (node.expression.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXEmptyExpression) return;
|
|
1856
|
+
checkValue(node.expression);
|
|
1857
|
+
}
|
|
1858
|
+
};
|
|
1840
1859
|
}
|
|
1841
1860
|
});
|
|
1842
1861
|
//#endregion
|