@agilebot/eslint-plugin 0.1.6 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/index.js +5 -20
- package/lib/rules/import/enforce-icon-alias.js +3 -4
- package/lib/rules/intl/id-missing.js +9 -3
- package/lib/rules/intl/id-prefix.js +9 -3
- package/lib/rules/intl/id-unused.js +9 -3
- package/lib/rules/intl/no-default.js +9 -3
- package/lib/rules/react/better-exhaustive-deps.js +3 -1
- package/lib/rules/react/hook-use-ref.js +18 -20
- package/package.json +4 -2
package/lib/index.js
CHANGED
@@ -24,26 +24,6 @@ module.exports.configs = {
|
|
24
24
|
recommended: {
|
25
25
|
plugins: ['@agilebot'],
|
26
26
|
rules: {
|
27
|
-
'react-hooks/exhaustive-deps': 'off',
|
28
|
-
'@agilebot/react/better-exhaustive-deps': [
|
29
|
-
'warn',
|
30
|
-
{
|
31
|
-
checkMemoizedVariableIsStatic: true,
|
32
|
-
staticHooks: {
|
33
|
-
'useIpc.*': {
|
34
|
-
value: true,
|
35
|
-
regexp: true
|
36
|
-
},
|
37
|
-
useDialog: true,
|
38
|
-
useSnackbar: true,
|
39
|
-
useForm: true,
|
40
|
-
'use.*Store': {
|
41
|
-
value: true,
|
42
|
-
regexp: true
|
43
|
-
}
|
44
|
-
}
|
45
|
-
}
|
46
|
-
],
|
47
27
|
'@agilebot/react/prefer-named-property-access': 'error',
|
48
28
|
'@agilebot/react/hook-use-ref': 'warn',
|
49
29
|
'@agilebot/react/no-inline-styles': 'error',
|
@@ -53,6 +33,11 @@ module.exports.configs = {
|
|
53
33
|
'@agilebot/import/enforce-icon-alias': 'error',
|
54
34
|
'@agilebot/import/monorepo': 'error',
|
55
35
|
'@agilebot/others/no-unnecessary-template-literals': 'error'
|
36
|
+
},
|
37
|
+
settings: {
|
38
|
+
react: {
|
39
|
+
version: '18.0.0'
|
40
|
+
}
|
56
41
|
}
|
57
42
|
}
|
58
43
|
};
|
@@ -28,12 +28,11 @@ module.exports = {
|
|
28
28
|
context.report({
|
29
29
|
node,
|
30
30
|
message: `Import for ${node.source.value} should be aliased.`,
|
31
|
-
fix: fixer =>
|
32
|
-
|
31
|
+
fix: fixer =>
|
32
|
+
fixer.replaceText(
|
33
33
|
specifier,
|
34
34
|
`${specifier.imported.name} as ${specifier.imported.name}Icon`
|
35
|
-
)
|
36
|
-
}
|
35
|
+
)
|
37
36
|
});
|
38
37
|
}
|
39
38
|
}
|
@@ -88,17 +88,23 @@ module.exports = {
|
|
88
88
|
return {
|
89
89
|
JSXIdentifier: function (node) {
|
90
90
|
const attrNode = findFormattedMessageAttrNode(node, 'id');
|
91
|
-
if (attrNode)
|
91
|
+
if (attrNode) {
|
92
|
+
return processAttrNode(attrNode);
|
93
|
+
}
|
92
94
|
},
|
93
95
|
CallExpression: function (node) {
|
94
96
|
const attrNode = findFormatMessageAttrNode(node, 'id');
|
95
|
-
if (attrNode)
|
97
|
+
if (attrNode) {
|
98
|
+
return processAttrNode(attrNode);
|
99
|
+
}
|
96
100
|
},
|
97
101
|
Property: function (node) {
|
98
102
|
const attrNode =
|
99
103
|
findAttrNodeInDefineMessages(node, 'id') ||
|
100
104
|
findAttrNodeInDefineMessage(node, 'id');
|
101
|
-
if (attrNode)
|
105
|
+
if (attrNode) {
|
106
|
+
return processAttrNode(attrNode);
|
107
|
+
}
|
102
108
|
}
|
103
109
|
};
|
104
110
|
}
|
@@ -80,17 +80,23 @@ module.exports = {
|
|
80
80
|
return {
|
81
81
|
JSXIdentifier: function (node) {
|
82
82
|
const attrNode = findFormattedMessageAttrNode(node, 'id');
|
83
|
-
if (attrNode)
|
83
|
+
if (attrNode) {
|
84
|
+
return processAttrNode(attrNode);
|
85
|
+
}
|
84
86
|
},
|
85
87
|
CallExpression: function (node) {
|
86
88
|
const attrNode = findFormatMessageAttrNode(node, 'id');
|
87
|
-
if (attrNode)
|
89
|
+
if (attrNode) {
|
90
|
+
return processAttrNode(attrNode);
|
91
|
+
}
|
88
92
|
},
|
89
93
|
Property: function (node) {
|
90
94
|
const attrNode =
|
91
95
|
findAttrNodeInDefineMessages(node, 'id') ||
|
92
96
|
findAttrNodeInDefineMessage(node, 'id');
|
93
|
-
if (attrNode)
|
97
|
+
if (attrNode) {
|
98
|
+
return processAttrNode(attrNode);
|
99
|
+
}
|
94
100
|
}
|
95
101
|
};
|
96
102
|
}
|
@@ -93,17 +93,23 @@ module.exports = {
|
|
93
93
|
return {
|
94
94
|
JSXIdentifier: function (node) {
|
95
95
|
const attrNode = findFormattedMessageAttrNode(node, 'id');
|
96
|
-
if (attrNode)
|
96
|
+
if (attrNode) {
|
97
|
+
return processAttrNode(attrNode);
|
98
|
+
}
|
97
99
|
},
|
98
100
|
CallExpression: function (node) {
|
99
101
|
const attrNode = findFormatMessageAttrNode(node, 'id');
|
100
|
-
if (attrNode)
|
102
|
+
if (attrNode) {
|
103
|
+
return processAttrNode(attrNode);
|
104
|
+
}
|
101
105
|
},
|
102
106
|
Property: function (node) {
|
103
107
|
const attrNode =
|
104
108
|
findAttrNodeInDefineMessages(node, 'id') ||
|
105
109
|
findAttrNodeInDefineMessage(node, 'id');
|
106
|
-
if (attrNode)
|
110
|
+
if (attrNode) {
|
111
|
+
return processAttrNode(attrNode);
|
112
|
+
}
|
107
113
|
},
|
108
114
|
'Program:exit': function () {
|
109
115
|
// 将usedIdSet转为数组,然后与translatedIds取差集,即为未使用的id
|
@@ -39,18 +39,24 @@ module.exports = {
|
|
39
39
|
return {
|
40
40
|
JSXIdentifier: function (node) {
|
41
41
|
const attrNode = findFormattedMessageAttrNode(node, 'defaultMessage');
|
42
|
-
if (attrNode)
|
42
|
+
if (attrNode) {
|
43
|
+
return processAttrNode(attrNode);
|
44
|
+
}
|
43
45
|
},
|
44
46
|
CallExpression: function (node) {
|
45
47
|
const attrNode = findFormatMessageAttrNode(node, 'defaultMessage');
|
46
|
-
if (attrNode)
|
48
|
+
if (attrNode) {
|
49
|
+
return processAttrNode(attrNode);
|
50
|
+
}
|
47
51
|
},
|
48
52
|
Property: function (node) {
|
49
53
|
const attrNode =
|
50
54
|
findAttrNodeInDefineMessages(node, 'defaultMessage') ||
|
51
55
|
findAttrNodeInDefineMessage(node, 'defaultMessage');
|
52
56
|
|
53
|
-
if (attrNode)
|
57
|
+
if (attrNode) {
|
58
|
+
return processAttrNode(attrNode);
|
59
|
+
}
|
54
60
|
}
|
55
61
|
};
|
56
62
|
}
|
@@ -326,7 +326,9 @@ module.exports = {
|
|
326
326
|
// useMemo(() => { ... }, []) / useCallback((...) => { ... }, [])
|
327
327
|
const hookArgs = callee.parent.arguments;
|
328
328
|
// check it has dependency list
|
329
|
-
if (hookArgs.length < 2)
|
329
|
+
if (hookArgs.length < 2) {
|
330
|
+
return false;
|
331
|
+
}
|
330
332
|
|
331
333
|
const dependencies = hookArgs[1].elements;
|
332
334
|
if (dependencies.length === 0) {
|
@@ -11,27 +11,25 @@ module.exports = {
|
|
11
11
|
hasSuggestions: true
|
12
12
|
},
|
13
13
|
|
14
|
-
create: Components.detect((context, component, util) => {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
node.parent && node.parent.type === 'ReturnStatement';
|
14
|
+
create: Components.detect((context, component, util) => ({
|
15
|
+
CallExpression(node) {
|
16
|
+
const isImmediateReturn =
|
17
|
+
node.parent && node.parent.type === 'ReturnStatement';
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
if (isImmediateReturn || !util.isReactHookCall(node, ['useRef'])) {
|
20
|
+
return;
|
21
|
+
}
|
22
|
+
if (node.parent.id.type !== 'Identifier') {
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
const variable = node.parent.id.name;
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
}
|
27
|
+
if (!variable.endsWith('Ref')) {
|
28
|
+
context.report({
|
29
|
+
node: node,
|
30
|
+
message: 'useRef call is not end with "Ref"'
|
31
|
+
});
|
34
32
|
}
|
35
|
-
}
|
36
|
-
})
|
33
|
+
}
|
34
|
+
}))
|
37
35
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@agilebot/eslint-plugin",
|
3
|
-
"version": "0.1
|
3
|
+
"version": "0.2.1",
|
4
4
|
"description": "Agilebot's ESLint plugin",
|
5
5
|
"main": "lib",
|
6
6
|
"license": "MIT",
|
@@ -18,7 +18,9 @@
|
|
18
18
|
},
|
19
19
|
"dependencies": {
|
20
20
|
"@typescript-eslint/utils": "^7.6.0",
|
21
|
-
"
|
21
|
+
"eslint-plugin-react": "^7.34.1",
|
22
|
+
"fast-glob": "^3.3.2",
|
23
|
+
"@agilebot/eslint-utils": "0.2.1"
|
22
24
|
},
|
23
25
|
"peerDependencies": {
|
24
26
|
"eslint": "^7.0.0 || ^8.0.0"
|