eslint-plugin-absolute 0.2.0 → 0.2.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.
@@ -4,33 +4,13 @@ type Options = [number?];
4
4
  type MessageIds = "tooDeep";
5
5
 
6
6
  export const maxDepthExtended: TSESLint.RuleModule<MessageIds, Options> = {
7
- meta: {
8
- type: "suggestion",
9
- docs: {
10
- description:
11
- "disallow too many nested blocks except when the block only contains an early exit (return or throw)"
12
- },
13
- schema: [
14
- {
15
- // Accepts a single number as the maximum allowed depth.
16
- type: "number"
17
- }
18
- ],
19
- messages: {
20
- tooDeep:
21
- "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}} or an early exit."
22
- }
23
- },
24
-
25
- defaultOptions: [1],
26
-
27
7
  create(context) {
28
- const option = context.options[0];
8
+ const [option] = context.options;
29
9
  const maxDepth = typeof option === "number" ? option : 1;
30
10
  const functionStack: number[] = [];
31
11
 
32
12
  // Helper to get ancestors of a node by walking its parent chain.
33
- function getAncestors(node: TSESTree.Node) {
13
+ const getAncestors = (node: TSESTree.Node) => {
34
14
  const ancestors: TSESTree.Node[] = [];
35
15
  let current: TSESTree.Node | null | undefined = node.parent;
36
16
  while (current) {
@@ -38,14 +18,14 @@ export const maxDepthExtended: TSESLint.RuleModule<MessageIds, Options> = {
38
18
  current = current.parent;
39
19
  }
40
20
  return ancestors;
41
- }
21
+ };
42
22
 
43
23
  // Check if a block only contains a single early exit: return or throw.
44
- function isEarlyExitBlock(node: TSESTree.BlockStatement) {
24
+ const isEarlyExitBlock = (node: TSESTree.BlockStatement) => {
45
25
  if (node.body.length !== 1) {
46
26
  return false;
47
27
  }
48
- const first = node.body[0];
28
+ const [first] = node.body;
49
29
  if (!first) {
50
30
  return false;
51
31
  }
@@ -53,9 +33,21 @@ export const maxDepthExtended: TSESLint.RuleModule<MessageIds, Options> = {
53
33
  first.type === "ReturnStatement" ||
54
34
  first.type === "ThrowStatement"
55
35
  );
56
- }
36
+ };
57
37
 
58
- function incrementCurrentDepth(): number | null {
38
+ const isFunctionBody = (node: TSESTree.BlockStatement) => {
39
+ const ancestors = getAncestors(node);
40
+ const [parent] = ancestors;
41
+ return (
42
+ parent &&
43
+ (parent.type === "FunctionDeclaration" ||
44
+ parent.type === "FunctionExpression" ||
45
+ parent.type === "ArrowFunctionExpression") &&
46
+ node === parent.body
47
+ );
48
+ };
49
+
50
+ const incrementCurrentDepth = () => {
59
51
  if (functionStack.length === 0) {
60
52
  return null;
61
53
  }
@@ -67,9 +59,9 @@ export const maxDepthExtended: TSESLint.RuleModule<MessageIds, Options> = {
67
59
  const nextDepth = currentDepth + 1;
68
60
  functionStack[index] = nextDepth;
69
61
  return nextDepth;
70
- }
62
+ };
71
63
 
72
- function decrementCurrentDepth(): void {
64
+ const decrementCurrentDepth = () => {
73
65
  if (functionStack.length === 0) {
74
66
  return;
75
67
  }
@@ -79,42 +71,29 @@ export const maxDepthExtended: TSESLint.RuleModule<MessageIds, Options> = {
79
71
  return;
80
72
  }
81
73
  functionStack[index] = currentDepth - 1;
82
- }
74
+ };
83
75
 
84
76
  // Report if the current depth exceeds the allowed maximum.
85
- function checkDepth(node: TSESTree.BlockStatement, depth: number) {
77
+ const checkDepth = (node: TSESTree.BlockStatement, depth: number) => {
86
78
  if (depth > maxDepth) {
87
79
  context.report({
88
- node,
80
+ data: { depth, maxDepth },
89
81
  messageId: "tooDeep",
90
- data: { depth, maxDepth }
82
+ node
91
83
  });
92
84
  }
93
- }
85
+ };
94
86
 
95
87
  return {
96
- FunctionDeclaration() {
97
- functionStack.push(0);
98
- },
99
- FunctionExpression() {
100
- functionStack.push(0);
101
- },
102
88
  ArrowFunctionExpression() {
103
89
  functionStack.push(0);
104
90
  },
105
-
91
+ "ArrowFunctionExpression:exit"() {
92
+ functionStack.pop();
93
+ },
106
94
  BlockStatement(node: TSESTree.BlockStatement) {
107
- const ancestors = getAncestors(node);
108
- const parent = ancestors.length > 0 ? ancestors[0] : undefined;
109
-
110
95
  // Do not count if this block is the body of a function.
111
- if (
112
- parent &&
113
- (parent.type === "FunctionDeclaration" ||
114
- parent.type === "FunctionExpression" ||
115
- parent.type === "ArrowFunctionExpression") &&
116
- node === parent.body
117
- ) {
96
+ if (isFunctionBody(node)) {
118
97
  return;
119
98
  }
120
99
 
@@ -128,18 +107,8 @@ export const maxDepthExtended: TSESLint.RuleModule<MessageIds, Options> = {
128
107
  checkDepth(node, depth);
129
108
  }
130
109
  },
131
-
132
110
  "BlockStatement:exit"(node: TSESTree.BlockStatement) {
133
- const ancestors = getAncestors(node);
134
- const parent = ancestors.length > 0 ? ancestors[0] : undefined;
135
-
136
- if (
137
- parent &&
138
- (parent.type === "FunctionDeclaration" ||
139
- parent.type === "FunctionExpression" ||
140
- parent.type === "ArrowFunctionExpression") &&
141
- node === parent.body
142
- ) {
111
+ if (isFunctionBody(node)) {
143
112
  return;
144
113
  }
145
114
 
@@ -149,16 +118,36 @@ export const maxDepthExtended: TSESLint.RuleModule<MessageIds, Options> = {
149
118
 
150
119
  decrementCurrentDepth();
151
120
  },
152
-
121
+ FunctionDeclaration() {
122
+ functionStack.push(0);
123
+ },
153
124
  "FunctionDeclaration:exit"() {
154
125
  functionStack.pop();
155
126
  },
156
- "FunctionExpression:exit"() {
157
- functionStack.pop();
127
+ FunctionExpression() {
128
+ functionStack.push(0);
158
129
  },
159
- "ArrowFunctionExpression:exit"() {
130
+ "FunctionExpression:exit"() {
160
131
  functionStack.pop();
161
132
  }
162
133
  };
134
+ },
135
+ defaultOptions: [1],
136
+ meta: {
137
+ docs: {
138
+ description:
139
+ "disallow too many nested blocks except when the block only contains an early exit (return or throw)"
140
+ },
141
+ messages: {
142
+ tooDeep:
143
+ "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}} or an early exit."
144
+ },
145
+ schema: [
146
+ {
147
+ // Accepts a single number as the maximum allowed depth.
148
+ type: "number"
149
+ }
150
+ ],
151
+ type: "suggestion"
163
152
  }
164
153
  };
@@ -3,65 +3,57 @@ import { TSESLint, TSESTree } from "@typescript-eslint/utils";
3
3
  type Options = [number];
4
4
  type MessageIds = "tooDeeplyNested";
5
5
 
6
- export const maxJSXNesting: TSESLint.RuleModule<MessageIds, Options> = {
7
- meta: {
8
- type: "suggestion",
9
- docs: {
10
- description:
11
- "Warn when JSX elements are nested too deeply, suggesting refactoring into a separate component."
12
- },
13
- // The rule accepts a single numeric option (minimum 1)
14
- schema: [
15
- {
16
- type: "number",
17
- minimum: 1
18
- }
19
- ],
20
- messages: {
21
- tooDeeplyNested:
22
- "JSX element is nested too deeply ({{level}} levels, allowed is {{maxAllowed}} levels). Consider refactoring into a separate component."
23
- }
24
- },
25
-
26
- defaultOptions: [1],
6
+ const isJSXAncestor = (node: TSESTree.Node) =>
7
+ node.type === "JSXElement" || node.type === "JSXFragment";
27
8
 
9
+ export const maxJSXNesting: TSESLint.RuleModule<MessageIds, Options> = {
28
10
  create(context) {
29
- const option = context.options[0];
11
+ const [option] = context.options;
30
12
  const maxAllowed = typeof option === "number" ? option : 1;
31
13
 
32
14
  /**
33
15
  * Calculates the JSX nesting level for the given node by traversing the node.parent chain.
34
- * The level is computed by counting the current node (level 1) plus each ancestor
35
- * that is a JSXElement or JSXFragment.
36
- * @param {ASTNode} node The JSX element node.
37
- * @returns {number} The nesting level.
38
16
  */
39
- function getJSXNestingLevel(node: TSESTree.Node): number {
17
+ const getJSXNestingLevel = (node: TSESTree.Node) => {
40
18
  let level = 1; // count the current node as level 1
41
19
  let current: TSESTree.Node | null | undefined = node.parent;
42
20
  while (current) {
43
- if (
44
- current.type === "JSXElement" ||
45
- current.type === "JSXFragment"
46
- ) {
47
- level++;
48
- }
21
+ level += isJSXAncestor(current) ? 1 : 0;
49
22
  current = current.parent;
50
23
  }
51
24
  return level;
52
- }
25
+ };
53
26
 
54
27
  return {
55
28
  JSXElement(node: TSESTree.JSXElement) {
56
29
  const level = getJSXNestingLevel(node);
57
30
  if (level > maxAllowed) {
58
31
  context.report({
59
- node,
32
+ data: { level, maxAllowed },
60
33
  messageId: "tooDeeplyNested",
61
- data: { level, maxAllowed }
34
+ node
62
35
  });
63
36
  }
64
37
  }
65
38
  };
39
+ },
40
+ defaultOptions: [1],
41
+ meta: {
42
+ docs: {
43
+ description:
44
+ "Warn when JSX elements are nested too deeply, suggesting refactoring into a separate component."
45
+ },
46
+ messages: {
47
+ tooDeeplyNested:
48
+ "JSX element is nested too deeply ({{level}} levels, allowed is {{maxAllowed}} levels). Consider refactoring into a separate component."
49
+ },
50
+ // The rule accepts a single numeric option (minimum 1)
51
+ schema: [
52
+ {
53
+ minimum: 1,
54
+ type: "number"
55
+ }
56
+ ],
57
+ type: "suggestion"
66
58
  }
67
59
  };