@agilebot/eslint-plugin 0.5.3 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.js +43 -18
- package/package.json +4 -5
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.5
|
3
3
|
*
|
4
4
|
* Copyright (c) Agilebot, Inc. and its affiliates.
|
5
5
|
*
|
@@ -34,8 +34,8 @@ function _interopNamespaceDefault(e) {
|
|
34
34
|
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
35
35
|
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
36
36
|
|
37
|
-
const rule
|
38
|
-
const compatRule
|
37
|
+
const rule = require('eslint-plugin-deprecation/dist/rules/deprecation')["default"];
|
38
|
+
const compatRule = compat.fixupRule(rule);
|
39
39
|
|
40
40
|
const docBaseUrl = 'https://github.com/sh-agilebot/frontend-toolkit/blob/master/packages/eslint-plugin/src/rules/';
|
41
41
|
const hasDocs = typeof ["enforce-mui-icon-alias","intl-id-missing","intl-id-prefix","intl-no-default","react-better-exhaustive-deps"] !== 'undefined' ?
|
@@ -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';
|
@@ -2203,11 +2234,6 @@ var reactPreferSxProp = createRule({
|
|
2203
2234
|
}
|
2204
2235
|
});
|
2205
2236
|
|
2206
|
-
const pluginReactHooks = require('eslint-plugin-react-hooks');
|
2207
|
-
const rule = pluginReactHooks.rules['rules-of-hooks'];
|
2208
|
-
const compatRule = compat.fixupRule(rule);
|
2209
|
-
compatRule.meta.docs.recommended = false;
|
2210
|
-
|
2211
2237
|
function getBasicIdentifier(node) {
|
2212
2238
|
if (node.type === 'Identifier') {
|
2213
2239
|
return node.name;
|
@@ -2903,7 +2929,7 @@ var varNaming = createRule({
|
|
2903
2929
|
|
2904
2930
|
var ruleFiles = /*#__PURE__*/Object.freeze({
|
2905
2931
|
__proto__: null,
|
2906
|
-
rules_deprecation: compatRule
|
2932
|
+
rules_deprecation: compatRule,
|
2907
2933
|
rules_enforce_mui_icon_alias: enforceMuiIconAlias,
|
2908
2934
|
rules_import_monorepo: importMonorepo,
|
2909
2935
|
rules_intl_id_missing: intlIdMissing,
|
@@ -2919,7 +2945,6 @@ var ruleFiles = /*#__PURE__*/Object.freeze({
|
|
2919
2945
|
rules_react_hook_use_ref: reactHookUseRef,
|
2920
2946
|
rules_react_prefer_named_property_access: reactPreferNamedPropertyAccess,
|
2921
2947
|
rules_react_prefer_sx_prop: reactPreferSxProp,
|
2922
|
-
rules_react_rules_of_hooks: compatRule,
|
2923
2948
|
rules_tss_class_naming: tssClassNaming,
|
2924
2949
|
rules_tss_no_color_name: tssNoColorName,
|
2925
2950
|
rules_tss_no_color_value: tssNoColorValue,
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@agilebot/eslint-plugin",
|
3
|
-
"version": "0.5.
|
3
|
+
"version": "0.5.5",
|
4
4
|
"description": "Agilebot's ESLint plugin",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -18,12 +18,11 @@
|
|
18
18
|
"node": "^18.18.0 || >=20.0.0"
|
19
19
|
},
|
20
20
|
"dependencies": {
|
21
|
-
"@eslint/compat": "^1.
|
21
|
+
"@eslint/compat": "^1.2.1",
|
22
22
|
"@typescript-eslint/utils": "~8.7.0",
|
23
23
|
"eslint-plugin-deprecation": "^3.0.0",
|
24
|
-
"eslint-plugin-react": "^7.
|
25
|
-
"eslint-
|
26
|
-
"@agilebot/eslint-utils": "0.5.3"
|
24
|
+
"eslint-plugin-react": "^7.37.2",
|
25
|
+
"@agilebot/eslint-utils": "0.5.5"
|
27
26
|
},
|
28
27
|
"peerDependencies": {
|
29
28
|
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
|