eslint-plugin-react-web-api 2.0.0-beta.4 → 2.0.0-beta.41
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 +43 -29
- package/package.json +14 -15
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { getDocsUrl, DEFAULT_ESLINT_REACT_SETTINGS } from '@eslint-react/shared';
|
|
2
2
|
import * as AST from '@eslint-react/ast';
|
|
3
3
|
import * as ER4 from '@eslint-react/core';
|
|
4
|
-
import {
|
|
4
|
+
import { or, unit } from '@eslint-react/eff';
|
|
5
5
|
import * as VAR from '@eslint-react/var';
|
|
6
|
-
import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
6
|
+
import { ESLintUtils, AST_NODE_TYPES as AST_NODE_TYPES$1 } from '@typescript-eslint/utils';
|
|
7
7
|
import { match, isMatching, P } from 'ts-pattern';
|
|
8
|
-
import { AST_NODE_TYPES
|
|
8
|
+
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
9
9
|
|
|
10
10
|
var __defProp = Object.defineProperty;
|
|
11
11
|
var __export = (target, all) => {
|
|
@@ -33,18 +33,18 @@ var settings = {
|
|
|
33
33
|
|
|
34
34
|
// package.json
|
|
35
35
|
var name2 = "eslint-plugin-react-web-api";
|
|
36
|
-
var version = "2.0.0-beta.
|
|
36
|
+
var version = "2.0.0-beta.41";
|
|
37
37
|
var createRule = ESLintUtils.RuleCreator(getDocsUrl("web-api"));
|
|
38
38
|
function getPhaseKindOfFunction(node) {
|
|
39
39
|
return match(node).when(isFunctionOfUseEffectSetup, () => "setup").when(isFunctionOfUseEffectCleanup, () => "cleanup").when(isFunctionOfComponentDidMount, () => "mount").when(isFunctionOfComponentWillUnmount, () => "unmount").otherwise(() => null);
|
|
40
40
|
}
|
|
41
41
|
function isFunctionOfUseEffectSetup(node) {
|
|
42
42
|
if (node == null) return false;
|
|
43
|
-
return node.parent?.type === AST_NODE_TYPES
|
|
43
|
+
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && node.parent.callee.type === AST_NODE_TYPES.Identifier && node.parent.arguments.at(0) === node && ER4.isUseEffectCallLoose(node.parent);
|
|
44
44
|
}
|
|
45
45
|
function isFunctionOfUseEffectCleanup(node) {
|
|
46
46
|
if (node == null) return false;
|
|
47
|
-
const pReturn = AST.findParentNode(node, AST.is(AST_NODE_TYPES
|
|
47
|
+
const pReturn = AST.findParentNode(node, AST.is(AST_NODE_TYPES.ReturnStatement));
|
|
48
48
|
const pFunction = AST.findParentNode(node, AST.isFunction);
|
|
49
49
|
const pFunctionOfReturn = AST.findParentNode(pReturn, AST.isFunction);
|
|
50
50
|
if (pFunction !== pFunctionOfReturn) return false;
|
|
@@ -56,6 +56,20 @@ function isFunctionOfComponentDidMount(node) {
|
|
|
56
56
|
function isFunctionOfComponentWillUnmount(node) {
|
|
57
57
|
return AST.isFunction(node) && ER4.isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
58
58
|
}
|
|
59
|
+
var isControlFlow = or(
|
|
60
|
+
AST.isLoop,
|
|
61
|
+
AST.isOneOf([
|
|
62
|
+
AST_NODE_TYPES.IfStatement,
|
|
63
|
+
AST_NODE_TYPES.SwitchStatement
|
|
64
|
+
])
|
|
65
|
+
);
|
|
66
|
+
var isConditional = or(
|
|
67
|
+
isControlFlow,
|
|
68
|
+
AST.isOneOf([
|
|
69
|
+
AST_NODE_TYPES.LogicalExpression,
|
|
70
|
+
AST_NODE_TYPES.ConditionalExpression
|
|
71
|
+
])
|
|
72
|
+
);
|
|
59
73
|
|
|
60
74
|
// src/rules/no-leaked-event-listener.ts
|
|
61
75
|
var RULE_NAME = "no-leaked-event-listener";
|
|
@@ -67,9 +81,9 @@ var defaultOptions = {
|
|
|
67
81
|
};
|
|
68
82
|
function getCallKind(node) {
|
|
69
83
|
switch (true) {
|
|
70
|
-
case (node.callee.type === AST_NODE_TYPES.Identifier && isMatching(P.union("addEventListener", "removeEventListener", "abort"))(node.callee.name)):
|
|
84
|
+
case (node.callee.type === AST_NODE_TYPES$1.Identifier && isMatching(P.union("addEventListener", "removeEventListener", "abort"))(node.callee.name)):
|
|
71
85
|
return node.callee.name;
|
|
72
|
-
case (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && isMatching(P.union("addEventListener", "removeEventListener", "abort"))(node.callee.property.name)):
|
|
86
|
+
case (node.callee.type === AST_NODE_TYPES$1.MemberExpression && node.callee.property.type === AST_NODE_TYPES$1.Identifier && isMatching(P.union("addEventListener", "removeEventListener", "abort"))(node.callee.property.name)):
|
|
73
87
|
return node.callee.property.name;
|
|
74
88
|
default:
|
|
75
89
|
return "other";
|
|
@@ -81,10 +95,10 @@ function getFunctionKind(node) {
|
|
|
81
95
|
function getSignalValueExpression(node, initialScope) {
|
|
82
96
|
if (node == null) return unit;
|
|
83
97
|
switch (node.type) {
|
|
84
|
-
case AST_NODE_TYPES.Identifier: {
|
|
98
|
+
case AST_NODE_TYPES$1.Identifier: {
|
|
85
99
|
return getSignalValueExpression(VAR.getVariableInitNode(VAR.findVariable(node, initialScope), 0), initialScope);
|
|
86
100
|
}
|
|
87
|
-
case AST_NODE_TYPES.MemberExpression:
|
|
101
|
+
case AST_NODE_TYPES$1.MemberExpression:
|
|
88
102
|
return node;
|
|
89
103
|
default:
|
|
90
104
|
return unit;
|
|
@@ -95,11 +109,11 @@ function getOptions(node, initialScope) {
|
|
|
95
109
|
return VAR.findPropertyInProperties(propName, properties, initialScope);
|
|
96
110
|
}
|
|
97
111
|
function getPropValue(prop, filter = (a) => true) {
|
|
98
|
-
if (prop?.type !== AST_NODE_TYPES.Property) return unit;
|
|
112
|
+
if (prop?.type !== AST_NODE_TYPES$1.Property) return unit;
|
|
99
113
|
const { value } = prop;
|
|
100
114
|
let v = value;
|
|
101
115
|
switch (value.type) {
|
|
102
|
-
case AST_NODE_TYPES.Literal: {
|
|
116
|
+
case AST_NODE_TYPES$1.Literal: {
|
|
103
117
|
v = value.value;
|
|
104
118
|
break;
|
|
105
119
|
}
|
|
@@ -112,22 +126,22 @@ function getOptions(node, initialScope) {
|
|
|
112
126
|
}
|
|
113
127
|
function getOpts(node2) {
|
|
114
128
|
switch (node2.type) {
|
|
115
|
-
case AST_NODE_TYPES.Identifier: {
|
|
129
|
+
case AST_NODE_TYPES$1.Identifier: {
|
|
116
130
|
const variable = VAR.findVariable(node2, initialScope);
|
|
117
131
|
const variableNode = VAR.getVariableInitNode(variable, 0);
|
|
118
|
-
if (variableNode?.type === AST_NODE_TYPES.ObjectExpression) {
|
|
132
|
+
if (variableNode?.type === AST_NODE_TYPES$1.ObjectExpression) {
|
|
119
133
|
return getOpts(variableNode);
|
|
120
134
|
}
|
|
121
135
|
return defaultOptions;
|
|
122
136
|
}
|
|
123
|
-
case AST_NODE_TYPES.Literal: {
|
|
137
|
+
case AST_NODE_TYPES$1.Literal: {
|
|
124
138
|
return { ...defaultOptions, capture: Boolean(node2.value) };
|
|
125
139
|
}
|
|
126
|
-
case AST_NODE_TYPES.ObjectExpression: {
|
|
140
|
+
case AST_NODE_TYPES$1.ObjectExpression: {
|
|
127
141
|
const pCapture = findProp(node2.properties, "capture");
|
|
128
142
|
const vCapture = !!getPropValue(pCapture);
|
|
129
143
|
const pSignal = findProp(node2.properties, "signal");
|
|
130
|
-
const vSignal = pSignal?.type === AST_NODE_TYPES.Property ? getSignalValueExpression(pSignal.value, initialScope) : unit;
|
|
144
|
+
const vSignal = pSignal?.type === AST_NODE_TYPES$1.Property ? getSignalValueExpression(pSignal.value, initialScope) : unit;
|
|
131
145
|
return { capture: vCapture, signal: vSignal };
|
|
132
146
|
}
|
|
133
147
|
default: {
|
|
@@ -168,7 +182,7 @@ function create(context) {
|
|
|
168
182
|
const abortedSignals = [];
|
|
169
183
|
function isSameObject(a, b) {
|
|
170
184
|
switch (true) {
|
|
171
|
-
case (a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression):
|
|
185
|
+
case (a.type === AST_NODE_TYPES$1.MemberExpression && b.type === AST_NODE_TYPES$1.MemberExpression):
|
|
172
186
|
return AST.isNodeEqual(a.object, b.object);
|
|
173
187
|
// TODO: Maybe there other cases to consider here.
|
|
174
188
|
default:
|
|
@@ -290,9 +304,9 @@ var RULE_NAME2 = "no-leaked-interval";
|
|
|
290
304
|
var RULE_FEATURES2 = [];
|
|
291
305
|
function getCallKind2(node) {
|
|
292
306
|
switch (true) {
|
|
293
|
-
case (node.callee.type === AST_NODE_TYPES.Identifier && isMatching(P.union("setInterval", "clearInterval"))(node.callee.name)):
|
|
307
|
+
case (node.callee.type === AST_NODE_TYPES$1.Identifier && isMatching(P.union("setInterval", "clearInterval"))(node.callee.name)):
|
|
294
308
|
return node.callee.name;
|
|
295
|
-
case (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && isMatching(P.union("setInterval", "clearInterval"))(node.callee.property.name)):
|
|
309
|
+
case (node.callee.type === AST_NODE_TYPES$1.MemberExpression && node.callee.property.type === AST_NODE_TYPES$1.Identifier && isMatching(P.union("setInterval", "clearInterval"))(node.callee.property.name)):
|
|
296
310
|
return node.callee.property.name;
|
|
297
311
|
default:
|
|
298
312
|
return "other";
|
|
@@ -418,16 +432,16 @@ function create2(context) {
|
|
|
418
432
|
var RULE_NAME3 = "no-leaked-resize-observer";
|
|
419
433
|
var RULE_FEATURES3 = [];
|
|
420
434
|
function isNewResizeObserver(node) {
|
|
421
|
-
return node?.type === AST_NODE_TYPES.NewExpression && node.callee.type === AST_NODE_TYPES.Identifier && node.callee.name === "ResizeObserver";
|
|
435
|
+
return node?.type === AST_NODE_TYPES$1.NewExpression && node.callee.type === AST_NODE_TYPES$1.Identifier && node.callee.name === "ResizeObserver";
|
|
422
436
|
}
|
|
423
437
|
function isFromObserver(context, node) {
|
|
424
438
|
switch (true) {
|
|
425
|
-
case node.type === AST_NODE_TYPES.Identifier: {
|
|
439
|
+
case node.type === AST_NODE_TYPES$1.Identifier: {
|
|
426
440
|
const initialScope = context.sourceCode.getScope(node);
|
|
427
441
|
const object = VAR.getVariableInitNode(VAR.findVariable(node, initialScope), 0);
|
|
428
442
|
return isNewResizeObserver(object);
|
|
429
443
|
}
|
|
430
|
-
case node.type === AST_NODE_TYPES.MemberExpression:
|
|
444
|
+
case node.type === AST_NODE_TYPES$1.MemberExpression:
|
|
431
445
|
return isFromObserver(context, node.object);
|
|
432
446
|
default:
|
|
433
447
|
return false;
|
|
@@ -435,9 +449,9 @@ function isFromObserver(context, node) {
|
|
|
435
449
|
}
|
|
436
450
|
function getCallKind3(context, node) {
|
|
437
451
|
switch (true) {
|
|
438
|
-
case (node.callee.type === AST_NODE_TYPES.Identifier && isMatching(P.union("observe", "unobserve", "disconnect"))(node.callee.name) && isFromObserver(context, node.callee)):
|
|
452
|
+
case (node.callee.type === AST_NODE_TYPES$1.Identifier && isMatching(P.union("observe", "unobserve", "disconnect"))(node.callee.name) && isFromObserver(context, node.callee)):
|
|
439
453
|
return node.callee.name;
|
|
440
|
-
case (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && isMatching(P.union("observe", "unobserve", "disconnect"))(node.callee.property.name) && isFromObserver(context, node.callee)):
|
|
454
|
+
case (node.callee.type === AST_NODE_TYPES$1.MemberExpression && node.callee.property.type === AST_NODE_TYPES$1.Identifier && isMatching(P.union("observe", "unobserve", "disconnect"))(node.callee.property.name) && isFromObserver(context, node.callee)):
|
|
441
455
|
return node.callee.property.name;
|
|
442
456
|
default:
|
|
443
457
|
return "other";
|
|
@@ -482,7 +496,7 @@ function create3(context) {
|
|
|
482
496
|
fEntries.pop();
|
|
483
497
|
},
|
|
484
498
|
["CallExpression"](node) {
|
|
485
|
-
if (node.callee.type !== AST_NODE_TYPES.MemberExpression) {
|
|
499
|
+
if (node.callee.type !== AST_NODE_TYPES$1.MemberExpression) {
|
|
486
500
|
return;
|
|
487
501
|
}
|
|
488
502
|
const fKind = fEntries.findLast((x) => x.kind !== "other")?.kind;
|
|
@@ -560,7 +574,7 @@ function create3(context) {
|
|
|
560
574
|
}
|
|
561
575
|
const oentries = oEntries.filter((e) => ER4.isInstanceIdEqual(context, e.observer, id));
|
|
562
576
|
const uentries = uEntries.filter((e) => ER4.isInstanceIdEqual(context, e.observer, id));
|
|
563
|
-
const isDynamic = (node2) => node2?.type === AST_NODE_TYPES.CallExpression ||
|
|
577
|
+
const isDynamic = (node2) => node2?.type === AST_NODE_TYPES$1.CallExpression || isConditional(node2);
|
|
564
578
|
const isPhaseNode = (node2) => node2 === phaseNode;
|
|
565
579
|
const hasDynamicallyAdded = oentries.some((e) => !isPhaseNode(AST.findParentNode(e.node, or(isDynamic, isPhaseNode))));
|
|
566
580
|
if (hasDynamicallyAdded) {
|
|
@@ -581,9 +595,9 @@ var RULE_NAME4 = "no-leaked-timeout";
|
|
|
581
595
|
var RULE_FEATURES4 = [];
|
|
582
596
|
function getCallKind4(node) {
|
|
583
597
|
switch (true) {
|
|
584
|
-
case (node.callee.type === AST_NODE_TYPES.Identifier && isMatching(P.union("setTimeout", "clearTimeout"))(node.callee.name)):
|
|
598
|
+
case (node.callee.type === AST_NODE_TYPES$1.Identifier && isMatching(P.union("setTimeout", "clearTimeout"))(node.callee.name)):
|
|
585
599
|
return node.callee.name;
|
|
586
|
-
case (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && isMatching(P.union("setTimeout", "clearTimeout"))(node.callee.property.name)):
|
|
600
|
+
case (node.callee.type === AST_NODE_TYPES$1.MemberExpression && node.callee.property.type === AST_NODE_TYPES$1.Identifier && isMatching(P.union("setTimeout", "clearTimeout"))(node.callee.property.name)):
|
|
587
601
|
return node.callee.property.name;
|
|
588
602
|
default:
|
|
589
603
|
return "other";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-web-api",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.41",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for interacting with Web APIs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -35,26 +35,26 @@
|
|
|
35
35
|
"./package.json"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@typescript-eslint/scope-manager": "^8.
|
|
39
|
-
"@typescript-eslint/types": "^8.
|
|
40
|
-
"@typescript-eslint/utils": "^8.
|
|
38
|
+
"@typescript-eslint/scope-manager": "^8.40.0",
|
|
39
|
+
"@typescript-eslint/types": "^8.40.0",
|
|
40
|
+
"@typescript-eslint/utils": "^8.40.0",
|
|
41
41
|
"string-ts": "^2.2.1",
|
|
42
|
-
"ts-pattern": "^5.
|
|
43
|
-
"@eslint-react/ast": "2.0.0-beta.
|
|
44
|
-
"@eslint-react/core": "2.0.0-beta.
|
|
45
|
-
"@eslint-react/kit": "2.0.0-beta.
|
|
46
|
-
"@eslint-react/eff": "2.0.0-beta.
|
|
47
|
-
"@eslint-react/shared": "2.0.0-beta.
|
|
48
|
-
"@eslint-react/var": "2.0.0-beta.
|
|
42
|
+
"ts-pattern": "^5.8.0",
|
|
43
|
+
"@eslint-react/ast": "2.0.0-beta.41",
|
|
44
|
+
"@eslint-react/core": "2.0.0-beta.41",
|
|
45
|
+
"@eslint-react/kit": "2.0.0-beta.41",
|
|
46
|
+
"@eslint-react/eff": "2.0.0-beta.41",
|
|
47
|
+
"@eslint-react/shared": "2.0.0-beta.41",
|
|
48
|
+
"@eslint-react/var": "2.0.0-beta.41"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@types/react": "^19.1.
|
|
52
|
-
"@types/react-dom": "^19.1.
|
|
51
|
+
"@types/react": "^19.1.11",
|
|
52
|
+
"@types/react-dom": "^19.1.7",
|
|
53
53
|
"tsup": "^8.5.0",
|
|
54
54
|
"@local/configs": "0.0.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"eslint": "^9.
|
|
57
|
+
"eslint": "^9.33.0",
|
|
58
58
|
"typescript": "^4.9.5 || ^5.4.5"
|
|
59
59
|
},
|
|
60
60
|
"peerDependenciesMeta": {
|
|
@@ -66,7 +66,6 @@
|
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"engines": {
|
|
69
|
-
"bun": ">=1.0.15",
|
|
70
69
|
"node": ">=20.19.0"
|
|
71
70
|
},
|
|
72
71
|
"publishConfig": {
|