eslint-plugin-formatjs 4.11.2 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE.md +1 -1
  2. package/index.d.ts +3 -23
  3. package/index.js +36 -37
  4. package/package.json +5 -5
  5. package/rules/blocklist-elements.d.ts +17 -3
  6. package/rules/blocklist-elements.js +50 -46
  7. package/rules/enforce-default-message.d.ts +10 -3
  8. package/rules/enforce-default-message.js +21 -9
  9. package/rules/enforce-description.d.ts +10 -3
  10. package/rules/enforce-description.js +19 -6
  11. package/rules/enforce-id.d.ts +10 -3
  12. package/rules/enforce-id.js +53 -24
  13. package/rules/enforce-placeholders.d.ts +8 -3
  14. package/rules/enforce-placeholders.js +18 -7
  15. package/rules/enforce-plural-rules.d.ts +17 -3
  16. package/rules/enforce-plural-rules.js +20 -20
  17. package/rules/no-camel-case.d.ts +6 -3
  18. package/rules/no-camel-case.js +20 -20
  19. package/rules/no-complex-selectors.d.ts +9 -3
  20. package/rules/no-complex-selectors.js +18 -16
  21. package/rules/no-emoji.d.ts +9 -3
  22. package/rules/no-emoji.js +6 -4
  23. package/rules/no-id.d.ts +6 -3
  24. package/rules/no-id.js +11 -4
  25. package/rules/no-invalid-icu.d.ts +6 -3
  26. package/rules/no-invalid-icu.js +12 -5
  27. package/rules/no-literal-string-in-jsx.d.ts +13 -3
  28. package/rules/no-literal-string-in-jsx.js +10 -7
  29. package/rules/no-multiple-plurals.d.ts +6 -3
  30. package/rules/no-multiple-plurals.js +20 -20
  31. package/rules/no-multiple-whitespaces.d.ts +6 -3
  32. package/rules/no-multiple-whitespaces.js +10 -5
  33. package/rules/no-offset.d.ts +6 -3
  34. package/rules/no-offset.js +19 -19
  35. package/rules/no-useless-message.d.ts +6 -3
  36. package/rules/no-useless-message.js +23 -39
  37. package/rules/prefer-formatted-message.d.ts +6 -3
  38. package/rules/prefer-formatted-message.js +5 -3
  39. package/rules/prefer-pound-in-plural.d.ts +6 -3
  40. package/rules/prefer-pound-in-plural.js +10 -4
  41. package/util.d.ts +2 -2
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 FormatJS
3
+ Copyright (c) 2023 FormatJS
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
6
 
package/index.d.ts CHANGED
@@ -1,24 +1,4 @@
1
- declare const plugin: {
2
- rules: {
3
- 'blocklist-elements': import("eslint").Rule.RuleModule;
4
- 'enforce-default-message': import("eslint").Rule.RuleModule;
5
- 'enforce-description': import("eslint").Rule.RuleModule;
6
- 'enforce-id': import("eslint").Rule.RuleModule;
7
- 'enforce-placeholders': import("eslint").Rule.RuleModule;
8
- 'enforce-plural-rules': import("eslint").Rule.RuleModule;
9
- 'no-camel-case': import("eslint").Rule.RuleModule;
10
- 'no-complex-selectors': import("eslint").Rule.RuleModule;
11
- 'no-emoji': import("eslint").Rule.RuleModule;
12
- 'no-id': import("eslint").Rule.RuleModule;
13
- 'no-invalid-icu': import("eslint").Rule.RuleModule;
14
- 'no-literal-string-in-jsx': import("eslint").Rule.RuleModule;
15
- 'no-multiple-plurals': import("eslint").Rule.RuleModule;
16
- 'no-multiple-whitespaces': import("eslint").Rule.RuleModule;
17
- 'no-offset': import("eslint").Rule.RuleModule;
18
- 'no-useless-message': import("eslint").Rule.RuleModule;
19
- 'prefer-formatted-message': import("eslint").Rule.RuleModule;
20
- 'prefer-pound-in-plural': import("eslint").Rule.RuleModule;
21
- };
1
+ import { RuleModule } from '@typescript-eslint/utils/ts-eslint';
2
+ export type Plugin = {
3
+ rules: Record<string, RuleModule<string, readonly unknown[]>>;
22
4
  };
23
- export type Plugin = typeof plugin;
24
- export {};
package/index.js CHANGED
@@ -1,44 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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 no_useless_message_1 = tslib_1.__importDefault(require("./rules/no-useless-message"));
20
- const prefer_formatted_message_1 = tslib_1.__importDefault(require("./rules/prefer-formatted-message"));
21
- const prefer_pound_in_plural_1 = tslib_1.__importDefault(require("./rules/prefer-pound-in-plural"));
3
+ const blocklist_elements_1 = require("./rules/blocklist-elements");
4
+ const enforce_default_message_1 = require("./rules/enforce-default-message");
5
+ const enforce_description_1 = require("./rules/enforce-description");
6
+ const enforce_id_1 = require("./rules/enforce-id");
7
+ const enforce_placeholders_1 = require("./rules/enforce-placeholders");
8
+ const no_invalid_icu_1 = require("./rules/no-invalid-icu");
9
+ const enforce_plural_rules_1 = require("./rules/enforce-plural-rules");
10
+ const no_camel_case_1 = require("./rules/no-camel-case");
11
+ const no_complex_selectors_1 = require("./rules/no-complex-selectors");
12
+ const no_emoji_1 = require("./rules/no-emoji");
13
+ const no_id_1 = require("./rules/no-id");
14
+ const no_multiple_plurals_1 = require("./rules/no-multiple-plurals");
15
+ const no_multiple_whitespaces_1 = require("./rules/no-multiple-whitespaces");
16
+ const no_offset_1 = require("./rules/no-offset");
17
+ const no_literal_string_in_jsx_1 = require("./rules/no-literal-string-in-jsx");
18
+ const no_useless_message_1 = require("./rules/no-useless-message");
19
+ const prefer_formatted_message_1 = require("./rules/prefer-formatted-message");
20
+ const prefer_pound_in_plural_1 = require("./rules/prefer-pound-in-plural");
22
21
  const plugin = {
23
22
  rules: {
24
- 'blocklist-elements': blocklist_elements_1.default,
25
- 'enforce-default-message': enforce_default_message_1.default,
26
- 'enforce-description': enforce_description_1.default,
27
- 'enforce-id': enforce_id_1.default,
28
- 'enforce-placeholders': enforce_placeholders_1.default,
29
- 'enforce-plural-rules': enforce_plural_rules_1.default,
30
- 'no-camel-case': no_camel_case_1.default,
31
- 'no-complex-selectors': no_complex_selectors_1.default,
32
- 'no-emoji': no_emoji_1.default,
33
- 'no-id': no_id_1.default,
34
- 'no-invalid-icu': no_invalid_icu_1.default,
35
- 'no-literal-string-in-jsx': no_literal_string_in_jsx_1.default,
36
- 'no-multiple-plurals': no_multiple_plurals_1.default,
37
- 'no-multiple-whitespaces': no_multiple_whitespaces_1.default,
38
- 'no-offset': no_offset_1.default,
39
- 'no-useless-message': no_useless_message_1.default,
40
- 'prefer-formatted-message': prefer_formatted_message_1.default,
41
- 'prefer-pound-in-plural': prefer_pound_in_plural_1.default,
23
+ [blocklist_elements_1.name]: blocklist_elements_1.rule,
24
+ [enforce_default_message_1.name]: enforce_default_message_1.rule,
25
+ [enforce_description_1.name]: enforce_description_1.rule,
26
+ [enforce_id_1.name]: enforce_id_1.rule,
27
+ [enforce_placeholders_1.name]: enforce_placeholders_1.rule,
28
+ [enforce_plural_rules_1.name]: enforce_plural_rules_1.rule,
29
+ [no_camel_case_1.name]: no_camel_case_1.rule,
30
+ [no_complex_selectors_1.name]: no_complex_selectors_1.rule,
31
+ [no_emoji_1.name]: no_emoji_1.rule,
32
+ [no_id_1.name]: no_id_1.rule,
33
+ [no_invalid_icu_1.name]: no_invalid_icu_1.rule,
34
+ [no_literal_string_in_jsx_1.name]: no_literal_string_in_jsx_1.rule,
35
+ [no_multiple_plurals_1.name]: no_multiple_plurals_1.rule,
36
+ [no_multiple_whitespaces_1.name]: no_multiple_whitespaces_1.rule,
37
+ [no_offset_1.name]: no_offset_1.rule,
38
+ [no_useless_message_1.name]: no_useless_message_1.rule,
39
+ [prefer_formatted_message_1.name]: prefer_formatted_message_1.rule,
40
+ [prefer_pound_in_plural_1.name]: prefer_pound_in_plural_1.rule,
42
41
  },
43
42
  };
44
43
  module.exports = plugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-formatjs",
3
- "version": "4.11.2",
3
+ "version": "4.12.0",
4
4
  "description": "ESLint plugin for formatjs",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -22,15 +22,15 @@
22
22
  "dependencies": {
23
23
  "@types/eslint": "7 || 8",
24
24
  "@types/picomatch": "^2.3.0",
25
- "@typescript-eslint/utils": "^6.5.0",
25
+ "@typescript-eslint/utils": "^6.18.1",
26
26
  "emoji-regex": "^10.2.1",
27
27
  "magic-string": "^0.30.0",
28
28
  "picomatch": "^2.3.1",
29
29
  "tslib": "2.6.2",
30
30
  "typescript": "5",
31
- "unicode-emoji-utils": "^1.1.1",
32
- "@formatjs/icu-messageformat-parser": "2.7.2",
33
- "@formatjs/ts-transformer": "3.13.8"
31
+ "unicode-emoji-utils": "^1.2.0",
32
+ "@formatjs/ts-transformer": "3.13.10",
33
+ "@formatjs/icu-messageformat-parser": "2.7.4"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "eslint": "7 || 8"
@@ -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
+ type MessageIds = 'blocklist';
3
+ type Options = [Element[]?];
4
+ export declare const name = "blocklist-elements";
5
+ export declare enum Element {
6
+ literal = "literal",
7
+ argument = "argument",
8
+ number = "number",
9
+ date = "date",
10
+ time = "time",
11
+ select = "select",
12
+ selectordinal = "selectordinal",
13
+ plural = "plural",
14
+ tag = "tag"
15
+ }
16
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
17
+ export {};
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rule = exports.Element = 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 BlacklistElement extends Error {
6
- constructor(type) {
7
- super();
8
- this.message = `${type} element is blocklisted`;
9
- }
6
+ exports.name = 'blocklist-elements';
7
+ function getMessage(type) {
8
+ return {
9
+ messageId: 'blocklist',
10
+ data: { type },
11
+ };
10
12
  }
11
13
  var Element;
12
14
  (function (Element) {
@@ -19,37 +21,38 @@ var Element;
19
21
  Element["selectordinal"] = "selectordinal";
20
22
  Element["plural"] = "plural";
21
23
  Element["tag"] = "tag";
22
- })(Element || (Element = {}));
24
+ })(Element || (exports.Element = Element = {}));
23
25
  function verifyAst(blocklist, ast) {
26
+ const errors = [];
24
27
  for (const el of ast) {
25
28
  if ((0, icu_messageformat_parser_1.isLiteralElement)(el) && blocklist.includes(Element.literal)) {
26
- throw new BlacklistElement(Element.literal);
29
+ errors.push(getMessage(Element.literal));
27
30
  }
28
31
  if ((0, icu_messageformat_parser_1.isArgumentElement)(el) && blocklist.includes(Element.argument)) {
29
- throw new BlacklistElement(Element.argument);
32
+ errors.push(getMessage(Element.argument));
30
33
  }
31
34
  if ((0, icu_messageformat_parser_1.isNumberElement)(el) && blocklist.includes(Element.number)) {
32
- throw new BlacklistElement(Element.number);
35
+ errors.push(getMessage(Element.number));
33
36
  }
34
37
  if ((0, icu_messageformat_parser_1.isDateElement)(el) && blocklist.includes(Element.date)) {
35
- throw new BlacklistElement(Element.date);
38
+ errors.push(getMessage(Element.date));
36
39
  }
37
40
  if ((0, icu_messageformat_parser_1.isTimeElement)(el) && blocklist.includes(Element.time)) {
38
- throw new BlacklistElement(Element.time);
41
+ errors.push(getMessage(Element.time));
39
42
  }
40
43
  if ((0, icu_messageformat_parser_1.isSelectElement)(el) && blocklist.includes(Element.select)) {
41
- throw new BlacklistElement(Element.select);
44
+ errors.push(getMessage(Element.select));
42
45
  }
43
46
  if ((0, icu_messageformat_parser_1.isTagElement)(el) && blocklist.includes(Element.tag)) {
44
- throw new BlacklistElement(Element.tag);
47
+ errors.push(getMessage(Element.tag));
45
48
  }
46
49
  if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
47
50
  if (blocklist.includes(Element.plural)) {
48
- throw new BlacklistElement(Element.argument);
51
+ errors.push(getMessage(Element.argument));
49
52
  }
50
53
  if (el.pluralType === 'ordinal' &&
51
54
  blocklist.includes(Element.selectordinal)) {
52
- throw new BlacklistElement(Element.selectordinal);
55
+ errors.push(getMessage(Element.selectordinal));
53
56
  }
54
57
  }
55
58
  if ((0, icu_messageformat_parser_1.isSelectElement)(el) || (0, icu_messageformat_parser_1.isPluralElement)(el)) {
@@ -59,6 +62,7 @@ function verifyAst(blocklist, ast) {
59
62
  }
60
63
  }
61
64
  }
65
+ return errors;
62
66
  }
63
67
  function checkNode(context, node) {
64
68
  const settings = (0, util_1.getSettings)(context);
@@ -74,54 +78,54 @@ function checkNode(context, node) {
74
78
  if (!defaultMessage || !messageNode) {
75
79
  continue;
76
80
  }
77
- try {
78
- verifyAst(context.options[0], (0, icu_messageformat_parser_1.parse)(defaultMessage, {
79
- ignoreTag: settings.ignoreTag,
80
- }));
81
- }
82
- catch (e) {
81
+ const errors = verifyAst(blocklist, (0, icu_messageformat_parser_1.parse)(defaultMessage, {
82
+ ignoreTag: settings.ignoreTag,
83
+ }));
84
+ for (const error of errors) {
83
85
  context.report({
84
- node: messageNode,
85
- message: e instanceof Error ? e.message : String(e),
86
+ node,
87
+ ...error,
86
88
  });
87
89
  }
88
90
  }
89
91
  }
90
- const rule = {
92
+ const create = (context) => {
93
+ const callExpressionVisitor = (node) => checkNode(context, node);
94
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
95
+ if (context.parserServices?.defineTemplateBodyVisitor) {
96
+ //@ts-expect-error
97
+ return context.parserServices.defineTemplateBodyVisitor({
98
+ CallExpression: callExpressionVisitor,
99
+ }, {
100
+ CallExpression: callExpressionVisitor,
101
+ });
102
+ }
103
+ return {
104
+ JSXOpeningElement: (node) => checkNode(context, node),
105
+ CallExpression: callExpressionVisitor,
106
+ };
107
+ };
108
+ exports.rule = {
91
109
  meta: {
92
110
  type: 'problem',
93
111
  docs: {
94
112
  description: 'Disallow specific elements in ICU message format',
95
- category: 'Errors',
96
- recommended: false,
97
113
  url: 'https://formatjs.io/docs/tooling/linter#blocklist-elements',
98
114
  },
99
115
  fixable: 'code',
100
116
  schema: [
101
117
  {
102
118
  type: 'array',
103
- properties: {
104
- items: {
105
- type: 'string',
106
- enum: Object.keys(Element),
107
- },
119
+ items: {
120
+ type: 'string',
121
+ enum: Object.keys(Element),
108
122
  },
109
123
  },
110
124
  ],
125
+ messages: {
126
+ blocklist: `{{type}} element is blocklisted`,
127
+ },
111
128
  },
112
- create(context) {
113
- const callExpressionVisitor = (node) => checkNode(context, node);
114
- if (context.parserServices.defineTemplateBodyVisitor) {
115
- return context.parserServices.defineTemplateBodyVisitor({
116
- CallExpression: callExpressionVisitor,
117
- }, {
118
- CallExpression: callExpressionVisitor,
119
- });
120
- }
121
- return {
122
- JSXOpeningElement: (node) => checkNode(context, node),
123
- CallExpression: callExpressionVisitor,
124
- };
125
- },
129
+ defaultOptions: [],
130
+ create,
126
131
  };
127
- exports.default = rule;
@@ -1,3 +1,10 @@
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 enum Option {
3
+ literal = "literal",
4
+ anything = "anything"
5
+ }
6
+ type MessageIds = 'defaultMessage' | 'defaultMessageLiteral';
7
+ type Options = [`${Option}`?];
8
+ export declare const name = "enforce-default-message";
9
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
10
+ export {};
@@ -1,6 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rule = exports.name = exports.Option = void 0;
3
4
  const util_1 = require("../util");
5
+ var Option;
6
+ (function (Option) {
7
+ Option["literal"] = "literal";
8
+ Option["anything"] = "anything";
9
+ })(Option || (exports.Option = Option = {}));
10
+ exports.name = 'enforce-default-message';
4
11
  function checkNode(context, node) {
5
12
  const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
6
13
  const { options: [type], } = context;
@@ -9,39 +16,45 @@ function checkNode(context, node) {
9
16
  if (type === 'literal' && messageNode) {
10
17
  context.report({
11
18
  node: messageNode,
12
- message: `"defaultMessage" must be:
13
- - a string literal or
14
- - template literal without variable`,
19
+ messageId: 'defaultMessageLiteral',
15
20
  });
16
21
  }
17
22
  else if (!messageNode) {
18
23
  context.report({
19
24
  node: node,
20
- message: '`defaultMessage` has to be specified in message descriptor',
25
+ messageId: 'defaultMessage',
21
26
  });
22
27
  }
23
28
  }
24
29
  }
25
30
  }
26
- const rule = {
31
+ exports.rule = {
27
32
  meta: {
28
33
  type: 'problem',
29
34
  docs: {
30
35
  description: 'Enforce defaultMessage in message descriptor',
31
- category: 'Errors',
32
- recommended: false,
33
36
  url: 'https://formatjs.io/docs/tooling/linter#enforce-default-message',
34
37
  },
35
38
  fixable: 'code',
36
39
  schema: [
37
40
  {
38
- enum: ['literal', 'anything'],
41
+ type: 'string',
42
+ enum: Object.keys(Option),
39
43
  },
40
44
  ],
45
+ messages: {
46
+ defaultMessageLiteral: `"defaultMessage" must be:
47
+ - a string literal or
48
+ - template literal without variable`,
49
+ defaultMessage: '`defaultMessage` has to be specified in message descriptor',
50
+ },
41
51
  },
52
+ defaultOptions: [],
42
53
  create(context) {
43
54
  const callExpressionVisitor = (node) => checkNode(context, node);
55
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
44
56
  if (context.parserServices.defineTemplateBodyVisitor) {
57
+ //@ts-expect-error
45
58
  return context.parserServices.defineTemplateBodyVisitor({
46
59
  CallExpression: callExpressionVisitor,
47
60
  }, {
@@ -54,4 +67,3 @@ const rule = {
54
67
  };
55
68
  },
56
69
  };
57
- exports.default = rule;
@@ -1,3 +1,10 @@
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
+ export declare enum Option {
3
+ literal = "literal",
4
+ anything = "anything"
5
+ }
6
+ type MessageIds = 'enforceDescription' | 'enforceDescriptionLiteral';
7
+ type Options = [`${Option}`?];
8
+ export declare const name = "enforce-description";
9
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
10
+ export {};
@@ -1,6 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rule = exports.name = exports.Option = void 0;
3
4
  const util_1 = require("../util");
5
+ var Option;
6
+ (function (Option) {
7
+ Option["literal"] = "literal";
8
+ Option["anything"] = "anything";
9
+ })(Option || (exports.Option = Option = {}));
4
10
  function checkNode(context, node) {
5
11
  const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
6
12
  const { options: [type], } = context;
@@ -9,37 +15,44 @@ function checkNode(context, node) {
9
15
  if (type === 'literal' && descriptionNode) {
10
16
  context.report({
11
17
  node: descriptionNode,
12
- message: '`description` has to be a string literal (not function call or variable)',
18
+ messageId: 'enforceDescriptionLiteral',
13
19
  });
14
20
  }
15
21
  else if (!descriptionNode) {
16
22
  context.report({
17
23
  node: node,
18
- message: '`description` has to be specified in message descriptor',
24
+ messageId: 'enforceDescription',
19
25
  });
20
26
  }
21
27
  }
22
28
  }
23
29
  }
24
- exports.default = {
30
+ exports.name = 'enforce-description';
31
+ exports.rule = {
25
32
  meta: {
26
33
  type: 'problem',
27
34
  docs: {
28
35
  description: 'Enforce description in message descriptor',
29
- category: 'Errors',
30
- recommended: false,
31
36
  url: 'https://formatjs.io/docs/tooling/linter#enforce-description',
32
37
  },
33
38
  fixable: 'code',
34
39
  schema: [
35
40
  {
36
- enum: ['literal', 'anything'],
41
+ type: 'string',
42
+ enum: Object.keys(Option),
37
43
  },
38
44
  ],
45
+ messages: {
46
+ enforceDescription: '`description` has to be specified in message descriptor',
47
+ enforceDescriptionLiteral: '`description` has to be a string literal (not function call or variable)',
48
+ },
39
49
  },
50
+ defaultOptions: [],
40
51
  create(context) {
41
52
  const callExpressionVisitor = (node) => checkNode(context, node);
53
+ //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
42
54
  if (context.parserServices.defineTemplateBodyVisitor) {
55
+ //@ts-expect-error
43
56
  return context.parserServices.defineTemplateBodyVisitor({
44
57
  CallExpression: callExpressionVisitor,
45
58
  }, {
@@ -1,3 +1,10 @@
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
+ export type Option = {
3
+ idInterpolationPattern: string;
4
+ idWhitelist?: string[];
5
+ };
6
+ type MessageIds = 'enforceId' | 'enforceIdDefaultMessage' | 'enforceIdDescription' | 'enforceIdMatching' | 'enforceIdMatchingAllowlisted';
7
+ type Options = [Option];
8
+ export declare const name = "enforce-id";
9
+ export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
10
+ export {};