@agilebot/eslint-plugin 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,103 +1,103 @@
1
- const {
2
- findFormatMessageAttrNode,
3
- findFormattedMessageAttrNode,
4
- findAttrNodeInDefineMessages,
5
- findAttrNodeInDefineMessage,
6
- templateLiteralDisplayStr
7
- } = require('../../util/intl');
8
-
9
- // ------------------------------------------------------------------------------
10
- // Rule Definition
11
- // ------------------------------------------------------------------------------
12
-
13
- module.exports = {
14
- meta: {
15
- docs: {
16
- description: 'Validates intl message ids has correct prefixes',
17
- category: 'Intl',
18
- recommended: true
19
- },
20
- fixable: null,
21
- schema: [
22
- {
23
- type: 'array',
24
- items: {
25
- type: 'string'
26
- }
27
- }
28
- ]
29
- },
30
-
31
- create: function (context) {
32
- if (context.options[0].length === 0) {
33
- throw new Error('Prefixes are required in settings');
34
- }
35
-
36
- // ----------------------------------------------------------------------
37
- // Helpers
38
- // ----------------------------------------------------------------------
39
-
40
- const hasPrefix = value =>
41
- context.options[0].some(p => value.startsWith(p));
42
-
43
- function report(node, value) {
44
- if (!hasPrefix(value)) {
45
- context.report({
46
- node: node,
47
- message: `Invalid id prefix: ${value}`
48
- });
49
- }
50
- }
51
-
52
- function processLiteral(node) {
53
- report(node, node.value);
54
- }
55
-
56
- function processTemplateLiteral(node) {
57
- const displayStr = templateLiteralDisplayStr(node);
58
- report(node, displayStr);
59
- }
60
-
61
- function processAttrNode(node) {
62
- if (node.value.type === 'Literal') {
63
- return processLiteral(node.value);
64
- }
65
- if (
66
- node.value.type === 'JSXExpressionContainer' &&
67
- node.value.expression.type === 'TemplateLiteral'
68
- ) {
69
- return processTemplateLiteral(node.value.expression);
70
- }
71
- if (node.value.type === 'TemplateLiteral') {
72
- return processTemplateLiteral(node.value);
73
- }
74
- }
75
-
76
- // ----------------------------------------------------------------------
77
- // Public
78
- // ----------------------------------------------------------------------
79
-
80
- return {
81
- JSXIdentifier: function (node) {
82
- const attrNode = findFormattedMessageAttrNode(node, 'id');
83
- if (attrNode) {
84
- return processAttrNode(attrNode);
85
- }
86
- },
87
- CallExpression: function (node) {
88
- const attrNode = findFormatMessageAttrNode(node, 'id');
89
- if (attrNode) {
90
- return processAttrNode(attrNode);
91
- }
92
- },
93
- Property: function (node) {
94
- const attrNode =
95
- findAttrNodeInDefineMessages(node, 'id') ||
96
- findAttrNodeInDefineMessage(node, 'id');
97
- if (attrNode) {
98
- return processAttrNode(attrNode);
99
- }
100
- }
101
- };
102
- }
103
- };
1
+ const {
2
+ findFormatMessageAttrNode,
3
+ findFormattedMessageAttrNode,
4
+ findAttrNodeInDefineMessages,
5
+ findAttrNodeInDefineMessage,
6
+ templateLiteralDisplayStr
7
+ } = require('../../util/intl');
8
+
9
+ // ------------------------------------------------------------------------------
10
+ // Rule Definition
11
+ // ------------------------------------------------------------------------------
12
+
13
+ module.exports = {
14
+ meta: {
15
+ docs: {
16
+ description: 'Validates intl message ids has correct prefixes',
17
+ category: 'Intl',
18
+ recommended: true
19
+ },
20
+ fixable: null,
21
+ schema: [
22
+ {
23
+ type: 'array',
24
+ items: {
25
+ type: 'string'
26
+ }
27
+ }
28
+ ]
29
+ },
30
+
31
+ create: function (context) {
32
+ if (context.options[0].length === 0) {
33
+ throw new Error('Prefixes are required in settings');
34
+ }
35
+
36
+ // ----------------------------------------------------------------------
37
+ // Helpers
38
+ // ----------------------------------------------------------------------
39
+
40
+ const hasPrefix = value =>
41
+ context.options[0].some(p => value.startsWith(p));
42
+
43
+ function report(node, value) {
44
+ if (!hasPrefix(value)) {
45
+ context.report({
46
+ node: node,
47
+ message: `Invalid id prefix: ${value}`
48
+ });
49
+ }
50
+ }
51
+
52
+ function processLiteral(node) {
53
+ report(node, node.value);
54
+ }
55
+
56
+ function processTemplateLiteral(node) {
57
+ const displayStr = templateLiteralDisplayStr(node);
58
+ report(node, displayStr);
59
+ }
60
+
61
+ function processAttrNode(node) {
62
+ if (node.value.type === 'Literal') {
63
+ return processLiteral(node.value);
64
+ }
65
+ if (
66
+ node.value.type === 'JSXExpressionContainer' &&
67
+ node.value.expression.type === 'TemplateLiteral'
68
+ ) {
69
+ return processTemplateLiteral(node.value.expression);
70
+ }
71
+ if (node.value.type === 'TemplateLiteral') {
72
+ return processTemplateLiteral(node.value);
73
+ }
74
+ }
75
+
76
+ // ----------------------------------------------------------------------
77
+ // Public
78
+ // ----------------------------------------------------------------------
79
+
80
+ return {
81
+ JSXIdentifier: function (node) {
82
+ const attrNode = findFormattedMessageAttrNode(node, 'id');
83
+ if (attrNode) {
84
+ return processAttrNode(attrNode);
85
+ }
86
+ },
87
+ CallExpression: function (node) {
88
+ const attrNode = findFormatMessageAttrNode(node, 'id');
89
+ if (attrNode) {
90
+ return processAttrNode(attrNode);
91
+ }
92
+ },
93
+ Property: function (node) {
94
+ const attrNode =
95
+ findAttrNodeInDefineMessages(node, 'id') ||
96
+ findAttrNodeInDefineMessage(node, 'id');
97
+ if (attrNode) {
98
+ return processAttrNode(attrNode);
99
+ }
100
+ }
101
+ };
102
+ }
103
+ };
@@ -1,123 +1,123 @@
1
- const path = require('node:path');
2
- const fs = require('node:fs');
3
- const {
4
- sortedTemplateElements,
5
- findFormatMessageAttrNode,
6
- findFormattedMessageAttrNode,
7
- findAttrNodeInDefineMessages,
8
- findAttrNodeInDefineMessage
9
- } = require('../../util/intl');
10
- const { getIntlIds } = require('../../util/translations');
11
- const { getSetting } = require('../../util/settings');
12
-
13
- // 已经使用的id集合 key为项目目录,value为id集合Set
14
- const usedIds = new Map();
15
-
16
- // ------------------------------------------------------------------------------
17
- // Rule Definition
18
- // ------------------------------------------------------------------------------
19
-
20
- module.exports = {
21
- meta: {
22
- docs: {
23
- description: 'Finds unused intl message ids in locale file',
24
- category: 'Intl',
25
- recommended: true
26
- },
27
- fixable: null,
28
- schema: []
29
- },
30
-
31
- create: function (context) {
32
- const projectRoot = getSetting(context, 'project-root');
33
- if (!projectRoot) {
34
- throw new Error('projectRoot must be set in this rule');
35
- }
36
- if (!usedIds.has(projectRoot)) {
37
- usedIds.set(projectRoot, new Set());
38
- }
39
- const usedIdSet = usedIds.get(projectRoot);
40
-
41
- const translatedIds = getIntlIds(context);
42
- const translatedIdSet = new Set(translatedIds);
43
-
44
- // ----------------------------------------------------------------------
45
- // Helpers
46
- // ----------------------------------------------------------------------
47
-
48
- function isLiteralTranslated(id) {
49
- return translatedIdSet.has(id);
50
- }
51
-
52
- function isTemplateTranslated(re) {
53
- return translatedIds.some(k => re.test(k));
54
- }
55
-
56
- function processLiteral(node) {
57
- if (isLiteralTranslated(node.value)) {
58
- // 将已使用的id加入usedIdSet
59
- usedIdSet.add(node.value);
60
- }
61
- }
62
-
63
- function processTemplateLiteral(node) {
64
- const exStr = sortedTemplateElements(node)
65
- .map(e => (!e.value ? '.*' : e.value.raw))
66
- .join('');
67
- const re = new RegExp(exStr);
68
-
69
- if (isTemplateTranslated(re)) {
70
- // TODO: 暂时没有这种情况
71
- }
72
- }
73
-
74
- function processAttrNode(node) {
75
- if (node.value.type === 'Literal') {
76
- return processLiteral(node.value);
77
- }
78
- if (
79
- node.value.type === 'JSXExpressionContainer' &&
80
- node.value.expression.type === 'TemplateLiteral'
81
- ) {
82
- return processTemplateLiteral(node.value.expression);
83
- }
84
- if (node.value.type === 'TemplateLiteral') {
85
- return processTemplateLiteral(node.value);
86
- }
87
- }
88
-
89
- // ----------------------------------------------------------------------
90
- // Public
91
- // ----------------------------------------------------------------------
92
-
93
- return {
94
- JSXIdentifier: function (node) {
95
- const attrNode = findFormattedMessageAttrNode(node, 'id');
96
- if (attrNode) {
97
- return processAttrNode(attrNode);
98
- }
99
- },
100
- CallExpression: function (node) {
101
- const attrNode = findFormatMessageAttrNode(node, 'id');
102
- if (attrNode) {
103
- return processAttrNode(attrNode);
104
- }
105
- },
106
- Property: function (node) {
107
- const attrNode =
108
- findAttrNodeInDefineMessages(node, 'id') ||
109
- findAttrNodeInDefineMessage(node, 'id');
110
- if (attrNode) {
111
- return processAttrNode(attrNode);
112
- }
113
- },
114
- 'Program:exit': function () {
115
- // 将usedIdSet转为数组,然后与translatedIds取差集,即为未使用的id
116
- const unusedIds = [...translatedIdSet].filter(id => !usedIdSet.has(id));
117
- // 在项目目录下生成intl-unused.json
118
- const jsonPath = path.join(projectRoot, 'intl-unused.json');
119
- fs.writeFileSync(jsonPath, JSON.stringify(unusedIds, null, 2));
120
- }
121
- };
122
- }
123
- };
1
+ const path = require('node:path');
2
+ const fs = require('node:fs');
3
+ const {
4
+ sortedTemplateElements,
5
+ findFormatMessageAttrNode,
6
+ findFormattedMessageAttrNode,
7
+ findAttrNodeInDefineMessages,
8
+ findAttrNodeInDefineMessage
9
+ } = require('../../util/intl');
10
+ const { getIntlIds } = require('../../util/translations');
11
+ const { getSetting } = require('../../util/settings');
12
+
13
+ // 已经使用的id集合 key为项目目录,value为id集合Set
14
+ const usedIds = new Map();
15
+
16
+ // ------------------------------------------------------------------------------
17
+ // Rule Definition
18
+ // ------------------------------------------------------------------------------
19
+
20
+ module.exports = {
21
+ meta: {
22
+ docs: {
23
+ description: 'Finds unused intl message ids in locale file',
24
+ category: 'Intl',
25
+ recommended: true
26
+ },
27
+ fixable: null,
28
+ schema: []
29
+ },
30
+
31
+ create: function (context) {
32
+ const projectRoot = getSetting(context, 'project-root');
33
+ if (!projectRoot) {
34
+ throw new Error('projectRoot must be set in this rule');
35
+ }
36
+ if (!usedIds.has(projectRoot)) {
37
+ usedIds.set(projectRoot, new Set());
38
+ }
39
+ const usedIdSet = usedIds.get(projectRoot);
40
+
41
+ const translatedIds = getIntlIds(context);
42
+ const translatedIdSet = new Set(translatedIds);
43
+
44
+ // ----------------------------------------------------------------------
45
+ // Helpers
46
+ // ----------------------------------------------------------------------
47
+
48
+ function isLiteralTranslated(id) {
49
+ return translatedIdSet.has(id);
50
+ }
51
+
52
+ function isTemplateTranslated(re) {
53
+ return translatedIds.some(k => re.test(k));
54
+ }
55
+
56
+ function processLiteral(node) {
57
+ if (isLiteralTranslated(node.value)) {
58
+ // 将已使用的id加入usedIdSet
59
+ usedIdSet.add(node.value);
60
+ }
61
+ }
62
+
63
+ function processTemplateLiteral(node) {
64
+ const exStr = sortedTemplateElements(node)
65
+ .map(e => (!e.value ? '.*' : e.value.raw))
66
+ .join('');
67
+ const re = new RegExp(exStr);
68
+
69
+ if (isTemplateTranslated(re)) {
70
+ // TODO: 暂时没有这种情况
71
+ }
72
+ }
73
+
74
+ function processAttrNode(node) {
75
+ if (node.value.type === 'Literal') {
76
+ return processLiteral(node.value);
77
+ }
78
+ if (
79
+ node.value.type === 'JSXExpressionContainer' &&
80
+ node.value.expression.type === 'TemplateLiteral'
81
+ ) {
82
+ return processTemplateLiteral(node.value.expression);
83
+ }
84
+ if (node.value.type === 'TemplateLiteral') {
85
+ return processTemplateLiteral(node.value);
86
+ }
87
+ }
88
+
89
+ // ----------------------------------------------------------------------
90
+ // Public
91
+ // ----------------------------------------------------------------------
92
+
93
+ return {
94
+ JSXIdentifier: function (node) {
95
+ const attrNode = findFormattedMessageAttrNode(node, 'id');
96
+ if (attrNode) {
97
+ return processAttrNode(attrNode);
98
+ }
99
+ },
100
+ CallExpression: function (node) {
101
+ const attrNode = findFormatMessageAttrNode(node, 'id');
102
+ if (attrNode) {
103
+ return processAttrNode(attrNode);
104
+ }
105
+ },
106
+ Property: function (node) {
107
+ const attrNode =
108
+ findAttrNodeInDefineMessages(node, 'id') ||
109
+ findAttrNodeInDefineMessage(node, 'id');
110
+ if (attrNode) {
111
+ return processAttrNode(attrNode);
112
+ }
113
+ },
114
+ 'Program:exit': function () {
115
+ // 将usedIdSet转为数组,然后与translatedIds取差集,即为未使用的id
116
+ const unusedIds = [...translatedIdSet].filter(id => !usedIdSet.has(id));
117
+ // 在项目目录下生成intl-unused.json
118
+ const jsonPath = path.join(projectRoot, 'intl-unused.json');
119
+ fs.writeFileSync(jsonPath, JSON.stringify(unusedIds, null, 2));
120
+ }
121
+ };
122
+ }
123
+ };
@@ -1,63 +1,63 @@
1
- const {
2
- findFormatMessageAttrNode,
3
- findFormattedMessageAttrNode,
4
- findAttrNodeInDefineMessages,
5
- findAttrNodeInDefineMessage
6
- } = require('../../util/intl');
7
-
8
- // ------------------------------------------------------------------------------
9
- // Rule Definition
10
- // ------------------------------------------------------------------------------
11
-
12
- module.exports = {
13
- meta: {
14
- docs: {
15
- description: 'Validates defaultMessage is not used with react-intl',
16
- category: 'Intl',
17
- recommended: true
18
- },
19
- fixable: null,
20
- schema: []
21
- },
22
-
23
- create: function (context) {
24
- // ----------------------------------------------------------------------
25
- // Helpers
26
- // ----------------------------------------------------------------------
27
-
28
- function processAttrNode(node) {
29
- context.report({
30
- node: node,
31
- message: 'Do not use defaultMessage'
32
- });
33
- }
34
-
35
- // ----------------------------------------------------------------------
36
- // Public
37
- // ----------------------------------------------------------------------
38
-
39
- return {
40
- JSXIdentifier: function (node) {
41
- const attrNode = findFormattedMessageAttrNode(node, 'defaultMessage');
42
- if (attrNode) {
43
- return processAttrNode(attrNode);
44
- }
45
- },
46
- CallExpression: function (node) {
47
- const attrNode = findFormatMessageAttrNode(node, 'defaultMessage');
48
- if (attrNode) {
49
- return processAttrNode(attrNode);
50
- }
51
- },
52
- Property: function (node) {
53
- const attrNode =
54
- findAttrNodeInDefineMessages(node, 'defaultMessage') ||
55
- findAttrNodeInDefineMessage(node, 'defaultMessage');
56
-
57
- if (attrNode) {
58
- return processAttrNode(attrNode);
59
- }
60
- }
61
- };
62
- }
63
- };
1
+ const {
2
+ findFormatMessageAttrNode,
3
+ findFormattedMessageAttrNode,
4
+ findAttrNodeInDefineMessages,
5
+ findAttrNodeInDefineMessage
6
+ } = require('../../util/intl');
7
+
8
+ // ------------------------------------------------------------------------------
9
+ // Rule Definition
10
+ // ------------------------------------------------------------------------------
11
+
12
+ module.exports = {
13
+ meta: {
14
+ docs: {
15
+ description: 'Validates defaultMessage is not used with react-intl',
16
+ category: 'Intl',
17
+ recommended: true
18
+ },
19
+ fixable: null,
20
+ schema: []
21
+ },
22
+
23
+ create: function (context) {
24
+ // ----------------------------------------------------------------------
25
+ // Helpers
26
+ // ----------------------------------------------------------------------
27
+
28
+ function processAttrNode(node) {
29
+ context.report({
30
+ node: node,
31
+ message: 'Do not use defaultMessage'
32
+ });
33
+ }
34
+
35
+ // ----------------------------------------------------------------------
36
+ // Public
37
+ // ----------------------------------------------------------------------
38
+
39
+ return {
40
+ JSXIdentifier: function (node) {
41
+ const attrNode = findFormattedMessageAttrNode(node, 'defaultMessage');
42
+ if (attrNode) {
43
+ return processAttrNode(attrNode);
44
+ }
45
+ },
46
+ CallExpression: function (node) {
47
+ const attrNode = findFormatMessageAttrNode(node, 'defaultMessage');
48
+ if (attrNode) {
49
+ return processAttrNode(attrNode);
50
+ }
51
+ },
52
+ Property: function (node) {
53
+ const attrNode =
54
+ findAttrNodeInDefineMessages(node, 'defaultMessage') ||
55
+ findAttrNodeInDefineMessage(node, 'defaultMessage');
56
+
57
+ if (attrNode) {
58
+ return processAttrNode(attrNode);
59
+ }
60
+ }
61
+ };
62
+ }
63
+ };
@@ -1,38 +1,38 @@
1
- module.exports = {
2
- meta: {
3
- type: 'problem',
4
- docs: {
5
- description: 'Check if a template string contains only one ${}',
6
- recommended: true
7
- },
8
- fixable: 'code', // Or `code` or `whitespace`
9
- schema: [] // Add a schema if the rule has options
10
- },
11
-
12
- create(context) {
13
- return {
14
- TemplateLiteral(node) {
15
- // Get the entire source code of the template string
16
- const code = context.getSourceCode().getText(node);
17
- // Check if the template string contains only one `${}`
18
- if (
19
- code.startsWith('`${') &&
20
- code.endsWith('}`') &&
21
- code.split('${').length === 2
22
- ) {
23
- context.report({
24
- node,
25
- message: 'Unnecessary template string with only one ${}.',
26
- fix(fixer) {
27
- // Replace the entire template string with the content inside ${}
28
- return fixer.replaceText(
29
- node,
30
- code.substring(3, code.length - 2)
31
- );
32
- }
33
- });
34
- }
35
- }
36
- };
37
- }
38
- };
1
+ module.exports = {
2
+ meta: {
3
+ type: 'problem',
4
+ docs: {
5
+ description: 'Check if a template string contains only one ${}',
6
+ recommended: true
7
+ },
8
+ fixable: 'code', // Or `code` or `whitespace`
9
+ schema: [] // Add a schema if the rule has options
10
+ },
11
+
12
+ create(context) {
13
+ return {
14
+ TemplateLiteral(node) {
15
+ // Get the entire source code of the template string
16
+ const code = context.getSourceCode().getText(node);
17
+ // Check if the template string contains only one `${}`
18
+ if (
19
+ code.startsWith('`${') &&
20
+ code.endsWith('}`') &&
21
+ code.split('${').length === 2
22
+ ) {
23
+ context.report({
24
+ node,
25
+ message: 'Unnecessary template string with only one ${}.',
26
+ fix(fixer) {
27
+ // Replace the entire template string with the content inside ${}
28
+ return fixer.replaceText(
29
+ node,
30
+ code.substring(3, code.length - 2)
31
+ );
32
+ }
33
+ });
34
+ }
35
+ }
36
+ };
37
+ }
38
+ };