eslint-plugin-formatjs 4.0.2 → 4.2.2
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/LICENSE.md +0 -0
- package/README.md +0 -0
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +18 -16
- package/package.json +4 -4
- package/rules/blocklist-elements.d.ts +0 -0
- package/rules/blocklist-elements.d.ts.map +1 -1
- package/rules/blocklist-elements.js +19 -27
- package/rules/enforce-default-message.d.ts +0 -0
- package/rules/enforce-default-message.d.ts.map +1 -1
- package/rules/enforce-default-message.js +11 -12
- package/rules/enforce-description.d.ts +0 -0
- package/rules/enforce-description.d.ts.map +1 -1
- package/rules/enforce-description.js +7 -10
- package/rules/enforce-id.d.ts +0 -0
- package/rules/enforce-id.d.ts.map +1 -1
- package/rules/enforce-id.js +35 -44
- package/rules/enforce-placeholders.d.ts +0 -0
- package/rules/enforce-placeholders.d.ts.map +1 -1
- package/rules/enforce-placeholders.js +26 -31
- package/rules/enforce-plural-rules.d.ts +0 -0
- package/rules/enforce-plural-rules.d.ts.map +1 -1
- package/rules/enforce-plural-rules.js +26 -35
- package/rules/no-camel-case.d.ts +0 -0
- package/rules/no-camel-case.d.ts.map +1 -1
- package/rules/no-camel-case.js +19 -27
- package/rules/no-complex-selectors.d.ts +0 -0
- package/rules/no-complex-selectors.d.ts.map +1 -1
- package/rules/no-complex-selectors.js +32 -24
- package/rules/no-emoji.d.ts +0 -0
- package/rules/no-emoji.d.ts.map +1 -1
- package/rules/no-emoji.js +10 -13
- package/rules/no-id.d.ts +0 -0
- package/rules/no-id.d.ts.map +1 -1
- package/rules/no-id.js +11 -17
- package/rules/no-invalid-icu.d.ts +4 -0
- package/rules/no-invalid-icu.d.ts.map +1 -0
- package/rules/no-invalid-icu.js +54 -0
- package/rules/no-literal-string-in-jsx.d.ts +0 -0
- package/rules/no-literal-string-in-jsx.d.ts.map +1 -1
- package/rules/no-literal-string-in-jsx.js +41 -35
- package/rules/no-multiple-plurals.d.ts +0 -0
- package/rules/no-multiple-plurals.d.ts.map +1 -1
- package/rules/no-multiple-plurals.js +19 -28
- package/rules/no-multiple-whitespaces.d.ts +0 -0
- package/rules/no-multiple-whitespaces.d.ts.map +1 -1
- package/rules/no-multiple-whitespaces.js +24 -37
- package/rules/no-offset.d.ts +0 -0
- package/rules/no-offset.d.ts.map +1 -1
- package/rules/no-offset.js +18 -26
- package/util.d.ts +2 -0
- package/util.d.ts.map +1 -1
- package/util.js +45 -43
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var _this = _super.call(this) || this;
|
|
10
|
-
_this.message = message;
|
|
11
|
-
return _this;
|
|
3
|
+
const util_1 = require("../util");
|
|
4
|
+
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
5
|
+
class PluralRulesEnforcement extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super();
|
|
8
|
+
this.message = message;
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
}(Error));
|
|
10
|
+
}
|
|
15
11
|
var LDML;
|
|
16
12
|
(function (LDML) {
|
|
17
13
|
LDML["zero"] = "zero";
|
|
@@ -22,44 +18,41 @@ var LDML;
|
|
|
22
18
|
LDML["other"] = "other";
|
|
23
19
|
})(LDML || (LDML = {}));
|
|
24
20
|
function verifyAst(plConfig, ast) {
|
|
25
|
-
for (
|
|
26
|
-
var el = ast_1[_i];
|
|
21
|
+
for (const el of ast) {
|
|
27
22
|
if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
|
|
28
|
-
|
|
29
|
-
for (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
throw new PluralRulesEnforcement("Missing plural rule \"".concat(rule_1, "\""));
|
|
23
|
+
const rules = Object.keys(plConfig);
|
|
24
|
+
for (const rule of rules) {
|
|
25
|
+
if (plConfig[rule] && !el.options[rule]) {
|
|
26
|
+
throw new PluralRulesEnforcement(`Missing plural rule "${rule}"`);
|
|
33
27
|
}
|
|
34
|
-
if (!plConfig[
|
|
35
|
-
throw new PluralRulesEnforcement(
|
|
28
|
+
if (!plConfig[rule] && el.options[rule]) {
|
|
29
|
+
throw new PluralRulesEnforcement(`Plural rule "${rule}" is forbidden`);
|
|
36
30
|
}
|
|
37
31
|
}
|
|
38
|
-
|
|
39
|
-
for (
|
|
40
|
-
var selector = _c[_b];
|
|
32
|
+
const { options } = el;
|
|
33
|
+
for (const selector of Object.keys(options)) {
|
|
41
34
|
verifyAst(plConfig, options[selector].value);
|
|
42
35
|
}
|
|
43
36
|
}
|
|
44
37
|
}
|
|
45
38
|
}
|
|
46
39
|
function checkNode(context, node) {
|
|
47
|
-
|
|
40
|
+
const settings = (0, util_1.getSettings)(context);
|
|
41
|
+
const msgs = (0, util_1.extractMessages)(node, settings);
|
|
48
42
|
if (!msgs.length) {
|
|
49
43
|
return;
|
|
50
44
|
}
|
|
51
|
-
|
|
45
|
+
const plConfig = context.options[0];
|
|
52
46
|
if (!plConfig) {
|
|
53
47
|
return;
|
|
54
48
|
}
|
|
55
|
-
for (
|
|
56
|
-
var _a = msgs_1[_i][0], defaultMessage = _a.message.defaultMessage, messageNode = _a.messageNode;
|
|
49
|
+
for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
|
|
57
50
|
if (!defaultMessage || !messageNode) {
|
|
58
51
|
continue;
|
|
59
52
|
}
|
|
60
53
|
try {
|
|
61
54
|
verifyAst(context.options[0], (0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
62
|
-
ignoreTag:
|
|
55
|
+
ignoreTag: settings.ignoreTag,
|
|
63
56
|
}));
|
|
64
57
|
}
|
|
65
58
|
catch (e) {
|
|
@@ -70,7 +63,7 @@ function checkNode(context, node) {
|
|
|
70
63
|
}
|
|
71
64
|
}
|
|
72
65
|
}
|
|
73
|
-
|
|
66
|
+
const rule = {
|
|
74
67
|
meta: {
|
|
75
68
|
type: 'problem',
|
|
76
69
|
docs: {
|
|
@@ -83,7 +76,7 @@ var rule = {
|
|
|
83
76
|
schema: [
|
|
84
77
|
{
|
|
85
78
|
type: 'object',
|
|
86
|
-
properties: Object.keys(LDML).reduce(
|
|
79
|
+
properties: Object.keys(LDML).reduce((schema, k) => {
|
|
87
80
|
schema[k] = {
|
|
88
81
|
type: 'boolean',
|
|
89
82
|
};
|
|
@@ -93,10 +86,8 @@ var rule = {
|
|
|
93
86
|
},
|
|
94
87
|
],
|
|
95
88
|
},
|
|
96
|
-
create
|
|
97
|
-
|
|
98
|
-
return checkNode(context, node);
|
|
99
|
-
};
|
|
89
|
+
create(context) {
|
|
90
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
100
91
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
101
92
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
102
93
|
CallExpression: callExpressionVisitor,
|
|
@@ -105,7 +96,7 @@ var rule = {
|
|
|
105
96
|
});
|
|
106
97
|
}
|
|
107
98
|
return {
|
|
108
|
-
JSXOpeningElement:
|
|
99
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
109
100
|
CallExpression: callExpressionVisitor,
|
|
110
101
|
};
|
|
111
102
|
},
|
package/rules/no-camel-case.d.ts
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-camel-case.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"no-camel-case.d.ts","sourceRoot":"","sources":["no-camel-case.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAgE3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA8BhB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
package/rules/no-camel-case.js
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
11
|
-
_this.message = 'Camel case arguments are not allowed';
|
|
12
|
-
return _this;
|
|
3
|
+
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
|
+
const util_1 = require("../util");
|
|
5
|
+
const CAMEL_CASE_REGEX = /[A-Z]/;
|
|
6
|
+
class CamelCase extends Error {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.message = 'Camel case arguments are not allowed';
|
|
13
10
|
}
|
|
14
|
-
|
|
15
|
-
}(Error));
|
|
11
|
+
}
|
|
16
12
|
function verifyAst(ast) {
|
|
17
|
-
for (
|
|
18
|
-
var el = ast_1[_i];
|
|
13
|
+
for (const el of ast) {
|
|
19
14
|
if ((0, icu_messageformat_parser_1.isArgumentElement)(el)) {
|
|
20
15
|
if (CAMEL_CASE_REGEX.test(el.value)) {
|
|
21
16
|
throw new CamelCase();
|
|
@@ -26,24 +21,23 @@ function verifyAst(ast) {
|
|
|
26
21
|
if (CAMEL_CASE_REGEX.test(el.value)) {
|
|
27
22
|
throw new CamelCase();
|
|
28
23
|
}
|
|
29
|
-
|
|
30
|
-
for (
|
|
31
|
-
var selector = _b[_a];
|
|
24
|
+
const { options } = el;
|
|
25
|
+
for (const selector of Object.keys(options)) {
|
|
32
26
|
verifyAst(options[selector].value);
|
|
33
27
|
}
|
|
34
28
|
}
|
|
35
29
|
}
|
|
36
30
|
}
|
|
37
31
|
function checkNode(context, node) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
const settings = (0, util_1.getSettings)(context);
|
|
33
|
+
const msgs = (0, util_1.extractMessages)(node, settings);
|
|
34
|
+
for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
|
|
41
35
|
if (!defaultMessage || !messageNode) {
|
|
42
36
|
continue;
|
|
43
37
|
}
|
|
44
38
|
try {
|
|
45
39
|
verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
46
|
-
ignoreTag:
|
|
40
|
+
ignoreTag: settings.ignoreTag,
|
|
47
41
|
}));
|
|
48
42
|
}
|
|
49
43
|
catch (e) {
|
|
@@ -54,7 +48,7 @@ function checkNode(context, node) {
|
|
|
54
48
|
}
|
|
55
49
|
}
|
|
56
50
|
}
|
|
57
|
-
|
|
51
|
+
const rule = {
|
|
58
52
|
meta: {
|
|
59
53
|
type: 'problem',
|
|
60
54
|
docs: {
|
|
@@ -65,10 +59,8 @@ var rule = {
|
|
|
65
59
|
},
|
|
66
60
|
fixable: 'code',
|
|
67
61
|
},
|
|
68
|
-
create
|
|
69
|
-
|
|
70
|
-
return checkNode(context, node);
|
|
71
|
-
};
|
|
62
|
+
create(context) {
|
|
63
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
72
64
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
73
65
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
74
66
|
CallExpression: callExpressionVisitor,
|
|
@@ -77,7 +69,7 @@ var rule = {
|
|
|
77
69
|
});
|
|
78
70
|
}
|
|
79
71
|
return {
|
|
80
|
-
JSXOpeningElement:
|
|
72
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
81
73
|
CallExpression: callExpressionVisitor,
|
|
82
74
|
};
|
|
83
75
|
},
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-complex-selectors.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"no-complex-selectors.d.ts","sourceRoot":"","sources":["no-complex-selectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAyE3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAiDhB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var manipulator_1 = require("@formatjs/icu-messageformat-parser/manipulator");
|
|
3
|
+
const util_1 = require("../util");
|
|
4
|
+
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
5
|
+
const manipulator_1 = require("@formatjs/icu-messageformat-parser/manipulator");
|
|
7
6
|
function calculateComplexity(ast) {
|
|
8
7
|
if (ast.length === 1) {
|
|
9
|
-
|
|
10
|
-
if ((0, icu_messageformat_parser_1.isPluralElement)(
|
|
11
|
-
return Object.keys(
|
|
12
|
-
return complexity + calculateComplexity(
|
|
8
|
+
const el = ast[0];
|
|
9
|
+
if ((0, icu_messageformat_parser_1.isPluralElement)(el) || (0, icu_messageformat_parser_1.isSelectElement)(el)) {
|
|
10
|
+
return Object.keys(el.options).reduce((complexity, k) => {
|
|
11
|
+
return complexity + calculateComplexity(el.options[k].value);
|
|
13
12
|
}, 0);
|
|
14
13
|
}
|
|
15
14
|
}
|
|
16
15
|
return 1;
|
|
17
16
|
}
|
|
18
17
|
function checkNode(context, node) {
|
|
19
|
-
|
|
18
|
+
const settings = (0, util_1.getSettings)(context);
|
|
19
|
+
const msgs = (0, util_1.extractMessages)(node, settings);
|
|
20
20
|
if (!msgs.length) {
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
const config = {
|
|
24
|
+
limit: 20,
|
|
25
|
+
...(context.options[0] || {}),
|
|
26
|
+
};
|
|
27
|
+
for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
|
|
26
28
|
if (!defaultMessage || !messageNode) {
|
|
27
29
|
continue;
|
|
28
30
|
}
|
|
29
|
-
|
|
31
|
+
let ast;
|
|
30
32
|
try {
|
|
31
33
|
ast = (0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
32
|
-
ignoreTag:
|
|
34
|
+
ignoreTag: settings.ignoreTag,
|
|
33
35
|
});
|
|
34
36
|
}
|
|
35
37
|
catch (e) {
|
|
@@ -39,21 +41,29 @@ function checkNode(context, node) {
|
|
|
39
41
|
});
|
|
40
42
|
return;
|
|
41
43
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
const hoistedAst = (0, manipulator_1.hoistSelectors)(ast);
|
|
45
|
+
const complexity = calculateComplexity(hoistedAst);
|
|
44
46
|
if (complexity > config.limit) {
|
|
45
47
|
context.report({
|
|
46
48
|
node: messageNode,
|
|
47
|
-
message:
|
|
49
|
+
message: `Message complexity is too high (${complexity} vs limit at ${config.limit})`,
|
|
48
50
|
});
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
|
-
|
|
54
|
+
const rule = {
|
|
53
55
|
meta: {
|
|
54
56
|
type: 'problem',
|
|
55
57
|
docs: {
|
|
56
|
-
description:
|
|
58
|
+
description: `Make sure a sentence is not too complex.
|
|
59
|
+
Complexity is determined by how many strings are produced when we try to
|
|
60
|
+
flatten the sentence given its selectors. For example:
|
|
61
|
+
"I have {count, plural, one{a dog} other{many dogs}}"
|
|
62
|
+
has the complexity of 2 because flattening the plural selector
|
|
63
|
+
results in 2 sentences: "I have a dog" & "I have many dogs".
|
|
64
|
+
Default complexity limit is 20
|
|
65
|
+
(using Smartling as a reference: https://help.smartling.com/hc/en-us/articles/360008030994-ICU-MessageFormat)
|
|
66
|
+
`,
|
|
57
67
|
category: 'Errors',
|
|
58
68
|
recommended: false,
|
|
59
69
|
url: 'https://formatjs.io/docs/tooling/linter#no-complex-selectors',
|
|
@@ -71,10 +81,8 @@ var rule = {
|
|
|
71
81
|
],
|
|
72
82
|
fixable: 'code',
|
|
73
83
|
},
|
|
74
|
-
create
|
|
75
|
-
|
|
76
|
-
return checkNode(context, node);
|
|
77
|
-
};
|
|
84
|
+
create(context) {
|
|
85
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
78
86
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
79
87
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
80
88
|
CallExpression: callExpressionVisitor,
|
|
@@ -83,7 +91,7 @@ var rule = {
|
|
|
83
91
|
});
|
|
84
92
|
}
|
|
85
93
|
return {
|
|
86
|
-
JSXOpeningElement:
|
|
94
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
87
95
|
CallExpression: callExpressionVisitor,
|
|
88
96
|
};
|
|
89
97
|
},
|
package/rules/no-emoji.d.ts
CHANGED
|
File without changes
|
package/rules/no-emoji.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-emoji.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"no-emoji.d.ts","sourceRoot":"","sources":["no-emoji.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AA2B3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA8BhB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
package/rules/no-emoji.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const util_1 = require("../util");
|
|
5
|
+
const emoji_regex_1 = tslib_1.__importDefault(require("emoji-regex"));
|
|
6
|
+
const EMOJI_REGEX = emoji_regex_1.default();
|
|
7
7
|
function checkNode(context, node) {
|
|
8
|
-
|
|
9
|
-
for (
|
|
10
|
-
var _a = msgs_1[_i][0], defaultMessage = _a.message.defaultMessage, messageNode = _a.messageNode;
|
|
8
|
+
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
|
|
9
|
+
for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
|
|
11
10
|
if (!defaultMessage || !messageNode) {
|
|
12
11
|
continue;
|
|
13
12
|
}
|
|
@@ -19,7 +18,7 @@ function checkNode(context, node) {
|
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
20
|
}
|
|
22
|
-
|
|
21
|
+
const rule = {
|
|
23
22
|
meta: {
|
|
24
23
|
type: 'problem',
|
|
25
24
|
docs: {
|
|
@@ -30,10 +29,8 @@ var rule = {
|
|
|
30
29
|
},
|
|
31
30
|
fixable: 'code',
|
|
32
31
|
},
|
|
33
|
-
create
|
|
34
|
-
|
|
35
|
-
return checkNode(context, node);
|
|
36
|
-
};
|
|
32
|
+
create(context) {
|
|
33
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
37
34
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
38
35
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
39
36
|
CallExpression: callExpressionVisitor,
|
|
@@ -42,7 +39,7 @@ var rule = {
|
|
|
42
39
|
});
|
|
43
40
|
}
|
|
44
41
|
return {
|
|
45
|
-
JSXOpeningElement:
|
|
42
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
46
43
|
CallExpression: callExpressionVisitor,
|
|
47
44
|
};
|
|
48
45
|
},
|
package/rules/no-id.d.ts
CHANGED
|
File without changes
|
package/rules/no-id.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-id.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"no-id.d.ts","sourceRoot":"","sources":["no-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAa,MAAM,QAAQ,CAAA;;AAgCvC,wBA8BoB"}
|
package/rules/no-id.js
CHANGED
|
@@ -1,31 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
const util_1 = require("../util");
|
|
4
4
|
function isComment(token) {
|
|
5
5
|
return !!token && (token.type === 'Block' || token.type === 'Line');
|
|
6
6
|
}
|
|
7
7
|
function checkNode(context, node) {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
|
|
9
|
+
for (const [{ idPropNode }] of msgs) {
|
|
10
10
|
if (idPropNode) {
|
|
11
11
|
context.report({
|
|
12
12
|
node: idPropNode,
|
|
13
13
|
message: 'Manual `id` are not allowed in message descriptor',
|
|
14
|
-
fix
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (token && !isComment(token) &&
|
|
14
|
+
fix(fixer) {
|
|
15
|
+
const src = context.getSourceCode();
|
|
16
|
+
const token = src.getTokenAfter(idPropNode);
|
|
17
|
+
const fixes = [fixer.remove(idPropNode)];
|
|
18
|
+
if (token && !isComment(token) && token?.value === ',') {
|
|
19
19
|
fixes.push(fixer.remove(token));
|
|
20
20
|
}
|
|
21
21
|
return fixes;
|
|
22
22
|
},
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
};
|
|
26
|
-
for (var _i = 0, msgs_1 = msgs; _i < msgs_1.length; _i++) {
|
|
27
|
-
var idPropNode = msgs_1[_i][0].idPropNode;
|
|
28
|
-
_loop_1(idPropNode);
|
|
29
25
|
}
|
|
30
26
|
}
|
|
31
27
|
exports.default = {
|
|
@@ -39,10 +35,8 @@ exports.default = {
|
|
|
39
35
|
},
|
|
40
36
|
fixable: 'code',
|
|
41
37
|
},
|
|
42
|
-
create
|
|
43
|
-
|
|
44
|
-
return checkNode(context, node);
|
|
45
|
-
};
|
|
38
|
+
create(context) {
|
|
39
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
46
40
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
47
41
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
48
42
|
CallExpression: callExpressionVisitor,
|
|
@@ -51,7 +45,7 @@ exports.default = {
|
|
|
51
45
|
});
|
|
52
46
|
}
|
|
53
47
|
return {
|
|
54
|
-
JSXOpeningElement:
|
|
48
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
55
49
|
CallExpression: callExpressionVisitor,
|
|
56
50
|
};
|
|
57
51
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-invalid-icu.d.ts","sourceRoot":"","sources":["no-invalid-icu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAqC3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA6BhB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
function checkNode(context, node) {
|
|
6
|
+
const settings = (0, util_1.getSettings)(context);
|
|
7
|
+
const msgs = (0, util_1.extractMessages)(node, settings);
|
|
8
|
+
if (!msgs.length) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
|
|
12
|
+
if (!defaultMessage || !messageNode) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
(0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
17
|
+
ignoreTag: settings.ignoreTag,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
const msg = e instanceof Error ? e.message : e;
|
|
22
|
+
context.report({
|
|
23
|
+
node: messageNode,
|
|
24
|
+
message: `Error parsing ICU string: ${msg}`,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const rule = {
|
|
30
|
+
meta: {
|
|
31
|
+
type: 'problem',
|
|
32
|
+
docs: {
|
|
33
|
+
description: `Make sure ICU messages are formatted correctly with no bad select statements, plurals, etc.`,
|
|
34
|
+
category: 'Errors',
|
|
35
|
+
recommended: true,
|
|
36
|
+
},
|
|
37
|
+
fixable: 'code',
|
|
38
|
+
},
|
|
39
|
+
create(context) {
|
|
40
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
41
|
+
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
42
|
+
return context.parserServices.defineTemplateBodyVisitor({
|
|
43
|
+
CallExpression: callExpressionVisitor,
|
|
44
|
+
}, {
|
|
45
|
+
CallExpression: callExpressionVisitor,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
50
|
+
CallExpression: callExpressionVisitor,
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
exports.default = rule;
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-literal-string-in-jsx.d.ts","sourceRoot":"","sources":["
|
|
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,UA4JhB,CAAA;AAED,eAAe,IAAI,CAAA"}
|