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
package/LICENSE.md
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
File without changes
|
package/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ declare const plugin: {
|
|
|
13
13
|
'no-literal-string-in-jsx': import("eslint").Rule.RuleModule;
|
|
14
14
|
'no-multiple-plurals': import("eslint").Rule.RuleModule;
|
|
15
15
|
'no-multiple-whitespaces': import("eslint").Rule.RuleModule;
|
|
16
|
+
'no-invalid-icu': import("eslint").Rule.RuleModule;
|
|
16
17
|
'no-offset': import("eslint").Rule.RuleModule;
|
|
17
18
|
};
|
|
18
19
|
};
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAeA,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;CAkBX,CAAA;AAED,oBAAY,MAAM,GAAG,OAAO,MAAM,CAAA"}
|
package/index.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const blocklist_elements_1 = tslib_1.__importDefault(require("./rules/blocklist-elements"));
|
|
5
|
+
const enforce_default_message_1 = tslib_1.__importDefault(require("./rules/enforce-default-message"));
|
|
6
|
+
const enforce_description_1 = tslib_1.__importDefault(require("./rules/enforce-description"));
|
|
7
|
+
const enforce_id_1 = tslib_1.__importDefault(require("./rules/enforce-id"));
|
|
8
|
+
const enforce_placeholders_1 = tslib_1.__importDefault(require("./rules/enforce-placeholders"));
|
|
9
|
+
const no_invalid_icu_1 = tslib_1.__importDefault(require("./rules/no-invalid-icu"));
|
|
10
|
+
const enforce_plural_rules_1 = tslib_1.__importDefault(require("./rules/enforce-plural-rules"));
|
|
11
|
+
const no_camel_case_1 = tslib_1.__importDefault(require("./rules/no-camel-case"));
|
|
12
|
+
const no_complex_selectors_1 = tslib_1.__importDefault(require("./rules/no-complex-selectors"));
|
|
13
|
+
const no_emoji_1 = tslib_1.__importDefault(require("./rules/no-emoji"));
|
|
14
|
+
const no_id_1 = tslib_1.__importDefault(require("./rules/no-id"));
|
|
15
|
+
const no_multiple_plurals_1 = tslib_1.__importDefault(require("./rules/no-multiple-plurals"));
|
|
16
|
+
const no_multiple_whitespaces_1 = tslib_1.__importDefault(require("./rules/no-multiple-whitespaces"));
|
|
17
|
+
const no_offset_1 = tslib_1.__importDefault(require("./rules/no-offset"));
|
|
18
|
+
const no_literal_string_in_jsx_1 = tslib_1.__importDefault(require("./rules/no-literal-string-in-jsx"));
|
|
19
|
+
const plugin = {
|
|
19
20
|
rules: {
|
|
20
21
|
'blocklist-elements': blocklist_elements_1.default,
|
|
21
22
|
'enforce-default-message': enforce_default_message_1.default,
|
|
@@ -30,6 +31,7 @@ var plugin = {
|
|
|
30
31
|
'no-literal-string-in-jsx': no_literal_string_in_jsx_1.default,
|
|
31
32
|
'no-multiple-plurals': no_multiple_plurals_1.default,
|
|
32
33
|
'no-multiple-whitespaces': no_multiple_whitespaces_1.default,
|
|
34
|
+
'no-invalid-icu': no_invalid_icu_1.default,
|
|
33
35
|
'no-offset': no_offset_1.default,
|
|
34
36
|
},
|
|
35
37
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-formatjs",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.2",
|
|
4
4
|
"description": "ESLint plugin for formatjs",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
"homepage": "https://github.com/formatjs/formatjs#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@formatjs/icu-messageformat-parser": "2.1.
|
|
24
|
-
"@formatjs/ts-transformer": "3.9.
|
|
23
|
+
"@formatjs/icu-messageformat-parser": "2.1.6",
|
|
24
|
+
"@formatjs/ts-transformer": "3.9.11",
|
|
25
25
|
"@types/eslint": "7 || 8",
|
|
26
26
|
"@types/picomatch": "^2.3.0",
|
|
27
27
|
"@typescript-eslint/typescript-estree": "^5.9.1",
|
|
@@ -33,4 +33,4 @@
|
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"eslint": "7 || 8"
|
|
35
35
|
}
|
|
36
|
-
}
|
|
36
|
+
}
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocklist-elements.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"blocklist-elements.d.ts","sourceRoot":"","sources":["blocklist-elements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAmH3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAyChB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -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 = "".concat(type, " element is blocklisted");
|
|
11
|
-
return _this;
|
|
3
|
+
const util_1 = require("../util");
|
|
4
|
+
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
5
|
+
class BlacklistElement extends Error {
|
|
6
|
+
constructor(type) {
|
|
7
|
+
super();
|
|
8
|
+
this.message = `${type} element is blocklisted`;
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
}(Error));
|
|
10
|
+
}
|
|
15
11
|
var Element;
|
|
16
12
|
(function (Element) {
|
|
17
13
|
Element["literal"] = "literal";
|
|
@@ -25,8 +21,7 @@ var Element;
|
|
|
25
21
|
Element["tag"] = "tag";
|
|
26
22
|
})(Element || (Element = {}));
|
|
27
23
|
function verifyAst(blocklist, ast) {
|
|
28
|
-
for (
|
|
29
|
-
var el = ast_1[_i];
|
|
24
|
+
for (const el of ast) {
|
|
30
25
|
if ((0, icu_messageformat_parser_1.isLiteralElement)(el) && blocklist.includes(Element.literal)) {
|
|
31
26
|
throw new BlacklistElement(Element.literal);
|
|
32
27
|
}
|
|
@@ -58,31 +53,30 @@ function verifyAst(blocklist, ast) {
|
|
|
58
53
|
}
|
|
59
54
|
}
|
|
60
55
|
if ((0, icu_messageformat_parser_1.isSelectElement)(el) || (0, icu_messageformat_parser_1.isPluralElement)(el)) {
|
|
61
|
-
|
|
62
|
-
for (
|
|
63
|
-
var selector = _b[_a];
|
|
56
|
+
const { options } = el;
|
|
57
|
+
for (const selector of Object.keys(options)) {
|
|
64
58
|
verifyAst(blocklist, options[selector].value);
|
|
65
59
|
}
|
|
66
60
|
}
|
|
67
61
|
}
|
|
68
62
|
}
|
|
69
63
|
function checkNode(context, node) {
|
|
70
|
-
|
|
64
|
+
const settings = (0, util_1.getSettings)(context);
|
|
65
|
+
const msgs = (0, util_1.extractMessages)(node, settings);
|
|
71
66
|
if (!msgs.length) {
|
|
72
67
|
return;
|
|
73
68
|
}
|
|
74
|
-
|
|
69
|
+
const blocklist = context.options[0];
|
|
75
70
|
if (!Array.isArray(blocklist) || !blocklist.length) {
|
|
76
71
|
return;
|
|
77
72
|
}
|
|
78
|
-
for (
|
|
79
|
-
var _a = msgs_1[_i][0], defaultMessage = _a.message.defaultMessage, messageNode = _a.messageNode;
|
|
73
|
+
for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
|
|
80
74
|
if (!defaultMessage || !messageNode) {
|
|
81
75
|
continue;
|
|
82
76
|
}
|
|
83
77
|
try {
|
|
84
78
|
verifyAst(context.options[0], (0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
85
|
-
ignoreTag:
|
|
79
|
+
ignoreTag: settings.ignoreTag,
|
|
86
80
|
}));
|
|
87
81
|
}
|
|
88
82
|
catch (e) {
|
|
@@ -93,7 +87,7 @@ function checkNode(context, node) {
|
|
|
93
87
|
}
|
|
94
88
|
}
|
|
95
89
|
}
|
|
96
|
-
|
|
90
|
+
const rule = {
|
|
97
91
|
meta: {
|
|
98
92
|
type: 'problem',
|
|
99
93
|
docs: {
|
|
@@ -115,10 +109,8 @@ var rule = {
|
|
|
115
109
|
},
|
|
116
110
|
],
|
|
117
111
|
},
|
|
118
|
-
create
|
|
119
|
-
|
|
120
|
-
return checkNode(context, node);
|
|
121
|
-
};
|
|
112
|
+
create(context) {
|
|
113
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
122
114
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
123
115
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
124
116
|
CallExpression: callExpressionVisitor,
|
|
@@ -127,7 +119,7 @@ var rule = {
|
|
|
127
119
|
});
|
|
128
120
|
}
|
|
129
121
|
return {
|
|
130
|
-
JSXOpeningElement:
|
|
122
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
131
123
|
CallExpression: callExpressionVisitor,
|
|
132
124
|
};
|
|
133
125
|
},
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce-default-message.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"enforce-default-message.d.ts","sourceRoot":"","sources":["enforce-default-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAiC3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAmChB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
const util_1 = require("../util");
|
|
4
4
|
function checkNode(context, node) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
for (
|
|
8
|
-
var _a = msgs_1[_i][0], defaultMessage = _a.message.defaultMessage, messageNode = _a.messageNode;
|
|
5
|
+
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
|
|
6
|
+
const { options: [type], } = context;
|
|
7
|
+
for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
|
|
9
8
|
if (!defaultMessage) {
|
|
10
9
|
if (type === 'literal' && messageNode) {
|
|
11
10
|
context.report({
|
|
12
11
|
node: messageNode,
|
|
13
|
-
message: "
|
|
12
|
+
message: `"defaultMessage" must be:
|
|
13
|
+
- a string literal or
|
|
14
|
+
- template literal without variable`,
|
|
14
15
|
});
|
|
15
16
|
}
|
|
16
17
|
else if (!messageNode) {
|
|
@@ -22,7 +23,7 @@ function checkNode(context, node) {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
+
const rule = {
|
|
26
27
|
meta: {
|
|
27
28
|
type: 'problem',
|
|
28
29
|
docs: {
|
|
@@ -38,10 +39,8 @@ var rule = {
|
|
|
38
39
|
},
|
|
39
40
|
],
|
|
40
41
|
},
|
|
41
|
-
create
|
|
42
|
-
|
|
43
|
-
return checkNode(context, node);
|
|
44
|
-
};
|
|
42
|
+
create(context) {
|
|
43
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
45
44
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
46
45
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
47
46
|
CallExpression: callExpressionVisitor,
|
|
@@ -50,7 +49,7 @@ var rule = {
|
|
|
50
49
|
});
|
|
51
50
|
}
|
|
52
51
|
return {
|
|
53
|
-
JSXOpeningElement:
|
|
52
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
54
53
|
CallExpression: callExpressionVisitor,
|
|
55
54
|
};
|
|
56
55
|
},
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce-description.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"enforce-description.d.ts","sourceRoot":"","sources":["enforce-description.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;;AAgC3B,wBAmCoB"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
const util_1 = require("../util");
|
|
4
4
|
function checkNode(context, node) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
for (
|
|
8
|
-
var _a = msgs_1[_i][0], description = _a.message.description, descriptionNode = _a.descriptionNode;
|
|
5
|
+
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
|
|
6
|
+
const { options: [type], } = context;
|
|
7
|
+
for (const [{ message: { description }, descriptionNode, },] of msgs) {
|
|
9
8
|
if (!description) {
|
|
10
9
|
if (type === 'literal' && descriptionNode) {
|
|
11
10
|
context.report({
|
|
@@ -38,10 +37,8 @@ exports.default = {
|
|
|
38
37
|
},
|
|
39
38
|
],
|
|
40
39
|
},
|
|
41
|
-
create
|
|
42
|
-
|
|
43
|
-
return checkNode(context, node);
|
|
44
|
-
};
|
|
40
|
+
create(context) {
|
|
41
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
45
42
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
46
43
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
47
44
|
CallExpression: callExpressionVisitor,
|
|
@@ -50,7 +47,7 @@ exports.default = {
|
|
|
50
47
|
});
|
|
51
48
|
}
|
|
52
49
|
return {
|
|
53
|
-
JSXOpeningElement:
|
|
50
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
54
51
|
CallExpression: callExpressionVisitor,
|
|
55
52
|
};
|
|
56
53
|
},
|
package/rules/enforce-id.d.ts
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce-id.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"enforce-id.d.ts","sourceRoot":"","sources":["enforce-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;;AA0G3B,wBAgEoB"}
|
package/rules/enforce-id.js
CHANGED
|
@@ -1,76 +1,72 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function checkNode(context, node,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var _loop_1 = function (defaultMessage, description, id, idPropNode, descriptionNode, messagePropNode) {
|
|
3
|
+
const util_1 = require("../util");
|
|
4
|
+
const ts_transformer_1 = require("@formatjs/ts-transformer");
|
|
5
|
+
function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps }) {
|
|
6
|
+
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
|
|
7
|
+
for (const [{ message: { defaultMessage, description, id }, idPropNode, descriptionNode, messagePropNode, },] of msgs) {
|
|
9
8
|
if (!idInterpolationPattern && !idPropNode) {
|
|
10
9
|
context.report({
|
|
11
10
|
node: node,
|
|
12
|
-
message:
|
|
11
|
+
message: `id must be specified`,
|
|
13
12
|
});
|
|
14
13
|
}
|
|
15
14
|
else if (idInterpolationPattern) {
|
|
16
15
|
if (!defaultMessage) {
|
|
17
16
|
context.report({
|
|
18
17
|
node: node,
|
|
19
|
-
message:
|
|
18
|
+
message: `defaultMessage must be a string literal to calculate generated IDs`,
|
|
20
19
|
});
|
|
21
20
|
}
|
|
22
21
|
else if (!description && descriptionNode) {
|
|
23
22
|
context.report({
|
|
24
23
|
node: node,
|
|
25
|
-
message:
|
|
24
|
+
message: `description must be a string literal to calculate generated IDs`,
|
|
26
25
|
});
|
|
27
26
|
}
|
|
28
27
|
else {
|
|
29
28
|
if (idWhitelistRegexps &&
|
|
30
29
|
id &&
|
|
31
|
-
idWhitelistRegexps.some(
|
|
32
|
-
|
|
30
|
+
idWhitelistRegexps.some((r) => r.test(id))) {
|
|
31
|
+
// messageId is allowlisted so skip interpolation id check
|
|
32
|
+
return;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
const correctId = (0, ts_transformer_1.interpolateName)({
|
|
35
35
|
resourcePath: context.getFilename(),
|
|
36
36
|
}, idInterpolationPattern, {
|
|
37
37
|
content: description
|
|
38
|
-
?
|
|
38
|
+
? `${defaultMessage}#${description}`
|
|
39
39
|
: defaultMessage,
|
|
40
40
|
});
|
|
41
|
-
if (id !==
|
|
42
|
-
|
|
41
|
+
if (id !== correctId) {
|
|
42
|
+
let message = `"id" does not match with hash pattern ${idInterpolationPattern}`;
|
|
43
43
|
if (idWhitelistRegexps) {
|
|
44
|
-
message +=
|
|
45
|
-
.map(
|
|
46
|
-
.join('", "')
|
|
44
|
+
message += ` or allowlisted patterns ["${idWhitelistRegexps
|
|
45
|
+
.map(r => r.toString())
|
|
46
|
+
.join('", "')}"]`;
|
|
47
47
|
}
|
|
48
48
|
context.report({
|
|
49
49
|
node: node,
|
|
50
|
-
message:
|
|
51
|
-
|
|
50
|
+
message: `${message}.
|
|
51
|
+
Expected: ${correctId}
|
|
52
|
+
Actual: ${id}`,
|
|
53
|
+
fix(fixer) {
|
|
52
54
|
if (idPropNode) {
|
|
53
55
|
if (idPropNode.type === 'JSXAttribute') {
|
|
54
|
-
return fixer.replaceText(idPropNode,
|
|
56
|
+
return fixer.replaceText(idPropNode, `id="${correctId}"`);
|
|
55
57
|
}
|
|
56
|
-
return fixer.replaceText(idPropNode,
|
|
58
|
+
return fixer.replaceText(idPropNode, `id: '${correctId}'`);
|
|
57
59
|
}
|
|
58
60
|
// Insert after default message node
|
|
59
61
|
if (messagePropNode.type === 'JSXAttribute') {
|
|
60
|
-
return fixer.insertTextAfter(messagePropNode,
|
|
62
|
+
return fixer.insertTextAfter(messagePropNode, ` id="${correctId}"`);
|
|
61
63
|
}
|
|
62
|
-
return fixer.replaceText(messagePropNode,
|
|
64
|
+
return fixer.replaceText(messagePropNode, `defaultMessage: '${defaultMessage}', id: '${correctId}'`);
|
|
63
65
|
},
|
|
64
66
|
});
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
|
-
};
|
|
69
|
-
for (var _i = 0, msgs_1 = msgs; _i < msgs_1.length; _i++) {
|
|
70
|
-
var _b = msgs_1[_i][0], _c = _b.message, defaultMessage = _c.defaultMessage, description = _c.description, id = _c.id, idPropNode = _b.idPropNode, descriptionNode = _b.descriptionNode, messagePropNode = _b.messagePropNode;
|
|
71
|
-
var state_1 = _loop_1(defaultMessage, description, id, idPropNode, descriptionNode, messagePropNode);
|
|
72
|
-
if (typeof state_1 === "object")
|
|
73
|
-
return state_1.value;
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
72
|
exports.default = {
|
|
@@ -104,19 +100,16 @@ exports.default = {
|
|
|
104
100
|
},
|
|
105
101
|
],
|
|
106
102
|
},
|
|
107
|
-
create
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
idInterpolationPattern: tmp === null || tmp === void 0 ? void 0 : tmp.idInterpolationPattern,
|
|
103
|
+
create(context) {
|
|
104
|
+
const tmp = context?.options?.[0];
|
|
105
|
+
const opts = {
|
|
106
|
+
idInterpolationPattern: tmp?.idInterpolationPattern,
|
|
112
107
|
};
|
|
113
|
-
if (Array.isArray(tmp
|
|
114
|
-
|
|
115
|
-
opts.idWhitelistRegexps = idWhitelist.map(
|
|
108
|
+
if (Array.isArray(tmp?.idWhitelist)) {
|
|
109
|
+
const { idWhitelist } = tmp;
|
|
110
|
+
opts.idWhitelistRegexps = idWhitelist.map((str) => new RegExp(str, 'i'));
|
|
116
111
|
}
|
|
117
|
-
|
|
118
|
-
return checkNode(context, node, opts);
|
|
119
|
-
};
|
|
112
|
+
const callExpressionVisitor = (node) => checkNode(context, node, opts);
|
|
120
113
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
121
114
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
122
115
|
CallExpression: callExpressionVisitor,
|
|
@@ -125,9 +118,7 @@ exports.default = {
|
|
|
125
118
|
});
|
|
126
119
|
}
|
|
127
120
|
return {
|
|
128
|
-
JSXOpeningElement:
|
|
129
|
-
return checkNode(context, node, opts);
|
|
130
|
-
},
|
|
121
|
+
JSXOpeningElement: (node) => checkNode(context, node, opts),
|
|
131
122
|
CallExpression: callExpressionVisitor,
|
|
132
123
|
};
|
|
133
124
|
},
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce-placeholders.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"enforce-placeholders.d.ts","sourceRoot":"","sources":["enforce-placeholders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAiH3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA6ChB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -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 PlaceholderEnforcement extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super();
|
|
8
|
+
this.message = message;
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
}(Error));
|
|
10
|
+
}
|
|
15
11
|
function keyExistsInExpression(key, values) {
|
|
16
12
|
if (!values) {
|
|
17
13
|
return false;
|
|
@@ -19,10 +15,10 @@ function keyExistsInExpression(key, values) {
|
|
|
19
15
|
if (values.type !== 'ObjectExpression') {
|
|
20
16
|
return true; // True bc we cannot evaluate this
|
|
21
17
|
}
|
|
22
|
-
if (values.properties.find(
|
|
18
|
+
if (values.properties.find(prop => prop.type === 'SpreadElement')) {
|
|
23
19
|
return true; // True bc there's a spread element
|
|
24
20
|
}
|
|
25
|
-
return !!values.properties.find(
|
|
21
|
+
return !!values.properties.find(prop => {
|
|
26
22
|
if (prop.type !== 'Property') {
|
|
27
23
|
return false;
|
|
28
24
|
}
|
|
@@ -36,18 +32,16 @@ function keyExistsInExpression(key, values) {
|
|
|
36
32
|
});
|
|
37
33
|
}
|
|
38
34
|
function verifyAst(ast, values, ignoreList) {
|
|
39
|
-
for (
|
|
40
|
-
var el = ast_1[_i];
|
|
35
|
+
for (const el of ast) {
|
|
41
36
|
if ((0, icu_messageformat_parser_1.isLiteralElement)(el) || (0, icu_messageformat_parser_1.isPoundElement)(el)) {
|
|
42
37
|
continue;
|
|
43
38
|
}
|
|
44
|
-
|
|
39
|
+
const key = el.value;
|
|
45
40
|
if (!ignoreList.has(key) && !keyExistsInExpression(key, values)) {
|
|
46
|
-
throw new PlaceholderEnforcement(
|
|
41
|
+
throw new PlaceholderEnforcement(`Missing value for placeholder "${el.value}"`);
|
|
47
42
|
}
|
|
48
43
|
if ((0, icu_messageformat_parser_1.isPluralElement)(el) || (0, icu_messageformat_parser_1.isSelectElement)(el)) {
|
|
49
|
-
for (
|
|
50
|
-
var selector = _b[_a];
|
|
44
|
+
for (const selector of Object.keys(el.options)) {
|
|
51
45
|
verifyAst(el.options[selector].value, values, ignoreList);
|
|
52
46
|
}
|
|
53
47
|
}
|
|
@@ -57,17 +51,20 @@ function verifyAst(ast, values, ignoreList) {
|
|
|
57
51
|
}
|
|
58
52
|
}
|
|
59
53
|
function checkNode(context, node) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
const settings = (0, util_1.getSettings)(context);
|
|
55
|
+
const msgs = (0, util_1.extractMessages)(node, {
|
|
56
|
+
excludeMessageDeclCalls: true,
|
|
57
|
+
...settings,
|
|
58
|
+
});
|
|
59
|
+
const { options: [opt], } = context;
|
|
60
|
+
const ignoreList = new Set(opt?.ignoreList || []);
|
|
61
|
+
for (const [{ message: { defaultMessage }, messageNode, }, values,] of msgs) {
|
|
65
62
|
if (!defaultMessage || !messageNode) {
|
|
66
63
|
continue;
|
|
67
64
|
}
|
|
68
65
|
try {
|
|
69
66
|
verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
70
|
-
ignoreTag:
|
|
67
|
+
ignoreTag: settings.ignoreTag,
|
|
71
68
|
}), values, ignoreList);
|
|
72
69
|
}
|
|
73
70
|
catch (e) {
|
|
@@ -78,7 +75,7 @@ function checkNode(context, node) {
|
|
|
78
75
|
}
|
|
79
76
|
}
|
|
80
77
|
}
|
|
81
|
-
|
|
78
|
+
const rule = {
|
|
82
79
|
meta: {
|
|
83
80
|
type: 'problem',
|
|
84
81
|
docs: {
|
|
@@ -103,10 +100,8 @@ var rule = {
|
|
|
103
100
|
},
|
|
104
101
|
],
|
|
105
102
|
},
|
|
106
|
-
create
|
|
107
|
-
|
|
108
|
-
return checkNode(context, node);
|
|
109
|
-
};
|
|
103
|
+
create(context) {
|
|
104
|
+
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
110
105
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
111
106
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
112
107
|
CallExpression: callExpressionVisitor,
|
|
@@ -115,7 +110,7 @@ var rule = {
|
|
|
115
110
|
});
|
|
116
111
|
}
|
|
117
112
|
return {
|
|
118
|
-
JSXOpeningElement:
|
|
113
|
+
JSXOpeningElement: (node) => checkNode(context, node),
|
|
119
114
|
CallExpression: callExpressionVisitor,
|
|
120
115
|
};
|
|
121
116
|
},
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce-plural-rules.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"enforce-plural-rules.d.ts","sourceRoot":"","sources":["enforce-plural-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAqF3B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA8ChB,CAAA;AAED,eAAe,IAAI,CAAA"}
|