eslint-plugin-formatjs 4.3.9 → 4.4.0
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/index.d.ts +2 -1
- package/index.d.ts.map +1 -1
- package/index.js +4 -2
- package/package.json +1 -1
- package/rules/no-literal-string-in-jsx.d.ts.map +1 -1
- package/rules/no-literal-string-in-jsx.js +19 -15
- package/rules/no-useless-message.d.ts +4 -0
- package/rules/no-useless-message.d.ts.map +1 -0
- package/rules/no-useless-message.js +89 -0
package/index.d.ts
CHANGED
|
@@ -10,11 +10,12 @@ declare const plugin: {
|
|
|
10
10
|
'no-complex-selectors': import("eslint").Rule.RuleModule;
|
|
11
11
|
'no-emoji': import("eslint").Rule.RuleModule;
|
|
12
12
|
'no-id': import("eslint").Rule.RuleModule;
|
|
13
|
+
'no-invalid-icu': import("eslint").Rule.RuleModule;
|
|
13
14
|
'no-literal-string-in-jsx': import("eslint").Rule.RuleModule;
|
|
14
15
|
'no-multiple-plurals': import("eslint").Rule.RuleModule;
|
|
15
16
|
'no-multiple-whitespaces': import("eslint").Rule.RuleModule;
|
|
16
|
-
'no-invalid-icu': import("eslint").Rule.RuleModule;
|
|
17
17
|
'no-offset': import("eslint").Rule.RuleModule;
|
|
18
|
+
'no-useless-message': import("eslint").Rule.RuleModule;
|
|
18
19
|
};
|
|
19
20
|
};
|
|
20
21
|
export type Plugin = typeof plugin;
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAiBA,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;CAmBX,CAAA;AAED,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAA"}
|
package/index.js
CHANGED
|
@@ -16,6 +16,7 @@ const no_multiple_plurals_1 = tslib_1.__importDefault(require("./rules/no-multip
|
|
|
16
16
|
const no_multiple_whitespaces_1 = tslib_1.__importDefault(require("./rules/no-multiple-whitespaces"));
|
|
17
17
|
const no_offset_1 = tslib_1.__importDefault(require("./rules/no-offset"));
|
|
18
18
|
const no_literal_string_in_jsx_1 = tslib_1.__importDefault(require("./rules/no-literal-string-in-jsx"));
|
|
19
|
+
const no_useless_message_1 = tslib_1.__importDefault(require("./rules/no-useless-message"));
|
|
19
20
|
const plugin = {
|
|
20
21
|
rules: {
|
|
21
22
|
'blocklist-elements': blocklist_elements_1.default,
|
|
@@ -28,11 +29,12 @@ const plugin = {
|
|
|
28
29
|
'no-complex-selectors': no_complex_selectors_1.default,
|
|
29
30
|
'no-emoji': no_emoji_1.default,
|
|
30
31
|
'no-id': no_id_1.default,
|
|
32
|
+
'no-invalid-icu': no_invalid_icu_1.default,
|
|
31
33
|
'no-literal-string-in-jsx': no_literal_string_in_jsx_1.default,
|
|
32
34
|
'no-multiple-plurals': no_multiple_plurals_1.default,
|
|
33
35
|
'no-multiple-whitespaces': no_multiple_whitespaces_1.default,
|
|
34
|
-
'no-invalid-icu': no_invalid_icu_1.default,
|
|
35
36
|
'no-offset': no_offset_1.default,
|
|
36
|
-
|
|
37
|
+
'no-useless-message': no_useless_message_1.default
|
|
38
|
+
}
|
|
37
39
|
};
|
|
38
40
|
module.exports = plugin;
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-literal-string-in-jsx.d.ts","sourceRoot":"","sources":["no-literal-string-in-jsx.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAqDhC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"no-literal-string-in-jsx.d.ts","sourceRoot":"","sources":["no-literal-string-in-jsx.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAqDhC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAuKhB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -7,8 +7,8 @@ const propMatcherSchema = {
|
|
|
7
7
|
type: 'array',
|
|
8
8
|
items: {
|
|
9
9
|
type: 'array',
|
|
10
|
-
items: [{ type: 'string' }, { type: 'string' }]
|
|
11
|
-
}
|
|
10
|
+
items: [{ type: 'string' }, { type: 'string' }]
|
|
11
|
+
}
|
|
12
12
|
};
|
|
13
13
|
const defaultPropIncludePattern = [
|
|
14
14
|
['*', 'aria-{label,description,details,errormessage}'],
|
|
@@ -41,7 +41,7 @@ const rule = {
|
|
|
41
41
|
description: 'Disallow untranslated literal strings without translation.',
|
|
42
42
|
category: 'Errors',
|
|
43
43
|
recommended: false,
|
|
44
|
-
url: 'https://formatjs.io/docs/tooling/linter#no-literal-string-in-jsx'
|
|
44
|
+
url: 'https://formatjs.io/docs/tooling/linter#no-literal-string-in-jsx'
|
|
45
45
|
},
|
|
46
46
|
schema: [
|
|
47
47
|
{
|
|
@@ -51,16 +51,16 @@ const rule = {
|
|
|
51
51
|
type: 'object',
|
|
52
52
|
properties: {
|
|
53
53
|
include: {
|
|
54
|
-
...propMatcherSchema
|
|
54
|
+
...propMatcherSchema
|
|
55
55
|
},
|
|
56
56
|
exclude: {
|
|
57
|
-
...propMatcherSchema
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
57
|
+
...propMatcherSchema
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
62
|
},
|
|
63
|
-
]
|
|
63
|
+
]
|
|
64
64
|
},
|
|
65
65
|
// TODO: Vue support
|
|
66
66
|
create(context) {
|
|
@@ -109,13 +109,17 @@ const rule = {
|
|
|
109
109
|
(node.quasis.length > 1 || node.quasis[0].value.raw.length > 0))) {
|
|
110
110
|
context.report({
|
|
111
111
|
node: node,
|
|
112
|
-
message: 'Cannot have untranslated text in JSX'
|
|
112
|
+
message: 'Cannot have untranslated text in JSX'
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
else if (node.type === 'BinaryExpression' && node.operator === '+') {
|
|
116
116
|
checkJSXExpression(node.left);
|
|
117
117
|
checkJSXExpression(node.right);
|
|
118
118
|
}
|
|
119
|
+
else if (node.type === 'ConditionalExpression') {
|
|
120
|
+
checkJSXExpression(node.consequent);
|
|
121
|
+
checkJSXExpression(node.alternate);
|
|
122
|
+
}
|
|
119
123
|
};
|
|
120
124
|
return {
|
|
121
125
|
JSXElement: (node) => {
|
|
@@ -142,7 +146,7 @@ const rule = {
|
|
|
142
146
|
node.value.value.length > 0) {
|
|
143
147
|
context.report({
|
|
144
148
|
node: node,
|
|
145
|
-
message: 'Cannot have untranslated text in JSX'
|
|
149
|
+
message: 'Cannot have untranslated text in JSX'
|
|
146
150
|
});
|
|
147
151
|
}
|
|
148
152
|
else if (node.value.type === 'JSXExpressionContainer' &&
|
|
@@ -157,7 +161,7 @@ const rule = {
|
|
|
157
161
|
}
|
|
158
162
|
context.report({
|
|
159
163
|
node: node,
|
|
160
|
-
message: 'Cannot have untranslated text in JSX'
|
|
164
|
+
message: 'Cannot have untranslated text in JSX'
|
|
161
165
|
});
|
|
162
166
|
},
|
|
163
167
|
// Children expression container
|
|
@@ -165,8 +169,8 @@ const rule = {
|
|
|
165
169
|
if (node.expression.type !== 'JSXEmptyExpression') {
|
|
166
170
|
checkJSXExpression(node.expression);
|
|
167
171
|
}
|
|
168
|
-
}
|
|
172
|
+
}
|
|
169
173
|
};
|
|
170
|
-
}
|
|
174
|
+
}
|
|
171
175
|
};
|
|
172
176
|
exports.default = rule;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-useless-message.d.ts","sourceRoot":"","sources":["no-useless-message.ts"],"names":[],"mappings":"AAMA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAmE3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA6BhB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
|
+
const util_1 = require("../util");
|
|
5
|
+
class JustArgument extends Error {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.message = 'Unnecessary formatted message.';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
class JustNumber extends Error {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.message = 'Unnecessary formatted message: just use FormattedNumber or intl.formatNumber.';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class JustDate extends Error {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.message = 'Unnecessary formatted message: just use FormattedDate or intl.formatDate.';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
class JustTime extends Error {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
this.message = 'Unnecessary formatted message: just use FormattedTime or intl.formatTime.';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function verifyAst(ast) {
|
|
30
|
+
if (ast.length !== 1) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
switch (ast[0].type) {
|
|
34
|
+
case icu_messageformat_parser_1.TYPE.argument:
|
|
35
|
+
throw new JustArgument();
|
|
36
|
+
case icu_messageformat_parser_1.TYPE.number:
|
|
37
|
+
throw new JustNumber();
|
|
38
|
+
case icu_messageformat_parser_1.TYPE.date:
|
|
39
|
+
throw new JustDate();
|
|
40
|
+
case icu_messageformat_parser_1.TYPE.time:
|
|
41
|
+
throw new JustTime();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function checkNode(context, node) {
|
|
45
|
+
const settings = (0, util_1.getSettings)(context);
|
|
46
|
+
const msgs = (0, util_1.extractMessages)(node, settings);
|
|
47
|
+
for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
|
|
48
|
+
if (!defaultMessage || !messageNode) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
53
|
+
ignoreTag: settings.ignoreTag
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
context.report({
|
|
58
|
+
node: messageNode,
|
|
59
|
+
message: e instanceof Error ? e.message : String(e)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const rule = {
|
|
65
|
+
meta: {
|
|
66
|
+
type: 'problem',
|
|
67
|
+
docs: {
|
|
68
|
+
description: 'Disallow unnecessary formatted message',
|
|
69
|
+
recommended: true,
|
|
70
|
+
url: 'https://formatjs.io/docs/tooling/linter#no-useless-message'
|
|
71
|
+
},
|
|
72
|
+
fixable: 'code'
|
|
73
|
+
},
|
|
74
|
+
create(context) {
|
|
75
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
76
|
+
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
77
|
+
return context.parserServices.defineTemplateBodyVisitor({
|
|
78
|
+
CallExpression: callExpressionVisitor
|
|
79
|
+
}, {
|
|
80
|
+
CallExpression: callExpressionVisitor
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
85
|
+
CallExpression: callExpressionVisitor
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
exports.default = rule;
|