eslint-plugin-react-x 1.22.2-next.6 → 1.22.2-next.7
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/dist/index.js +68 -122
- package/dist/index.mjs +68 -122
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var eff = require('@eslint-react/eff');
|
|
4
|
-
var
|
|
4
|
+
var JSX7 = require('@eslint-react/jsx');
|
|
5
5
|
var shared = require('@eslint-react/shared');
|
|
6
6
|
var AST11 = require('@eslint-react/ast');
|
|
7
7
|
var core = require('@eslint-react/core');
|
|
@@ -35,14 +35,14 @@ function _interopNamespace(e) {
|
|
|
35
35
|
return Object.freeze(n);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
var
|
|
38
|
+
var JSX7__namespace = /*#__PURE__*/_interopNamespace(JSX7);
|
|
39
39
|
var AST11__namespace = /*#__PURE__*/_interopNamespace(AST11);
|
|
40
40
|
var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
|
|
41
41
|
var ts__default = /*#__PURE__*/_interopDefault(ts);
|
|
42
42
|
|
|
43
43
|
// package.json
|
|
44
44
|
var name = "eslint-plugin-react-x";
|
|
45
|
-
var version = "1.22.2-next.
|
|
45
|
+
var version = "1.22.2-next.7";
|
|
46
46
|
var createRule = shared.createRuleForPlugin("x");
|
|
47
47
|
|
|
48
48
|
// src/rules/avoid-shorthand-boolean.ts
|
|
@@ -70,7 +70,7 @@ var avoid_shorthand_boolean_default = createRule({
|
|
|
70
70
|
messageId: "avoidShorthandBoolean",
|
|
71
71
|
node,
|
|
72
72
|
data: {
|
|
73
|
-
propName:
|
|
73
|
+
propName: JSX7__namespace.getPropName(node)
|
|
74
74
|
},
|
|
75
75
|
fix: (fixer) => fixer.insertTextAfter(node.name, `={true}`)
|
|
76
76
|
});
|
|
@@ -151,7 +151,7 @@ var RULE_FEATURES4 = [
|
|
|
151
151
|
"CHK"
|
|
152
152
|
];
|
|
153
153
|
function getName(node) {
|
|
154
|
-
if (node
|
|
154
|
+
if (AST11__namespace.isTypeExpression(node)) {
|
|
155
155
|
return getName(node.expression);
|
|
156
156
|
}
|
|
157
157
|
if (node.type === types.AST_NODE_TYPES.Identifier || node.type === types.AST_NODE_TYPES.PrivateIdentifier) {
|
|
@@ -537,7 +537,7 @@ var no_children_prop_default = createRule({
|
|
|
537
537
|
return {
|
|
538
538
|
JSXElement(node) {
|
|
539
539
|
const initialScope = context.sourceCode.getScope(node);
|
|
540
|
-
const prop =
|
|
540
|
+
const prop = JSX7__namespace.getProp(node.openingElement.attributes, "children", initialScope);
|
|
541
541
|
const reportDescriptor = eff.O.map(prop, (prop2) => ({ messageId: "noChildrenProp", node: prop2 }));
|
|
542
542
|
eff.O.map(reportDescriptor, context.report);
|
|
543
543
|
}
|
|
@@ -912,7 +912,7 @@ var no_context_provider_default = createRule({
|
|
|
912
912
|
if (compareVersions.compare(version2, "19.0.0", "<")) return {};
|
|
913
913
|
return {
|
|
914
914
|
JSXElement(node) {
|
|
915
|
-
const elementName =
|
|
915
|
+
const elementName = JSX7__namespace.getElementName(node.openingElement);
|
|
916
916
|
if (!elementName.endsWith(".Provider")) return;
|
|
917
917
|
context.report({
|
|
918
918
|
messageId: "noContextProvider",
|
|
@@ -1009,7 +1009,7 @@ var RULE_FEATURES22 = [
|
|
|
1009
1009
|
"CHK"
|
|
1010
1010
|
];
|
|
1011
1011
|
function getName2(node) {
|
|
1012
|
-
if (node
|
|
1012
|
+
if (AST11__namespace.isTypeExpression(node)) {
|
|
1013
1013
|
return getName2(node.expression);
|
|
1014
1014
|
}
|
|
1015
1015
|
if (node.type === types.AST_NODE_TYPES.Identifier || node.type === types.AST_NODE_TYPES.PrivateIdentifier) {
|
|
@@ -1123,117 +1123,63 @@ var no_duplicate_key_default = createRule({
|
|
|
1123
1123
|
},
|
|
1124
1124
|
name: RULE_NAME24,
|
|
1125
1125
|
create(context) {
|
|
1126
|
-
const
|
|
1127
|
-
function
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
eff.O.flatMap((k) => "value" in k ? eff.O.fromNullable(k.value) : eff.O.none()),
|
|
1136
|
-
eff.O.flatMap((v) => {
|
|
1137
|
-
return isKeyEqual(v, v) ? eff.O.some({
|
|
1138
|
-
messageId: "noDuplicateKey",
|
|
1139
|
-
node: v,
|
|
1140
|
-
data: {
|
|
1141
|
-
value: context.sourceCode.getText(v)
|
|
1142
|
-
}
|
|
1143
|
-
}) : eff.O.none();
|
|
1144
|
-
})
|
|
1145
|
-
);
|
|
1146
|
-
}
|
|
1147
|
-
function checkExpression(node) {
|
|
1148
|
-
switch (node.type) {
|
|
1149
|
-
case types.AST_NODE_TYPES.ConditionalExpression:
|
|
1150
|
-
if (!("consequent" in node)) return eff.O.none();
|
|
1151
|
-
return eff.F.pipe(
|
|
1152
|
-
checkIteratorElement(node.consequent),
|
|
1153
|
-
eff.O.orElse(() => checkIteratorElement(node.alternate))
|
|
1154
|
-
);
|
|
1155
|
-
case types.AST_NODE_TYPES.JSXElement:
|
|
1156
|
-
case types.AST_NODE_TYPES.JSXFragment:
|
|
1157
|
-
return checkIteratorElement(node);
|
|
1158
|
-
case types.AST_NODE_TYPES.LogicalExpression:
|
|
1159
|
-
if (!("left" in node)) return eff.O.none();
|
|
1160
|
-
return eff.F.pipe(
|
|
1161
|
-
checkIteratorElement(node.left),
|
|
1162
|
-
eff.O.orElse(() => checkIteratorElement(node.right))
|
|
1163
|
-
);
|
|
1164
|
-
default:
|
|
1165
|
-
return eff.O.none();
|
|
1166
|
-
}
|
|
1126
|
+
const keyedEntries = /* @__PURE__ */ new Map();
|
|
1127
|
+
function isKeyValueEqual(a, b) {
|
|
1128
|
+
const aValue = a.value;
|
|
1129
|
+
const bValue = b.value;
|
|
1130
|
+
if (aValue === null || bValue === null) return false;
|
|
1131
|
+
return VAR__namespace.isNodeValueEqual(aValue, bValue, [
|
|
1132
|
+
context.sourceCode.getScope(aValue),
|
|
1133
|
+
context.sourceCode.getScope(bValue)
|
|
1134
|
+
]);
|
|
1167
1135
|
}
|
|
1168
|
-
function checkBlockStatement(node) {
|
|
1169
|
-
return AST11__namespace.getNestedReturnStatements(node).reduce((acc, statement) => {
|
|
1170
|
-
if (!statement.argument) return acc;
|
|
1171
|
-
const maybeDescriptor = checkIteratorElement(statement.argument);
|
|
1172
|
-
if (eff.O.isNone(maybeDescriptor)) return acc;
|
|
1173
|
-
const descriptor = maybeDescriptor.value;
|
|
1174
|
-
return [...acc, descriptor];
|
|
1175
|
-
}, []);
|
|
1176
|
-
}
|
|
1177
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
1178
1136
|
return {
|
|
1179
|
-
"
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1137
|
+
"JSXAttribute[name.name='key']"(node) {
|
|
1138
|
+
const jsxElement = node.parent.parent;
|
|
1139
|
+
switch (jsxElement.parent.type) {
|
|
1140
|
+
case types.AST_NODE_TYPES.ArrayExpression:
|
|
1141
|
+
case types.AST_NODE_TYPES.JSXElement:
|
|
1142
|
+
case types.AST_NODE_TYPES.JSXFragment: {
|
|
1143
|
+
const root = jsxElement.parent;
|
|
1144
|
+
const prevKeys = keyedEntries.get(root)?.keys ?? [];
|
|
1145
|
+
keyedEntries.set(root, {
|
|
1146
|
+
hasDuplicate: prevKeys.some((prevKey) => isKeyValueEqual(prevKey, node)),
|
|
1147
|
+
keys: [...prevKeys, node],
|
|
1148
|
+
root: jsxElement.parent
|
|
1187
1149
|
});
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
data: {
|
|
1205
|
-
value: context.sourceCode.getText(value)
|
|
1150
|
+
break;
|
|
1151
|
+
}
|
|
1152
|
+
default: {
|
|
1153
|
+
const entry = eff.F.pipe(
|
|
1154
|
+
eff.O.Do,
|
|
1155
|
+
eff.O.bind("call", () => AST11__namespace.traverseUpGuard(jsxElement, AST11__namespace.isMapCallLoose)),
|
|
1156
|
+
eff.O.bind("ietr", ({ call }) => AST11__namespace.traverseUpStop(jsxElement, call, AST11__namespace.isFunction)),
|
|
1157
|
+
eff.O.bind("arg0", ({ call }) => eff.O.fromNullable(call.arguments[0]))
|
|
1158
|
+
);
|
|
1159
|
+
for (const { arg0, call, ietr } of eff.O.toArray(entry)) {
|
|
1160
|
+
if (AST11__namespace.unwrapTypeExpression(arg0) !== ietr) continue;
|
|
1161
|
+
keyedEntries.set(call, {
|
|
1162
|
+
hasDuplicate: node.value?.type === types.AST_NODE_TYPES.Literal,
|
|
1163
|
+
keys: [node],
|
|
1164
|
+
root: call
|
|
1165
|
+
});
|
|
1206
1166
|
}
|
|
1207
|
-
}
|
|
1167
|
+
}
|
|
1208
1168
|
}
|
|
1209
1169
|
},
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
}, node);
|
|
1223
|
-
if (!isMapCall && !isArrayFromCall) return;
|
|
1224
|
-
const fn = node.arguments[isMapCall ? 0 : 1];
|
|
1225
|
-
if (!AST11__namespace.isOneOf([types.AST_NODE_TYPES.ArrowFunctionExpression, types.AST_NODE_TYPES.FunctionExpression])(fn)) return;
|
|
1226
|
-
if (fn.body.type === types.AST_NODE_TYPES.BlockStatement) {
|
|
1227
|
-
for (const descriptor of checkBlockStatement(fn.body)) {
|
|
1228
|
-
context.report(descriptor);
|
|
1170
|
+
"Program:exit"() {
|
|
1171
|
+
for (const { hasDuplicate, keys } of keyedEntries.values()) {
|
|
1172
|
+
if (!hasDuplicate) continue;
|
|
1173
|
+
for (const key of keys) {
|
|
1174
|
+
context.report({
|
|
1175
|
+
messageId: "noDuplicateKey",
|
|
1176
|
+
node: key,
|
|
1177
|
+
data: {
|
|
1178
|
+
value: context.sourceCode.getText(key)
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1229
1181
|
}
|
|
1230
|
-
return;
|
|
1231
1182
|
}
|
|
1232
|
-
eff.O.map(checkExpression(fn.body), context.report);
|
|
1233
|
-
},
|
|
1234
|
-
"CallExpression:exit"(node) {
|
|
1235
|
-
if (!core.isChildrenToArrayCall(node, context)) return;
|
|
1236
|
-
state.isWithinChildrenToArray = false;
|
|
1237
1183
|
}
|
|
1238
1184
|
};
|
|
1239
1185
|
},
|
|
@@ -1356,7 +1302,7 @@ var no_implicit_key_default = createRule({
|
|
|
1356
1302
|
create(context) {
|
|
1357
1303
|
function getReportDescriptor(node) {
|
|
1358
1304
|
const initialScope = context.sourceCode.getScope(node);
|
|
1359
|
-
const keyPropFound =
|
|
1305
|
+
const keyPropFound = JSX7__namespace.findPropInAttributes(node.attributes, initialScope)("key");
|
|
1360
1306
|
const keyPropOnElement = node.attributes.some(
|
|
1361
1307
|
(n) => AST11__namespace.is(types.AST_NODE_TYPES.JSXAttribute)(n) && n.name.name === "key"
|
|
1362
1308
|
);
|
|
@@ -1601,7 +1547,7 @@ var no_missing_key_default = createRule({
|
|
|
1601
1547
|
switch (node.type) {
|
|
1602
1548
|
case types.AST_NODE_TYPES.JSXElement: {
|
|
1603
1549
|
const initialScope = context.sourceCode.getScope(node);
|
|
1604
|
-
if (!
|
|
1550
|
+
if (!JSX7__namespace.hasProp(node.openingElement.attributes, "key", initialScope)) {
|
|
1605
1551
|
return eff.O.some({
|
|
1606
1552
|
messageId: "noMissingKey",
|
|
1607
1553
|
node
|
|
@@ -1650,7 +1596,7 @@ var no_missing_key_default = createRule({
|
|
|
1650
1596
|
if (elements.length === 0) return;
|
|
1651
1597
|
const initialScope = context.sourceCode.getScope(node);
|
|
1652
1598
|
for (const element of elements) {
|
|
1653
|
-
if (!
|
|
1599
|
+
if (!JSX7__namespace.hasProp(element.openingElement.attributes, "key", initialScope)) {
|
|
1654
1600
|
context.report({
|
|
1655
1601
|
messageId: "noMissingKey",
|
|
1656
1602
|
node: element
|
|
@@ -1738,7 +1684,7 @@ var no_nested_components_default = createRule({
|
|
|
1738
1684
|
if (eff.O.isNone(componentName)) continue;
|
|
1739
1685
|
const name2 = componentName.value;
|
|
1740
1686
|
const isInsideProperty = component.parent.type === types.AST_NODE_TYPES.Property;
|
|
1741
|
-
const isInsideJSXPropValue = component.parent.type === types.AST_NODE_TYPES.JSXAttribute || eff.O.isSome(
|
|
1687
|
+
const isInsideJSXPropValue = component.parent.type === types.AST_NODE_TYPES.JSXAttribute || eff.O.isSome(JSX7__namespace.traverseUpProp(node, (n) => n.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer));
|
|
1742
1688
|
if (isInsideJSXPropValue) {
|
|
1743
1689
|
if (!core.isDeclaredInRenderPropLoose(component)) {
|
|
1744
1690
|
context.report({
|
|
@@ -2362,7 +2308,7 @@ var LIFECYCLE_METHODS = /* @__PURE__ */ new Set([
|
|
|
2362
2308
|
"UNSAFE_componentWillUpdate"
|
|
2363
2309
|
]);
|
|
2364
2310
|
function getName3(node) {
|
|
2365
|
-
if (node
|
|
2311
|
+
if (AST11__namespace.isTypeExpression(node)) {
|
|
2366
2312
|
return getName3(node.expression);
|
|
2367
2313
|
}
|
|
2368
2314
|
if (node.type === types.AST_NODE_TYPES.Identifier || node.type === types.AST_NODE_TYPES.PrivateIdentifier) {
|
|
@@ -2476,7 +2422,7 @@ var RULE_FEATURES43 = [
|
|
|
2476
2422
|
"CHK"
|
|
2477
2423
|
];
|
|
2478
2424
|
function getName4(node) {
|
|
2479
|
-
if (node
|
|
2425
|
+
if (AST11__namespace.isTypeExpression(node)) {
|
|
2480
2426
|
return getName4(node.expression);
|
|
2481
2427
|
}
|
|
2482
2428
|
if (node.type === types.AST_NODE_TYPES.Identifier || node.type === types.AST_NODE_TYPES.PrivateIdentifier) {
|
|
@@ -2619,18 +2565,18 @@ var no_unused_state_default = createRule({
|
|
|
2619
2565
|
var RULE_NAME44 = "no-useless-fragment";
|
|
2620
2566
|
function check(node, context, allowExpressions) {
|
|
2621
2567
|
const initialScope = context.sourceCode.getScope(node);
|
|
2622
|
-
if (
|
|
2623
|
-
if (
|
|
2568
|
+
if (JSX7__namespace.isKeyedElement(node, initialScope)) return;
|
|
2569
|
+
if (JSX7__namespace.isBuiltInElement(node.parent)) context.report({ messageId: "noUselessFragmentInBuiltIn", node });
|
|
2624
2570
|
if (node.children.length === 0) return context.report({ messageId: "noUselessFragment", node });
|
|
2625
2571
|
const isChildren = AST11__namespace.isOneOf([types.AST_NODE_TYPES.JSXElement, types.AST_NODE_TYPES.JSXFragment])(node.parent);
|
|
2626
2572
|
const [firstChildren] = node.children;
|
|
2627
|
-
if (allowExpressions && node.children.length === 1 &&
|
|
2573
|
+
if (allowExpressions && node.children.length === 1 && JSX7__namespace.isLiteral(firstChildren) && !isChildren) return;
|
|
2628
2574
|
if (!allowExpressions && isChildren) {
|
|
2629
2575
|
return context.report({ messageId: "noUselessFragment", node });
|
|
2630
2576
|
} else if (!allowExpressions && !isChildren && node.children.length === 1) {
|
|
2631
2577
|
return context.report({ messageId: "noUselessFragment", node });
|
|
2632
2578
|
}
|
|
2633
|
-
const nonPaddingChildren = node.children.filter((child) => !
|
|
2579
|
+
const nonPaddingChildren = node.children.filter((child) => !JSX7__namespace.isPaddingSpaces(child));
|
|
2634
2580
|
if (nonPaddingChildren.length > 1) return;
|
|
2635
2581
|
if (nonPaddingChildren.length === 0) return context.report({ messageId: "noUselessFragment", node });
|
|
2636
2582
|
const [first] = nonPaddingChildren;
|
|
@@ -2872,7 +2818,7 @@ var prefer_shorthand_boolean_default = createRule({
|
|
|
2872
2818
|
create(context) {
|
|
2873
2819
|
function getReportDescriptor(node) {
|
|
2874
2820
|
const { value } = node;
|
|
2875
|
-
const propName =
|
|
2821
|
+
const propName = JSX7__namespace.getPropName(node);
|
|
2876
2822
|
const hasValueTrue = value?.type === types.AST_NODE_TYPES.JSXExpressionContainer && value.expression.type === types.AST_NODE_TYPES.Literal && value.expression.value === true;
|
|
2877
2823
|
if (!hasValueTrue) return eff.O.none();
|
|
2878
2824
|
return eff.O.some({
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { F, O, isString, isNullable } from '@eslint-react/eff';
|
|
2
|
-
import * as
|
|
2
|
+
import * as JSX7 from '@eslint-react/jsx';
|
|
3
3
|
import { createRuleForPlugin, normalizeSettings, decodeSettings, unsafeReadSettings } from '@eslint-react/shared';
|
|
4
4
|
import * as AST11 from '@eslint-react/ast';
|
|
5
|
-
import { isForwardRefCall, isThisSetState, isClassComponent, isChildrenCount, isChildrenForEach, isChildrenMap, isChildrenOnly, isChildrenToArray, useComponentCollectorLegacy, isCloneElementCall, isCreateRefCall, isComponentName,
|
|
5
|
+
import { isForwardRefCall, isThisSetState, isClassComponent, isChildrenCount, isChildrenForEach, isChildrenMap, isChildrenOnly, isChildrenToArray, useComponentCollectorLegacy, isCloneElementCall, isCreateRefCall, isComponentName, useComponentCollector, ERFunctionComponentFlag, isChildrenToArrayCall, ERComponentHint, isDirectValueOfRenderPropertyLoose, isDeclaredInRenderPropLoose, isInsideCreateElementProps, isInsideRenderMethod, ERClassComponentFlag, isFragmentElement, isCreateElementCall, isInitializedFromReact } from '@eslint-react/core';
|
|
6
6
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
7
7
|
import { isMatching, P, match } from 'ts-pattern';
|
|
8
8
|
import { compare } from 'compare-versions';
|
|
@@ -15,7 +15,7 @@ import { getTypeImmutability, isUnknown, isImmutable, isReadonlyShallow, isReado
|
|
|
15
15
|
|
|
16
16
|
// package.json
|
|
17
17
|
var name = "eslint-plugin-react-x";
|
|
18
|
-
var version = "1.22.2-next.
|
|
18
|
+
var version = "1.22.2-next.7";
|
|
19
19
|
var createRule = createRuleForPlugin("x");
|
|
20
20
|
|
|
21
21
|
// src/rules/avoid-shorthand-boolean.ts
|
|
@@ -43,7 +43,7 @@ var avoid_shorthand_boolean_default = createRule({
|
|
|
43
43
|
messageId: "avoidShorthandBoolean",
|
|
44
44
|
node,
|
|
45
45
|
data: {
|
|
46
|
-
propName:
|
|
46
|
+
propName: JSX7.getPropName(node)
|
|
47
47
|
},
|
|
48
48
|
fix: (fixer) => fixer.insertTextAfter(node.name, `={true}`)
|
|
49
49
|
});
|
|
@@ -124,7 +124,7 @@ var RULE_FEATURES4 = [
|
|
|
124
124
|
"CHK"
|
|
125
125
|
];
|
|
126
126
|
function getName(node) {
|
|
127
|
-
if (node
|
|
127
|
+
if (AST11.isTypeExpression(node)) {
|
|
128
128
|
return getName(node.expression);
|
|
129
129
|
}
|
|
130
130
|
if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) {
|
|
@@ -510,7 +510,7 @@ var no_children_prop_default = createRule({
|
|
|
510
510
|
return {
|
|
511
511
|
JSXElement(node) {
|
|
512
512
|
const initialScope = context.sourceCode.getScope(node);
|
|
513
|
-
const prop =
|
|
513
|
+
const prop = JSX7.getProp(node.openingElement.attributes, "children", initialScope);
|
|
514
514
|
const reportDescriptor = O.map(prop, (prop2) => ({ messageId: "noChildrenProp", node: prop2 }));
|
|
515
515
|
O.map(reportDescriptor, context.report);
|
|
516
516
|
}
|
|
@@ -885,7 +885,7 @@ var no_context_provider_default = createRule({
|
|
|
885
885
|
if (compare(version2, "19.0.0", "<")) return {};
|
|
886
886
|
return {
|
|
887
887
|
JSXElement(node) {
|
|
888
|
-
const elementName =
|
|
888
|
+
const elementName = JSX7.getElementName(node.openingElement);
|
|
889
889
|
if (!elementName.endsWith(".Provider")) return;
|
|
890
890
|
context.report({
|
|
891
891
|
messageId: "noContextProvider",
|
|
@@ -982,7 +982,7 @@ var RULE_FEATURES22 = [
|
|
|
982
982
|
"CHK"
|
|
983
983
|
];
|
|
984
984
|
function getName2(node) {
|
|
985
|
-
if (node
|
|
985
|
+
if (AST11.isTypeExpression(node)) {
|
|
986
986
|
return getName2(node.expression);
|
|
987
987
|
}
|
|
988
988
|
if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) {
|
|
@@ -1096,117 +1096,63 @@ var no_duplicate_key_default = createRule({
|
|
|
1096
1096
|
},
|
|
1097
1097
|
name: RULE_NAME24,
|
|
1098
1098
|
create(context) {
|
|
1099
|
-
const
|
|
1100
|
-
function
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
O.flatMap((k) => "value" in k ? O.fromNullable(k.value) : O.none()),
|
|
1109
|
-
O.flatMap((v) => {
|
|
1110
|
-
return isKeyEqual(v, v) ? O.some({
|
|
1111
|
-
messageId: "noDuplicateKey",
|
|
1112
|
-
node: v,
|
|
1113
|
-
data: {
|
|
1114
|
-
value: context.sourceCode.getText(v)
|
|
1115
|
-
}
|
|
1116
|
-
}) : O.none();
|
|
1117
|
-
})
|
|
1118
|
-
);
|
|
1119
|
-
}
|
|
1120
|
-
function checkExpression(node) {
|
|
1121
|
-
switch (node.type) {
|
|
1122
|
-
case AST_NODE_TYPES.ConditionalExpression:
|
|
1123
|
-
if (!("consequent" in node)) return O.none();
|
|
1124
|
-
return F.pipe(
|
|
1125
|
-
checkIteratorElement(node.consequent),
|
|
1126
|
-
O.orElse(() => checkIteratorElement(node.alternate))
|
|
1127
|
-
);
|
|
1128
|
-
case AST_NODE_TYPES.JSXElement:
|
|
1129
|
-
case AST_NODE_TYPES.JSXFragment:
|
|
1130
|
-
return checkIteratorElement(node);
|
|
1131
|
-
case AST_NODE_TYPES.LogicalExpression:
|
|
1132
|
-
if (!("left" in node)) return O.none();
|
|
1133
|
-
return F.pipe(
|
|
1134
|
-
checkIteratorElement(node.left),
|
|
1135
|
-
O.orElse(() => checkIteratorElement(node.right))
|
|
1136
|
-
);
|
|
1137
|
-
default:
|
|
1138
|
-
return O.none();
|
|
1139
|
-
}
|
|
1099
|
+
const keyedEntries = /* @__PURE__ */ new Map();
|
|
1100
|
+
function isKeyValueEqual(a, b) {
|
|
1101
|
+
const aValue = a.value;
|
|
1102
|
+
const bValue = b.value;
|
|
1103
|
+
if (aValue === null || bValue === null) return false;
|
|
1104
|
+
return VAR.isNodeValueEqual(aValue, bValue, [
|
|
1105
|
+
context.sourceCode.getScope(aValue),
|
|
1106
|
+
context.sourceCode.getScope(bValue)
|
|
1107
|
+
]);
|
|
1140
1108
|
}
|
|
1141
|
-
function checkBlockStatement(node) {
|
|
1142
|
-
return AST11.getNestedReturnStatements(node).reduce((acc, statement) => {
|
|
1143
|
-
if (!statement.argument) return acc;
|
|
1144
|
-
const maybeDescriptor = checkIteratorElement(statement.argument);
|
|
1145
|
-
if (O.isNone(maybeDescriptor)) return acc;
|
|
1146
|
-
const descriptor = maybeDescriptor.value;
|
|
1147
|
-
return [...acc, descriptor];
|
|
1148
|
-
}, []);
|
|
1149
|
-
}
|
|
1150
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
1151
1109
|
return {
|
|
1152
|
-
"
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1110
|
+
"JSXAttribute[name.name='key']"(node) {
|
|
1111
|
+
const jsxElement = node.parent.parent;
|
|
1112
|
+
switch (jsxElement.parent.type) {
|
|
1113
|
+
case AST_NODE_TYPES.ArrayExpression:
|
|
1114
|
+
case AST_NODE_TYPES.JSXElement:
|
|
1115
|
+
case AST_NODE_TYPES.JSXFragment: {
|
|
1116
|
+
const root = jsxElement.parent;
|
|
1117
|
+
const prevKeys = keyedEntries.get(root)?.keys ?? [];
|
|
1118
|
+
keyedEntries.set(root, {
|
|
1119
|
+
hasDuplicate: prevKeys.some((prevKey) => isKeyValueEqual(prevKey, node)),
|
|
1120
|
+
keys: [...prevKeys, node],
|
|
1121
|
+
root: jsxElement.parent
|
|
1160
1122
|
});
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
data: {
|
|
1178
|
-
value: context.sourceCode.getText(value)
|
|
1123
|
+
break;
|
|
1124
|
+
}
|
|
1125
|
+
default: {
|
|
1126
|
+
const entry = F.pipe(
|
|
1127
|
+
O.Do,
|
|
1128
|
+
O.bind("call", () => AST11.traverseUpGuard(jsxElement, AST11.isMapCallLoose)),
|
|
1129
|
+
O.bind("ietr", ({ call }) => AST11.traverseUpStop(jsxElement, call, AST11.isFunction)),
|
|
1130
|
+
O.bind("arg0", ({ call }) => O.fromNullable(call.arguments[0]))
|
|
1131
|
+
);
|
|
1132
|
+
for (const { arg0, call, ietr } of O.toArray(entry)) {
|
|
1133
|
+
if (AST11.unwrapTypeExpression(arg0) !== ietr) continue;
|
|
1134
|
+
keyedEntries.set(call, {
|
|
1135
|
+
hasDuplicate: node.value?.type === AST_NODE_TYPES.Literal,
|
|
1136
|
+
keys: [node],
|
|
1137
|
+
root: call
|
|
1138
|
+
});
|
|
1179
1139
|
}
|
|
1180
|
-
}
|
|
1140
|
+
}
|
|
1181
1141
|
}
|
|
1182
1142
|
},
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
}, node);
|
|
1196
|
-
if (!isMapCall && !isArrayFromCall) return;
|
|
1197
|
-
const fn = node.arguments[isMapCall ? 0 : 1];
|
|
1198
|
-
if (!AST11.isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(fn)) return;
|
|
1199
|
-
if (fn.body.type === AST_NODE_TYPES.BlockStatement) {
|
|
1200
|
-
for (const descriptor of checkBlockStatement(fn.body)) {
|
|
1201
|
-
context.report(descriptor);
|
|
1143
|
+
"Program:exit"() {
|
|
1144
|
+
for (const { hasDuplicate, keys } of keyedEntries.values()) {
|
|
1145
|
+
if (!hasDuplicate) continue;
|
|
1146
|
+
for (const key of keys) {
|
|
1147
|
+
context.report({
|
|
1148
|
+
messageId: "noDuplicateKey",
|
|
1149
|
+
node: key,
|
|
1150
|
+
data: {
|
|
1151
|
+
value: context.sourceCode.getText(key)
|
|
1152
|
+
}
|
|
1153
|
+
});
|
|
1202
1154
|
}
|
|
1203
|
-
return;
|
|
1204
1155
|
}
|
|
1205
|
-
O.map(checkExpression(fn.body), context.report);
|
|
1206
|
-
},
|
|
1207
|
-
"CallExpression:exit"(node) {
|
|
1208
|
-
if (!isChildrenToArrayCall(node, context)) return;
|
|
1209
|
-
state.isWithinChildrenToArray = false;
|
|
1210
1156
|
}
|
|
1211
1157
|
};
|
|
1212
1158
|
},
|
|
@@ -1329,7 +1275,7 @@ var no_implicit_key_default = createRule({
|
|
|
1329
1275
|
create(context) {
|
|
1330
1276
|
function getReportDescriptor(node) {
|
|
1331
1277
|
const initialScope = context.sourceCode.getScope(node);
|
|
1332
|
-
const keyPropFound =
|
|
1278
|
+
const keyPropFound = JSX7.findPropInAttributes(node.attributes, initialScope)("key");
|
|
1333
1279
|
const keyPropOnElement = node.attributes.some(
|
|
1334
1280
|
(n) => AST11.is(AST_NODE_TYPES.JSXAttribute)(n) && n.name.name === "key"
|
|
1335
1281
|
);
|
|
@@ -1574,7 +1520,7 @@ var no_missing_key_default = createRule({
|
|
|
1574
1520
|
switch (node.type) {
|
|
1575
1521
|
case AST_NODE_TYPES.JSXElement: {
|
|
1576
1522
|
const initialScope = context.sourceCode.getScope(node);
|
|
1577
|
-
if (!
|
|
1523
|
+
if (!JSX7.hasProp(node.openingElement.attributes, "key", initialScope)) {
|
|
1578
1524
|
return O.some({
|
|
1579
1525
|
messageId: "noMissingKey",
|
|
1580
1526
|
node
|
|
@@ -1623,7 +1569,7 @@ var no_missing_key_default = createRule({
|
|
|
1623
1569
|
if (elements.length === 0) return;
|
|
1624
1570
|
const initialScope = context.sourceCode.getScope(node);
|
|
1625
1571
|
for (const element of elements) {
|
|
1626
|
-
if (!
|
|
1572
|
+
if (!JSX7.hasProp(element.openingElement.attributes, "key", initialScope)) {
|
|
1627
1573
|
context.report({
|
|
1628
1574
|
messageId: "noMissingKey",
|
|
1629
1575
|
node: element
|
|
@@ -1711,7 +1657,7 @@ var no_nested_components_default = createRule({
|
|
|
1711
1657
|
if (O.isNone(componentName)) continue;
|
|
1712
1658
|
const name2 = componentName.value;
|
|
1713
1659
|
const isInsideProperty = component.parent.type === AST_NODE_TYPES.Property;
|
|
1714
|
-
const isInsideJSXPropValue = component.parent.type === AST_NODE_TYPES.JSXAttribute || O.isSome(
|
|
1660
|
+
const isInsideJSXPropValue = component.parent.type === AST_NODE_TYPES.JSXAttribute || O.isSome(JSX7.traverseUpProp(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer));
|
|
1715
1661
|
if (isInsideJSXPropValue) {
|
|
1716
1662
|
if (!isDeclaredInRenderPropLoose(component)) {
|
|
1717
1663
|
context.report({
|
|
@@ -2335,7 +2281,7 @@ var LIFECYCLE_METHODS = /* @__PURE__ */ new Set([
|
|
|
2335
2281
|
"UNSAFE_componentWillUpdate"
|
|
2336
2282
|
]);
|
|
2337
2283
|
function getName3(node) {
|
|
2338
|
-
if (node
|
|
2284
|
+
if (AST11.isTypeExpression(node)) {
|
|
2339
2285
|
return getName3(node.expression);
|
|
2340
2286
|
}
|
|
2341
2287
|
if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) {
|
|
@@ -2449,7 +2395,7 @@ var RULE_FEATURES43 = [
|
|
|
2449
2395
|
"CHK"
|
|
2450
2396
|
];
|
|
2451
2397
|
function getName4(node) {
|
|
2452
|
-
if (node
|
|
2398
|
+
if (AST11.isTypeExpression(node)) {
|
|
2453
2399
|
return getName4(node.expression);
|
|
2454
2400
|
}
|
|
2455
2401
|
if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) {
|
|
@@ -2592,18 +2538,18 @@ var no_unused_state_default = createRule({
|
|
|
2592
2538
|
var RULE_NAME44 = "no-useless-fragment";
|
|
2593
2539
|
function check(node, context, allowExpressions) {
|
|
2594
2540
|
const initialScope = context.sourceCode.getScope(node);
|
|
2595
|
-
if (
|
|
2596
|
-
if (
|
|
2541
|
+
if (JSX7.isKeyedElement(node, initialScope)) return;
|
|
2542
|
+
if (JSX7.isBuiltInElement(node.parent)) context.report({ messageId: "noUselessFragmentInBuiltIn", node });
|
|
2597
2543
|
if (node.children.length === 0) return context.report({ messageId: "noUselessFragment", node });
|
|
2598
2544
|
const isChildren = AST11.isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment])(node.parent);
|
|
2599
2545
|
const [firstChildren] = node.children;
|
|
2600
|
-
if (allowExpressions && node.children.length === 1 &&
|
|
2546
|
+
if (allowExpressions && node.children.length === 1 && JSX7.isLiteral(firstChildren) && !isChildren) return;
|
|
2601
2547
|
if (!allowExpressions && isChildren) {
|
|
2602
2548
|
return context.report({ messageId: "noUselessFragment", node });
|
|
2603
2549
|
} else if (!allowExpressions && !isChildren && node.children.length === 1) {
|
|
2604
2550
|
return context.report({ messageId: "noUselessFragment", node });
|
|
2605
2551
|
}
|
|
2606
|
-
const nonPaddingChildren = node.children.filter((child) => !
|
|
2552
|
+
const nonPaddingChildren = node.children.filter((child) => !JSX7.isPaddingSpaces(child));
|
|
2607
2553
|
if (nonPaddingChildren.length > 1) return;
|
|
2608
2554
|
if (nonPaddingChildren.length === 0) return context.report({ messageId: "noUselessFragment", node });
|
|
2609
2555
|
const [first] = nonPaddingChildren;
|
|
@@ -2845,7 +2791,7 @@ var prefer_shorthand_boolean_default = createRule({
|
|
|
2845
2791
|
create(context) {
|
|
2846
2792
|
function getReportDescriptor(node) {
|
|
2847
2793
|
const { value } = node;
|
|
2848
|
-
const propName =
|
|
2794
|
+
const propName = JSX7.getPropName(node);
|
|
2849
2795
|
const hasValueTrue = value?.type === AST_NODE_TYPES.JSXExpressionContainer && value.expression.type === AST_NODE_TYPES.Literal && value.expression.value === true;
|
|
2850
2796
|
if (!hasValueTrue) return O.none();
|
|
2851
2797
|
return O.some({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "1.22.2-next.
|
|
3
|
+
"version": "1.22.2-next.7",
|
|
4
4
|
"description": "A set of composable ESLint rules for libraries and frameworks that use React as a UI runtime.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"string-ts": "^2.2.0",
|
|
50
50
|
"ts-api-utils": "^2.0.0",
|
|
51
51
|
"ts-pattern": "^5.6.0",
|
|
52
|
-
"@eslint-react/ast": "1.22.2-next.
|
|
53
|
-
"@eslint-react/core": "1.22.2-next.
|
|
54
|
-
"@eslint-react/eff": "1.22.2-next.
|
|
55
|
-
"@eslint-react/
|
|
56
|
-
"@eslint-react/
|
|
57
|
-
"@eslint-react/types": "1.22.2-next.
|
|
58
|
-
"@eslint-react/var": "1.22.2-next.
|
|
52
|
+
"@eslint-react/ast": "1.22.2-next.7",
|
|
53
|
+
"@eslint-react/core": "1.22.2-next.7",
|
|
54
|
+
"@eslint-react/eff": "1.22.2-next.7",
|
|
55
|
+
"@eslint-react/shared": "1.22.2-next.7",
|
|
56
|
+
"@eslint-react/jsx": "1.22.2-next.7",
|
|
57
|
+
"@eslint-react/types": "1.22.2-next.7",
|
|
58
|
+
"@eslint-react/var": "1.22.2-next.7"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/react": "^19.0.2",
|