eslint-plugin-unicorn 63.0.0 → 65.0.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/index.js +26 -18
- package/package.json +32 -30
- package/readme.md +183 -147
- package/rules/ast/call-or-new-expression.js +3 -5
- package/rules/ast/literal.js +1 -6
- package/rules/better-dom-traversing.js +291 -0
- package/rules/catch-error-name.js +3 -3
- package/rules/consistent-compound-words.js +452 -0
- package/rules/consistent-destructuring.js +234 -22
- package/rules/consistent-function-scoping.js +35 -11
- package/rules/consistent-json-file-read.js +245 -0
- package/rules/consistent-template-literal-escape.js +52 -0
- package/rules/custom-error-definition.js +176 -71
- package/rules/dom-node-dataset.js +431 -0
- package/rules/escape-case.js +2 -1
- package/rules/expiring-todo-comments.js +56 -102
- package/rules/explicit-length-check.js +145 -33
- package/rules/filename-case.js +97 -13
- package/rules/fix/append-argument.js +1 -1
- package/rules/fix/remove-expression-statement.js +1 -0
- package/rules/import-style.js +30 -10
- package/rules/index.js +37 -3
- package/rules/isolated-functions.js +11 -5
- package/rules/no-accessor-recursion.js +1 -2
- package/rules/no-anonymous-default-export.js +9 -11
- package/rules/no-array-callback-reference.js +148 -22
- package/rules/no-array-fill-with-reference-type.js +127 -0
- package/rules/no-array-for-each.js +18 -3
- package/rules/no-array-from-fill.js +76 -0
- package/rules/no-array-method-this-argument.js +1 -1
- package/rules/no-array-reduce.js +509 -2
- package/rules/no-blob-to-file.js +299 -0
- package/rules/no-canvas-to-image.js +152 -0
- package/rules/no-confusing-array-splice.js +164 -0
- package/rules/no-duplicate-set-values.js +57 -0
- package/rules/no-empty-file.js +31 -2
- package/rules/no-exports-in-scripts.js +34 -0
- package/rules/no-for-loop.js +1 -5
- package/rules/no-hex-escape.js +1 -1
- package/rules/no-incorrect-query-selector.js +347 -0
- package/rules/no-instanceof-builtins.js +4 -6
- package/rules/no-invalid-fetch-options.js +1 -1
- package/rules/no-invalid-file-input-accept.js +475 -0
- package/rules/no-keyword-prefix.js +23 -5
- package/rules/no-late-current-target-access.js +166 -0
- package/rules/no-lonely-if.js +152 -52
- package/rules/no-manually-wrapped-comments.js +151 -0
- package/rules/no-null.js +16 -5
- package/rules/no-process-exit.js +1 -1
- package/rules/no-this-outside-of-class.js +75 -0
- package/rules/no-typeof-undefined.js +7 -4
- package/rules/no-unnecessary-nested-ternary.js +132 -0
- package/rules/no-unnecessary-polyfills.js +253 -24
- package/rules/no-unreadable-iife.js +33 -3
- package/rules/no-unused-array-method-return.js +301 -0
- package/rules/no-unused-properties.js +13 -19
- package/rules/no-useless-iterator-to-array.js +249 -0
- package/rules/no-useless-length-check.js +5 -11
- package/rules/no-useless-promise-resolve-reject.js +5 -5
- package/rules/no-useless-spread.js +53 -4
- package/rules/no-useless-undefined.js +62 -46
- package/rules/numeric-separators-style.js +17 -6
- package/rules/prefer-add-event-listener.js +1 -0
- package/rules/prefer-array-find.js +1 -0
- package/rules/prefer-array-flat.js +76 -8
- package/rules/prefer-array-last-methods.js +93 -0
- package/rules/prefer-array-some.js +74 -8
- package/rules/prefer-at.js +118 -57
- package/rules/prefer-class-fields.js +2 -4
- package/rules/prefer-default-parameters.js +1 -2
- package/rules/prefer-dom-node-append.js +2 -2
- package/rules/prefer-dom-node-remove.js +24 -18
- package/rules/prefer-export-from.js +8 -7
- package/rules/prefer-get-or-insert-computed.js +159 -0
- package/rules/prefer-global-this.js +33 -29
- package/rules/prefer-https.js +83 -0
- package/rules/prefer-includes-over-repeated-comparisons.js +199 -0
- package/rules/prefer-iterator-concat.js +174 -0
- package/rules/prefer-iterator-to-array-at-end.js +123 -0
- package/rules/prefer-keyboard-event-key.js +202 -76
- package/rules/prefer-logical-operator-over-ternary.js +1 -1
- package/rules/prefer-math-abs.js +397 -0
- package/rules/prefer-math-min-max.js +54 -26
- package/rules/prefer-module.js +5 -7
- package/rules/prefer-native-coercion-functions.js +8 -1
- package/rules/prefer-node-protocol.js +7 -4
- package/rules/prefer-number-properties.js +2 -0
- package/rules/prefer-object-from-entries.js +12 -7
- package/rules/prefer-prototype-methods.js +1 -3
- package/rules/prefer-query-selector.js +119 -7
- package/rules/prefer-queue-microtask.js +204 -0
- package/rules/prefer-regexp-test.js +166 -20
- package/rules/prefer-set-has.js +474 -47
- package/rules/prefer-simple-condition-first.js +282 -0
- package/rules/prefer-single-call.js +129 -38
- package/rules/prefer-split-limit.js +107 -0
- package/rules/prefer-spread.js +150 -19
- package/rules/prefer-string-match-all.js +352 -0
- package/rules/prefer-string-pad-start-end.js +380 -0
- package/rules/prefer-string-raw.js +90 -19
- package/rules/prefer-string-repeat.js +173 -0
- package/rules/prefer-string-replace-all.js +180 -12
- package/rules/prefer-string-slice.js +55 -4
- package/rules/prefer-string-starts-ends-with.js +2 -2
- package/rules/prefer-structured-clone.js +1 -0
- package/rules/prefer-switch.js +2 -0
- package/rules/prefer-ternary.js +3 -2
- package/rules/prefer-top-level-await.js +168 -6
- package/rules/prevent-abbreviations.js +144 -158
- package/rules/relative-url-style.js +1 -0
- package/rules/require-css-escape.js +141 -0
- package/rules/require-module-attributes.js +16 -18
- package/rules/require-module-specifiers.js +62 -0
- package/rules/require-passive-events.js +292 -0
- package/rules/rule/to-eslint-rule.js +1 -1
- package/rules/rule/to-eslint-rules.js +4 -6
- package/rules/shared/abbreviations.js +1 -0
- package/rules/shared/dom-events.js +7 -7
- package/rules/shared/identifier-checks.js +205 -0
- package/rules/shared/package-json.js +1 -1
- package/rules/string-content.js +35 -5
- package/rules/switch-case-braces.js +2 -3
- package/rules/switch-case-break-position.js +138 -0
- package/rules/template-indent.js +59 -3
- package/rules/text-encoding-identifier-case.js +23 -5
- package/rules/throw-new-error.js +4 -0
- package/rules/try-complexity.js +184 -0
- package/rules/utils/assert-token.js +3 -5
- package/rules/utils/boolean.js +37 -28
- package/rules/utils/create-deprecated-rules.js +25 -27
- package/rules/utils/get-call-expression-arguments-text.js +3 -5
- package/rules/utils/get-duplicate-array-elements.js +77 -0
- package/rules/utils/index.js +4 -1
- package/rules/utils/is-node-contains-lexical-this.js +65 -0
- package/rules/utils/is-number.js +2 -2
- package/rules/utils/is-same-reference.js +25 -17
- package/rules/utils/should-add-parentheses-to-await-expression-argument.js +9 -9
- package/rules/utils/should-add-parentheses-to-call-expression-callee.js +12 -10
- package/rules/utils/should-add-parentheses-to-conditional-expression-child.js +9 -5
- package/rules/utils/should-add-parentheses-to-expression-statement-expression.js +1 -1
- package/rules/utils/should-add-parentheses-to-logical-expression-child.js +12 -8
- package/rules/utils/should-add-parentheses-to-member-expression-object.js +1 -1
- package/rules/utils/should-add-parentheses-to-unary-expression.js +10 -10
- package/rules/better-regex.js +0 -145
- package/rules/prefer-dom-node-dataset.js +0 -135
- package/rules/prefer-json-parse-buffer.js +0 -161
|
@@ -71,11 +71,9 @@ function create(node, options, types) {
|
|
|
71
71
|
const maximumArgumentsLength = Number.isFinite(maximumArguments) ? maximumArguments : argumentsLength;
|
|
72
72
|
if (
|
|
73
73
|
typeof maximumArgumentsLength === 'number'
|
|
74
|
-
&& node.arguments.some(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
&& index < maximumArgumentsLength,
|
|
78
|
-
)
|
|
74
|
+
&& node.arguments.some((node, index) =>
|
|
75
|
+
node.type === 'SpreadElement'
|
|
76
|
+
&& index < maximumArgumentsLength)
|
|
79
77
|
) {
|
|
80
78
|
return false;
|
|
81
79
|
}
|
package/rules/ast/literal.js
CHANGED
|
@@ -3,10 +3,6 @@ export function isLiteral(node, value) {
|
|
|
3
3
|
return false;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
if (value === null) {
|
|
7
|
-
return node.raw === 'null';
|
|
8
|
-
}
|
|
9
|
-
|
|
10
6
|
return node.value === value;
|
|
11
7
|
}
|
|
12
8
|
|
|
@@ -16,8 +12,7 @@ export const isNumericLiteral = node => node.type === 'Literal' && typeof node.v
|
|
|
16
12
|
|
|
17
13
|
export const isRegexLiteral = node => node.type === 'Literal' && Boolean(node.regex);
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
export const isNullLiteral = node => isLiteral(node, null);
|
|
15
|
+
export const isNullLiteral = node => node?.type === 'Literal' && node.raw === 'null';
|
|
21
16
|
|
|
22
17
|
export const isBigIntLiteral = node => node.type === 'Literal' && Boolean(node.bigint);
|
|
23
18
|
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import {isMethodCall, isMemberExpression, isNumericLiteral} from './ast/index.js';
|
|
2
|
+
import {escapeString, getParenthesizedText, isNodeValueNotDomNode} from './utils/index.js';
|
|
3
|
+
|
|
4
|
+
const MESSAGE_ID_FIRST_CHILD = 'first-child';
|
|
5
|
+
const MESSAGE_ID_FIRST_ELEMENT_CHILD = 'first-element-child';
|
|
6
|
+
const MESSAGE_ID_QUERY_SELECTOR = 'query-selector';
|
|
7
|
+
const MESSAGE_ID_CLOSEST = 'closest';
|
|
8
|
+
const MESSAGE_ID_MERGE_QUERY_SELECTOR = 'merge-query-selector';
|
|
9
|
+
const SUGGESTION_ID_FIRST_CHILD = 'suggestion-first-child';
|
|
10
|
+
const SUGGESTION_ID_FIRST_ELEMENT_CHILD = 'suggestion-first-element-child';
|
|
11
|
+
const SUGGESTION_ID_MERGE_QUERY_SELECTOR = 'suggestion-merge-query-selector';
|
|
12
|
+
const QUERY_SELECTOR_CALL = {
|
|
13
|
+
method: 'querySelector',
|
|
14
|
+
argumentsLength: 1,
|
|
15
|
+
optionalCall: false,
|
|
16
|
+
optionalMember: false,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const messages = {
|
|
20
|
+
[MESSAGE_ID_FIRST_CHILD]: 'Prefer `.firstChild` over `.childNodes[0]`.',
|
|
21
|
+
[MESSAGE_ID_FIRST_ELEMENT_CHILD]: 'Prefer `.firstElementChild` over `.children[0]`.',
|
|
22
|
+
[MESSAGE_ID_QUERY_SELECTOR]: 'Consider `.querySelector()` over positional child traversal.',
|
|
23
|
+
[MESSAGE_ID_CLOSEST]: 'Consider `.closest()` over chaining `.parentElement`.',
|
|
24
|
+
[MESSAGE_ID_MERGE_QUERY_SELECTOR]: 'Consider merging chained `.querySelector()` calls.',
|
|
25
|
+
[SUGGESTION_ID_FIRST_CHILD]: 'Switch to `.firstChild`.',
|
|
26
|
+
[SUGGESTION_ID_FIRST_ELEMENT_CHILD]: 'Switch to `.firstElementChild`.',
|
|
27
|
+
[SUGGESTION_ID_MERGE_QUERY_SELECTOR]: 'Merge the `.querySelector()` calls.',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const isNonOptionalMemberExpression = node =>
|
|
31
|
+
node.type === 'MemberExpression'
|
|
32
|
+
&& !node.optional;
|
|
33
|
+
|
|
34
|
+
const isDomCollectionMemberExpression = (node, property) =>
|
|
35
|
+
isMemberExpression(node, {
|
|
36
|
+
property,
|
|
37
|
+
optional: false,
|
|
38
|
+
computed: false,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const isNumericIndexMemberExpression = node =>
|
|
42
|
+
isNonOptionalMemberExpression(node)
|
|
43
|
+
&& node.computed
|
|
44
|
+
&& isNumericLiteral(node.property)
|
|
45
|
+
&& Number.isInteger(node.property.value)
|
|
46
|
+
&& node.property.value >= 0;
|
|
47
|
+
|
|
48
|
+
const getIndexedDomCollectionName = node => {
|
|
49
|
+
if (!isNumericIndexMemberExpression(node)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (isDomCollectionMemberExpression(node.object, 'childNodes')) {
|
|
54
|
+
return 'childNodes';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (isDomCollectionMemberExpression(node.object, 'children')) {
|
|
58
|
+
return 'children';
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const isNestedIndexedDomCollection = node =>
|
|
63
|
+
node.parent?.type === 'MemberExpression'
|
|
64
|
+
&& node.parent.object === node
|
|
65
|
+
&& isDomCollectionMemberExpression(node.parent, 'children')
|
|
66
|
+
&& isNumericIndexMemberExpression(node.parent.parent);
|
|
67
|
+
|
|
68
|
+
const hasCommentsInside = (node, sourceCode) =>
|
|
69
|
+
sourceCode.getCommentsInside(node).length > 0;
|
|
70
|
+
|
|
71
|
+
const getFirstChildSuggestion = (node, replacement, messageId, sourceCode) => {
|
|
72
|
+
if (hasCommentsInside(node, sourceCode)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const [, end] = sourceCode.getRange(node);
|
|
77
|
+
const [start] = sourceCode.getRange(node.object.property);
|
|
78
|
+
|
|
79
|
+
return [
|
|
80
|
+
{
|
|
81
|
+
messageId,
|
|
82
|
+
fix: fixer => fixer.replaceTextRange([start, end], replacement),
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const isParentElementMemberExpression = node =>
|
|
88
|
+
isMemberExpression(node, {
|
|
89
|
+
property: 'parentElement',
|
|
90
|
+
optional: false,
|
|
91
|
+
computed: false,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const getParentElementChainRoot = node => {
|
|
95
|
+
while (isParentElementMemberExpression(node)) {
|
|
96
|
+
node = node.object;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return node;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const isOutermostParentElementChain = node =>
|
|
103
|
+
!isParentElementMemberExpression(node.parent)
|
|
104
|
+
|| node.parent.object !== node;
|
|
105
|
+
|
|
106
|
+
const isStaticSelector = node =>
|
|
107
|
+
(node.type === 'Literal' && typeof node.value === 'string')
|
|
108
|
+
|| (node.type === 'TemplateLiteral' && node.expressions.length === 0 && node.quasis[0].value.cooked !== undefined);
|
|
109
|
+
|
|
110
|
+
const getStaticSelectorValue = node => {
|
|
111
|
+
if (node.type === 'Literal') {
|
|
112
|
+
return node.value;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return node.quasis[0].value.cooked;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const getSelectorQuote = node =>
|
|
119
|
+
node.type === 'Literal' && node.raw.startsWith('"') ? '"' : '\'';
|
|
120
|
+
|
|
121
|
+
const canMergeSelectorValues = selectors =>
|
|
122
|
+
selectors.every(selector => !selector.includes(','));
|
|
123
|
+
|
|
124
|
+
const isQuerySelectorCall = node =>
|
|
125
|
+
isMethodCall(node, QUERY_SELECTOR_CALL);
|
|
126
|
+
|
|
127
|
+
const isFollowedByStaticQuerySelectorCall = node =>
|
|
128
|
+
node.parent?.type === 'MemberExpression'
|
|
129
|
+
&& node.parent.object === node
|
|
130
|
+
&& node.parent.parent?.callee === node.parent
|
|
131
|
+
&& isQuerySelectorCall(node.parent.parent)
|
|
132
|
+
&& isStaticSelector(node.parent.parent.arguments[0]);
|
|
133
|
+
|
|
134
|
+
const isPartOfChainExpression = node => {
|
|
135
|
+
while (
|
|
136
|
+
(node.parent?.type === 'MemberExpression' && node.parent.object === node)
|
|
137
|
+
|| (node.parent?.type === 'CallExpression' && node.parent.callee === node)
|
|
138
|
+
) {
|
|
139
|
+
node = node.parent;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return node.parent?.type === 'ChainExpression';
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const getQuerySelectorChain = node => {
|
|
146
|
+
const calls = [];
|
|
147
|
+
|
|
148
|
+
while (isQuerySelectorCall(node)) {
|
|
149
|
+
const [selector] = node.arguments;
|
|
150
|
+
if (!isStaticSelector(selector)) {
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
calls.push(node);
|
|
155
|
+
node = node.callee.object;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (
|
|
159
|
+
calls.length < 2
|
|
160
|
+
|| node.type === 'ChainExpression'
|
|
161
|
+
|| isNodeValueNotDomNode(node)
|
|
162
|
+
) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const selectors = [];
|
|
167
|
+
for (const call of calls) {
|
|
168
|
+
selectors.unshift(getStaticSelectorValue(call.arguments[0]));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
root: node,
|
|
173
|
+
selectors,
|
|
174
|
+
quoteNode: calls.at(-1).arguments[0],
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const getMergeQuerySelectorSuggestion = (node, querySelectorChain, context) => {
|
|
179
|
+
const {sourceCode} = context;
|
|
180
|
+
if (hasCommentsInside(node, sourceCode)) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (!canMergeSelectorValues(querySelectorChain.selectors)) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const root = getParenthesizedText(querySelectorChain.root, context);
|
|
189
|
+
const selector = querySelectorChain.selectors.join(' ');
|
|
190
|
+
const replacement = `${root}.querySelector(${escapeString(selector, getSelectorQuote(querySelectorChain.quoteNode))})`;
|
|
191
|
+
|
|
192
|
+
return [
|
|
193
|
+
{
|
|
194
|
+
messageId: SUGGESTION_ID_MERGE_QUERY_SELECTOR,
|
|
195
|
+
fix: fixer => fixer.replaceText(node, replacement),
|
|
196
|
+
},
|
|
197
|
+
];
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/** @param {import('eslint').Rule.RuleContext} context */
|
|
201
|
+
const create = context => {
|
|
202
|
+
const {sourceCode} = context;
|
|
203
|
+
|
|
204
|
+
context.on('MemberExpression', node => {
|
|
205
|
+
const collectionName = getIndexedDomCollectionName(node);
|
|
206
|
+
if (
|
|
207
|
+
!collectionName
|
|
208
|
+
|| isNodeValueNotDomNode(node.object.object)
|
|
209
|
+
|| isNestedIndexedDomCollection(node)
|
|
210
|
+
) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const index = node.property.value;
|
|
215
|
+
if (collectionName === 'childNodes' && index === 0) {
|
|
216
|
+
return {
|
|
217
|
+
node,
|
|
218
|
+
messageId: MESSAGE_ID_FIRST_CHILD,
|
|
219
|
+
suggest: getFirstChildSuggestion(node, 'firstChild', SUGGESTION_ID_FIRST_CHILD, sourceCode),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (collectionName === 'children' && index === 0) {
|
|
224
|
+
return {
|
|
225
|
+
node,
|
|
226
|
+
messageId: MESSAGE_ID_FIRST_ELEMENT_CHILD,
|
|
227
|
+
suggest: getFirstChildSuggestion(node, 'firstElementChild', SUGGESTION_ID_FIRST_ELEMENT_CHILD, sourceCode),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (collectionName === 'children') {
|
|
232
|
+
return {
|
|
233
|
+
node,
|
|
234
|
+
messageId: MESSAGE_ID_QUERY_SELECTOR,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
context.on('MemberExpression', node => {
|
|
240
|
+
if (
|
|
241
|
+
!isParentElementMemberExpression(node)
|
|
242
|
+
|| !isParentElementMemberExpression(node.object)
|
|
243
|
+
|| !isOutermostParentElementChain(node)
|
|
244
|
+
|| isNodeValueNotDomNode(getParentElementChainRoot(node))
|
|
245
|
+
) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
node,
|
|
251
|
+
messageId: MESSAGE_ID_CLOSEST,
|
|
252
|
+
};
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
context.on('CallExpression', node => {
|
|
256
|
+
if (
|
|
257
|
+
!isQuerySelectorCall(node)
|
|
258
|
+
|| isFollowedByStaticQuerySelectorCall(node)
|
|
259
|
+
|| isPartOfChainExpression(node)
|
|
260
|
+
) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const querySelectorChain = getQuerySelectorChain(node);
|
|
265
|
+
if (!querySelectorChain) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
node,
|
|
271
|
+
messageId: MESSAGE_ID_MERGE_QUERY_SELECTOR,
|
|
272
|
+
suggest: getMergeQuerySelectorSuggestion(node, querySelectorChain, context),
|
|
273
|
+
};
|
|
274
|
+
});
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
/** @type {import('eslint').Rule.RuleModule} */
|
|
278
|
+
const config = {
|
|
279
|
+
create,
|
|
280
|
+
meta: {
|
|
281
|
+
type: 'suggestion',
|
|
282
|
+
docs: {
|
|
283
|
+
description: 'Prefer better DOM traversal APIs.',
|
|
284
|
+
recommended: 'unopinionated',
|
|
285
|
+
},
|
|
286
|
+
hasSuggestions: true,
|
|
287
|
+
messages,
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
export default config;
|
|
@@ -34,9 +34,7 @@ const isPromiseCatchParameter = node =>
|
|
|
34
34
|
const create = context => {
|
|
35
35
|
const options = context.options[0];
|
|
36
36
|
const {name: expectedName} = options;
|
|
37
|
-
const ignore = options.ignore.map(
|
|
38
|
-
pattern => isRegExp(pattern) ? pattern : new RegExp(pattern, 'u'),
|
|
39
|
-
);
|
|
37
|
+
const ignore = options.ignore.map(pattern => isRegExp(pattern) ? pattern : new RegExp(pattern, 'u'));
|
|
40
38
|
const isNameAllowed = name =>
|
|
41
39
|
name === expectedName
|
|
42
40
|
|| ignore.some(regexp => regexp.test(name))
|
|
@@ -104,10 +102,12 @@ const schema = [
|
|
|
104
102
|
properties: {
|
|
105
103
|
name: {
|
|
106
104
|
type: 'string',
|
|
105
|
+
description: 'The expected name for the error variable.',
|
|
107
106
|
},
|
|
108
107
|
ignore: {
|
|
109
108
|
type: 'array',
|
|
110
109
|
uniqueItems: true,
|
|
110
|
+
description: 'Patterns to ignore.',
|
|
111
111
|
},
|
|
112
112
|
},
|
|
113
113
|
},
|