@@ -25,6 +25,12 @@ export const minChainedCallDepth = createRule({
2525 minimum : 1 ,
2626 default : 100 ,
2727 } ,
28+ ignoreChainDeeperThan : {
29+ type : 'integer' ,
30+ minimum : 1 ,
31+ maximum : 10 ,
32+ default : 2 ,
33+ } ,
2834 } ,
2935 additionalProperties : false ,
3036 } ,
@@ -37,9 +43,13 @@ export const minChainedCallDepth = createRule({
3743 {
3844 maxLineLength : 100 ,
3945 } ,
46+ {
47+ ignoreChainDeeperThan : 3 ,
48+ } ,
4049 ] ,
4150 create : context => {
4251 const sourceCode = context . getSourceCode ( ) ;
52+ let maxDepth = 0 ;
4353
4454 function getDepth ( node : TSESTree . MemberExpression | TSESTree . CallExpression ) : number {
4555 let depth = 0 ;
@@ -88,29 +98,49 @@ export const minChainedCallDepth = createRule({
8898 : node ;
8999
90100 if (
91- // If the callee is not a member expression, we can skip.
101+ // If the callee is not a member expression, skip.
92102 // For example, root level calls like `foo();`.
93103 callee . type !== AST_NODE_TYPES . MemberExpression
94- // If the callee is a computed member expression, like `foo[bar]()`, we can skip.
104+ // If the callee is a computed member expression, like `foo[bar]()`, skip.
95105 || callee . computed
96106 /* eslint-disable-next-line @typescript-eslint/ban-ts-comment --
97- * NewExpression is a possible callee object type
98- */
107+ * NewExpression is a possible callee object type
108+ */
99109 // @ts -ignore
100110 || callee . object . type === AST_NODE_TYPES . NewExpression
101- // If the callee is already in the same line as it's object, we can skip.
111+ // If the callee is already in the same line as it's object, skip.
102112 || callee . object . loc . end . line === callee . property . loc . start . line
103113 ) {
104114 return ;
105115 }
106116
107- // We only inline the first level of chained calls.
108- // If the current call is nested inside another call, we can skip.
109- if ( getDepth ( callee ) > 1 ) {
117+ const currentDepth = getDepth ( callee ) ;
118+
119+ maxDepth = Math . max ( maxDepth , currentDepth ) ;
120+
121+ // Only affect the root level as the total depth is must be known.
122+ // If the current call is nested inside another call, skip.
123+ if ( currentDepth > 1 ) {
124+ return ;
125+ }
126+
127+ const { maxLineLength = 100 , ignoreChainDeeperThan = 2 } = context . options [ 0 ] ?? { } ;
128+
129+ // If the max depth is greater than ignore threshold, skip
130+ //
131+ // Example:
132+ // ```ts
133+ // Array(10)
134+ // .fill(0)
135+ // .map(x => x + 1)
136+ // .slice(0, 5);
137+ // ```
138+ // In this case the depth is 3, and the default value of ignoreChainDeeperThan is 2.
139+ // So the check can be skipped.
140+ if ( maxDepth > ignoreChainDeeperThan ) {
110141 return ;
111142 }
112143
113- const { maxLineLength = 100 } = context . options [ 0 ] ?? { } ;
114144 const { property} = callee ;
115145 const lastToken = sourceCode . getLastToken ( node , {
116146 filter : token => token . loc . end . line === property . loc . start . line ,
0 commit comments