New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-react-web-api

Package Overview
Dependencies
Maintainers
0
Versions
424
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-react-web-api - npm Package Compare versions

Comparing version 1.11.0-beta.4 to 1.11.0-beta.7

3

dist/index.d.ts
import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
type MessageID$1 = "noLeakedTimeoutInEffect" | "noLeakedTimeoutInLifecycle" | "noLeakedTimeoutNoTimeoutId";
type MessageID = "noLeakedEventListenerInEffect" | "noLeakedEventListenerInLifecycle" | "noLeakedEventListenerOfInlineFunction";

@@ -11,2 +13,3 @@

readonly "no-leaked-event-listener": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
readonly "no-leaked-timeout": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
};

@@ -13,0 +16,0 @@ declare const DEFAULT_ESLINT_REACT_SETTINGS: {

@@ -20,3 +20,3 @@ 'use strict';

var name = "eslint-plugin-react-web-api";
var version = "1.11.0-beta.4";
var version = "1.11.0-beta.7";
var createRule = shared.createRuleForPlugin("web-api");

@@ -32,18 +32,10 @@

function getCallKind(node) {
return tsPattern.match(node.callee).with({
type: utils.AST_NODE_TYPES.MemberExpression,
property: {
type: utils.AST_NODE_TYPES.Identifier,
name: tsPattern.P.select(tsPattern.P.union("addEventListener", "removeEventListener"))
}
}, tools.F.identity).with({
type: utils.AST_NODE_TYPES.Identifier,
name: tsPattern.P.select(tsPattern.P.union("addEventListener", "removeEventListener"))
}, tools.F.identity).with({
type: utils.AST_NODE_TYPES.MemberExpression,
property: {
type: utils.AST_NODE_TYPES.Identifier,
name: "abort"
}
}, tools.F.constant("abort")).otherwise(tools.F.constant("other"));
switch (true) {
case (node.callee.type === utils.AST_NODE_TYPES.Identifier && tsPattern.isMatching(tsPattern.P.union("addEventListener", "removeEventListener"), node.callee.name)):
return node.callee.name;
case (node.callee.type === utils.AST_NODE_TYPES.MemberExpression && node.callee.property.type === utils.AST_NODE_TYPES.Identifier && tsPattern.isMatching(tsPattern.P.union("addEventListener", "removeEventListener"), node.callee.property.name)):
return node.callee.property.name;
default:
return "other";
}
}

@@ -93,3 +85,3 @@ function getFunctionKind(node) {

docs: {
description: "prevent calling `addEventListener` without a corresponding `removeEventListener` in the same component or hook."
description: "enforce that every 'addEventListener' in a component or custom hook has a corresponding 'removeEventListener'."
},

@@ -163,3 +155,3 @@ messages: {

const listeners = callKind === "addEventListener" ? aEntries : rEntries;
listeners.push({ ...opts, _: node, type, callee, listener, phase: fKind });
listeners.push({ ...opts, self: node, type, callee, listener, phase: fKind });
}

@@ -178,3 +170,3 @@ break;

messageId: "noLeakedEventListenerInEffect",
node: aEntry._,
node: aEntry.self,
data: {

@@ -189,3 +181,3 @@ effectMethodKind: "useEffect"

messageId: "noLeakedEventListenerInLifecycle",
node: aEntry._
node: aEntry.self
});

@@ -200,2 +192,144 @@ continue;

});
var RULE_NAME2 = "no-leaked-timeout";
var functionKindPairs2 = birecord__default.default({
mount: "unmount",
setup: "cleanup"
});
function getCallKind2(node) {
switch (true) {
case (node.callee.type === utils.AST_NODE_TYPES.Identifier && tsPattern.isMatching(tsPattern.P.union("setTimeout", "clearTimeout"), node.callee.name)):
return node.callee.name;
case (node.callee.type === utils.AST_NODE_TYPES.MemberExpression && node.callee.property.type === utils.AST_NODE_TYPES.Identifier && tsPattern.isMatching(tsPattern.P.union("setTimeout", "clearTimeout"), node.callee.property.name)):
return node.callee.property.name;
default:
return "other";
}
}
function getFunctionKind2(node) {
return tsPattern.match(node).when(core.isSetupFunction, () => "setup").when(core.isCleanupFunction, () => "cleanup").when(core.isComponentDidMountFunction, () => "mount").when(core.isComponentWillUnmountFunction, () => "unmount").otherwise(() => "other");
}
function getTimeoutID(node, prev) {
switch (true) {
case (node.type === utils.AST_NODE_TYPES.VariableDeclarator && node.init === prev):
return tools.O.some(node.id);
case (node.type === utils.AST_NODE_TYPES.AssignmentExpression && node.right === prev):
return tools.O.some(node.left);
case (node.type === utils.AST_NODE_TYPES.BlockStatement || node.type === utils.AST_NODE_TYPES.Program || node.parent === node):
return tools.O.none();
default:
return getTimeoutID(node.parent, node);
}
}
var no_leaked_timeout_default = createRule({
meta: {
type: "problem",
docs: {
description: "enforce that every 'setTimeout' in a component or custom hook has a corresponding 'clearTimeout'."
},
messages: {
noLeakedTimeoutInEffect: "'setTimeout' must be paired with 'clearTimeout' in {{kind}}",
noLeakedTimeoutInLifecycle: "'setTimeout' must be paired with 'clearTimeout' in {{kind}}",
noLeakedTimeoutNoTimeoutId: "'setTimeout' must have a timeout ID assigned to a variable"
},
schema: []
},
name: RULE_NAME2,
create(context) {
const fStack = [];
const sEntries = [];
const rEntries = [];
const isPairedEntry = tools.F.dual(2, (a, b) => {
const aTimeoutID = a.timeoutID;
const bTimeoutID = b.timeoutID;
const aTimeoutIDScope = context.sourceCode.getScope(aTimeoutID);
const bTimeoutIDScope = context.sourceCode.getScope(bTimeoutID);
switch (true) {
case (aTimeoutID.type === utils.AST_NODE_TYPES.Identifier && bTimeoutID.type === utils.AST_NODE_TYPES.Identifier): {
return _var.isNodeValueEqual(aTimeoutID, bTimeoutID, [aTimeoutIDScope, bTimeoutIDScope]);
}
case (aTimeoutID.type === utils.AST_NODE_TYPES.AssignmentExpression && bTimeoutID.type === utils.AST_NODE_TYPES.AssignmentExpression): {
return ast.isNodeEqual(aTimeoutID.left, bTimeoutID.left);
}
default:
return _var.isNodeValueEqual(aTimeoutID, bTimeoutID, [aTimeoutIDScope, bTimeoutIDScope]);
}
});
return {
[":function"](node) {
const fKind = getFunctionKind2(node);
fStack.push([node, fKind]);
},
[":function:exit"]() {
fStack.pop();
},
["CallExpression"](node) {
const callKind = getCallKind2(node);
switch (callKind) {
case "setTimeout": {
const [fNode, fKind] = fStack.at(-1) ?? [];
if (!fNode || !fKind) break;
if (!functionKindPairs2.has(fKind)) break;
const timeoutIdNode = tools.O.getOrNull(getTimeoutID(node));
if (!timeoutIdNode) {
context.report({
messageId: "noLeakedTimeoutNoTimeoutId",
node
});
break;
}
sEntries.push({
self: node,
callee: node.callee,
phase: fKind,
timeoutID: timeoutIdNode
});
break;
}
case "clearTimeout": {
const [fNode, fKind] = fStack.at(-1) ?? [];
if (!fNode || !fKind) break;
if (!functionKindPairs2.has(fKind)) break;
const [timeoutIdNode] = node.arguments;
if (!timeoutIdNode) break;
rEntries.push({
self: node,
callee: node.callee,
phase: fKind,
timeoutID: timeoutIdNode
});
break;
}
}
},
["Program:exit"]() {
for (const sEntry of sEntries) {
if (rEntries.some(isPairedEntry(sEntry))) continue;
switch (sEntry.phase) {
case "setup":
case "cleanup":
context.report({
messageId: "noLeakedTimeoutInEffect",
node: sEntry.self,
data: {
kind: "useEffect"
}
});
continue;
case "mount":
case "unmount":
context.report({
messageId: "noLeakedTimeoutInLifecycle",
node: sEntry.self,
data: {
kind: "componentDidMount"
}
});
continue;
}
}
}
};
},
defaultOptions: []
});

@@ -208,3 +342,4 @@ // src/index.ts

var rules = {
"no-leaked-event-listener": no_leaked_event_listener_default
"no-leaked-event-listener": no_leaked_event_listener_default,
"no-leaked-timeout": no_leaked_timeout_default
};

@@ -211,0 +346,0 @@ var DEFAULT_ESLINT_REACT_SETTINGS = {

23

package.json
{
"name": "eslint-plugin-react-web-api",
"version": "1.11.0-beta.4",
"version": "1.11.0-beta.7",
"description": "ESLint React's ESLint plugin for interacting with Web APIs",

@@ -45,15 +45,14 @@ "keywords": [

"dependencies": {
"@typescript-eslint/scope-manager": "^8.1.0",
"@typescript-eslint/types": "^8.1.0",
"@typescript-eslint/utils": "^8.1.0",
"@typescript-eslint/scope-manager": "^8.2.0",
"@typescript-eslint/types": "^8.2.0",
"@typescript-eslint/utils": "^8.2.0",
"birecord": "^0.1.1",
"remeda": "^2.11.0",
"ts-pattern": "^5.3.1",
"@eslint-react/core": "1.11.0-beta.4",
"@eslint-react/shared": "1.11.0-beta.4",
"@eslint-react/ast": "1.11.0-beta.4",
"@eslint-react/jsx": "1.11.0-beta.4",
"@eslint-react/tools": "1.11.0-beta.4",
"@eslint-react/types": "1.11.0-beta.4",
"@eslint-react/var": "1.11.0-beta.4"
"@eslint-react/ast": "1.11.0-beta.7",
"@eslint-react/core": "1.11.0-beta.7",
"@eslint-react/jsx": "1.11.0-beta.7",
"@eslint-react/shared": "1.11.0-beta.7",
"@eslint-react/types": "1.11.0-beta.7",
"@eslint-react/var": "1.11.0-beta.7",
"@eslint-react/tools": "1.11.0-beta.7"
},

@@ -60,0 +59,0 @@ "devDependencies": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc