@agilebot/eslint-plugin 0.5.3 → 0.5.4
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 +40 -9
- package/package.json +2 -2
package/dist/index.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license @agilebot/eslint-plugin v0.5.
|
2
|
+
* @license @agilebot/eslint-plugin v0.5.4
|
3
3
|
*
|
4
4
|
* Copyright (c) Agilebot, Inc. and its affiliates.
|
5
5
|
*
|
@@ -859,6 +859,7 @@ var reactBetterExhaustiveDeps = {
|
|
859
859
|
const stateVariables = new WeakSet();
|
860
860
|
const stableKnownValueCache = new WeakMap();
|
861
861
|
const functionWithoutCapturedValueCache = new WeakMap();
|
862
|
+
const useEffectEventVariables = new WeakSet();
|
862
863
|
function memoizeWithWeakMap(fn, map) {
|
863
864
|
return function (arg) {
|
864
865
|
if (map.has(arg)) {
|
@@ -882,7 +883,7 @@ var reactBetterExhaustiveDeps = {
|
|
882
883
|
if (!isCustomHook) {
|
883
884
|
reportProblem({
|
884
885
|
node: node,
|
885
|
-
message: "Effect callbacks are synchronous to prevent race conditions. " + "Put the async function inside:\n\n" + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://
|
886
|
+
message: "Effect callbacks are synchronous to prevent race conditions. " + "Put the async function inside:\n\n" + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://react.dev/link/hooks-data-fetching'
|
886
887
|
});
|
887
888
|
}
|
888
889
|
}
|
@@ -921,7 +922,7 @@ var reactBetterExhaustiveDeps = {
|
|
921
922
|
if (init == null) {
|
922
923
|
return false;
|
923
924
|
}
|
924
|
-
while (init.type === 'TSAsExpression') {
|
925
|
+
while (init.type === 'TSAsExpression' || init.type === 'AsExpression') {
|
925
926
|
init = init.expression;
|
926
927
|
}
|
927
928
|
let declaration = def.node.parent;
|
@@ -951,7 +952,14 @@ var reactBetterExhaustiveDeps = {
|
|
951
952
|
} = callee;
|
952
953
|
if (name === 'useRef' && id.type === 'Identifier') {
|
953
954
|
return true;
|
954
|
-
} else if (
|
955
|
+
} else if (isUseEffectEventIdentifier() && id.type === 'Identifier') {
|
956
|
+
for (const ref of resolved.references) {
|
957
|
+
if (ref !== id) {
|
958
|
+
useEffectEventVariables.add(ref.identifier);
|
959
|
+
}
|
960
|
+
}
|
961
|
+
return true;
|
962
|
+
} else if (name === 'useState' || name === 'useReducer' || name === 'useActionState') {
|
955
963
|
if (id.type === 'ArrayPattern' && id.elements.length === 2 && isArray(resolved.identifiers)) {
|
956
964
|
if (id.elements[1] === resolved.identifiers[0]) {
|
957
965
|
if (name === 'useState') {
|
@@ -1238,13 +1246,16 @@ var reactBetterExhaustiveDeps = {
|
|
1238
1246
|
}
|
1239
1247
|
const declaredDependencies = [];
|
1240
1248
|
const externalDependencies = new Set();
|
1241
|
-
|
1249
|
+
const isArrayExpression = declaredDependenciesNode.type === 'ArrayExpression';
|
1250
|
+
const isTSAsArrayExpression = declaredDependenciesNode.type === 'TSAsExpression' && declaredDependenciesNode.expression.type === 'ArrayExpression';
|
1251
|
+
if (!isArrayExpression && !isTSAsArrayExpression) {
|
1242
1252
|
reportProblem({
|
1243
1253
|
node: declaredDependenciesNode,
|
1244
1254
|
message: "React Hook ".concat(getSource(reactiveHook), " was passed a ") + 'dependency list that is not an array literal. This means we ' + "can't statically verify whether you've passed the correct " + 'dependencies.'
|
1245
1255
|
});
|
1246
1256
|
} else {
|
1247
|
-
declaredDependenciesNode.
|
1257
|
+
const arrayExpression = isTSAsArrayExpression ? declaredDependenciesNode.expression : declaredDependenciesNode;
|
1258
|
+
arrayExpression.elements.forEach(declaredDependencyNode => {
|
1248
1259
|
if (declaredDependencyNode == null) {
|
1249
1260
|
return;
|
1250
1261
|
}
|
@@ -1255,6 +1266,18 @@ var reactBetterExhaustiveDeps = {
|
|
1255
1266
|
});
|
1256
1267
|
return;
|
1257
1268
|
}
|
1269
|
+
if (useEffectEventVariables.has(declaredDependencyNode)) {
|
1270
|
+
reportProblem({
|
1271
|
+
node: declaredDependencyNode,
|
1272
|
+
message: 'Functions returned from `useEffectEvent` must not be included in the dependency array. ' + "Remove `".concat(getSource(declaredDependencyNode), "` from the list."),
|
1273
|
+
suggest: [{
|
1274
|
+
desc: "Remove the dependency `".concat(getSource(declaredDependencyNode), "`"),
|
1275
|
+
fix(fixer) {
|
1276
|
+
return fixer.removeRange(declaredDependencyNode.range);
|
1277
|
+
}
|
1278
|
+
}]
|
1279
|
+
});
|
1280
|
+
}
|
1258
1281
|
let declaredDependency;
|
1259
1282
|
try {
|
1260
1283
|
declaredDependency = analyzePropertyChain(declaredDependencyNode, null);
|
@@ -1532,7 +1555,8 @@ var reactBetterExhaustiveDeps = {
|
|
1532
1555
|
extraWarning = " If '".concat(setStateRecommendation.setter, "' needs the ") + "current value of '".concat(setStateRecommendation.missingDep, "', ") + "you can also switch to useReducer instead of useState and " + "read '".concat(setStateRecommendation.missingDep, "' in the reducer.");
|
1533
1556
|
break;
|
1534
1557
|
case 'updater':
|
1535
|
-
extraWarning = " You can also do a functional update '".concat(setStateRecommendation.setter, "(").concat(setStateRecommendation.missingDep.slice(0, 1), " => ...)' if you only need '").concat(setStateRecommendation.missingDep
|
1558
|
+
extraWarning = " You can also do a functional update '".concat(setStateRecommendation.setter, "(").concat(setStateRecommendation.missingDep.slice(0, 1), " => ...)' if you only need '").concat(setStateRecommendation.missingDep
|
1559
|
+
, "'") + " in the '".concat(setStateRecommendation.setter, "' call.");
|
1536
1560
|
break;
|
1537
1561
|
default:
|
1538
1562
|
throw new Error('Unknown case.');
|
@@ -1559,7 +1583,8 @@ var reactBetterExhaustiveDeps = {
|
|
1559
1583
|
const callback = node.arguments[callbackIndex];
|
1560
1584
|
const reactiveHook = node.callee;
|
1561
1585
|
const reactiveHookName = getNodeWithoutReactNamespace(reactiveHook).name;
|
1562
|
-
const
|
1586
|
+
const maybeNode = node.arguments[callbackIndex + 1];
|
1587
|
+
const declaredDependenciesNode = maybeNode && !(maybeNode.type === 'Identifier' && maybeNode.name === 'undefined') ? maybeNode : undefined;
|
1563
1588
|
const isEffect = /Effect($|[^a-z])/g.test(reactiveHookName);
|
1564
1589
|
if (!callback) {
|
1565
1590
|
reportProblem({
|
@@ -1582,6 +1607,9 @@ var reactBetterExhaustiveDeps = {
|
|
1582
1607
|
case 'ArrowFunctionExpression':
|
1583
1608
|
visitFunctionWithDependencies(callback, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect);
|
1584
1609
|
return;
|
1610
|
+
case 'TSAsExpression':
|
1611
|
+
visitFunctionWithDependencies(callback.expression, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect);
|
1612
|
+
return;
|
1585
1613
|
case 'Identifier':
|
1586
1614
|
if (!declaredDependenciesNode) {
|
1587
1615
|
return;
|
@@ -1786,7 +1814,7 @@ function getConstructionExpressionType(node) {
|
|
1786
1814
|
}
|
1787
1815
|
return null;
|
1788
1816
|
case 'TypeCastExpression':
|
1789
|
-
|
1817
|
+
case 'AsExpression':
|
1790
1818
|
case 'TSAsExpression':
|
1791
1819
|
return getConstructionExpressionType(node.expression);
|
1792
1820
|
}
|
@@ -2008,6 +2036,9 @@ function isSameIdentifier(a, b) {
|
|
2008
2036
|
function isAncestorNodeOf(a, b) {
|
2009
2037
|
return a.range[0] <= b.range[0] && a.range[1] >= b.range[1];
|
2010
2038
|
}
|
2039
|
+
function isUseEffectEventIdentifier(node) {
|
2040
|
+
return false;
|
2041
|
+
}
|
2011
2042
|
|
2012
2043
|
const Components = require('eslint-plugin-react/lib/util/Components');
|
2013
2044
|
const RULE_NAME$7 = 'react-hook-use-ref';
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@agilebot/eslint-plugin",
|
3
|
-
"version": "0.5.
|
3
|
+
"version": "0.5.4",
|
4
4
|
"description": "Agilebot's ESLint plugin",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -23,7 +23,7 @@
|
|
23
23
|
"eslint-plugin-deprecation": "^3.0.0",
|
24
24
|
"eslint-plugin-react": "^7.35.0",
|
25
25
|
"eslint-plugin-react-hooks": "^4.6.2",
|
26
|
-
"@agilebot/eslint-utils": "0.5.
|
26
|
+
"@agilebot/eslint-utils": "0.5.4"
|
27
27
|
},
|
28
28
|
"peerDependencies": {
|
29
29
|
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
|