eslint-plugin-react-web-api 5.2.1-next.1 → 5.2.2-beta.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/dist/index.js +45 -14
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DEFAULT_ESLINT_REACT_SETTINGS } from "@eslint-react/shared";
|
|
2
|
-
import
|
|
2
|
+
import { Check, Compare, Traverse, isOneOf } from "@eslint-react/ast";
|
|
3
3
|
import * as core from "@eslint-react/core";
|
|
4
4
|
import { merge } from "@eslint-react/eslint";
|
|
5
|
-
import {
|
|
5
|
+
import { isAssignmentTargetEqual, isValueEqual, resolve, resolveEnclosingAssignmentTarget } from "@eslint-react/var";
|
|
6
6
|
import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
7
7
|
import { getStaticValue } from "@typescript-eslint/utils/ast-utils";
|
|
8
8
|
import { P, isMatching, match } from "ts-pattern";
|
|
@@ -27,7 +27,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
27
27
|
//#endregion
|
|
28
28
|
//#region package.json
|
|
29
29
|
var name$1 = "eslint-plugin-react-web-api";
|
|
30
|
-
var version = "5.2.
|
|
30
|
+
var version = "5.2.2-beta.0";
|
|
31
31
|
|
|
32
32
|
//#endregion
|
|
33
33
|
//#region src/types/component-phase.ts
|
|
@@ -65,7 +65,7 @@ function getSignalValueExpression(context, node) {
|
|
|
65
65
|
switch (node.type) {
|
|
66
66
|
case AST_NODE_TYPES.Identifier: {
|
|
67
67
|
const resolved = resolve(context, node);
|
|
68
|
-
if (resolved != null &&
|
|
68
|
+
if (resolved != null && Check.isFunction(resolved)) return node;
|
|
69
69
|
return getSignalValueExpression(context, resolved);
|
|
70
70
|
}
|
|
71
71
|
case AST_NODE_TYPES.MemberExpression: return node;
|
|
@@ -86,14 +86,14 @@ function getOptions(context, node) {
|
|
|
86
86
|
capture: Boolean(node.value)
|
|
87
87
|
};
|
|
88
88
|
case AST_NODE_TYPES.ObjectExpression: {
|
|
89
|
-
const vCapture = match(
|
|
89
|
+
const vCapture = match(Traverse.findProperty(node.properties, "capture")).with(P.nullish, () => false).with({ type: AST_NODE_TYPES.Property }, (prop) => {
|
|
90
90
|
const value = prop.value;
|
|
91
91
|
switch (value.type) {
|
|
92
92
|
case AST_NODE_TYPES.Literal: return Boolean(value.value);
|
|
93
93
|
default: return Boolean(getStaticValue(value, initialScope)?.value);
|
|
94
94
|
}
|
|
95
95
|
}).otherwise(() => false);
|
|
96
|
-
const pSignal =
|
|
96
|
+
const pSignal = Traverse.findProperty(node.properties, "signal");
|
|
97
97
|
return {
|
|
98
98
|
capture: vCapture,
|
|
99
99
|
signal: pSignal?.type === AST_NODE_TYPES.Property ? getSignalValueExpression(context, pSignal.value) : null
|
|
@@ -127,7 +127,7 @@ function create$3(context) {
|
|
|
127
127
|
const abortedSignals = [];
|
|
128
128
|
function isSameObject(a, b) {
|
|
129
129
|
switch (true) {
|
|
130
|
-
case a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression: return
|
|
130
|
+
case a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression: return Compare.areEqual(a.object, b.object);
|
|
131
131
|
default: return false;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -135,11 +135,11 @@ function create$3(context) {
|
|
|
135
135
|
const { type: aType, callee: aCallee, capture: aCapture, listener: aListener, phase: aPhase } = aEntry;
|
|
136
136
|
const { type: rType, callee: rCallee, capture: rCapture, listener: rListener, phase: rPhase } = rEntry;
|
|
137
137
|
if (ComponentPhaseRelevance.get(aPhase) !== rPhase) return false;
|
|
138
|
-
return isSameObject(aCallee, rCallee) &&
|
|
138
|
+
return isSameObject(aCallee, rCallee) && Compare.areEqual(aListener, rListener) && isValueEqual(context, aType, rType) && aCapture === rCapture;
|
|
139
139
|
}
|
|
140
140
|
function checkInlineFunction(node, callKind, options) {
|
|
141
141
|
const listener = node.arguments.at(1);
|
|
142
|
-
if (!
|
|
142
|
+
if (!Check.isFunction(listener)) return;
|
|
143
143
|
if (options.signal != null) return;
|
|
144
144
|
context.report({
|
|
145
145
|
data: { eventMethodKind: callKind },
|
|
@@ -265,7 +265,7 @@ function create$2(context) {
|
|
|
265
265
|
const fEntry = fEntries.findLast((x) => x.kind !== "other");
|
|
266
266
|
if (fEntry == null) break;
|
|
267
267
|
if (!ComponentPhaseRelevance.has(fEntry.kind)) break;
|
|
268
|
-
const intervalIdNode =
|
|
268
|
+
const intervalIdNode = resolveEnclosingAssignmentTarget(node);
|
|
269
269
|
if (intervalIdNode == null) {
|
|
270
270
|
context.report({
|
|
271
271
|
messageId: "expectedIntervalId",
|
|
@@ -438,6 +438,37 @@ const dual = function(arity, body) {
|
|
|
438
438
|
*/
|
|
439
439
|
const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
|
|
440
440
|
|
|
441
|
+
//#endregion
|
|
442
|
+
//#region src/rules/no-leaked-resize-observer/lib.ts
|
|
443
|
+
/**
|
|
444
|
+
* Check if a node is a loop statement
|
|
445
|
+
* @param node The node to check
|
|
446
|
+
* @returns True if the node is a loop
|
|
447
|
+
*/
|
|
448
|
+
const isLoop = isOneOf([
|
|
449
|
+
AST_NODE_TYPES.DoWhileStatement,
|
|
450
|
+
AST_NODE_TYPES.ForInStatement,
|
|
451
|
+
AST_NODE_TYPES.ForOfStatement,
|
|
452
|
+
AST_NODE_TYPES.ForStatement,
|
|
453
|
+
AST_NODE_TYPES.WhileStatement
|
|
454
|
+
]);
|
|
455
|
+
/**
|
|
456
|
+
* Check if a node is a conditional expression or control flow statement
|
|
457
|
+
* @param node The node to check
|
|
458
|
+
* @returns True if the node is conditional
|
|
459
|
+
*/
|
|
460
|
+
const isConditional = isOneOf([
|
|
461
|
+
AST_NODE_TYPES.DoWhileStatement,
|
|
462
|
+
AST_NODE_TYPES.ForInStatement,
|
|
463
|
+
AST_NODE_TYPES.ForOfStatement,
|
|
464
|
+
AST_NODE_TYPES.ForStatement,
|
|
465
|
+
AST_NODE_TYPES.WhileStatement,
|
|
466
|
+
AST_NODE_TYPES.IfStatement,
|
|
467
|
+
AST_NODE_TYPES.SwitchStatement,
|
|
468
|
+
AST_NODE_TYPES.LogicalExpression,
|
|
469
|
+
AST_NODE_TYPES.ConditionalExpression
|
|
470
|
+
]);
|
|
471
|
+
|
|
441
472
|
//#endregion
|
|
442
473
|
//#region src/rules/no-leaked-resize-observer/no-leaked-resize-observer.ts
|
|
443
474
|
const RULE_NAME$1 = "no-leaked-resize-observer";
|
|
@@ -539,7 +570,7 @@ function create$1(context) {
|
|
|
539
570
|
if (fEntry == null) return;
|
|
540
571
|
if (!ComponentPhaseRelevance.has(fEntry.kind)) return;
|
|
541
572
|
if (!isNewResizeObserver(node)) return;
|
|
542
|
-
const id =
|
|
573
|
+
const id = resolveEnclosingAssignmentTarget(node);
|
|
543
574
|
if (id == null) {
|
|
544
575
|
context.report({
|
|
545
576
|
messageId: "unexpectedFloatingInstance",
|
|
@@ -559,9 +590,9 @@ function create$1(context) {
|
|
|
559
590
|
if (dEntries.some((e) => isAssignmentTargetEqual(context, e.observer, id))) continue;
|
|
560
591
|
const oentries = oEntries.filter((e) => isAssignmentTargetEqual(context, e.observer, id));
|
|
561
592
|
const uentries = uEntries.filter((e) => isAssignmentTargetEqual(context, e.observer, id));
|
|
562
|
-
const isDynamic = (node) => node?.type === AST_NODE_TYPES.CallExpression ||
|
|
593
|
+
const isDynamic = (node) => node?.type === AST_NODE_TYPES.CallExpression || isConditional(node);
|
|
563
594
|
const isPhaseNode = (node) => node === phaseNode;
|
|
564
|
-
if (oentries.some((e) => !isPhaseNode(
|
|
595
|
+
if (oentries.some((e) => !isPhaseNode(Traverse.findParent(e.node, or(isDynamic, isPhaseNode))))) {
|
|
565
596
|
context.report({
|
|
566
597
|
messageId: "expectedDisconnectInControlFlow",
|
|
567
598
|
node
|
|
@@ -628,7 +659,7 @@ function create(context) {
|
|
|
628
659
|
if (!ComponentPhaseRelevance.has(fEntry?.kind)) return;
|
|
629
660
|
switch (getCallKind(node)) {
|
|
630
661
|
case "setTimeout": {
|
|
631
|
-
const timeoutIdNode =
|
|
662
|
+
const timeoutIdNode = resolveEnclosingAssignmentTarget(node);
|
|
632
663
|
if (timeoutIdNode == null) {
|
|
633
664
|
context.report({
|
|
634
665
|
messageId: "expectedTimeoutId",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-web-api",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.2-beta.0",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for interacting with Web APIs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -43,19 +43,19 @@
|
|
|
43
43
|
"@typescript-eslint/utils": "^8.58.1",
|
|
44
44
|
"birecord": "^0.1.1",
|
|
45
45
|
"ts-pattern": "^5.9.0",
|
|
46
|
-
"@eslint-react/
|
|
47
|
-
"@eslint-react/
|
|
48
|
-
"@eslint-react/
|
|
49
|
-
"@eslint-react/var": "5.2.
|
|
50
|
-
"@eslint-react/
|
|
46
|
+
"@eslint-react/core": "5.2.2-beta.0",
|
|
47
|
+
"@eslint-react/ast": "5.2.2-beta.0",
|
|
48
|
+
"@eslint-react/shared": "5.2.2-beta.0",
|
|
49
|
+
"@eslint-react/var": "5.2.2-beta.0",
|
|
50
|
+
"@eslint-react/eslint": "5.2.2-beta.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/react": "^19.2.14",
|
|
54
54
|
"@types/react-dom": "^19.2.3",
|
|
55
55
|
"eslint": "^10.2.0",
|
|
56
56
|
"tsdown": "^0.21.7",
|
|
57
|
-
"@local/
|
|
58
|
-
"@local/
|
|
57
|
+
"@local/eff": "3.0.0-beta.72",
|
|
58
|
+
"@local/configs": "0.0.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"eslint": "^10.2.0",
|