eslint-plugin-formatjs 4.11.3 → 4.12.1
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 +3 -23
- package/index.js +36 -37
- package/package.json +5 -5
- package/rules/blocklist-elements.d.ts +17 -3
- package/rules/blocklist-elements.js +50 -46
- package/rules/enforce-default-message.d.ts +10 -3
- package/rules/enforce-default-message.js +21 -9
- package/rules/enforce-description.d.ts +10 -3
- package/rules/enforce-description.js +19 -6
- package/rules/enforce-id.d.ts +10 -3
- package/rules/enforce-id.js +53 -24
- package/rules/enforce-placeholders.d.ts +8 -3
- package/rules/enforce-placeholders.js +18 -7
- package/rules/enforce-plural-rules.d.ts +17 -3
- package/rules/enforce-plural-rules.js +20 -20
- package/rules/no-camel-case.d.ts +6 -3
- package/rules/no-camel-case.js +20 -20
- package/rules/no-complex-selectors.d.ts +9 -3
- package/rules/no-complex-selectors.js +18 -16
- package/rules/no-emoji.d.ts +9 -3
- package/rules/no-emoji.js +6 -4
- package/rules/no-id.d.ts +6 -3
- package/rules/no-id.js +11 -4
- package/rules/no-invalid-icu.d.ts +6 -3
- package/rules/no-invalid-icu.js +12 -5
- package/rules/no-literal-string-in-jsx.d.ts +13 -3
- package/rules/no-literal-string-in-jsx.js +10 -7
- package/rules/no-multiple-plurals.d.ts +6 -3
- package/rules/no-multiple-plurals.js +20 -20
- package/rules/no-multiple-whitespaces.d.ts +6 -3
- package/rules/no-multiple-whitespaces.js +10 -5
- package/rules/no-offset.d.ts +6 -3
- package/rules/no-offset.js +19 -19
- package/rules/no-useless-message.d.ts +6 -3
- package/rules/no-useless-message.js +23 -39
- package/rules/prefer-formatted-message.d.ts +6 -3
- package/rules/prefer-formatted-message.js +5 -3
- package/rules/prefer-pound-in-plural.d.ts +6 -3
- package/rules/prefer-pound-in-plural.js +10 -4
- package/util.d.ts +2 -2
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'noMultiplePlurals';
|
|
3
|
+
type Options = [];
|
|
4
|
+
export declare const name = "no-multiple-plurals";
|
|
5
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
6
|
+
export {};
|
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
5
|
const util_1 = require("../util");
|
|
5
|
-
class MultiplePlurals extends Error {
|
|
6
|
-
constructor() {
|
|
7
|
-
super(...arguments);
|
|
8
|
-
this.message = 'Cannot specify more than 1 plural rules';
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
6
|
function verifyAst(ast, pluralCount = { count: 0 }) {
|
|
7
|
+
const errors = [];
|
|
12
8
|
for (const el of ast) {
|
|
13
9
|
if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
|
|
14
10
|
pluralCount.count++;
|
|
15
11
|
if (pluralCount.count > 1) {
|
|
16
|
-
|
|
12
|
+
errors.push({ messageId: 'noMultiplePlurals', data: {} });
|
|
17
13
|
}
|
|
18
14
|
const { options } = el;
|
|
19
15
|
for (const selector of Object.keys(options)) {
|
|
20
|
-
verifyAst(options[selector].value, pluralCount);
|
|
16
|
+
errors.push(...verifyAst(options[selector].value, pluralCount));
|
|
21
17
|
}
|
|
22
18
|
}
|
|
23
19
|
}
|
|
20
|
+
return errors;
|
|
24
21
|
}
|
|
25
22
|
function checkNode(context, node) {
|
|
26
23
|
const settings = (0, util_1.getSettings)(context);
|
|
@@ -29,33 +26,37 @@ function checkNode(context, node) {
|
|
|
29
26
|
if (!defaultMessage || !messageNode) {
|
|
30
27
|
continue;
|
|
31
28
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
catch (e) {
|
|
29
|
+
const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
30
|
+
ignoreTag: settings.ignoreTag,
|
|
31
|
+
}));
|
|
32
|
+
for (const error of errors) {
|
|
38
33
|
context.report({
|
|
39
|
-
node
|
|
40
|
-
|
|
34
|
+
node,
|
|
35
|
+
...error,
|
|
41
36
|
});
|
|
42
37
|
}
|
|
43
38
|
}
|
|
44
39
|
}
|
|
45
|
-
|
|
40
|
+
exports.name = 'no-multiple-plurals';
|
|
41
|
+
exports.rule = {
|
|
46
42
|
meta: {
|
|
47
43
|
type: 'problem',
|
|
48
44
|
docs: {
|
|
49
45
|
description: 'Disallow multiple plural rules in the same message',
|
|
50
|
-
category: 'Errors',
|
|
51
|
-
recommended: false,
|
|
52
46
|
url: 'https://formatjs.io/docs/tooling/linter#no-multiple-plurals',
|
|
53
47
|
},
|
|
54
48
|
fixable: 'code',
|
|
49
|
+
schema: [],
|
|
50
|
+
messages: {
|
|
51
|
+
noMultiplePlurals: 'Multiple plural rules in the same message',
|
|
52
|
+
},
|
|
55
53
|
},
|
|
54
|
+
defaultOptions: [],
|
|
56
55
|
create(context) {
|
|
57
56
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
57
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
58
58
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
59
|
+
//@ts-expect-error
|
|
59
60
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
60
61
|
CallExpression: callExpressionVisitor,
|
|
61
62
|
}, {
|
|
@@ -68,4 +69,3 @@ const rule = {
|
|
|
68
69
|
};
|
|
69
70
|
},
|
|
70
71
|
};
|
|
71
|
-
exports.default = rule;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'noMultipleWhitespaces' | 'parserError';
|
|
3
|
+
type Options = [];
|
|
4
|
+
export declare const name = "no-multiple-whitespaces";
|
|
5
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
6
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
5
|
const util_1 = require("../util");
|
|
5
6
|
function isAstValid(ast) {
|
|
@@ -89,7 +90,8 @@ function checkNode(context, node) {
|
|
|
89
90
|
catch (e) {
|
|
90
91
|
context.report({
|
|
91
92
|
node: messageNode,
|
|
92
|
-
|
|
93
|
+
messageId: 'parserError',
|
|
94
|
+
data: { message: e instanceof Error ? e.message : String(e) },
|
|
93
95
|
});
|
|
94
96
|
return;
|
|
95
97
|
}
|
|
@@ -105,23 +107,27 @@ function checkNode(context, node) {
|
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
|
-
|
|
110
|
+
exports.name = 'no-multiple-whitespaces';
|
|
111
|
+
exports.rule = {
|
|
109
112
|
meta: {
|
|
110
113
|
type: 'problem',
|
|
111
114
|
docs: {
|
|
112
115
|
description: 'Prevents usage of multiple consecutive whitespaces in message',
|
|
113
|
-
category: 'Errors',
|
|
114
|
-
recommended: false,
|
|
115
116
|
url: 'https://formatjs.io/docs/tooling/linter#no-multiple-whitespaces',
|
|
116
117
|
},
|
|
117
118
|
messages: {
|
|
118
119
|
noMultipleWhitespaces: 'Multiple consecutive whitespaces are not allowed',
|
|
120
|
+
parserError: '{{message}}',
|
|
119
121
|
},
|
|
120
122
|
fixable: 'code',
|
|
123
|
+
schema: [],
|
|
121
124
|
},
|
|
125
|
+
defaultOptions: [],
|
|
122
126
|
create(context) {
|
|
123
127
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
128
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
124
129
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
130
|
+
//@ts-expect-error
|
|
125
131
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
126
132
|
CallExpression: callExpressionVisitor,
|
|
127
133
|
}, {
|
|
@@ -134,4 +140,3 @@ const rule = {
|
|
|
134
140
|
};
|
|
135
141
|
},
|
|
136
142
|
};
|
|
137
|
-
exports.default = rule;
|
package/rules/no-offset.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'noOffset';
|
|
3
|
+
type Options = [];
|
|
4
|
+
export declare const name = "no-offset";
|
|
5
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
6
|
+
export {};
|
package/rules/no-offset.js
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
5
|
const util_1 = require("../util");
|
|
5
|
-
class NoOffsetError extends Error {
|
|
6
|
-
constructor() {
|
|
7
|
-
super(...arguments);
|
|
8
|
-
this.message = 'offset are not allowed in plural rules';
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
6
|
function verifyAst(ast) {
|
|
7
|
+
const errors = [];
|
|
12
8
|
for (const el of ast) {
|
|
13
9
|
if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
|
|
14
10
|
if (el.offset) {
|
|
15
|
-
|
|
11
|
+
errors.push({ messageId: 'noOffset', data: {} });
|
|
16
12
|
}
|
|
17
13
|
const { options } = el;
|
|
18
14
|
for (const selector of Object.keys(options)) {
|
|
19
|
-
verifyAst(options[selector].value);
|
|
15
|
+
errors.push(...verifyAst(options[selector].value));
|
|
20
16
|
}
|
|
21
17
|
}
|
|
22
18
|
}
|
|
19
|
+
return errors;
|
|
23
20
|
}
|
|
24
21
|
function checkNode(context, node) {
|
|
25
22
|
const settings = (0, util_1.getSettings)(context);
|
|
@@ -28,33 +25,37 @@ function checkNode(context, node) {
|
|
|
28
25
|
if (!defaultMessage || !messageNode) {
|
|
29
26
|
continue;
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
catch (e) {
|
|
28
|
+
const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
29
|
+
ignoreTag: settings.ignoreTag,
|
|
30
|
+
}));
|
|
31
|
+
for (const error of errors) {
|
|
37
32
|
context.report({
|
|
38
33
|
node: messageNode,
|
|
39
|
-
|
|
34
|
+
...error,
|
|
40
35
|
});
|
|
41
36
|
}
|
|
42
37
|
}
|
|
43
38
|
}
|
|
44
|
-
|
|
39
|
+
exports.name = 'no-offset';
|
|
40
|
+
exports.rule = {
|
|
45
41
|
meta: {
|
|
46
42
|
type: 'problem',
|
|
47
43
|
docs: {
|
|
48
44
|
description: 'Disallow offset in plural rules',
|
|
49
|
-
category: 'Errors',
|
|
50
|
-
recommended: false,
|
|
51
45
|
url: 'https://formatjs.io/docs/tooling/linter#no-offset',
|
|
52
46
|
},
|
|
53
47
|
fixable: 'code',
|
|
48
|
+
messages: {
|
|
49
|
+
noOffset: 'offset is not allowed',
|
|
50
|
+
},
|
|
51
|
+
schema: [],
|
|
54
52
|
},
|
|
53
|
+
defaultOptions: [],
|
|
55
54
|
create(context) {
|
|
56
55
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
56
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
57
57
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
58
|
+
//@ts-expect-error
|
|
58
59
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
59
60
|
CallExpression: callExpressionVisitor,
|
|
60
61
|
}, {
|
|
@@ -67,4 +68,3 @@ const rule = {
|
|
|
67
68
|
};
|
|
68
69
|
},
|
|
69
70
|
};
|
|
70
|
-
exports.default = rule;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'unnecessaryFormat' | 'unnecessaryFormatNumber' | 'unnecessaryFormatDate' | 'unnecessaryFormatTime';
|
|
3
|
+
type Options = [];
|
|
4
|
+
export declare const name = "no-useless-message";
|
|
5
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
6
|
+
export {};
|
|
@@ -1,44 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
5
|
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
6
|
function verifyAst(ast) {
|
|
30
7
|
if (ast.length !== 1) {
|
|
31
8
|
return;
|
|
32
9
|
}
|
|
33
10
|
switch (ast[0].type) {
|
|
34
11
|
case icu_messageformat_parser_1.TYPE.argument:
|
|
35
|
-
|
|
12
|
+
return 'unnecessaryFormat';
|
|
36
13
|
case icu_messageformat_parser_1.TYPE.number:
|
|
37
|
-
|
|
14
|
+
return 'unnecessaryFormatNumber';
|
|
38
15
|
case icu_messageformat_parser_1.TYPE.date:
|
|
39
|
-
|
|
16
|
+
return 'unnecessaryFormatDate';
|
|
40
17
|
case icu_messageformat_parser_1.TYPE.time:
|
|
41
|
-
|
|
18
|
+
return 'unnecessaryFormatTime';
|
|
42
19
|
}
|
|
43
20
|
}
|
|
44
21
|
function checkNode(context, node) {
|
|
@@ -48,32 +25,40 @@ function checkNode(context, node) {
|
|
|
48
25
|
if (!defaultMessage || !messageNode) {
|
|
49
26
|
continue;
|
|
50
27
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
28
|
+
const messageId = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
29
|
+
ignoreTag: settings.ignoreTag,
|
|
30
|
+
}));
|
|
31
|
+
if (messageId)
|
|
57
32
|
context.report({
|
|
58
33
|
node: messageNode,
|
|
59
|
-
|
|
34
|
+
messageId,
|
|
60
35
|
});
|
|
61
|
-
}
|
|
62
36
|
}
|
|
63
37
|
}
|
|
64
|
-
|
|
38
|
+
exports.name = 'no-useless-message';
|
|
39
|
+
exports.rule = {
|
|
65
40
|
meta: {
|
|
66
41
|
type: 'problem',
|
|
67
42
|
docs: {
|
|
68
43
|
description: 'Disallow unnecessary formatted message',
|
|
69
|
-
recommended:
|
|
44
|
+
recommended: 'recommended',
|
|
70
45
|
url: 'https://formatjs.io/docs/tooling/linter#no-useless-message',
|
|
71
46
|
},
|
|
72
47
|
fixable: 'code',
|
|
48
|
+
schema: [],
|
|
49
|
+
messages: {
|
|
50
|
+
unnecessaryFormat: 'Unnecessary formatted message.',
|
|
51
|
+
unnecessaryFormatNumber: 'Unnecessary formatted message: just use FormattedNumber or intl.formatNumber.',
|
|
52
|
+
unnecessaryFormatDate: 'Unnecessary formatted message: just use FormattedDate or intl.formatDate.',
|
|
53
|
+
unnecessaryFormatTime: 'Unnecessary formatted message: just use FormattedTime or intl.formatTime.',
|
|
54
|
+
},
|
|
73
55
|
},
|
|
56
|
+
defaultOptions: [],
|
|
74
57
|
create(context) {
|
|
75
58
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
59
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
76
60
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
61
|
+
//@ts-expect-error
|
|
77
62
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
78
63
|
CallExpression: callExpressionVisitor,
|
|
79
64
|
}, {
|
|
@@ -86,4 +71,3 @@ const rule = {
|
|
|
86
71
|
};
|
|
87
72
|
},
|
|
88
73
|
};
|
|
89
|
-
exports.default = rule;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'jsxChildren';
|
|
3
|
+
type Options = [];
|
|
4
|
+
export declare const name = "prefer-formatted-message";
|
|
5
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
6
|
+
export {};
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const util_1 = require("../util");
|
|
4
|
-
|
|
5
|
+
exports.name = 'prefer-formatted-message';
|
|
6
|
+
exports.rule = {
|
|
5
7
|
meta: {
|
|
6
8
|
type: 'suggestion',
|
|
7
9
|
docs: {
|
|
8
10
|
description: 'Prefer `FormattedMessage` component over `intl.formatMessage` if applicable.',
|
|
9
|
-
recommended: false,
|
|
10
11
|
url: 'https://formatjs.io/docs/tooling/linter#prefer-formatted-message',
|
|
11
12
|
},
|
|
12
13
|
messages: {
|
|
13
14
|
jsxChildren: 'Prefer `FormattedMessage` over `intl.formatMessage` in the JSX children expression.',
|
|
14
15
|
},
|
|
16
|
+
schema: [],
|
|
15
17
|
},
|
|
18
|
+
defaultOptions: [],
|
|
16
19
|
// TODO: Vue support
|
|
17
20
|
create(context) {
|
|
18
21
|
return {
|
|
@@ -31,4 +34,3 @@ const rule = {
|
|
|
31
34
|
};
|
|
32
35
|
},
|
|
33
36
|
};
|
|
34
|
-
exports.default = rule;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'preferPoundInPlurals' | 'parseError';
|
|
3
|
+
type Options = [];
|
|
4
|
+
export declare const name = "prefer-pound-in-plural";
|
|
5
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
6
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
5
6
|
const magic_string_1 = tslib_1.__importDefault(require("magic-string"));
|
|
@@ -148,30 +149,36 @@ function checkNode(context, node) {
|
|
|
148
149
|
catch (e) {
|
|
149
150
|
context.report({
|
|
150
151
|
node: messageNode,
|
|
151
|
-
|
|
152
|
+
messageId: 'parseError',
|
|
153
|
+
data: { message: e instanceof Error ? e.message : String(e) },
|
|
152
154
|
});
|
|
153
155
|
return;
|
|
154
156
|
}
|
|
155
157
|
verifyAst(context, messageNode, ast);
|
|
156
158
|
}
|
|
157
159
|
}
|
|
158
|
-
|
|
160
|
+
exports.name = 'prefer-pound-in-plural';
|
|
161
|
+
exports.rule = {
|
|
159
162
|
meta: {
|
|
160
163
|
type: 'suggestion',
|
|
161
164
|
docs: {
|
|
162
165
|
description: 'Prefer using # to reference the count in the plural argument.',
|
|
163
|
-
recommended: false,
|
|
164
166
|
url: 'https://formatjs.io/docs/tooling/linter#prefer-pound-in-plurals',
|
|
165
167
|
},
|
|
166
168
|
messages: {
|
|
167
169
|
preferPoundInPlurals: 'Prefer using # to reference the count in the plural argument instead of repeating the argument.',
|
|
170
|
+
parseError: '{{message}}',
|
|
168
171
|
},
|
|
169
172
|
fixable: 'code',
|
|
173
|
+
schema: [],
|
|
170
174
|
},
|
|
175
|
+
defaultOptions: [],
|
|
171
176
|
// TODO: Vue support
|
|
172
177
|
create(context) {
|
|
173
178
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
179
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
174
180
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
181
|
+
//@ts-expect-error
|
|
175
182
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
176
183
|
CallExpression: callExpressionVisitor,
|
|
177
184
|
}, {
|
|
@@ -184,4 +191,3 @@ const rule = {
|
|
|
184
191
|
};
|
|
185
192
|
},
|
|
186
193
|
};
|
|
187
|
-
exports.default = rule;
|
package/util.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MessageFormatElement } from '@formatjs/icu-messageformat-parser';
|
|
2
2
|
import { TSESTree } from '@typescript-eslint/utils';
|
|
3
|
-
import {
|
|
3
|
+
import { RuleContext } from '@typescript-eslint/utils/ts-eslint';
|
|
4
4
|
export interface MessageDescriptor {
|
|
5
5
|
id?: string;
|
|
6
6
|
defaultMessage?: string;
|
|
@@ -20,7 +20,7 @@ export interface MessageDescriptorNodeInfo {
|
|
|
20
20
|
idValueNode?: TSESTree.Property['value'] | TSESTree.JSXAttribute['value'];
|
|
21
21
|
idPropNode?: TSESTree.Property | TSESTree.JSXAttribute;
|
|
22
22
|
}
|
|
23
|
-
export declare function getSettings({ settings }:
|
|
23
|
+
export declare function getSettings<TMessageIds extends string, TOptions extends readonly unknown[]>({ settings }: RuleContext<TMessageIds, TOptions>): Settings;
|
|
24
24
|
export declare function isIntlFormatMessageCall(node: TSESTree.Node): node is TSESTree.CallExpression;
|
|
25
25
|
export declare function extractMessageDescriptor(node?: TSESTree.Expression): MessageDescriptorNodeInfo | undefined;
|
|
26
26
|
export declare function extractMessages(node: TSESTree.Node, { additionalComponentNames, additionalFunctionNames, excludeMessageDeclCalls, }?: Settings): Array<[MessageDescriptorNodeInfo, TSESTree.Expression | undefined]>;
|