eslint-plugin-react-x 5.20.8 → 5.21.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.
- package/dist/index.js +49 -138
- package/package.json +16 -12
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DEFAULT_ESLINT_REACT_SETTINGS, getSettingsFromContext, toRegExp } from "@eslint-react/shared";
|
|
2
|
-
import
|
|
2
|
+
import * as ESLintUtils from "@typescript-eslint/utils/eslint-utils";
|
|
3
3
|
import { Check, Compare, Extract, Traverse } from "@eslint-react/ast";
|
|
4
4
|
import * as core from "@eslint-react/core";
|
|
5
|
-
import { merge } from "@eslint-react/eslint";
|
|
5
|
+
import { getConstrainedTypeAtLocation, merge, report } from "@eslint-react/eslint";
|
|
6
6
|
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
7
7
|
import { P, isMatching, match } from "ts-pattern";
|
|
8
8
|
import { isAssignmentTargetEqual, isInitializedFromReact, resolveEnclosingAssignmentTarget, resolveObjectType, resolveOrigin } from "@eslint-react/var";
|
|
@@ -10,7 +10,6 @@ import { DefinitionType, ScopeType } from "@typescript-eslint/scope-manager";
|
|
|
10
10
|
import { findVariable, getStaticValue } from "@typescript-eslint/utils/ast-utils";
|
|
11
11
|
import { findParentAttribute, getElementFullType, hasAttribute } from "@eslint-react/jsx";
|
|
12
12
|
import { compare } from "compare-versions";
|
|
13
|
-
import { getConstrainedTypeAtLocation } from "@typescript-eslint/type-utils";
|
|
14
13
|
import { unionConstituents } from "ts-api-utils";
|
|
15
14
|
import "typescript";
|
|
16
15
|
import { simpleTraverse } from "@typescript-eslint/typescript-estree";
|
|
@@ -145,7 +144,7 @@ const rules$6 = {
|
|
|
145
144
|
//#endregion
|
|
146
145
|
//#region package.json
|
|
147
146
|
var name$6 = "eslint-plugin-react-x";
|
|
148
|
-
var version = "5.
|
|
147
|
+
var version = "5.21.1";
|
|
149
148
|
|
|
150
149
|
//#endregion
|
|
151
150
|
//#region src/utils/create-rule.ts
|
|
@@ -1806,71 +1805,15 @@ var no_access_state_in_setstate_default = createRule({
|
|
|
1806
1805
|
});
|
|
1807
1806
|
function create$47(context) {
|
|
1808
1807
|
if (!context.sourceCode.text.includes("setState")) return {};
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
}
|
|
1817
|
-
|
|
1818
|
-
if (!core.isThisSetStateCall(node)) return;
|
|
1819
|
-
setStateStack.pop();
|
|
1820
|
-
},
|
|
1821
|
-
ClassDeclaration(node) {
|
|
1822
|
-
classStack.push([node, core.isClassComponent(node)]);
|
|
1823
|
-
},
|
|
1824
|
-
"ClassDeclaration:exit"() {
|
|
1825
|
-
classStack.pop();
|
|
1826
|
-
},
|
|
1827
|
-
ClassExpression(node) {
|
|
1828
|
-
classStack.push([node, core.isClassComponent(node)]);
|
|
1829
|
-
},
|
|
1830
|
-
"ClassExpression:exit"() {
|
|
1831
|
-
classStack.pop();
|
|
1832
|
-
},
|
|
1833
|
-
MemberExpression(node) {
|
|
1834
|
-
if (node.object.type !== AST_NODE_TYPES.ThisExpression) return;
|
|
1835
|
-
const [currClass, isComponent = false] = classStack.at(-1) ?? [];
|
|
1836
|
-
if (currClass == null || !isComponent) return;
|
|
1837
|
-
const [currMethod, isStatic = false] = methodStack.at(-1) ?? [];
|
|
1838
|
-
if (currMethod == null || isStatic) return;
|
|
1839
|
-
const [setState, hasThisState = false] = setStateStack.at(-1) ?? [];
|
|
1840
|
-
if (setState == null || hasThisState) return;
|
|
1841
|
-
if (!Check.isIdentifier(node.property, "state")) return;
|
|
1842
|
-
context.report({
|
|
1843
|
-
messageId: "default",
|
|
1844
|
-
node
|
|
1845
|
-
});
|
|
1846
|
-
},
|
|
1847
|
-
MethodDefinition(node) {
|
|
1848
|
-
methodStack.push([node, node.static]);
|
|
1849
|
-
},
|
|
1850
|
-
"MethodDefinition:exit"() {
|
|
1851
|
-
methodStack.pop();
|
|
1852
|
-
},
|
|
1853
|
-
PropertyDefinition(node) {
|
|
1854
|
-
methodStack.push([node, node.static]);
|
|
1855
|
-
},
|
|
1856
|
-
"PropertyDefinition:exit"() {
|
|
1857
|
-
methodStack.pop();
|
|
1858
|
-
},
|
|
1859
|
-
VariableDeclarator(node) {
|
|
1860
|
-
const [currClass, isComponent = false] = classStack.at(-1) ?? [];
|
|
1861
|
-
if (currClass == null || !isComponent) return;
|
|
1862
|
-
const [currMethod, isStatic = false] = methodStack.at(-1) ?? [];
|
|
1863
|
-
if (currMethod == null || isStatic) return;
|
|
1864
|
-
const [setState, hasThisState = false] = setStateStack.at(-1) ?? [];
|
|
1865
|
-
if (setState == null || hasThisState) return;
|
|
1866
|
-
if (node.init == null || node.init.type !== AST_NODE_TYPES.ThisExpression || node.id.type !== AST_NODE_TYPES.ObjectPattern) return;
|
|
1867
|
-
if (!node.id.properties.some((prop) => prop.type === AST_NODE_TYPES.Property && !prop.computed && Check.isIdentifier(prop.key, "state"))) return;
|
|
1868
|
-
context.report({
|
|
1869
|
-
messageId: "default",
|
|
1870
|
-
node
|
|
1871
|
-
});
|
|
1872
|
-
}
|
|
1873
|
-
};
|
|
1808
|
+
return { MemberExpression(node) {
|
|
1809
|
+
if (!core.isAPI("this.state")(context, node)) return;
|
|
1810
|
+
const fact = Traverse.findParent(Traverse.findParent(node, (n) => Check.is(AST_NODE_TYPES.CallExpression)(n) && core.isThisSetStateCall(n)), Check.isClass);
|
|
1811
|
+
if (fact == null || !core.isClassComponent(fact)) return;
|
|
1812
|
+
context.report({
|
|
1813
|
+
messageId: "default",
|
|
1814
|
+
node
|
|
1815
|
+
});
|
|
1816
|
+
} };
|
|
1874
1817
|
}
|
|
1875
1818
|
|
|
1876
1819
|
//#endregion
|
|
@@ -2374,9 +2317,6 @@ function create$34(context) {
|
|
|
2374
2317
|
//#endregion
|
|
2375
2318
|
//#region src/rules/no-direct-mutation-state/no-direct-mutation-state.ts
|
|
2376
2319
|
const RULE_NAME$33 = "no-direct-mutation-state";
|
|
2377
|
-
function isConstructorFunction(node) {
|
|
2378
|
-
return Check.isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && Check.isPropertyOrMethod(node.parent) && Check.isIdentifier(node.parent.key) && node.parent.key.name === "constructor";
|
|
2379
|
-
}
|
|
2380
2320
|
var no_direct_mutation_state_default = createRule({
|
|
2381
2321
|
meta: {
|
|
2382
2322
|
type: "problem",
|
|
@@ -2388,12 +2328,26 @@ var no_direct_mutation_state_default = createRule({
|
|
|
2388
2328
|
create: create$33,
|
|
2389
2329
|
defaultOptions: []
|
|
2390
2330
|
});
|
|
2331
|
+
function isConstructorFunction(node) {
|
|
2332
|
+
return Check.isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && Check.isPropertyOrMethod(node.parent) && Check.isIdentifier(node.parent.key) && node.parent.key.name === "constructor";
|
|
2333
|
+
}
|
|
2334
|
+
function isAssignmentToThisState(node) {
|
|
2335
|
+
const { left } = node;
|
|
2336
|
+
let current = Extract.unwrap(left);
|
|
2337
|
+
while (current.type === AST_NODE_TYPES.MemberExpression) {
|
|
2338
|
+
const object = Extract.unwrap(current.object);
|
|
2339
|
+
const property = current.property;
|
|
2340
|
+
if (object.type === AST_NODE_TYPES.ThisExpression && Check.isIdentifier(property, "state")) return true;
|
|
2341
|
+
current = object;
|
|
2342
|
+
}
|
|
2343
|
+
return false;
|
|
2344
|
+
}
|
|
2391
2345
|
function create$33(context) {
|
|
2392
2346
|
return { AssignmentExpression(node) {
|
|
2393
|
-
if (!
|
|
2394
|
-
const
|
|
2395
|
-
if (
|
|
2396
|
-
if (core.isClassComponent(
|
|
2347
|
+
if (!isAssignmentToThisState(node)) return;
|
|
2348
|
+
const fact = Traverse.findParent(node, Check.isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]));
|
|
2349
|
+
if (fact == null) return;
|
|
2350
|
+
if (core.isClassComponent(fact) && context.sourceCode.getScope(node).block !== Traverse.findParent(node, isConstructorFunction)) context.report({
|
|
2397
2351
|
messageId: "default",
|
|
2398
2352
|
node
|
|
2399
2353
|
});
|
|
@@ -3249,20 +3203,6 @@ const takeWhile = dual(2, (xs, pred) => {
|
|
|
3249
3203
|
return xs.slice(0, idx);
|
|
3250
3204
|
});
|
|
3251
3205
|
|
|
3252
|
-
//#endregion
|
|
3253
|
-
//#region src/rules/no-leaked-conditional-rendering/lib.ts
|
|
3254
|
-
/**
|
|
3255
|
-
* Creates a report function for the given rule context.
|
|
3256
|
-
* @param context The ESLint rule context.
|
|
3257
|
-
* @returns A function that can be used to report violations.
|
|
3258
|
-
*/
|
|
3259
|
-
function report(context) {
|
|
3260
|
-
return (descriptor) => {
|
|
3261
|
-
if (descriptor == null) return;
|
|
3262
|
-
context.report(descriptor);
|
|
3263
|
-
};
|
|
3264
|
-
}
|
|
3265
|
-
|
|
3266
3206
|
//#endregion
|
|
3267
3207
|
//#region src/rules/no-leaked-conditional-rendering/no-leaked-conditional-rendering.ts
|
|
3268
3208
|
const RULE_NAME$27 = "no-leaked-conditional-rendering";
|
|
@@ -4208,21 +4148,6 @@ var no_unstable_default_props_default = createRule({
|
|
|
4208
4148
|
create: create$12,
|
|
4209
4149
|
defaultOptions: defaultOptions$1
|
|
4210
4150
|
});
|
|
4211
|
-
function extractIdentifier(node) {
|
|
4212
|
-
if (node.type === AST_NODE_TYPES.NewExpression) {
|
|
4213
|
-
const callee = Extract.unwrap(node.callee);
|
|
4214
|
-
if (Check.isIdentifier(callee)) return callee.name;
|
|
4215
|
-
}
|
|
4216
|
-
if (node.type === AST_NODE_TYPES.CallExpression) {
|
|
4217
|
-
const callee = Extract.unwrap(node.callee);
|
|
4218
|
-
if (Check.isIdentifier(callee)) return callee.name;
|
|
4219
|
-
if (callee.type === AST_NODE_TYPES.MemberExpression) {
|
|
4220
|
-
const { object } = callee;
|
|
4221
|
-
if (Check.isIdentifier(object)) return object.name;
|
|
4222
|
-
}
|
|
4223
|
-
}
|
|
4224
|
-
return null;
|
|
4225
|
-
}
|
|
4226
4151
|
function create$12(context, [options]) {
|
|
4227
4152
|
const { compilationMode } = getSettingsFromContext(context);
|
|
4228
4153
|
if (compilationMode === "infer" || compilationMode === "all") return {};
|
|
@@ -4248,8 +4173,11 @@ function create$12(context, [options]) {
|
|
|
4248
4173
|
if (construction == null) continue;
|
|
4249
4174
|
if (core.isHookCall(construction.node)) continue;
|
|
4250
4175
|
if (safePatterns.length > 0) {
|
|
4251
|
-
const
|
|
4252
|
-
|
|
4176
|
+
const getName = (n) => Check.isIdentifier(n) ? n.name : null;
|
|
4177
|
+
const name = match(right).with({ type: AST_NODE_TYPES.NewExpression }, (n) => getName(n.callee)).with({ type: AST_NODE_TYPES.CallExpression }, (n) => {
|
|
4178
|
+
return match(Extract.unwrap(n.callee)).when(Check.isIdentifier, ({ name }) => name).when(Check.is(AST_NODE_TYPES.MemberExpression), ({ object }) => getName(object)).otherwise(() => null);
|
|
4179
|
+
}).otherwise(() => null);
|
|
4180
|
+
if (name != null && safePatterns.some((pattern) => pattern.test(name))) continue;
|
|
4253
4181
|
}
|
|
4254
4182
|
context.report({
|
|
4255
4183
|
data: { kind: getHumanReadableKind(right) },
|
|
@@ -4302,28 +4230,19 @@ var no_unused_class_component_members_default = createRule({
|
|
|
4302
4230
|
defaultOptions: []
|
|
4303
4231
|
});
|
|
4304
4232
|
function create$11(context) {
|
|
4305
|
-
const classStack = [];
|
|
4306
|
-
const methodStack = [];
|
|
4307
4233
|
const propertyDefs = /* @__PURE__ */ new WeakMap();
|
|
4308
4234
|
const propertyUsages = /* @__PURE__ */ new WeakMap();
|
|
4309
|
-
function
|
|
4310
|
-
classStack.push(node);
|
|
4235
|
+
function classExit(node) {
|
|
4311
4236
|
if (!core.isClassComponent(node)) return;
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
}
|
|
4315
|
-
function classExit() {
|
|
4316
|
-
const currentClass = classStack.pop();
|
|
4317
|
-
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
4318
|
-
const id = core.getClassId(currentClass);
|
|
4319
|
-
const defs = propertyDefs.get(currentClass);
|
|
4320
|
-
const usages = propertyUsages.get(currentClass);
|
|
4237
|
+
const id = core.getClassId(node);
|
|
4238
|
+
const defs = propertyDefs.get(node);
|
|
4321
4239
|
if (defs == null) return;
|
|
4240
|
+
const usages = propertyUsages.get(node);
|
|
4322
4241
|
for (const def of defs) {
|
|
4323
4242
|
const methodName = def.name;
|
|
4324
4243
|
if (usages?.has(methodName) ?? false) continue;
|
|
4325
4244
|
if (LIFECYCLE_METHODS.has(methodName)) {
|
|
4326
|
-
if (methodName === "shouldComponentUpdate" && core.isPureComponent(
|
|
4245
|
+
if (methodName === "shouldComponentUpdate" && core.isPureComponent(node)) {} else continue;
|
|
4327
4246
|
}
|
|
4328
4247
|
context.report({
|
|
4329
4248
|
data: {
|
|
@@ -4336,43 +4255,35 @@ function create$11(context) {
|
|
|
4336
4255
|
}
|
|
4337
4256
|
}
|
|
4338
4257
|
function methodEnter(node) {
|
|
4339
|
-
|
|
4340
|
-
const currentClass = classStack.at(-1);
|
|
4258
|
+
const currentClass = Traverse.findParent(node, Check.isClass);
|
|
4341
4259
|
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
4342
4260
|
if (node.static) return;
|
|
4343
|
-
if (!node.computed && node.key.type === AST_NODE_TYPES.Identifier) propertyDefs
|
|
4344
|
-
}
|
|
4345
|
-
function methodExit() {
|
|
4346
|
-
methodStack.pop();
|
|
4261
|
+
if (!node.computed && node.key.type === AST_NODE_TYPES.Identifier) getOrInsertComputed(propertyDefs, currentClass, () => /* @__PURE__ */ new Set()).add(node.key);
|
|
4347
4262
|
}
|
|
4348
4263
|
return {
|
|
4349
|
-
ClassDeclaration: classEnter,
|
|
4350
4264
|
"ClassDeclaration:exit": classExit,
|
|
4351
|
-
ClassExpression: classEnter,
|
|
4352
4265
|
"ClassExpression:exit": classExit,
|
|
4353
4266
|
MemberExpression(node) {
|
|
4354
|
-
const currentClass =
|
|
4355
|
-
const currentMethod =
|
|
4267
|
+
const currentClass = Traverse.findParent(node, Check.isClass);
|
|
4268
|
+
const currentMethod = Traverse.findParent(node, Check.isPropertyOrMethod);
|
|
4356
4269
|
if (currentClass == null || currentMethod == null) return;
|
|
4357
4270
|
if (!core.isClassComponent(currentClass) || currentMethod.static) return;
|
|
4358
4271
|
if (node.object.type !== AST_NODE_TYPES.ThisExpression || node.computed || node.property.type !== AST_NODE_TYPES.Identifier) return;
|
|
4359
4272
|
if (node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.left === node) {
|
|
4360
|
-
propertyDefs
|
|
4273
|
+
getOrInsertComputed(propertyDefs, currentClass, () => /* @__PURE__ */ new Set()).add(node.property);
|
|
4361
4274
|
return;
|
|
4362
4275
|
}
|
|
4363
|
-
propertyUsages
|
|
4276
|
+
getOrInsertComputed(propertyUsages, currentClass, () => /* @__PURE__ */ new Set()).add(node.property.name);
|
|
4364
4277
|
},
|
|
4365
4278
|
MethodDefinition: methodEnter,
|
|
4366
|
-
"MethodDefinition:exit": methodExit,
|
|
4367
4279
|
PropertyDefinition: methodEnter,
|
|
4368
|
-
"PropertyDefinition:exit": methodExit,
|
|
4369
4280
|
VariableDeclarator(node) {
|
|
4370
|
-
const currentClass =
|
|
4371
|
-
const currentMethod =
|
|
4281
|
+
const currentClass = Traverse.findParent(node, Check.isClass);
|
|
4282
|
+
const currentMethod = Traverse.findParent(node, Check.isPropertyOrMethod);
|
|
4372
4283
|
if (currentClass == null || currentMethod == null) return;
|
|
4373
4284
|
if (!core.isClassComponent(currentClass) || currentMethod.static) return;
|
|
4374
4285
|
if (node.init != null && node.init.type === AST_NODE_TYPES.ThisExpression && node.id.type === AST_NODE_TYPES.ObjectPattern) {
|
|
4375
|
-
for (const prop of node.id.properties) if (prop.type === AST_NODE_TYPES.Property && !prop.computed && prop.key.type === AST_NODE_TYPES.Identifier) propertyUsages
|
|
4286
|
+
for (const prop of node.id.properties) if (prop.type === AST_NODE_TYPES.Property && !prop.computed && prop.key.type === AST_NODE_TYPES.Identifier) getOrInsertComputed(propertyUsages, currentClass, () => /* @__PURE__ */ new Set()).add(prop.key.name);
|
|
4376
4287
|
}
|
|
4377
4288
|
}
|
|
4378
4289
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.21.1",
|
|
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",
|
|
@@ -36,17 +36,16 @@
|
|
|
36
36
|
"dist"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@eslint-react/ast": "5.
|
|
40
|
-
"@eslint-react/core": "5.
|
|
41
|
-
"@eslint-react/eslint": "5.
|
|
42
|
-
"@eslint-react/jsx": "5.
|
|
43
|
-
"@eslint-react/shared": "5.
|
|
44
|
-
"@eslint-react/var": "5.
|
|
45
|
-
"@typescript-eslint/scope-manager": "^8.70.
|
|
46
|
-
"@typescript-eslint/
|
|
47
|
-
"@typescript-eslint/
|
|
48
|
-
"@typescript-eslint/
|
|
49
|
-
"@typescript-eslint/utils": "^8.70.0",
|
|
39
|
+
"@eslint-react/ast": "5.21.1",
|
|
40
|
+
"@eslint-react/core": "5.21.1",
|
|
41
|
+
"@eslint-react/eslint": "5.21.1",
|
|
42
|
+
"@eslint-react/jsx": "5.21.1",
|
|
43
|
+
"@eslint-react/shared": "5.21.1",
|
|
44
|
+
"@eslint-react/var": "5.21.1",
|
|
45
|
+
"@typescript-eslint/scope-manager": "^8.70.1",
|
|
46
|
+
"@typescript-eslint/types": "^8.70.1",
|
|
47
|
+
"@typescript-eslint/typescript-estree": "^8.70.1",
|
|
48
|
+
"@typescript-eslint/utils": "^8.70.1",
|
|
50
49
|
"compare-versions": "^6.1.1",
|
|
51
50
|
"string-ts": "^2.3.1",
|
|
52
51
|
"ts-api-utils": "^2.5.0",
|
|
@@ -70,6 +69,11 @@
|
|
|
70
69
|
"eslint": "*",
|
|
71
70
|
"typescript": "*"
|
|
72
71
|
},
|
|
72
|
+
"peerDependenciesMeta": {
|
|
73
|
+
"eslint": {
|
|
74
|
+
"optional": true
|
|
75
|
+
}
|
|
76
|
+
},
|
|
73
77
|
"engines": {
|
|
74
78
|
"node": ">=22.0.0"
|
|
75
79
|
},
|