eslint-plugin-react-web-api
Advanced tools
Comparing version 1.12.2 to 1.12.3-next.0
@@ -16,3 +16,3 @@ 'use strict'; | ||
var name = "eslint-plugin-react-web-api"; | ||
var version = "1.12.2"; | ||
var version = "1.12.3-next.0"; | ||
var createRule = shared.createRuleForPlugin("web-api"); | ||
@@ -32,11 +32,3 @@ function getTimerID(node, prev) { | ||
function isTimerIDEqual(a, b, context) { | ||
const aScope = context.sourceCode.getScope(a); | ||
const bScope = context.sourceCode.getScope(b); | ||
switch (true) { | ||
case (a.type === types.AST_NODE_TYPES.AssignmentExpression && b.type === types.AST_NODE_TYPES.AssignmentExpression): { | ||
return ast.isNodeEqual(a.left, b.left); | ||
} | ||
default: | ||
return _var.isNodeValueEqual(a, b, [aScope, bScope]); | ||
} | ||
return ast.isNodeEqual(a, b) || _var.isNodeValueEqual(a, b, [context.sourceCode.getScope(a), context.sourceCode.getScope(b)]); | ||
} | ||
@@ -47,8 +39,12 @@ var EventListenerEntry = tools.Data.taggedEnum(); | ||
var RULE_NAME = "no-leaked-event-listener"; | ||
var defaultOptions = tools.Data.struct({ capture: tools.O.some(false), once: tools.O.none(), signal: tools.O.none() }); | ||
var defaultOptions = tools.Data.struct({ | ||
capture: tools.O.some(false), | ||
once: tools.O.some(false), | ||
signal: tools.O.none() | ||
}); | ||
function getCallKind(node) { | ||
switch (true) { | ||
case (node.callee.type === utils.AST_NODE_TYPES.Identifier && tsPattern.isMatching(tsPattern.P.union("addEventListener", "removeEventListener"), node.callee.name)): | ||
case (node.callee.type === utils.AST_NODE_TYPES.Identifier && tsPattern.isMatching(tsPattern.P.union("addEventListener", "removeEventListener", "abort"), 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)): | ||
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", "abort"), node.callee.property.name)): | ||
return node.callee.property.name; | ||
@@ -69,30 +65,40 @@ default: | ||
const { value } = prop; | ||
return tsPattern.match(value).with({ type: utils.AST_NODE_TYPES.Literal }, (v) => tools.O.some(v.value)).otherwise(() => tools.O.fromNullable(astUtils.getStaticValue(value, initialScope)?.value)); | ||
switch (value.type) { | ||
case utils.AST_NODE_TYPES.Literal: { | ||
return tools.O.some(value.value); | ||
} | ||
default: { | ||
return tools.O.fromNullable(astUtils.getStaticValue(value, initialScope)?.value); | ||
} | ||
} | ||
}; | ||
switch (node.type) { | ||
case utils.AST_NODE_TYPES.Literal: { | ||
return tools.Data.struct({ ...defaultOptions, capture: tools.O.some(!!node.value) }); | ||
} | ||
case utils.AST_NODE_TYPES.ObjectExpression: { | ||
const pCapture = findProp(node.properties, "capture"); | ||
const vCapture = tools.O.flatMap(pCapture, getPropValue).pipe(tools.O.filter(tools.isBoolean)); | ||
const pSignal = findProp(node.properties, "signal"); | ||
const vSignal = tools.O.flatMap(pSignal, getPropValue); | ||
return tools.Data.struct({ capture: vCapture, signal: vSignal }); | ||
} | ||
case utils.AST_NODE_TYPES.Identifier: | ||
case utils.AST_NODE_TYPES.MemberExpression: { | ||
const options = astUtils.getStaticValue(node, initialScope); | ||
if (!tools.isObject(options?.value)) return defaultOptions; | ||
if (!tsPattern.isMatching({ capture: tsPattern.P.optional(tsPattern.P.any), signal: tsPattern.P.optional(tsPattern.P.any) }, options.value)) { | ||
function getOpts(node2) { | ||
switch (node2.type) { | ||
case utils.AST_NODE_TYPES.Literal: { | ||
return tools.Data.struct({ ...defaultOptions, capture: tools.O.some(!!node2.value) }); | ||
} | ||
case utils.AST_NODE_TYPES.ObjectExpression: { | ||
const pOnce = findProp(node2.properties, "once"); | ||
const vOnce = tools.O.flatMap(pOnce, getPropValue).pipe(tools.O.filter(tools.isBoolean)); | ||
const pCapture = findProp(node2.properties, "capture"); | ||
const vCapture = tools.O.flatMap(pCapture, getPropValue).pipe(tools.O.filter(tools.isBoolean)); | ||
const pSignal = findProp(node2.properties, "signal"); | ||
const vSignal = tools.O.flatMapNullable(pSignal, (prop) => prop.type === utils.AST_NODE_TYPES.Property ? prop.value : null); | ||
return tools.Data.struct({ capture: vCapture, once: vOnce, signal: vSignal }); | ||
} | ||
case utils.AST_NODE_TYPES.Identifier: { | ||
return tools.F.pipe( | ||
_var.findVariable(node2, initialScope), | ||
tools.O.flatMap(_var.getVariableNode(0)), | ||
tools.O.filter(ast.is(utils.AST_NODE_TYPES.ObjectExpression)), | ||
tools.O.map(getOpts), | ||
tools.O.getOrElse(() => defaultOptions) | ||
); | ||
} | ||
default: { | ||
return defaultOptions; | ||
} | ||
const capture = tools.O.fromNullable(options.value.capture).pipe(tools.O.filter(tools.isBoolean)); | ||
const signal = tools.O.fromNullable(options.value.signal); | ||
return tools.Data.struct({ capture, signal }); | ||
} | ||
default: { | ||
return defaultOptions; | ||
} | ||
} | ||
return getOpts(node); | ||
} | ||
@@ -120,2 +126,3 @@ var no_leaked_event_listener_default = createRule({ | ||
const rEntries = []; | ||
const abortedSignals = []; | ||
function checkInlineFunction(node, callKind) { | ||
@@ -130,3 +137,3 @@ const [_, listener] = node.arguments; | ||
} | ||
function isSameEventTarget(a, b) { | ||
const isSameObject = tools.F.dual(2, (a, b) => { | ||
switch (true) { | ||
@@ -139,14 +146,12 @@ case (a.type === utils.AST_NODE_TYPES.MemberExpression && b.type === utils.AST_NODE_TYPES.MemberExpression): | ||
} | ||
} | ||
function isInverseEntry(aEntry) { | ||
return (rEntry) => { | ||
const { type: aType, callee: aCallee, capture: aCapture, listener: aListener, phase: aPhase } = aEntry; | ||
const { type: rType, callee: rCallee, capture: rCapture, listener: rListener, phase: rPhase } = rEntry; | ||
if (!core.isInversePhase(aPhase, rPhase)) return false; | ||
return isSameEventTarget(aCallee, rCallee) && ast.isNodeEqual(aListener, rListener) && _var.isNodeValueEqual(aType, rType, [ | ||
context.sourceCode.getScope(aType), | ||
context.sourceCode.getScope(rType) | ||
]) && tools.O.getOrElse(aCapture, tools.F.constFalse) === tools.O.getOrElse(rCapture, tools.F.constFalse); | ||
}; | ||
} | ||
}); | ||
const isInverseEntry = tools.F.dual(2, (aEntry, rEntry) => { | ||
const { type: aType, callee: aCallee, capture: aCapture, listener: aListener, phase: aPhase } = aEntry; | ||
const { type: rType, callee: rCallee, capture: rCapture, listener: rListener, phase: rPhase } = rEntry; | ||
if (!core.isInversePhase(aPhase, rPhase)) return false; | ||
return isSameObject(aCallee, rCallee) && ast.isNodeEqual(aListener, rListener) && _var.isNodeValueEqual(aType, rType, [ | ||
context.sourceCode.getScope(aType), | ||
context.sourceCode.getScope(rType) | ||
]) && tools.O.getOrElse(aCapture, tools.F.constFalse) === tools.O.getOrElse(rCapture, tools.F.constFalse); | ||
}); | ||
return { | ||
@@ -199,2 +204,6 @@ [":function"](node) { | ||
} | ||
case "abort": { | ||
abortedSignals.push(node.callee); | ||
break; | ||
} | ||
} | ||
@@ -204,2 +213,3 @@ }, | ||
for (const aEntry of aEntries) { | ||
if (tools.O.exists(aEntry.signal, (signal) => abortedSignals.some(isSameObject(signal)))) continue; | ||
if (rEntries.some(isInverseEntry(aEntry))) continue; | ||
@@ -206,0 +216,0 @@ switch (aEntry.phase) { |
{ | ||
"name": "eslint-plugin-react-web-api", | ||
"version": "1.12.2", | ||
"version": "1.12.3-next.0", | ||
"description": "ESLint React's ESLint plugin for interacting with Web APIs", | ||
@@ -50,9 +50,9 @@ "keywords": [ | ||
"ts-pattern": "^5.3.1", | ||
"@eslint-react/ast": "1.12.2", | ||
"@eslint-react/shared": "1.12.2", | ||
"@eslint-react/core": "1.12.2", | ||
"@eslint-react/jsx": "1.12.2", | ||
"@eslint-react/tools": "1.12.2", | ||
"@eslint-react/types": "1.12.2", | ||
"@eslint-react/var": "1.12.2" | ||
"@eslint-react/ast": "1.12.3-next.0", | ||
"@eslint-react/core": "1.12.3-next.0", | ||
"@eslint-react/tools": "1.12.3-next.0", | ||
"@eslint-react/shared": "1.12.3-next.0", | ||
"@eslint-react/jsx": "1.12.3-next.0", | ||
"@eslint-react/var": "1.12.3-next.0", | ||
"@eslint-react/types": "1.12.3-next.0" | ||
}, | ||
@@ -59,0 +59,0 @@ "devDependencies": { |
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
43694
954
1
+ Added@eslint-react/ast@1.12.3-next.0(transitive)
+ Added@eslint-react/core@1.12.3-next.0(transitive)
+ Added@eslint-react/jsx@1.12.3-next.0(transitive)
+ Added@eslint-react/shared@1.12.3-next.0(transitive)
+ Added@eslint-react/tools@1.12.3-next.0(transitive)
+ Added@eslint-react/types@1.12.3-next.0(transitive)
+ Added@eslint-react/var@1.12.3-next.0(transitive)
+ Addedeslint@9.20.1(transitive)
- Removed@eslint-react/ast@1.12.2(transitive)
- Removed@eslint-react/core@1.12.2(transitive)
- Removed@eslint-react/jsx@1.12.2(transitive)
- Removed@eslint-react/shared@1.12.2(transitive)
- Removed@eslint-react/tools@1.12.2(transitive)
- Removed@eslint-react/types@1.12.2(transitive)
- Removed@eslint-react/var@1.12.2(transitive)
- Removedeslint@9.20.0(transitive)