eslint-plugin-formatjs 5.4.2 → 6.0.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 (74) hide show
  1. package/context-compat.js +1 -5
  2. package/index.d.ts +15 -1
  3. package/index.js +46 -45
  4. package/package.json +5 -3
  5. package/rules/blocklist-elements.d.ts +1 -2
  6. package/rules/blocklist-elements.js +23 -26
  7. package/rules/enforce-default-message.js +8 -11
  8. package/rules/enforce-description.js +8 -11
  9. package/rules/enforce-id.d.ts +1 -0
  10. package/rules/enforce-id.js +21 -14
  11. package/rules/enforce-placeholders.js +14 -17
  12. package/rules/enforce-plural-rules.js +10 -13
  13. package/rules/no-camel-case.js +11 -14
  14. package/rules/no-complex-selectors.js +13 -16
  15. package/rules/no-emoji.js +11 -14
  16. package/rules/no-id.js +6 -9
  17. package/rules/no-invalid-icu.js +9 -12
  18. package/rules/no-literal-string-in-jsx.js +33 -13
  19. package/rules/no-literal-string-in-object.js +8 -11
  20. package/rules/no-missing-icu-plural-one-placeholders.js +15 -19
  21. package/rules/no-multiple-plurals.js +10 -13
  22. package/rules/no-multiple-whitespaces.js +27 -32
  23. package/rules/no-offset.js +10 -13
  24. package/rules/no-useless-message.js +13 -16
  25. package/rules/prefer-formatted-message.js +4 -7
  26. package/rules/prefer-pound-in-plural.js +25 -29
  27. package/util.js +5 -12
  28. package/lib_esnext/context-compat.d.ts +0 -3
  29. package/lib_esnext/context-compat.js +0 -6
  30. package/lib_esnext/index.d.ts +0 -1
  31. package/lib_esnext/index.js +0 -146
  32. package/lib_esnext/package.json +0 -31
  33. package/lib_esnext/rules/blocklist-elements.d.ts +0 -15
  34. package/lib_esnext/rules/blocklist-elements.js +0 -132
  35. package/lib_esnext/rules/enforce-default-message.d.ts +0 -10
  36. package/lib_esnext/rules/enforce-default-message.js +0 -68
  37. package/lib_esnext/rules/enforce-description.d.ts +0 -10
  38. package/lib_esnext/rules/enforce-description.js +0 -66
  39. package/lib_esnext/rules/enforce-id.d.ts +0 -10
  40. package/lib_esnext/rules/enforce-id.js +0 -153
  41. package/lib_esnext/rules/enforce-placeholders.d.ts +0 -8
  42. package/lib_esnext/rules/enforce-placeholders.js +0 -147
  43. package/lib_esnext/rules/enforce-plural-rules.d.ts +0 -17
  44. package/lib_esnext/rules/enforce-plural-rules.js +0 -103
  45. package/lib_esnext/rules/no-camel-case.d.ts +0 -5
  46. package/lib_esnext/rules/no-camel-case.js +0 -76
  47. package/lib_esnext/rules/no-complex-selectors.d.ts +0 -9
  48. package/lib_esnext/rules/no-complex-selectors.js +0 -136
  49. package/lib_esnext/rules/no-emoji.d.ts +0 -9
  50. package/lib_esnext/rules/no-emoji.js +0 -99
  51. package/lib_esnext/rules/no-id.d.ts +0 -5
  52. package/lib_esnext/rules/no-id.js +0 -58
  53. package/lib_esnext/rules/no-invalid-icu.d.ts +0 -5
  54. package/lib_esnext/rules/no-invalid-icu.js +0 -60
  55. package/lib_esnext/rules/no-literal-string-in-jsx.d.ts +0 -13
  56. package/lib_esnext/rules/no-literal-string-in-jsx.js +0 -179
  57. package/lib_esnext/rules/no-literal-string-in-object.d.ts +0 -9
  58. package/lib_esnext/rules/no-literal-string-in-object.js +0 -90
  59. package/lib_esnext/rules/no-missing-icu-plural-one-placeholders.d.ts +0 -6
  60. package/lib_esnext/rules/no-missing-icu-plural-one-placeholders.js +0 -99
  61. package/lib_esnext/rules/no-multiple-plurals.d.ts +0 -5
  62. package/lib_esnext/rules/no-multiple-plurals.js +0 -70
  63. package/lib_esnext/rules/no-multiple-whitespaces.d.ts +0 -5
  64. package/lib_esnext/rules/no-multiple-whitespaces.js +0 -141
  65. package/lib_esnext/rules/no-offset.d.ts +0 -5
  66. package/lib_esnext/rules/no-offset.js +0 -69
  67. package/lib_esnext/rules/no-useless-message.d.ts +0 -5
  68. package/lib_esnext/rules/no-useless-message.js +0 -71
  69. package/lib_esnext/rules/prefer-formatted-message.d.ts +0 -5
  70. package/lib_esnext/rules/prefer-formatted-message.js +0 -33
  71. package/lib_esnext/rules/prefer-pound-in-plural.d.ts +0 -5
  72. package/lib_esnext/rules/prefer-pound-in-plural.js +0 -191
  73. package/lib_esnext/util.d.ts +0 -32
  74. package/lib_esnext/util.js +0 -280
package/context-compat.js CHANGED
@@ -1,10 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getParserServices = void 0;
4
- const getParserServices = (context) => {
1
+ export const getParserServices = (context) => {
5
2
  if (context.parserServices) {
6
3
  return context.parserServices;
7
4
  }
8
5
  return context.sourceCode.parserServices;
9
6
  };
10
- exports.getParserServices = getParserServices;
package/index.d.ts CHANGED
@@ -1 +1,15 @@
1
- export {};
1
+ import type { Linter } from 'eslint';
2
+ import { ESLint } from 'eslint';
3
+ type Plugin = {
4
+ meta: {
5
+ name: string;
6
+ version: string;
7
+ };
8
+ rules: ESLint.Plugin['rules'];
9
+ configs: {
10
+ strict: Linter.Config;
11
+ recommended: Linter.Config;
12
+ };
13
+ };
14
+ declare const plugin: Plugin;
15
+ export default plugin;
package/index.js CHANGED
@@ -1,73 +1,74 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
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 enforce_plural_rules_1 = require("./rules/enforce-plural-rules");
9
- const no_camel_case_1 = require("./rules/no-camel-case");
10
- const no_complex_selectors_1 = require("./rules/no-complex-selectors");
11
- const no_emoji_1 = require("./rules/no-emoji");
12
- const no_id_1 = require("./rules/no-id");
13
- const no_invalid_icu_1 = require("./rules/no-invalid-icu");
14
- const no_literal_string_in_jsx_1 = require("./rules/no-literal-string-in-jsx");
15
- const no_missing_icu_plural_one_placeholders_1 = require("./rules/no-missing-icu-plural-one-placeholders");
16
- const no_multiple_plurals_1 = require("./rules/no-multiple-plurals");
17
- const no_multiple_whitespaces_1 = require("./rules/no-multiple-whitespaces");
18
- const no_offset_1 = require("./rules/no-offset");
19
- const no_useless_message_1 = require("./rules/no-useless-message");
20
- const prefer_formatted_message_1 = require("./rules/prefer-formatted-message");
21
- const prefer_pound_in_plural_1 = require("./rules/prefer-pound-in-plural");
22
- const no_literal_string_in_object_1 = require("./rules/no-literal-string-in-object");
23
- const package_json_1 = require("./package.json");
1
+ import { name as blocklistElementRuleName, rule as blocklistElements, } from './rules/blocklist-elements.js';
2
+ import { rule as enforceDefaultMessage, name as enforceDefaultMessageName, } from './rules/enforce-default-message.js';
3
+ import { rule as enforceDescription, name as enforceDescriptionName, } from './rules/enforce-description.js';
4
+ import { rule as enforceId, name as enforceIdName } from './rules/enforce-id.js';
5
+ import { rule as enforcePlaceholders, name as enforcePlaceholdersName, } from './rules/enforce-placeholders.js';
6
+ import { rule as enforcePluralRules, name as enforcePluralRulesName, } from './rules/enforce-plural-rules.js';
7
+ import { rule as noCamelCase, name as noCamelCaseName, } from './rules/no-camel-case.js';
8
+ import { rule as noComplexSelectors, name as noComplexSelectorsName, } from './rules/no-complex-selectors.js';
9
+ import { rule as noEmoji, name as noEmojiName } from './rules/no-emoji.js';
10
+ import { rule as noId, name as noIdName } from './rules/no-id.js';
11
+ import { rule as noInvalidICU, name as noInvalidICUName, } from './rules/no-invalid-icu.js';
12
+ import { rule as noLiteralStringInJsx, name as noLiteralStringInJsxName, } from './rules/no-literal-string-in-jsx.js';
13
+ import { rule as noMissingIcuPluralOnePlaceholders, name as noMissingIcuPluralOnePlaceholdersName, } from './rules/no-missing-icu-plural-one-placeholders.js';
14
+ import { rule as noMultiplePlurals, name as noMultiplePluralsName, } from './rules/no-multiple-plurals.js';
15
+ import { rule as noMultipleWhitespaces, name as noMultipleWhitespacesName, } from './rules/no-multiple-whitespaces.js';
16
+ import { rule as noOffset, name as noOffsetName } from './rules/no-offset.js';
17
+ import { rule as noUselessMessage, name as noUselessMessageName, } from './rules/no-useless-message.js';
18
+ import { rule as preferFormattedMessage, name as preferFormattedMessageName, } from './rules/prefer-formatted-message.js';
19
+ import { rule as preferPoundInPlural, name as preferPoundInPluralName, } from './rules/prefer-pound-in-plural.js';
20
+ import { rule as noLiteralStringInObject, name as noLiteralStringInObjectName, } from './rules/no-literal-string-in-object.js';
21
+ import * as packageJsonNs from './package.json' with { type: 'json' };
22
+ const packageJson = packageJsonNs.default ?? packageJsonNs;
23
+ const { name, version } = packageJson;
24
24
  // All rules
25
25
  const rules = {
26
26
  // @ts-expect-error
27
- [blocklist_elements_1.name]: blocklist_elements_1.rule,
27
+ [blocklistElementRuleName]: blocklistElements,
28
28
  // @ts-expect-error
29
- [enforce_default_message_1.name]: enforce_default_message_1.rule,
29
+ [enforceDefaultMessageName]: enforceDefaultMessage,
30
30
  // @ts-expect-error
31
- [enforce_description_1.name]: enforce_description_1.rule,
31
+ [enforceDescriptionName]: enforceDescription,
32
32
  // @ts-expect-error
33
- [enforce_id_1.name]: enforce_id_1.rule,
33
+ [enforceIdName]: enforceId,
34
34
  // @ts-expect-error
35
- [enforce_placeholders_1.name]: enforce_placeholders_1.rule,
35
+ [enforcePlaceholdersName]: enforcePlaceholders,
36
36
  // @ts-expect-error
37
- [enforce_plural_rules_1.name]: enforce_plural_rules_1.rule,
37
+ [enforcePluralRulesName]: enforcePluralRules,
38
38
  // @ts-expect-error
39
- [no_camel_case_1.name]: no_camel_case_1.rule,
39
+ [noCamelCaseName]: noCamelCase,
40
40
  // @ts-expect-error
41
- [no_complex_selectors_1.name]: no_complex_selectors_1.rule,
41
+ [noComplexSelectorsName]: noComplexSelectors,
42
42
  // @ts-expect-error
43
- [no_emoji_1.name]: no_emoji_1.rule,
43
+ [noEmojiName]: noEmoji,
44
44
  // @ts-expect-error
45
- [no_id_1.name]: no_id_1.rule,
45
+ [noIdName]: noId,
46
46
  // @ts-expect-error
47
- [no_invalid_icu_1.name]: no_invalid_icu_1.rule,
47
+ [noInvalidICUName]: noInvalidICU,
48
48
  // @ts-expect-error
49
- [no_literal_string_in_jsx_1.name]: no_literal_string_in_jsx_1.rule,
49
+ [noLiteralStringInJsxName]: noLiteralStringInJsx,
50
50
  // @ts-expect-error
51
- [no_multiple_plurals_1.name]: no_multiple_plurals_1.rule,
51
+ [noMultiplePluralsName]: noMultiplePlurals,
52
52
  // @ts-expect-error
53
- [no_multiple_whitespaces_1.name]: no_multiple_whitespaces_1.rule,
53
+ [noMultipleWhitespacesName]: noMultipleWhitespaces,
54
54
  // @ts-expect-error
55
- [no_offset_1.name]: no_offset_1.rule,
55
+ [noOffsetName]: noOffset,
56
56
  // @ts-expect-error
57
- [no_useless_message_1.name]: no_useless_message_1.rule,
57
+ [noUselessMessageName]: noUselessMessage,
58
58
  // @ts-expect-error
59
- [prefer_formatted_message_1.name]: prefer_formatted_message_1.rule,
59
+ [preferFormattedMessageName]: preferFormattedMessage,
60
60
  // @ts-expect-error
61
- [prefer_pound_in_plural_1.name]: prefer_pound_in_plural_1.rule,
61
+ [preferPoundInPluralName]: preferPoundInPlural,
62
62
  // @ts-expect-error
63
- [no_missing_icu_plural_one_placeholders_1.name]: no_missing_icu_plural_one_placeholders_1.rule,
63
+ [noMissingIcuPluralOnePlaceholdersName]: noMissingIcuPluralOnePlaceholders,
64
64
  // @ts-expect-error
65
- [no_literal_string_in_object_1.name]: no_literal_string_in_object_1.rule,
65
+ [noLiteralStringInObjectName]: noLiteralStringInObject,
66
66
  };
67
67
  // Base plugin
68
68
  const plugin = {
69
- meta: { name: package_json_1.name, version: package_json_1.version },
69
+ meta: { name, version },
70
70
  rules,
71
+ configs: {}, // will be populated later
71
72
  };
72
73
  // Configs
73
74
  const configs = {
@@ -145,4 +146,4 @@ const configs = {
145
146
  },
146
147
  };
147
148
  plugin.configs = configs;
148
- module.exports = plugin;
149
+ export default plugin;
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "eslint-plugin-formatjs",
3
3
  "description": "ESLint plugin for formatjs",
4
- "version": "5.4.2",
4
+ "version": "6.0.1",
5
5
  "license": "MIT",
6
6
  "author": "Long Ho <holevietlong@gmail.com>",
7
+ "type": "module",
8
+ "types": "index.d.ts",
7
9
  "dependencies": {
8
10
  "@types/eslint": "^9.6.1",
9
11
  "@types/picomatch": "^3",
@@ -12,8 +14,8 @@
12
14
  "picomatch": "2 || 3 || 4",
13
15
  "tslib": "^2.8.0",
14
16
  "unicode-emoji-utils": "^1.2.0",
15
- "@formatjs/icu-messageformat-parser": "2.11.4",
16
- "@formatjs/ts-transformer": "3.14.2"
17
+ "@formatjs/icu-messageformat-parser": "3.0.1",
18
+ "@formatjs/ts-transformer": "4.0.1"
17
19
  },
18
20
  "peerDependencies": {
19
21
  "eslint": "^9.23.0"
@@ -11,5 +11,4 @@ export declare enum Element {
11
11
  plural = "plural",
12
12
  tag = "tag"
13
13
  }
14
- export declare const rule: ESLintUtils.RuleModule<'blocklist', [
15
- ], unknown, ESLintUtils.RuleListener>;
14
+ export declare const rule: ESLintUtils.RuleModule<'blocklist', Element[][], unknown, ESLintUtils.RuleListener>;
@@ -1,18 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.Element = exports.name = void 0;
4
- const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
5
- const utils_1 = require("@typescript-eslint/utils");
6
- const context_compat_1 = require("../context-compat");
7
- const util_1 = require("../util");
8
- exports.name = 'blocklist-elements';
1
+ import { isArgumentElement, isDateElement, isLiteralElement, isNumberElement, isPluralElement, isSelectElement, isTagElement, isTimeElement, parse, } from '@formatjs/icu-messageformat-parser';
2
+ import { ESLintUtils } from '@typescript-eslint/utils';
3
+ import { getParserServices } from '../context-compat.js';
4
+ import { extractMessages, getSettings } from '../util.js';
5
+ export const name = 'blocklist-elements';
9
6
  function getMessage(type) {
10
7
  return {
11
8
  messageId: 'blocklist',
12
9
  data: { type },
13
10
  };
14
11
  }
15
- var Element;
12
+ export var Element;
16
13
  (function (Element) {
17
14
  Element["literal"] = "literal";
18
15
  Element["argument"] = "argument";
@@ -23,32 +20,32 @@ var Element;
23
20
  Element["selectordinal"] = "selectordinal";
24
21
  Element["plural"] = "plural";
25
22
  Element["tag"] = "tag";
26
- })(Element || (exports.Element = Element = {}));
23
+ })(Element || (Element = {}));
27
24
  function verifyAst(blocklist, ast) {
28
25
  const errors = [];
29
26
  for (const el of ast) {
30
- if ((0, icu_messageformat_parser_1.isLiteralElement)(el) && blocklist.includes(Element.literal)) {
27
+ if (isLiteralElement(el) && blocklist.includes(Element.literal)) {
31
28
  errors.push(getMessage(Element.literal));
32
29
  }
33
- if ((0, icu_messageformat_parser_1.isArgumentElement)(el) && blocklist.includes(Element.argument)) {
30
+ if (isArgumentElement(el) && blocklist.includes(Element.argument)) {
34
31
  errors.push(getMessage(Element.argument));
35
32
  }
36
- if ((0, icu_messageformat_parser_1.isNumberElement)(el) && blocklist.includes(Element.number)) {
33
+ if (isNumberElement(el) && blocklist.includes(Element.number)) {
37
34
  errors.push(getMessage(Element.number));
38
35
  }
39
- if ((0, icu_messageformat_parser_1.isDateElement)(el) && blocklist.includes(Element.date)) {
36
+ if (isDateElement(el) && blocklist.includes(Element.date)) {
40
37
  errors.push(getMessage(Element.date));
41
38
  }
42
- if ((0, icu_messageformat_parser_1.isTimeElement)(el) && blocklist.includes(Element.time)) {
39
+ if (isTimeElement(el) && blocklist.includes(Element.time)) {
43
40
  errors.push(getMessage(Element.time));
44
41
  }
45
- if ((0, icu_messageformat_parser_1.isSelectElement)(el) && blocklist.includes(Element.select)) {
42
+ if (isSelectElement(el) && blocklist.includes(Element.select)) {
46
43
  errors.push(getMessage(Element.select));
47
44
  }
48
- if ((0, icu_messageformat_parser_1.isTagElement)(el) && blocklist.includes(Element.tag)) {
45
+ if (isTagElement(el) && blocklist.includes(Element.tag)) {
49
46
  errors.push(getMessage(Element.tag));
50
47
  }
51
- if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
48
+ if (isPluralElement(el)) {
52
49
  if (blocklist.includes(Element.plural)) {
53
50
  errors.push(getMessage(Element.argument));
54
51
  }
@@ -57,7 +54,7 @@ function verifyAst(blocklist, ast) {
57
54
  errors.push(getMessage(Element.selectordinal));
58
55
  }
59
56
  }
60
- if ((0, icu_messageformat_parser_1.isSelectElement)(el) || (0, icu_messageformat_parser_1.isPluralElement)(el)) {
57
+ if (isSelectElement(el) || isPluralElement(el)) {
61
58
  const { options } = el;
62
59
  for (const selector of Object.keys(options)) {
63
60
  verifyAst(blocklist, options[selector].value);
@@ -67,8 +64,8 @@ function verifyAst(blocklist, ast) {
67
64
  return errors;
68
65
  }
69
66
  function checkNode(context, node) {
70
- const settings = (0, util_1.getSettings)(context);
71
- const msgs = (0, util_1.extractMessages)(node, settings);
67
+ const settings = getSettings(context);
68
+ const msgs = extractMessages(node, settings);
72
69
  if (!msgs.length) {
73
70
  return;
74
71
  }
@@ -80,7 +77,7 @@ function checkNode(context, node) {
80
77
  if (!defaultMessage || !messageNode) {
81
78
  continue;
82
79
  }
83
- const errors = verifyAst(blocklist, (0, icu_messageformat_parser_1.parse)(defaultMessage, {
80
+ const errors = verifyAst(blocklist, parse(defaultMessage, {
84
81
  ignoreTag: settings.ignoreTag,
85
82
  }));
86
83
  for (const error of errors) {
@@ -91,9 +88,9 @@ function checkNode(context, node) {
91
88
  }
92
89
  }
93
90
  }
94
- const createRule = utils_1.ESLintUtils.RuleCreator(_ => 'https://formatjs.github.io/docs/tooling/linter#blocklist-elements');
95
- exports.rule = createRule({
96
- name: exports.name,
91
+ const createRule = ESLintUtils.RuleCreator(_ => 'https://formatjs.github.io/docs/tooling/linter#blocklist-elements');
92
+ export const rule = createRule({
93
+ name,
97
94
  meta: {
98
95
  type: 'problem',
99
96
  docs: {
@@ -117,7 +114,7 @@ exports.rule = createRule({
117
114
  defaultOptions: [],
118
115
  create(context) {
119
116
  const callExpressionVisitor = node => checkNode(context, node);
120
- const parserServices = (0, context_compat_1.getParserServices)(context);
117
+ const parserServices = getParserServices(context);
121
118
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
122
119
  if (parserServices?.defineTemplateBodyVisitor) {
123
120
  //@ts-expect-error
@@ -1,16 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = exports.Option = void 0;
4
- const context_compat_1 = require("../context-compat");
5
- const util_1 = require("../util");
6
- var Option;
1
+ import { getParserServices } from '../context-compat.js';
2
+ import { extractMessages, getSettings } from '../util.js';
3
+ export var Option;
7
4
  (function (Option) {
8
5
  Option["literal"] = "literal";
9
6
  Option["anything"] = "anything";
10
- })(Option || (exports.Option = Option = {}));
11
- exports.name = 'enforce-default-message';
7
+ })(Option || (Option = {}));
8
+ export const name = 'enforce-default-message';
12
9
  function checkNode(context, node) {
13
- const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
10
+ const msgs = extractMessages(node, getSettings(context));
14
11
  const { options: [type], } = context;
15
12
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
16
13
  if (!defaultMessage) {
@@ -29,7 +26,7 @@ function checkNode(context, node) {
29
26
  }
30
27
  }
31
28
  }
32
- exports.rule = {
29
+ export const rule = {
33
30
  meta: {
34
31
  type: 'problem',
35
32
  docs: {
@@ -53,7 +50,7 @@ exports.rule = {
53
50
  defaultOptions: [],
54
51
  create(context) {
55
52
  const callExpressionVisitor = (node) => checkNode(context, node);
56
- const parserServices = (0, context_compat_1.getParserServices)(context);
53
+ const parserServices = getParserServices(context);
57
54
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
58
55
  if (parserServices?.defineTemplateBodyVisitor) {
59
56
  //@ts-expect-error
@@ -1,15 +1,12 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = exports.Option = void 0;
4
- const context_compat_1 = require("../context-compat");
5
- const util_1 = require("../util");
6
- var Option;
1
+ import { getParserServices } from '../context-compat.js';
2
+ import { extractMessages, getSettings } from '../util.js';
3
+ export var Option;
7
4
  (function (Option) {
8
5
  Option["literal"] = "literal";
9
6
  Option["anything"] = "anything";
10
- })(Option || (exports.Option = Option = {}));
7
+ })(Option || (Option = {}));
11
8
  function checkNode(context, node) {
12
- const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
9
+ const msgs = extractMessages(node, getSettings(context));
13
10
  const { options: [type], } = context;
14
11
  for (const [{ message: { description }, descriptionNode, },] of msgs) {
15
12
  if (!description) {
@@ -28,8 +25,8 @@ function checkNode(context, node) {
28
25
  }
29
26
  }
30
27
  }
31
- exports.name = 'enforce-description';
32
- exports.rule = {
28
+ export const name = 'enforce-description';
29
+ export const rule = {
33
30
  meta: {
34
31
  type: 'problem',
35
32
  docs: {
@@ -51,7 +48,7 @@ exports.rule = {
51
48
  defaultOptions: [],
52
49
  create(context) {
53
50
  const callExpressionVisitor = (node) => checkNode(context, node);
54
- const parserServices = (0, context_compat_1.getParserServices)(context);
51
+ const parserServices = getParserServices(context);
55
52
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
56
53
  if (parserServices?.defineTemplateBodyVisitor) {
57
54
  //@ts-expect-error
@@ -2,6 +2,7 @@ import { RuleModule } from '@typescript-eslint/utils/ts-eslint';
2
2
  export type Option = {
3
3
  idInterpolationPattern: string;
4
4
  idWhitelist?: string[];
5
+ quoteStyle?: 'single' | 'double';
5
6
  };
6
7
  type MessageIds = 'enforceId' | 'enforceIdDefaultMessage' | 'enforceIdDescription' | 'enforceIdMatching' | 'enforceIdMatchingAllowlisted';
7
8
  type Options = [Option];
@@ -1,11 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = void 0;
4
- const ts_transformer_1 = require("@formatjs/ts-transformer");
5
- const context_compat_1 = require("../context-compat");
6
- const util_1 = require("../util");
7
- function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps, }) {
8
- const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
1
+ import { interpolateName } from '@formatjs/ts-transformer';
2
+ import { getParserServices } from '../context-compat.js';
3
+ import { extractMessages, getSettings } from '../util.js';
4
+ function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps, quoteStyle, }) {
5
+ const msgs = extractMessages(node, getSettings(context));
9
6
  for (const [{ message: { defaultMessage, description, id }, idPropNode, descriptionNode, messagePropNode, },] of msgs) {
10
7
  if (!idInterpolationPattern && !idPropNode) {
11
8
  context.report({
@@ -33,7 +30,7 @@ function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps,
33
30
  // messageId is allowlisted so skip interpolation id check
34
31
  continue;
35
32
  }
36
- const correctId = (0, ts_transformer_1.interpolateName)({
33
+ const correctId = interpolateName({
37
34
  resourcePath: context.getFilename(),
38
35
  }, idInterpolationPattern, {
39
36
  content: description
@@ -56,6 +53,7 @@ function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps,
56
53
  .join(', '),
57
54
  };
58
55
  }
56
+ const quote = quoteStyle === 'double' ? '"' : "'";
59
57
  context.report({
60
58
  node,
61
59
  messageId,
@@ -63,16 +61,18 @@ function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps,
63
61
  fix(fixer) {
64
62
  if (idPropNode) {
65
63
  if (idPropNode.type === 'JSXAttribute') {
64
+ // Always use double quotes for JSX attributes
66
65
  return fixer.replaceText(idPropNode, `id="${correctId}"`);
67
66
  }
68
- return fixer.replaceText(idPropNode, `id: '${correctId}'`);
67
+ return fixer.replaceText(idPropNode, `id: ${quote}${correctId}${quote}`);
69
68
  }
70
69
  if (messagePropNode) {
71
70
  // Insert after default message node
72
71
  if (messagePropNode.type === 'JSXAttribute') {
72
+ // Always use double quotes for JSX attributes
73
73
  return fixer.insertTextAfter(messagePropNode, ` id="${correctId}"`);
74
74
  }
75
- return fixer.insertTextAfter(messagePropNode, `, id: '${correctId}'`);
75
+ return fixer.insertTextAfter(messagePropNode, `, id: ${quote}${correctId}${quote}`);
76
76
  }
77
77
  return null;
78
78
  },
@@ -82,8 +82,8 @@ function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps,
82
82
  }
83
83
  }
84
84
  }
85
- exports.name = 'enforce-id';
86
- exports.rule = {
85
+ export const name = 'enforce-id';
86
+ export const rule = {
87
87
  meta: {
88
88
  type: 'problem',
89
89
  docs: {
@@ -106,6 +106,11 @@ exports.rule = {
106
106
  type: 'string',
107
107
  },
108
108
  },
109
+ quoteStyle: {
110
+ type: 'string',
111
+ enum: ['single', 'double'],
112
+ description: 'Quote style for generated IDs. Defaults to single quotes.',
113
+ },
109
114
  },
110
115
  required: ['idInterpolationPattern'],
111
116
  additionalProperties: false,
@@ -126,19 +131,21 @@ Actual: {{actual}}`,
126
131
  defaultOptions: [
127
132
  {
128
133
  idInterpolationPattern: '[sha512:contenthash:base64:6]',
134
+ quoteStyle: 'single',
129
135
  },
130
136
  ],
131
137
  create(context) {
132
138
  const tmp = context.options[0];
133
139
  let opts = {
134
140
  idInterpolationPattern: tmp?.idInterpolationPattern,
141
+ quoteStyle: tmp?.quoteStyle || 'single',
135
142
  };
136
143
  if (Array.isArray(tmp?.idWhitelist)) {
137
144
  const { idWhitelist } = tmp;
138
145
  opts.idWhitelistRegexps = idWhitelist.map((str) => new RegExp(str, 'i'));
139
146
  }
140
147
  const callExpressionVisitor = (node) => checkNode(context, node, opts);
141
- const parserServices = (0, context_compat_1.getParserServices)(context);
148
+ const parserServices = getParserServices(context);
142
149
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
143
150
  if (parserServices?.defineTemplateBodyVisitor) {
144
151
  //@ts-expect-error
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = void 0;
4
- const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
5
- const context_compat_1 = require("../context-compat");
6
- const util_1 = require("../util");
1
+ import { TYPE, parse, } from '@formatjs/icu-messageformat-parser';
2
+ import { getParserServices } from '../context-compat.js';
3
+ import { extractMessages, getSettings } from '../util.js';
7
4
  function collectPlaceholderNames(ast) {
8
5
  const placeholderNames = new Set();
9
6
  _traverse(ast);
@@ -11,15 +8,15 @@ function collectPlaceholderNames(ast) {
11
8
  function _traverse(ast) {
12
9
  for (const element of ast) {
13
10
  switch (element.type) {
14
- case icu_messageformat_parser_1.TYPE.literal:
15
- case icu_messageformat_parser_1.TYPE.pound:
11
+ case TYPE.literal:
12
+ case TYPE.pound:
16
13
  break;
17
- case icu_messageformat_parser_1.TYPE.tag:
14
+ case TYPE.tag:
18
15
  placeholderNames.add(element.value);
19
16
  _traverse(element.children);
20
17
  break;
21
- case icu_messageformat_parser_1.TYPE.plural:
22
- case icu_messageformat_parser_1.TYPE.select:
18
+ case TYPE.plural:
19
+ case TYPE.select:
23
20
  placeholderNames.add(element.value);
24
21
  for (const { value } of Object.values(element.options)) {
25
22
  _traverse(value);
@@ -33,8 +30,8 @@ function collectPlaceholderNames(ast) {
33
30
  }
34
31
  }
35
32
  function checkNode(context, node) {
36
- const settings = (0, util_1.getSettings)(context);
37
- const msgs = (0, util_1.extractMessages)(node, {
33
+ const settings = getSettings(context);
34
+ const msgs = extractMessages(node, {
38
35
  excludeMessageDeclCalls: true,
39
36
  ...settings,
40
37
  });
@@ -65,7 +62,7 @@ function checkNode(context, node) {
65
62
  }
66
63
  let ast;
67
64
  try {
68
- ast = (0, icu_messageformat_parser_1.parse)(defaultMessage, { ignoreTag: settings.ignoreTag });
65
+ ast = parse(defaultMessage, { ignoreTag: settings.ignoreTag });
69
66
  }
70
67
  catch (e) {
71
68
  context.report({
@@ -101,8 +98,8 @@ function checkNode(context, node) {
101
98
  });
102
99
  }
103
100
  }
104
- exports.name = 'enforce-placeholders';
105
- exports.rule = {
101
+ export const name = 'enforce-placeholders';
102
+ export const rule = {
106
103
  meta: {
107
104
  type: 'problem',
108
105
  docs: {
@@ -132,7 +129,7 @@ exports.rule = {
132
129
  defaultOptions: [],
133
130
  create(context) {
134
131
  const callExpressionVisitor = (node) => checkNode(context, node);
135
- const parserServices = (0, context_compat_1.getParserServices)(context);
132
+ const parserServices = getParserServices(context);
136
133
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
137
134
  if (parserServices?.defineTemplateBodyVisitor) {
138
135
  //@ts-expect-error
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = void 0;
4
- const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
5
- const context_compat_1 = require("../context-compat");
6
- const util_1 = require("../util");
1
+ import { isPluralElement, parse, } from '@formatjs/icu-messageformat-parser';
2
+ import { getParserServices } from '../context-compat.js';
3
+ import { extractMessages, getSettings } from '../util.js';
7
4
  var LDML;
8
5
  (function (LDML) {
9
6
  LDML["zero"] = "zero";
@@ -16,7 +13,7 @@ var LDML;
16
13
  function verifyAst(plConfig, ast) {
17
14
  const errors = [];
18
15
  for (const el of ast) {
19
- if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
16
+ if (isPluralElement(el)) {
20
17
  const rules = Object.keys(plConfig);
21
18
  for (const rule of rules) {
22
19
  if (plConfig[rule] && !el.options[rule]) {
@@ -35,8 +32,8 @@ function verifyAst(plConfig, ast) {
35
32
  return errors;
36
33
  }
37
34
  function checkNode(context, node) {
38
- const settings = (0, util_1.getSettings)(context);
39
- const msgs = (0, util_1.extractMessages)(node, settings);
35
+ const settings = getSettings(context);
36
+ const msgs = extractMessages(node, settings);
40
37
  if (!msgs.length) {
41
38
  return;
42
39
  }
@@ -48,7 +45,7 @@ function checkNode(context, node) {
48
45
  if (!defaultMessage || !messageNode) {
49
46
  continue;
50
47
  }
51
- const errors = verifyAst(plConfig, (0, icu_messageformat_parser_1.parse)(defaultMessage, {
48
+ const errors = verifyAst(plConfig, parse(defaultMessage, {
52
49
  ignoreTag: settings.ignoreTag,
53
50
  }));
54
51
  for (const error of errors) {
@@ -59,8 +56,8 @@ function checkNode(context, node) {
59
56
  }
60
57
  }
61
58
  }
62
- exports.name = 'enforce-plural-rules';
63
- exports.rule = {
59
+ export const name = 'enforce-plural-rules';
60
+ export const rule = {
64
61
  meta: {
65
62
  type: 'problem',
66
63
  docs: {
@@ -88,7 +85,7 @@ exports.rule = {
88
85
  defaultOptions: [],
89
86
  create(context) {
90
87
  const callExpressionVisitor = (node) => checkNode(context, node);
91
- const parserServices = (0, context_compat_1.getParserServices)(context);
88
+ const parserServices = getParserServices(context);
92
89
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
93
90
  if (parserServices?.defineTemplateBodyVisitor) {
94
91
  //@ts-expect-error