@croct/eslint-plugin 0.2.2 → 0.3.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.
@@ -74,6 +74,12 @@ export declare const configs: {
74
74
  };
75
75
  })[];
76
76
  };
77
+ overrides: {
78
+ files: string[];
79
+ rules: {
80
+ 'sort-keys-fix/sort-keys-fix': string;
81
+ };
82
+ }[];
77
83
  };
78
84
  typescript: {
79
85
  extends: string[];
@@ -142,6 +148,10 @@ export declare const configs: {
142
148
  };
143
149
  })[];
144
150
  'no-undef': string;
151
+ '@typescript-eslint/no-namespace': string;
152
+ '@typescript-eslint/no-redeclare': (string | {
153
+ ignoreDeclarationMerge: boolean;
154
+ })[];
145
155
  'no-new-object'?: undefined;
146
156
  };
147
157
  plugins?: undefined;
@@ -178,6 +188,8 @@ export declare const configs: {
178
188
  '@typescript-eslint/object-curly-spacing'?: undefined;
179
189
  '@typescript-eslint/member-delimiter-style'?: undefined;
180
190
  'no-undef'?: undefined;
191
+ '@typescript-eslint/no-namespace'?: undefined;
192
+ '@typescript-eslint/no-redeclare'?: undefined;
181
193
  };
182
194
  env: {
183
195
  jest: boolean;
@@ -193,6 +205,11 @@ export declare const configs: {
193
205
  '@croct/complex-expression-spacing': string;
194
206
  '@croct/newline-per-chained-call': string;
195
207
  '@croct/min-chained-call-depth': string;
208
+ '@croct/parameter-destructuring': string;
209
+ 'eslint-comments/disable-enable-pair': (string | {
210
+ allowWholeFile: boolean;
211
+ })[];
212
+ 'eslint-comments/require-description': string;
196
213
  'newline-per-chained-call': string;
197
214
  'no-plusplus': string;
198
215
  'array-bracket-newline': string[];
@@ -281,6 +298,10 @@ export declare const configs: {
281
298
  prev: string[];
282
299
  next: string;
283
300
  })[];
301
+ 'no-useless-escape': string;
302
+ 'newline-destructuring/newline': (string | {
303
+ maxLength: number;
304
+ })[];
284
305
  };
285
306
  overrides: {
286
307
  files: string[];
@@ -6,6 +6,11 @@ export declare const javascript: {
6
6
  '@croct/complex-expression-spacing': string;
7
7
  '@croct/newline-per-chained-call': string;
8
8
  '@croct/min-chained-call-depth': string;
9
+ '@croct/parameter-destructuring': string;
10
+ 'eslint-comments/disable-enable-pair': (string | {
11
+ allowWholeFile: boolean;
12
+ })[];
13
+ 'eslint-comments/require-description': string;
9
14
  'newline-per-chained-call': string;
10
15
  'no-plusplus': string;
11
16
  'array-bracket-newline': string[];
@@ -94,6 +99,10 @@ export declare const javascript: {
94
99
  prev: string[];
95
100
  next: string;
96
101
  })[];
102
+ 'no-useless-escape': string;
103
+ 'newline-destructuring/newline': (string | {
104
+ maxLength: number;
105
+ })[];
97
106
  };
98
107
  overrides: {
99
108
  files: string[];
@@ -5,12 +5,14 @@ exports.javascript = {
5
5
  extends: [
6
6
  'plugin:jest/recommended',
7
7
  'airbnb-base',
8
+ 'plugin:eslint-comments/recommended',
8
9
  ],
9
10
  plugins: [
10
11
  'jest',
11
12
  'import',
12
13
  'no-smart-quotes',
13
14
  'import-newlines',
15
+ 'newline-destructuring',
14
16
  '@croct',
15
17
  ],
16
18
  rules: {
@@ -18,6 +20,14 @@ exports.javascript = {
18
20
  '@croct/complex-expression-spacing': 'error',
19
21
  '@croct/newline-per-chained-call': 'error',
20
22
  '@croct/min-chained-call-depth': 'error',
23
+ '@croct/parameter-destructuring': 'error',
24
+ 'eslint-comments/disable-enable-pair': [
25
+ 'error',
26
+ {
27
+ allowWholeFile: true,
28
+ },
29
+ ],
30
+ 'eslint-comments/require-description': 'error',
21
31
  'newline-per-chained-call': 'off',
22
32
  'no-plusplus': 'off',
23
33
  'array-bracket-newline': [
@@ -205,6 +215,10 @@ exports.javascript = {
205
215
  ],
206
216
  },
207
217
  ],
218
+ 'no-useless-escape': 'error',
219
+ 'newline-destructuring/newline': ['error', {
220
+ maxLength: 100,
221
+ }],
208
222
  },
209
223
  overrides: [
210
224
  {
@@ -60,4 +60,10 @@ export declare const react: {
60
60
  };
61
61
  })[];
62
62
  };
63
+ overrides: {
64
+ files: string[];
65
+ rules: {
66
+ 'sort-keys-fix/sort-keys-fix': string;
67
+ };
68
+ }[];
63
69
  };
package/configs/react.js CHANGED
@@ -17,6 +17,7 @@ exports.react = {
17
17
  'testing-library',
18
18
  'jest-dom',
19
19
  '@croct',
20
+ 'sort-keys-fix',
20
21
  ],
21
22
  rules: {
22
23
  '@croct/jsx-attribute-spacing': 'error',
@@ -120,4 +121,12 @@ exports.react = {
120
121
  },
121
122
  ],
122
123
  },
124
+ overrides: [
125
+ {
126
+ files: ['**/styles.ts'],
127
+ rules: {
128
+ 'sort-keys-fix/sort-keys-fix': 'error',
129
+ },
130
+ },
131
+ ],
123
132
  };
@@ -65,6 +65,10 @@ export declare const typescript: {
65
65
  };
66
66
  })[];
67
67
  'no-undef': string;
68
+ '@typescript-eslint/no-namespace': string;
69
+ '@typescript-eslint/no-redeclare': (string | {
70
+ ignoreDeclarationMerge: boolean;
71
+ })[];
68
72
  'no-new-object'?: undefined;
69
73
  };
70
74
  plugins?: undefined;
@@ -101,6 +105,8 @@ export declare const typescript: {
101
105
  '@typescript-eslint/object-curly-spacing'?: undefined;
102
106
  '@typescript-eslint/member-delimiter-style'?: undefined;
103
107
  'no-undef'?: undefined;
108
+ '@typescript-eslint/no-namespace'?: undefined;
109
+ '@typescript-eslint/no-redeclare'?: undefined;
104
110
  };
105
111
  env: {
106
112
  jest: boolean;
@@ -77,6 +77,10 @@ exports.typescript = {
77
77
  },
78
78
  }],
79
79
  'no-undef': 'off',
80
+ '@typescript-eslint/no-namespace': 'off',
81
+ '@typescript-eslint/no-redeclare': ['error', {
82
+ ignoreDeclarationMerge: true,
83
+ }],
80
84
  },
81
85
  },
82
86
  {
package/index.d.ts CHANGED
@@ -1,26 +1,30 @@
1
1
  declare const configuration: {
2
2
  rules: {
3
3
  'argument-spacing': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"missing", never[], {
4
- CallExpression: (node: import("@typescript-eslint/types/dist/ast-spec").CallExpression | import("@typescript-eslint/types/dist/ast-spec").NewExpression) => void;
5
- NewExpression: (node: import("@typescript-eslint/types/dist/ast-spec").CallExpression | import("@typescript-eslint/types/dist/ast-spec").NewExpression) => void;
4
+ CallExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").CallExpression | import("@typescript-eslint/types/dist/generated/ast-spec").NewExpression) => void;
5
+ NewExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").CallExpression | import("@typescript-eslint/types/dist/generated/ast-spec").NewExpression) => void;
6
6
  }>;
7
7
  'jsx-attribute-spacing': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"missing", never[], {
8
- JSXAttribute: (node: import("@typescript-eslint/types/dist/ast-spec").JSXAttribute) => void;
8
+ JSXAttribute: (node: import("@typescript-eslint/types/dist/generated/ast-spec").JSXAttribute) => void;
9
9
  }>;
10
10
  'complex-expression-spacing': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"missing", never[], {
11
- ArrowFunctionExpression: (node: import("@typescript-eslint/types/dist/ast-spec").ArrowFunctionExpression) => void;
12
- IfStatement: (node: import("@typescript-eslint/types/dist/ast-spec").IfStatement) => void;
11
+ ArrowFunctionExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").ArrowFunctionExpression) => void;
12
+ IfStatement: (node: import("@typescript-eslint/types/dist/generated/ast-spec").IfStatement) => void;
13
13
  }>;
14
14
  'newline-per-chained-call': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"expectedLineBreak", {
15
15
  ignoreChainWithDepth: number;
16
16
  }[], {
17
- CallExpression: (node: import("@typescript-eslint/types/dist/ast-spec").CallExpression) => void;
18
- MemberExpression: (node: import("@typescript-eslint/types/dist/ast-spec").MemberExpression) => void;
17
+ CallExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").CallExpression) => void;
18
+ MemberExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").MemberExpression) => void;
19
19
  }>;
20
20
  'min-chained-call-depth': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"unexpectedLineBreak", {
21
21
  maxLineLength: number;
22
22
  }[], {
23
- CallExpression: (node: import("@typescript-eslint/types/dist/ast-spec").CallExpression) => void;
23
+ CallExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").CallExpression) => void;
24
+ MemberExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").MemberExpression) => void;
25
+ }>;
26
+ 'parameter-destructuring': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"unexpectedDestructuring", never[], {
27
+ ObjectPattern: (node: import("@typescript-eslint/types/dist/generated/ast-spec").ObjectPattern) => void;
24
28
  }>;
25
29
  };
26
30
  configs: {
@@ -99,6 +103,12 @@ declare const configuration: {
99
103
  };
100
104
  })[];
101
105
  };
106
+ overrides: {
107
+ files: string[];
108
+ rules: {
109
+ 'sort-keys-fix/sort-keys-fix': string;
110
+ };
111
+ }[];
102
112
  };
103
113
  typescript: {
104
114
  extends: string[];
@@ -167,6 +177,10 @@ declare const configuration: {
167
177
  };
168
178
  })[];
169
179
  'no-undef': string;
180
+ '@typescript-eslint/no-namespace': string;
181
+ '@typescript-eslint/no-redeclare': (string | {
182
+ ignoreDeclarationMerge: boolean;
183
+ })[];
170
184
  'no-new-object'?: undefined;
171
185
  };
172
186
  plugins?: undefined;
@@ -203,6 +217,8 @@ declare const configuration: {
203
217
  '@typescript-eslint/object-curly-spacing'?: undefined;
204
218
  '@typescript-eslint/member-delimiter-style'?: undefined;
205
219
  'no-undef'?: undefined;
220
+ '@typescript-eslint/no-namespace'?: undefined;
221
+ '@typescript-eslint/no-redeclare'?: undefined;
206
222
  };
207
223
  env: {
208
224
  jest: boolean;
@@ -218,6 +234,11 @@ declare const configuration: {
218
234
  '@croct/complex-expression-spacing': string;
219
235
  '@croct/newline-per-chained-call': string;
220
236
  '@croct/min-chained-call-depth': string;
237
+ '@croct/parameter-destructuring': string;
238
+ 'eslint-comments/disable-enable-pair': (string | {
239
+ allowWholeFile: boolean;
240
+ })[];
241
+ 'eslint-comments/require-description': string;
221
242
  'newline-per-chained-call': string;
222
243
  'no-plusplus': string;
223
244
  'array-bracket-newline': string[];
@@ -306,6 +327,10 @@ declare const configuration: {
306
327
  prev: string[];
307
328
  next: string;
308
329
  })[];
330
+ 'no-useless-escape': string;
331
+ 'newline-destructuring/newline': (string | {
332
+ maxLength: number;
333
+ })[];
309
334
  };
310
335
  overrides: {
311
336
  files: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@croct/eslint-plugin",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "ESLint rules and presets applied to all Croct JavaScript projects.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -42,11 +42,13 @@
42
42
  "eslint-config-airbnb": "^19.0",
43
43
  "eslint-config-airbnb-base": "^15.0",
44
44
  "eslint-plugin-cypress": "^2.12",
45
+ "eslint-plugin-eslint-comments": "^3.2.0",
45
46
  "eslint-plugin-import": "^2.25",
46
47
  "eslint-plugin-import-newlines": "^1.1",
47
48
  "eslint-plugin-jest": "^26.1",
48
49
  "eslint-plugin-jest-dom": "^4.0",
49
50
  "eslint-plugin-jsx-a11y": "^6.5",
51
+ "eslint-plugin-newline-destructuring": "^1.0.1",
50
52
  "eslint-plugin-no-smart-quotes": "^1.3",
51
53
  "eslint-plugin-react": "^7.28",
52
54
  "eslint-plugin-react-hooks": "^4.3",
@@ -61,6 +63,7 @@
61
63
  "eslint": "^8.8",
62
64
  "eslint-plugin-eslint-plugin": "^4.1.0",
63
65
  "eslint-plugin-self": "^1.2.1",
66
+ "eslint-plugin-sort-keys-fix": "^1.1.2",
64
67
  "jest": "^27.5",
65
68
  "ts-jest": "^27.1",
66
69
  "typescript": "^4.5"
package/rules/index.d.ts CHANGED
@@ -1,24 +1,28 @@
1
1
  export declare const rules: {
2
2
  'argument-spacing': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"missing", never[], {
3
- CallExpression: (node: import("@typescript-eslint/types/dist/ast-spec").CallExpression | import("@typescript-eslint/types/dist/ast-spec").NewExpression) => void;
4
- NewExpression: (node: import("@typescript-eslint/types/dist/ast-spec").CallExpression | import("@typescript-eslint/types/dist/ast-spec").NewExpression) => void;
3
+ CallExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").CallExpression | import("@typescript-eslint/types/dist/generated/ast-spec").NewExpression) => void;
4
+ NewExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").CallExpression | import("@typescript-eslint/types/dist/generated/ast-spec").NewExpression) => void;
5
5
  }>;
6
6
  'jsx-attribute-spacing': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"missing", never[], {
7
- JSXAttribute: (node: import("@typescript-eslint/types/dist/ast-spec").JSXAttribute) => void;
7
+ JSXAttribute: (node: import("@typescript-eslint/types/dist/generated/ast-spec").JSXAttribute) => void;
8
8
  }>;
9
9
  'complex-expression-spacing': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"missing", never[], {
10
- ArrowFunctionExpression: (node: import("@typescript-eslint/types/dist/ast-spec").ArrowFunctionExpression) => void;
11
- IfStatement: (node: import("@typescript-eslint/types/dist/ast-spec").IfStatement) => void;
10
+ ArrowFunctionExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").ArrowFunctionExpression) => void;
11
+ IfStatement: (node: import("@typescript-eslint/types/dist/generated/ast-spec").IfStatement) => void;
12
12
  }>;
13
13
  'newline-per-chained-call': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"expectedLineBreak", {
14
14
  ignoreChainWithDepth: number;
15
15
  }[], {
16
- CallExpression: (node: import("@typescript-eslint/types/dist/ast-spec").CallExpression) => void;
17
- MemberExpression: (node: import("@typescript-eslint/types/dist/ast-spec").MemberExpression) => void;
16
+ CallExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").CallExpression) => void;
17
+ MemberExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").MemberExpression) => void;
18
18
  }>;
19
19
  'min-chained-call-depth': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"unexpectedLineBreak", {
20
20
  maxLineLength: number;
21
21
  }[], {
22
- CallExpression: (node: import("@typescript-eslint/types/dist/ast-spec").CallExpression) => void;
22
+ CallExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").CallExpression) => void;
23
+ MemberExpression: (node: import("@typescript-eslint/types/dist/generated/ast-spec").MemberExpression) => void;
24
+ }>;
25
+ 'parameter-destructuring': import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"unexpectedDestructuring", never[], {
26
+ ObjectPattern: (node: import("@typescript-eslint/types/dist/generated/ast-spec").ObjectPattern) => void;
23
27
  }>;
24
28
  };
package/rules/index.js CHANGED
@@ -6,10 +6,12 @@ const jsx_attribute_spacing_1 = require("./jsx-attribute-spacing");
6
6
  const complex_expression_spacing_1 = require("./complex-expression-spacing");
7
7
  const newline_per_chained_call_1 = require("./newline-per-chained-call");
8
8
  const min_chained_call_depth_1 = require("./min-chained-call-depth");
9
+ const parameter_destructuring_1 = require("./parameter-destructuring");
9
10
  exports.rules = {
10
11
  'argument-spacing': argument_spacing_1.argumentSpacing,
11
12
  'jsx-attribute-spacing': jsx_attribute_spacing_1.jsxAttributeSpacing,
12
13
  'complex-expression-spacing': complex_expression_spacing_1.complexExpressionSpacing,
13
14
  'newline-per-chained-call': newline_per_chained_call_1.newlinePerChainedCall,
14
15
  'min-chained-call-depth': min_chained_call_depth_1.minChainedCallDepth,
16
+ 'parameter-destructuring': parameter_destructuring_1.parameterDestructuring,
15
17
  };
@@ -3,4 +3,5 @@ export declare const minChainedCallDepth: import("@typescript-eslint/utils/dist/
3
3
  maxLineLength: number;
4
4
  }[], {
5
5
  CallExpression: (node: TSESTree.CallExpression) => void;
6
+ MemberExpression: (node: TSESTree.MemberExpression) => void;
6
7
  }>;
@@ -43,28 +43,51 @@ exports.minChainedCallDepth = (0, createRule_1.createRule)({
43
43
  || currentNode.type === 'MemberExpression') {
44
44
  if (currentNode.type === 'MemberExpression') {
45
45
  currentNode = currentNode.object;
46
+ depth += 1;
46
47
  }
47
48
  else if (currentNode.type === 'CallExpression') {
48
49
  currentNode = currentNode.callee;
49
50
  }
50
- depth += 1;
51
51
  }
52
52
  return depth;
53
53
  }
54
54
  function check(node) {
55
- var _a, _b, _c;
56
- if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === 'MemberExpression'
57
- || ((_b = node.parent) === null || _b === void 0 ? void 0 : _b.type) === 'CallExpression'
58
- || node.callee.type !== 'MemberExpression'
59
- || node.callee.computed
60
- || node.callee.object.loc.end.line === node.callee.property.loc.start.line) {
55
+ var _a, _b;
56
+ // If the node is a member expression inside a call expression skip, this is to ensure
57
+ // that we consider the correct line length of the result.
58
+ //
59
+ // Example:
60
+ // ```ts
61
+ // foo
62
+ // .bar();
63
+ // ```
64
+ // The replacement of this input should be `foo.bar();`, which has 10 character.
65
+ // Without this check it would consider the length up to `r`, which is 7.
66
+ if (node.type === 'MemberExpression' && ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === 'CallExpression') {
61
67
  return;
62
68
  }
63
- if (getDepth(node) > 3) {
69
+ // If the node is a call expression we need to validate it's callee as a member
70
+ // expression.
71
+ // If the node itself is already a member expression, like the
72
+ // `property` in `this.property.function()`, we validate the node directly.
73
+ const callee = node.type === 'CallExpression' ? node.callee : node;
74
+ if (
75
+ // If the callee is not a member expression, we can skip.
76
+ // For example, root level calls like `foo();`.
77
+ callee.type !== 'MemberExpression'
78
+ // If the callee is a computed member expression, like `foo[bar]()`, we can skip.
79
+ || callee.computed
80
+ // If the callee is already in the same line as it's object, we can skip.
81
+ || callee.object.loc.end.line === callee.property.loc.start.line) {
64
82
  return;
65
83
  }
66
- const { maxLineLength = 100 } = (_c = context.options[0]) !== null && _c !== void 0 ? _c : {};
67
- const { property } = node.callee;
84
+ // We only inline the first level of chained calls.
85
+ // If the current call is nested inside another call, we can skip.
86
+ if (getDepth(callee) > 1) {
87
+ return;
88
+ }
89
+ const { maxLineLength = 100 } = (_b = context.options[0]) !== null && _b !== void 0 ? _b : {};
90
+ const { property } = callee;
68
91
  const lastToken = sourceCode.getLastToken(node, {
69
92
  filter: token => token.loc.end.line === property.loc.start.line,
70
93
  });
@@ -73,14 +96,14 @@ exports.minChainedCallDepth = (0, createRule_1.createRule)({
73
96
  && token.type === 'Punctuator'
74
97
  && token.value === ';'),
75
98
  });
76
- const lineLength = node.callee.object.loc.end.column
99
+ const lineLength = callee.object.loc.end.column
77
100
  + lastToken.loc.end.column - property.loc.start.column
78
101
  + 1
79
102
  + (semicolon !== null ? 1 : 0);
80
103
  if (maxLineLength !== null && lineLength > maxLineLength) {
81
104
  return;
82
105
  }
83
- const punctuator = sourceCode.getTokenBefore(node.callee.property);
106
+ const punctuator = sourceCode.getTokenBefore(callee.property);
84
107
  const previousToken = sourceCode.getTokenBefore(punctuator, { includeComments: true });
85
108
  const nextToken = sourceCode.getTokenAfter(punctuator, { includeComments: true });
86
109
  if ((0, ast_utils_1.isCommentToken)(previousToken) || (0, ast_utils_1.isCommentToken)(nextToken)) {
@@ -89,8 +112,8 @@ exports.minChainedCallDepth = (0, createRule_1.createRule)({
89
112
  context.report({
90
113
  node: node,
91
114
  loc: {
92
- start: node.callee.object.loc.end,
93
- end: node.callee.property.loc.start,
115
+ start: callee.object.loc.end,
116
+ end: callee.property.loc.start,
94
117
  },
95
118
  messageId: 'unexpectedLineBreak',
96
119
  fix: fixer => fixer.replaceTextRange([previousToken.range[1], nextToken.range[0]], punctuator.value),
@@ -100,6 +123,9 @@ exports.minChainedCallDepth = (0, createRule_1.createRule)({
100
123
  CallExpression: (node) => {
101
124
  check(node);
102
125
  },
126
+ MemberExpression: (node) => {
127
+ check(node);
128
+ },
103
129
  };
104
130
  },
105
131
  });
@@ -42,8 +42,7 @@ exports.newlinePerChainedCall = (0, createRule_1.createRule)({
42
42
  const sourceCode = context.getSourceCode();
43
43
  function getPropertyText(node) {
44
44
  const prefix = '.';
45
- const lines = sourceCode.getText(node.property)
46
- .split(LINEBREAK_MATCHER);
45
+ const lines = sourceCode.getText(node.property).split(LINEBREAK_MATCHER);
47
46
  return prefix + lines[0];
48
47
  }
49
48
  function hasObjectAndPropertyOnSameLine(node) {
@@ -53,7 +52,7 @@ exports.newlinePerChainedCall = (0, createRule_1.createRule)({
53
52
  return token.value !== ')' || token.type !== 'Punctuator';
54
53
  }
55
54
  function validateCallExpressionIgnoreDepth(node) {
56
- var _a;
55
+ var _a, _b;
57
56
  let hasCallExpression = false;
58
57
  if (node.type === 'CallExpression') {
59
58
  hasCallExpression = true;
@@ -85,7 +84,8 @@ exports.newlinePerChainedCall = (0, createRule_1.createRule)({
85
84
  .filter(hasObjectAndPropertyOnSameLine);
86
85
  const rootNode = expressionsOnSameLine[expressionsOnSameLine.length - 1];
87
86
  if (rootNode.type === 'MemberExpression'
88
- && ((_a = rootNode.parent) === null || _a === void 0 ? void 0 : _a.type) === 'CallExpression'
87
+ && (((_a = rootNode.parent) === null || _a === void 0 ? void 0 : _a.type) === 'CallExpression'
88
+ || ((_b = rootNode.parent) === null || _b === void 0 ? void 0 : _b.type) === 'MemberExpression')
89
89
  && (rootNode.object.type === 'ThisExpression'
90
90
  || rootNode.object.type === 'Identifier')) {
91
91
  expressionsOnSameLine.pop();
@@ -0,0 +1,3 @@
1
+ export declare const parameterDestructuring: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"unexpectedDestructuring", never[], {
2
+ ObjectPattern: (node: import("@typescript-eslint/types/dist/generated/ast-spec").ObjectPattern) => void;
3
+ }>;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parameterDestructuring = void 0;
4
+ /*
5
+ eslint-disable @typescript-eslint/no-non-null-assertion
6
+ --
7
+ Disable the rule to reduce the number of branches
8
+ */
9
+ const types_1 = require("@typescript-eslint/types");
10
+ const createRule_1 = require("../createRule");
11
+ exports.parameterDestructuring = (0, createRule_1.createRule)({
12
+ name: 'parameter-destructuring',
13
+ meta: {
14
+ type: 'layout',
15
+ docs: {
16
+ description: 'Prevent noisy destructuring on parameters',
17
+ recommended: 'error',
18
+ },
19
+ hasSuggestions: true,
20
+ schema: [],
21
+ messages: {
22
+ unexpectedDestructuring: ('Destructuring should not be done in the parameters. '
23
+ + 'Bind to a variable and destructure inside the function.'),
24
+ },
25
+ },
26
+ defaultOptions: [],
27
+ create: context => {
28
+ const sourceCode = context.getSourceCode();
29
+ return {
30
+ ObjectPattern: function checkObjectPattern(node) {
31
+ const { parent } = node;
32
+ // Skip for destructuring in contexts unrelated to function parameters
33
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) !== types_1.AST_NODE_TYPES.FunctionExpression
34
+ && (parent === null || parent === void 0 ? void 0 : parent.type) !== types_1.AST_NODE_TYPES.FunctionDeclaration
35
+ && (parent === null || parent === void 0 ? void 0 : parent.type) !== types_1.AST_NODE_TYPES.ArrowFunctionExpression) {
36
+ return;
37
+ }
38
+ // Allow one-line destructuring
39
+ if (node.loc.start.line === node.loc.end.line) {
40
+ return;
41
+ }
42
+ const { body } = parent;
43
+ context.report({
44
+ node: node,
45
+ messageId: 'unexpectedDestructuring',
46
+ suggest: body.type === types_1.AST_NODE_TYPES.BlockStatement
47
+ ? [
48
+ {
49
+ messageId: 'unexpectedDestructuring',
50
+ fix: (fixer) => [
51
+ // Replace the destructuring with a variable declaration
52
+ fixer.replaceText(node, 'value'),
53
+ // Add the destructuring inside the body
54
+ fixer.insertTextAfter(
55
+ // Null safety: a block expression always have the `{` token
56
+ // opening the body of the function.
57
+ sourceCode.getFirstToken(body), `\nconst ${sourceCode.getText(node)} = value;\n`),
58
+ ],
59
+ },
60
+ ]
61
+ : null,
62
+ });
63
+ },
64
+ };
65
+ },
66
+ });