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.
Files changed (40) hide show
  1. package/index.d.ts +3 -23
  2. package/index.js +36 -37
  3. package/package.json +5 -5
  4. package/rules/blocklist-elements.d.ts +17 -3
  5. package/rules/blocklist-elements.js +50 -46
  6. package/rules/enforce-default-message.d.ts +10 -3
  7. package/rules/enforce-default-message.js +21 -9
  8. package/rules/enforce-description.d.ts +10 -3
  9. package/rules/enforce-description.js +19 -6
  10. package/rules/enforce-id.d.ts +10 -3
  11. package/rules/enforce-id.js +53 -24
  12. package/rules/enforce-placeholders.d.ts +8 -3
  13. package/rules/enforce-placeholders.js +18 -7
  14. package/rules/enforce-plural-rules.d.ts +17 -3
  15. package/rules/enforce-plural-rules.js +20 -20
  16. package/rules/no-camel-case.d.ts +6 -3
  17. package/rules/no-camel-case.js +20 -20
  18. package/rules/no-complex-selectors.d.ts +9 -3
  19. package/rules/no-complex-selectors.js +18 -16
  20. package/rules/no-emoji.d.ts +9 -3
  21. package/rules/no-emoji.js +6 -4
  22. package/rules/no-id.d.ts +6 -3
  23. package/rules/no-id.js +11 -4
  24. package/rules/no-invalid-icu.d.ts +6 -3
  25. package/rules/no-invalid-icu.js +12 -5
  26. package/rules/no-literal-string-in-jsx.d.ts +13 -3
  27. package/rules/no-literal-string-in-jsx.js +10 -7
  28. package/rules/no-multiple-plurals.d.ts +6 -3
  29. package/rules/no-multiple-plurals.js +20 -20
  30. package/rules/no-multiple-whitespaces.d.ts +6 -3
  31. package/rules/no-multiple-whitespaces.js +10 -5
  32. package/rules/no-offset.d.ts +6 -3
  33. package/rules/no-offset.js +19 -19
  34. package/rules/no-useless-message.d.ts +6 -3
  35. package/rules/no-useless-message.js +23 -39
  36. package/rules/prefer-formatted-message.d.ts +6 -3
  37. package/rules/prefer-formatted-message.js +5 -3
  38. package/rules/prefer-pound-in-plural.d.ts +6 -3
  39. package/rules/prefer-pound-in-plural.js +10 -4
  40. package/util.d.ts +2 -2
@@ -1,3 +1,8 @@
1
- import { Rule } from 'eslint';
2
- declare const rule: Rule.RuleModule;
3
- export default rule;
1
+ import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
2
+ type MessageIds = 'parserError' | 'missingValue' | 'unusedValue';
3
+ type Options = [{
4
+ ignoreList: string[];
5
+ }?];
6
+ export declare const name = "enforce-placeholders";
7
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
8
+ 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 collectPlaceholderNames(ast) {
@@ -68,7 +69,8 @@ function checkNode(context, node) {
68
69
  catch (e) {
69
70
  context.report({
70
71
  node: messageNode,
71
- message: e instanceof Error ? e.message : String(e),
72
+ messageId: 'parserError',
73
+ data: { message: e instanceof Error ? e.message : String(e) },
72
74
  });
73
75
  continue;
74
76
  }
@@ -82,26 +84,28 @@ function checkNode(context, node) {
82
84
  if (missingPlaceholders.length > 0) {
83
85
  context.report({
84
86
  node: messageNode,
85
- message: `Missing value(s) for the following placeholder(s): ${missingPlaceholders.join(', ')}.`,
87
+ messageId: 'missingValue',
88
+ data: {
89
+ list: missingPlaceholders.join(', '),
90
+ },
86
91
  });
87
92
  }
88
93
  literalElementByLiteralKey.forEach((element, key) => {
89
94
  if (!ignoreList.has(key) && !placeholderNames.has(key)) {
90
95
  context.report({
91
96
  node: element,
92
- message: 'Value not used by the message.',
97
+ messageId: 'unusedValue',
93
98
  });
94
99
  }
95
100
  });
96
101
  }
97
102
  }
98
- const rule = {
103
+ exports.name = 'enforce-placeholders';
104
+ exports.rule = {
99
105
  meta: {
100
106
  type: 'problem',
101
107
  docs: {
102
108
  description: 'Enforce that all messages with placeholders have enough passed-in values',
103
- category: 'Errors',
104
- recommended: true,
105
109
  url: 'https://formatjs.io/docs/tooling/linter#enforce-placeholders',
106
110
  },
107
111
  schema: [
@@ -118,10 +122,18 @@ const rule = {
118
122
  additionalProperties: false,
119
123
  },
120
124
  ],
125
+ messages: {
126
+ parserError: '{{message}}',
127
+ missingValue: 'Missing value(s) for the following placeholder(s): {{list}}.',
128
+ unusedValue: 'Value not used by the message.',
129
+ },
121
130
  },
131
+ defaultOptions: [],
122
132
  create(context) {
123
133
  const callExpressionVisitor = (node) => checkNode(context, node);
134
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
124
135
  if (context.parserServices.defineTemplateBodyVisitor) {
136
+ //@ts-expect-error
125
137
  return context.parserServices.defineTemplateBodyVisitor({
126
138
  CallExpression: callExpressionVisitor,
127
139
  }, {
@@ -134,4 +146,3 @@ const rule = {
134
146
  };
135
147
  },
136
148
  };
137
- exports.default = rule;
@@ -1,3 +1,17 @@
1
- import { Rule } from 'eslint';
2
- declare const rule: Rule.RuleModule;
3
- export default rule;
1
+ import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
2
+ declare enum LDML {
3
+ zero = "zero",
4
+ one = "one",
5
+ two = "two",
6
+ few = "few",
7
+ many = "many",
8
+ other = "other"
9
+ }
10
+ type PluralConfig = {
11
+ [key in LDML]?: boolean;
12
+ };
13
+ export type Options = [PluralConfig?];
14
+ type MessageIds = 'missingPlural' | 'forbidden';
15
+ export declare const name = "enforce-plural-rules";
16
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
17
+ export {};
@@ -1,13 +1,8 @@
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 PluralRulesEnforcement extends Error {
6
- constructor(message) {
7
- super();
8
- this.message = message;
9
- }
10
- }
11
6
  var LDML;
12
7
  (function (LDML) {
13
8
  LDML["zero"] = "zero";
@@ -18,23 +13,25 @@ var LDML;
18
13
  LDML["other"] = "other";
19
14
  })(LDML || (LDML = {}));
20
15
  function verifyAst(plConfig, ast) {
16
+ const errors = [];
21
17
  for (const el of ast) {
22
18
  if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
23
19
  const rules = Object.keys(plConfig);
24
20
  for (const rule of rules) {
25
21
  if (plConfig[rule] && !el.options[rule]) {
26
- throw new PluralRulesEnforcement(`Missing plural rule "${rule}"`);
22
+ errors.push({ messageId: 'missingPlural', data: { rule } });
27
23
  }
28
24
  if (!plConfig[rule] && el.options[rule]) {
29
- throw new PluralRulesEnforcement(`Plural rule "${rule}" is forbidden`);
25
+ errors.push({ messageId: 'forbidden', data: { rule } });
30
26
  }
31
27
  }
32
28
  const { options } = el;
33
29
  for (const selector of Object.keys(options)) {
34
- verifyAst(plConfig, options[selector].value);
30
+ errors.push(...verifyAst(plConfig, options[selector].value));
35
31
  }
36
32
  }
37
33
  }
34
+ return errors;
38
35
  }
39
36
  function checkNode(context, node) {
40
37
  const settings = (0, util_1.getSettings)(context);
@@ -50,26 +47,23 @@ function checkNode(context, node) {
50
47
  if (!defaultMessage || !messageNode) {
51
48
  continue;
52
49
  }
53
- try {
54
- verifyAst(context.options[0], (0, icu_messageformat_parser_1.parse)(defaultMessage, {
55
- ignoreTag: settings.ignoreTag,
56
- }));
57
- }
58
- catch (e) {
50
+ const errors = verifyAst(plConfig, (0, icu_messageformat_parser_1.parse)(defaultMessage, {
51
+ ignoreTag: settings.ignoreTag,
52
+ }));
53
+ for (const error of errors) {
59
54
  context.report({
60
55
  node: messageNode,
61
- message: e instanceof Error ? e.message : String(e),
56
+ ...error,
62
57
  });
63
58
  }
64
59
  }
65
60
  }
66
- const rule = {
61
+ exports.name = 'enforce-plural-rules';
62
+ exports.rule = {
67
63
  meta: {
68
64
  type: 'problem',
69
65
  docs: {
70
66
  description: 'Enforce plural rules to always specify certain categories like `one`/`other`',
71
- category: 'Errors',
72
- recommended: false,
73
67
  url: 'https://formatjs.io/docs/tooling/linter#enforce-plural-rules',
74
68
  },
75
69
  fixable: 'code',
@@ -85,10 +79,17 @@ const rule = {
85
79
  additionalProperties: false,
86
80
  },
87
81
  ],
82
+ messages: {
83
+ missingPlural: `Missing plural rule "{{rule}}"`,
84
+ forbidden: `Plural rule "{{rule}}" is forbidden`,
85
+ },
88
86
  },
87
+ defaultOptions: [],
89
88
  create(context) {
90
89
  const callExpressionVisitor = (node) => checkNode(context, node);
90
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
91
91
  if (context.parserServices.defineTemplateBodyVisitor) {
92
+ //@ts-expect-error
92
93
  return context.parserServices.defineTemplateBodyVisitor({
93
94
  CallExpression: callExpressionVisitor,
94
95
  }, {
@@ -101,4 +102,3 @@ const rule = {
101
102
  };
102
103
  },
103
104
  };
104
- exports.default = rule;
@@ -1,3 +1,6 @@
1
- import { Rule } from 'eslint';
2
- declare const rule: Rule.RuleModule;
3
- export default rule;
1
+ import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
2
+ type MessageIds = 'camelcase';
3
+ type Options = [Element[]?];
4
+ export declare const name = "no-camel-case";
5
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
6
+ export {};
@@ -1,32 +1,30 @@
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");
6
+ exports.name = 'no-camel-case';
5
7
  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';
10
- }
11
- }
12
8
  function verifyAst(ast) {
9
+ const errors = [];
13
10
  for (const el of ast) {
14
11
  if ((0, icu_messageformat_parser_1.isArgumentElement)(el)) {
15
12
  if (CAMEL_CASE_REGEX.test(el.value)) {
16
- throw new CamelCase();
13
+ errors.push({ messageId: 'camelcase', data: {} });
17
14
  }
18
15
  continue;
19
16
  }
20
17
  if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
21
18
  if (CAMEL_CASE_REGEX.test(el.value)) {
22
- throw new CamelCase();
19
+ errors.push({ messageId: 'camelcase', data: {} });
23
20
  }
24
21
  const { options } = el;
25
22
  for (const selector of Object.keys(options)) {
26
- verifyAst(options[selector].value);
23
+ errors.push(...verifyAst(options[selector].value));
27
24
  }
28
25
  }
29
26
  }
27
+ return errors;
30
28
  }
31
29
  function checkNode(context, node) {
32
30
  const settings = (0, util_1.getSettings)(context);
@@ -35,33 +33,36 @@ function checkNode(context, node) {
35
33
  if (!defaultMessage || !messageNode) {
36
34
  continue;
37
35
  }
38
- try {
39
- verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
40
- ignoreTag: settings.ignoreTag,
41
- }));
42
- }
43
- catch (e) {
36
+ const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
37
+ ignoreTag: settings.ignoreTag,
38
+ }));
39
+ for (const error of errors) {
44
40
  context.report({
45
41
  node: messageNode,
46
- message: e instanceof Error ? e.message : String(e),
42
+ ...error,
47
43
  });
48
44
  }
49
45
  }
50
46
  }
51
- const rule = {
47
+ exports.rule = {
52
48
  meta: {
53
49
  type: 'problem',
54
50
  docs: {
55
51
  description: 'Disallow camel case placeholders in message',
56
- category: 'Errors',
57
- recommended: false,
58
52
  url: 'https://formatjs.io/docs/tooling/linter#no-camel-case',
59
53
  },
60
54
  fixable: 'code',
55
+ schema: [],
56
+ messages: {
57
+ camelcase: 'Camel case arguments are not allowed',
58
+ },
61
59
  },
60
+ defaultOptions: [],
62
61
  create(context) {
63
62
  const callExpressionVisitor = (node) => checkNode(context, node);
63
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
64
64
  if (context.parserServices.defineTemplateBodyVisitor) {
65
+ //@ts-expect-error
65
66
  return context.parserServices.defineTemplateBodyVisitor({
66
67
  CallExpression: callExpressionVisitor,
67
68
  }, {
@@ -74,4 +75,3 @@ const rule = {
74
75
  };
75
76
  },
76
77
  };
77
- exports.default = rule;
@@ -1,3 +1,9 @@
1
- import { Rule } from 'eslint';
2
- declare const rule: Rule.RuleModule;
3
- export default rule;
1
+ import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
2
+ interface Config {
3
+ limit: number;
4
+ }
5
+ type MessageIds = 'tooComplex' | 'parserError';
6
+ type Options = [Config?];
7
+ export declare const name = "no-complex-selectors";
8
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
9
+ 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 calculateComplexity(ast) {
@@ -65,29 +66,26 @@ function checkNode(context, node) {
65
66
  catch (e) {
66
67
  context.report({
67
68
  node: messageNode,
68
- message: e instanceof Error ? e.message : String(e),
69
+ messageId: 'parserError',
70
+ data: { message: e instanceof Error ? e.message : String(e) },
69
71
  });
70
72
  return;
71
73
  }
72
- let complexity = 0;
73
- try {
74
- complexity = calculateComplexity(ast);
75
- }
76
- catch (e) {
77
- context.report({
78
- node: messageNode,
79
- message: e instanceof Error ? e.message : e,
80
- });
81
- }
74
+ const complexity = calculateComplexity(ast);
82
75
  if (complexity > config.limit) {
83
76
  context.report({
84
77
  node: messageNode,
85
- message: `Message complexity is too high (${complexity} vs limit at ${config.limit})`,
78
+ messageId: 'tooComplex',
79
+ data: {
80
+ complexity,
81
+ limit: config.limit,
82
+ },
86
83
  });
87
84
  }
88
85
  }
89
86
  }
90
- const rule = {
87
+ exports.name = 'no-complex-selectors';
88
+ exports.rule = {
91
89
  meta: {
92
90
  type: 'problem',
93
91
  docs: {
@@ -100,8 +98,6 @@ results in 2 sentences: "I have a dog" & "I have many dogs".
100
98
  Default complexity limit is 20
101
99
  (using Smartling as a reference: https://help.smartling.com/hc/en-us/articles/360008030994-ICU-MessageFormat)
102
100
  `,
103
- category: 'Errors',
104
- recommended: false,
105
101
  url: 'https://formatjs.io/docs/tooling/linter#no-complex-selectors',
106
102
  },
107
103
  schema: [
@@ -116,10 +112,17 @@ Default complexity limit is 20
116
112
  },
117
113
  ],
118
114
  fixable: 'code',
115
+ messages: {
116
+ tooComplex: `Message complexity is too high ({{complexity}} vs limit at {{limit}})`,
117
+ parserError: '{{meesage}}',
118
+ },
119
119
  },
120
+ defaultOptions: [{ limit: 20 }],
120
121
  create(context) {
121
122
  const callExpressionVisitor = (node) => checkNode(context, node);
123
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
122
124
  if (context.parserServices.defineTemplateBodyVisitor) {
125
+ //@ts-expect-error
123
126
  return context.parserServices.defineTemplateBodyVisitor({
124
127
  CallExpression: callExpressionVisitor,
125
128
  }, {
@@ -132,4 +135,3 @@ Default complexity limit is 20
132
135
  };
133
136
  },
134
137
  };
135
- exports.default = rule;
@@ -1,3 +1,9 @@
1
- import { Rule } from 'eslint';
2
- declare const rule: Rule.RuleModule;
3
- export default rule;
1
+ import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
2
+ export declare const name = "no-emoji";
3
+ type MessageIds = 'notAllowed' | 'notAllowedAboveVersion';
4
+ type NoEmojiConfig = {
5
+ versionAbove: string;
6
+ };
7
+ export type Options = [NoEmojiConfig?];
8
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
9
+ export {};
package/rules/no-emoji.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rule = exports.name = void 0;
3
4
  const unicode_emoji_utils_1 = require("unicode-emoji-utils");
4
5
  const util_1 = require("../util");
6
+ exports.name = 'no-emoji';
5
7
  function checkNode(context, node) {
6
8
  const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
7
9
  let allowedEmojis = [];
@@ -58,13 +60,11 @@ const versionAboveEnums = [
58
60
  '14.0',
59
61
  '15.0',
60
62
  ];
61
- const rule = {
63
+ exports.rule = {
62
64
  meta: {
63
65
  type: 'problem',
64
66
  docs: {
65
67
  description: 'Disallow emojis in message',
66
- category: 'Errors',
67
- recommended: false,
68
68
  url: 'https://formatjs.io/docs/tooling/linter#no-emoji',
69
69
  },
70
70
  fixable: 'code',
@@ -80,9 +80,12 @@ const rule = {
80
80
  notAllowedAboveVersion: 'Emojis above version {{versionAbove}} are not allowed - Emoji: {{emoji}}',
81
81
  },
82
82
  },
83
+ defaultOptions: [],
83
84
  create(context) {
84
85
  const callExpressionVisitor = (node) => checkNode(context, node);
86
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
85
87
  if (context.parserServices.defineTemplateBodyVisitor) {
88
+ //@ts-expect-error
86
89
  return context.parserServices.defineTemplateBodyVisitor({
87
90
  CallExpression: callExpressionVisitor,
88
91
  }, {
@@ -95,4 +98,3 @@ const rule = {
95
98
  };
96
99
  },
97
100
  };
98
- exports.default = rule;
package/rules/no-id.d.ts CHANGED
@@ -1,3 +1,6 @@
1
- import { Rule } from 'eslint';
2
- declare const _default: Rule.RuleModule;
3
- export default _default;
1
+ import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
2
+ type MessageIds = 'noId';
3
+ type Options = [];
4
+ export declare const name = "no-id";
5
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
6
+ export {};
package/rules/no-id.js CHANGED
@@ -1,16 +1,18 @@
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
  function isComment(token) {
5
6
  return !!token && (token.type === 'Block' || token.type === 'Line');
6
7
  }
8
+ exports.name = 'no-id';
7
9
  function checkNode(context, node) {
8
10
  const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
9
11
  for (const [{ idPropNode }] of msgs) {
10
12
  if (idPropNode) {
11
13
  context.report({
12
14
  node: idPropNode,
13
- message: 'Manual `id` are not allowed in message descriptor',
15
+ messageId: 'noId',
14
16
  fix(fixer) {
15
17
  const src = context.getSourceCode();
16
18
  const token = src.getTokenAfter(idPropNode);
@@ -24,20 +26,25 @@ function checkNode(context, node) {
24
26
  }
25
27
  }
26
28
  }
27
- exports.default = {
29
+ exports.rule = {
28
30
  meta: {
29
31
  type: 'problem',
30
32
  docs: {
31
33
  description: 'Ban explicit ID from MessageDescriptor',
32
- category: 'Errors',
33
- recommended: false,
34
34
  url: 'https://formatjs.io/docs/tooling/linter#no-id',
35
35
  },
36
36
  fixable: 'code',
37
+ schema: [],
38
+ messages: {
39
+ noId: 'Manual `id` are not allowed in message descriptor',
40
+ },
37
41
  },
42
+ defaultOptions: [],
38
43
  create(context) {
39
44
  const callExpressionVisitor = (node) => checkNode(context, node);
45
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
40
46
  if (context.parserServices.defineTemplateBodyVisitor) {
47
+ //@ts-expect-error
41
48
  return context.parserServices.defineTemplateBodyVisitor({
42
49
  CallExpression: callExpressionVisitor,
43
50
  }, {
@@ -1,3 +1,6 @@
1
- import { Rule } from 'eslint';
2
- declare const rule: Rule.RuleModule;
3
- export default rule;
1
+ import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
2
+ type MessageIds = 'icuError';
3
+ type Options = [];
4
+ export declare const name = "no-invalid-icu";
5
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
6
+ export {};
@@ -1,7 +1,9 @@
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");
6
+ exports.name = 'no-invalid-icu';
5
7
  function checkNode(context, node) {
6
8
  const settings = (0, util_1.getSettings)(context);
7
9
  const msgs = (0, util_1.extractMessages)(node, settings);
@@ -21,24 +23,30 @@ function checkNode(context, node) {
21
23
  const msg = e instanceof Error ? e.message : e;
22
24
  context.report({
23
25
  node: messageNode,
24
- message: `Error parsing ICU string: ${msg}`,
26
+ messageId: 'icuError',
27
+ data: { message: `Error parsing ICU string: ${msg}` },
25
28
  });
26
29
  }
27
30
  }
28
31
  }
29
- const rule = {
32
+ exports.rule = {
30
33
  meta: {
31
34
  type: 'problem',
32
35
  docs: {
33
36
  description: `Make sure ICU messages are formatted correctly with no bad select statements, plurals, etc.`,
34
- category: 'Errors',
35
- recommended: true,
36
37
  },
37
38
  fixable: 'code',
39
+ schema: [],
40
+ messages: {
41
+ icuError: 'Invalid ICU Message format: {{message}}',
42
+ },
38
43
  },
44
+ defaultOptions: [],
39
45
  create(context) {
40
46
  const callExpressionVisitor = (node) => checkNode(context, node);
47
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
41
48
  if (context.parserServices.defineTemplateBodyVisitor) {
49
+ //@ts-expect-error
42
50
  return context.parserServices.defineTemplateBodyVisitor({
43
51
  CallExpression: callExpressionVisitor,
44
52
  }, {
@@ -51,4 +59,3 @@ const rule = {
51
59
  };
52
60
  },
53
61
  };
54
- exports.default = rule;
@@ -1,3 +1,13 @@
1
- import type { Rule } from 'eslint';
2
- declare const rule: Rule.RuleModule;
3
- export default rule;
1
+ import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
2
+ type PropMatcher = readonly [TagNamePattern: string, PropNamePattern: string][];
3
+ type Config = {
4
+ props?: {
5
+ include?: PropMatcher;
6
+ exclude?: PropMatcher;
7
+ };
8
+ };
9
+ type MessageIds = 'noLiteralStringInJsx';
10
+ type Options = [Config?];
11
+ export declare const name = "no-literal-string-in-jsx";
12
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
13
+ 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 utils_1 = require("@typescript-eslint/utils");
5
6
  const picomatch_1 = tslib_1.__importDefault(require("picomatch"));
@@ -34,13 +35,12 @@ function compilePropMatcher(propMatcher) {
34
35
  ];
35
36
  });
36
37
  }
37
- const rule = {
38
+ exports.name = 'no-literal-string-in-jsx';
39
+ exports.rule = {
38
40
  meta: {
39
41
  type: 'problem',
40
42
  docs: {
41
43
  description: 'Disallow untranslated literal strings without translation.',
42
- category: 'Errors',
43
- recommended: false,
44
44
  url: 'https://formatjs.io/docs/tooling/linter#no-literal-string-in-jsx',
45
45
  },
46
46
  schema: [
@@ -61,7 +61,11 @@ const rule = {
61
61
  },
62
62
  },
63
63
  ],
64
+ messages: {
65
+ noLiteralStringInJsx: 'Cannot have untranslated text in JSX',
66
+ },
64
67
  },
68
+ defaultOptions: [],
65
69
  // TODO: Vue support
66
70
  create(context) {
67
71
  const userConfig = context.options[0] || {};
@@ -109,7 +113,7 @@ const rule = {
109
113
  (node.quasis.length > 1 || node.quasis[0].value.raw.length > 0))) {
110
114
  context.report({
111
115
  node: node,
112
- message: 'Cannot have untranslated text in JSX',
116
+ messageId: 'noLiteralStringInJsx',
113
117
  });
114
118
  }
115
119
  else if (node.type === 'BinaryExpression' && node.operator === '+') {
@@ -150,7 +154,7 @@ const rule = {
150
154
  node.value.value.length > 0) {
151
155
  context.report({
152
156
  node: node,
153
- message: 'Cannot have untranslated text in JSX',
157
+ messageId: 'noLiteralStringInJsx',
154
158
  });
155
159
  }
156
160
  else if (node.value.type === 'JSXExpressionContainer' &&
@@ -165,7 +169,7 @@ const rule = {
165
169
  }
166
170
  context.report({
167
171
  node: node,
168
- message: 'Cannot have untranslated text in JSX',
172
+ messageId: 'noLiteralStringInJsx',
169
173
  });
170
174
  },
171
175
  // Children expression container
@@ -177,4 +181,3 @@ const rule = {
177
181
  };
178
182
  },
179
183
  };
180
- exports.default = rule;