eslint-plugin-formatjs 5.4.2 → 6.0.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 (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 +12 -10
  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
@@ -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
@@ -1,21 +1,18 @@
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");
7
- exports.name = 'no-camel-case';
1
+ import { isArgumentElement, isPluralElement, parse, } from '@formatjs/icu-messageformat-parser';
2
+ import { getParserServices } from '../context-compat.js';
3
+ import { extractMessages, getSettings } from '../util.js';
4
+ export const name = 'no-camel-case';
8
5
  const CAMEL_CASE_REGEX = /[A-Z]/;
9
6
  function verifyAst(ast) {
10
7
  const errors = [];
11
8
  for (const el of ast) {
12
- if ((0, icu_messageformat_parser_1.isArgumentElement)(el)) {
9
+ if (isArgumentElement(el)) {
13
10
  if (CAMEL_CASE_REGEX.test(el.value)) {
14
11
  errors.push({ messageId: 'camelcase', data: {} });
15
12
  }
16
13
  continue;
17
14
  }
18
- if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
15
+ if (isPluralElement(el)) {
19
16
  if (CAMEL_CASE_REGEX.test(el.value)) {
20
17
  errors.push({ messageId: 'camelcase', data: {} });
21
18
  }
@@ -28,13 +25,13 @@ function verifyAst(ast) {
28
25
  return errors;
29
26
  }
30
27
  function checkNode(context, node) {
31
- const settings = (0, util_1.getSettings)(context);
32
- const msgs = (0, util_1.extractMessages)(node, settings);
28
+ const settings = getSettings(context);
29
+ const msgs = extractMessages(node, settings);
33
30
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
34
31
  if (!defaultMessage || !messageNode) {
35
32
  continue;
36
33
  }
37
- const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
34
+ const errors = verifyAst(parse(defaultMessage, {
38
35
  ignoreTag: settings.ignoreTag,
39
36
  }));
40
37
  for (const error of errors) {
@@ -45,7 +42,7 @@ function checkNode(context, node) {
45
42
  }
46
43
  }
47
44
  }
48
- exports.rule = {
45
+ export const rule = {
49
46
  meta: {
50
47
  type: 'problem',
51
48
  docs: {
@@ -61,7 +58,7 @@ exports.rule = {
61
58
  defaultOptions: [],
62
59
  create(context) {
63
60
  const callExpressionVisitor = (node) => checkNode(context, node);
64
- const parserServices = (0, context_compat_1.getParserServices)(context);
61
+ const parserServices = getParserServices(context);
65
62
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
66
63
  if (parserServices?.defineTemplateBodyVisitor) {
67
64
  //@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 calculateComplexity(ast) {
8
5
  // Dynamic programming: define a complexity function f, where:
9
6
  // f(plural | select) = sum(f(option) for each option) * f(next element),
@@ -23,8 +20,8 @@ function calculateComplexity(ast) {
23
20
  }
24
21
  let complexity;
25
22
  switch (element.type) {
26
- case icu_messageformat_parser_1.TYPE.plural:
27
- case icu_messageformat_parser_1.TYPE.select: {
23
+ case TYPE.plural:
24
+ case TYPE.select: {
28
25
  let sumOfOptions = 0;
29
26
  for (const { value } of Object.values(element.options)) {
30
27
  sumOfOptions += _calculate(value, 0);
@@ -32,7 +29,7 @@ function calculateComplexity(ast) {
32
29
  complexity = sumOfOptions * _calculate(ast, index + 1);
33
30
  break;
34
31
  }
35
- case icu_messageformat_parser_1.TYPE.tag:
32
+ case TYPE.tag:
36
33
  complexity =
37
34
  _calculate(element.children, 0) * _calculate(ast, index + 1);
38
35
  break;
@@ -45,14 +42,14 @@ function calculateComplexity(ast) {
45
42
  }
46
43
  }
47
44
  function checkNode(context, node) {
48
- const settings = (0, util_1.getSettings)(context);
49
- const msgs = (0, util_1.extractMessages)(node, settings);
45
+ const settings = getSettings(context);
46
+ const msgs = extractMessages(node, settings);
50
47
  if (!msgs.length) {
51
48
  return;
52
49
  }
53
50
  const config = {
54
51
  limit: 20,
55
- ...(context.options[0] || {}),
52
+ ...context.options[0],
56
53
  };
57
54
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
58
55
  if (!defaultMessage || !messageNode) {
@@ -60,7 +57,7 @@ function checkNode(context, node) {
60
57
  }
61
58
  let ast;
62
59
  try {
63
- ast = (0, icu_messageformat_parser_1.parse)(defaultMessage, {
60
+ ast = parse(defaultMessage, {
64
61
  ignoreTag: settings.ignoreTag,
65
62
  });
66
63
  }
@@ -85,8 +82,8 @@ function checkNode(context, node) {
85
82
  }
86
83
  }
87
84
  }
88
- exports.name = 'no-complex-selectors';
89
- exports.rule = {
85
+ export const name = 'no-complex-selectors';
86
+ export const rule = {
90
87
  meta: {
91
88
  type: 'problem',
92
89
  docs: {
@@ -121,7 +118,7 @@ Default complexity limit is 20
121
118
  defaultOptions: [{ limit: 20 }],
122
119
  create(context) {
123
120
  const callExpressionVisitor = (node) => checkNode(context, node);
124
- const parserServices = (0, context_compat_1.getParserServices)(context);
121
+ const parserServices = getParserServices(context);
125
122
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
126
123
  if (parserServices?.defineTemplateBodyVisitor) {
127
124
  //@ts-expect-error
package/rules/no-emoji.js CHANGED
@@ -1,29 +1,26 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = void 0;
4
- const unicode_emoji_utils_1 = require("unicode-emoji-utils");
5
- const context_compat_1 = require("../context-compat");
6
- const util_1 = require("../util");
7
- exports.name = 'no-emoji';
1
+ import { extractEmojis, filterEmojis, getAllEmojis, hasEmoji, isValidEmojiVersion, } from 'unicode-emoji-utils';
2
+ import { getParserServices } from '../context-compat.js';
3
+ import { extractMessages, getSettings } from '../util.js';
4
+ export const name = 'no-emoji';
8
5
  function checkNode(context, node) {
9
- const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
6
+ const msgs = extractMessages(node, getSettings(context));
10
7
  let allowedEmojis = [];
11
8
  let versionAbove;
12
9
  const [emojiConfig] = context.options;
13
10
  if (emojiConfig?.versionAbove &&
14
- (0, unicode_emoji_utils_1.isValidEmojiVersion)(emojiConfig.versionAbove) &&
11
+ isValidEmojiVersion(emojiConfig.versionAbove) &&
15
12
  !versionAbove &&
16
13
  allowedEmojis.length === 0) {
17
14
  versionAbove = emojiConfig.versionAbove;
18
- allowedEmojis = (0, unicode_emoji_utils_1.getAllEmojis)((0, unicode_emoji_utils_1.filterEmojis)(versionAbove));
15
+ allowedEmojis = getAllEmojis(filterEmojis(versionAbove));
19
16
  }
20
17
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
21
18
  if (!defaultMessage || !messageNode) {
22
19
  continue;
23
20
  }
24
- if ((0, unicode_emoji_utils_1.hasEmoji)(defaultMessage)) {
21
+ if (hasEmoji(defaultMessage)) {
25
22
  if (versionAbove) {
26
- for (const emoji of (0, unicode_emoji_utils_1.extractEmojis)(defaultMessage)) {
23
+ for (const emoji of extractEmojis(defaultMessage)) {
27
24
  if (!allowedEmojis.includes(emoji)) {
28
25
  context.report({
29
26
  node: messageNode,
@@ -61,7 +58,7 @@ const versionAboveEnums = [
61
58
  '14.0',
62
59
  '15.0',
63
60
  ];
64
- exports.rule = {
61
+ export const rule = {
65
62
  meta: {
66
63
  type: 'problem',
67
64
  docs: {
@@ -84,7 +81,7 @@ exports.rule = {
84
81
  defaultOptions: [],
85
82
  create(context) {
86
83
  const callExpressionVisitor = (node) => checkNode(context, node);
87
- const parserServices = (0, context_compat_1.getParserServices)(context);
84
+ const parserServices = getParserServices(context);
88
85
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
89
86
  if (parserServices?.defineTemplateBodyVisitor) {
90
87
  //@ts-expect-error
package/rules/no-id.js CHANGED
@@ -1,14 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = void 0;
4
- const context_compat_1 = require("../context-compat");
5
- const util_1 = require("../util");
1
+ import { getParserServices } from '../context-compat.js';
2
+ import { extractMessages, getSettings } from '../util.js';
6
3
  function isComment(token) {
7
4
  return !!token && (token.type === 'Block' || token.type === 'Line');
8
5
  }
9
- exports.name = 'no-id';
6
+ export const name = 'no-id';
10
7
  function checkNode(context, node) {
11
- const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
8
+ const msgs = extractMessages(node, getSettings(context));
12
9
  for (const [{ idPropNode }] of msgs) {
13
10
  if (idPropNode) {
14
11
  context.report({
@@ -27,7 +24,7 @@ function checkNode(context, node) {
27
24
  }
28
25
  }
29
26
  }
30
- exports.rule = {
27
+ export const rule = {
31
28
  meta: {
32
29
  type: 'problem',
33
30
  docs: {
@@ -43,7 +40,7 @@ exports.rule = {
43
40
  defaultOptions: [],
44
41
  create(context) {
45
42
  const callExpressionVisitor = (node) => checkNode(context, node);
46
- const parserServices = (0, context_compat_1.getParserServices)(context);
43
+ const parserServices = getParserServices(context);
47
44
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
48
45
  if (parserServices?.defineTemplateBodyVisitor) {
49
46
  //@ts-expect-error
@@ -1,13 +1,10 @@
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");
7
- exports.name = 'no-invalid-icu';
1
+ import { parse } from '@formatjs/icu-messageformat-parser';
2
+ import { getParserServices } from '../context-compat.js';
3
+ import { extractMessages, getSettings } from '../util.js';
4
+ export const name = 'no-invalid-icu';
8
5
  function checkNode(context, node) {
9
- const settings = (0, util_1.getSettings)(context);
10
- const msgs = (0, util_1.extractMessages)(node, settings);
6
+ const settings = getSettings(context);
7
+ const msgs = extractMessages(node, settings);
11
8
  if (!msgs.length) {
12
9
  return;
13
10
  }
@@ -16,7 +13,7 @@ function checkNode(context, node) {
16
13
  continue;
17
14
  }
18
15
  try {
19
- (0, icu_messageformat_parser_1.parse)(defaultMessage, {
16
+ parse(defaultMessage, {
20
17
  ignoreTag: settings.ignoreTag,
21
18
  });
22
19
  }
@@ -30,7 +27,7 @@ function checkNode(context, node) {
30
27
  }
31
28
  }
32
29
  }
33
- exports.rule = {
30
+ export const rule = {
34
31
  meta: {
35
32
  type: 'problem',
36
33
  docs: {
@@ -45,7 +42,7 @@ exports.rule = {
45
42
  defaultOptions: [],
46
43
  create(context) {
47
44
  const callExpressionVisitor = (node) => checkNode(context, node);
48
- const parserServices = (0, context_compat_1.getParserServices)(context);
45
+ const parserServices = getParserServices(context);
49
46
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
50
47
  if (parserServices?.defineTemplateBodyVisitor) {
51
48
  //@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 tslib_1 = require("tslib");
5
- const utils_1 = require("@typescript-eslint/utils");
6
- const picomatch_1 = tslib_1.__importDefault(require("picomatch"));
1
+ import { TSESTree } from '@typescript-eslint/utils';
2
+ import * as picomatchNs from 'picomatch';
3
+ const picomatch = picomatchNs.default ?? picomatchNs;
7
4
  const propMatcherSchema = {
8
5
  type: 'array',
9
6
  items: {
@@ -19,24 +16,24 @@ const defaultPropIncludePattern = [
19
16
  const defaultPropExcludePattern = [];
20
17
  function stringifyJsxTagName(tagName) {
21
18
  switch (tagName.type) {
22
- case utils_1.TSESTree.AST_NODE_TYPES.JSXIdentifier:
19
+ case TSESTree.AST_NODE_TYPES.JSXIdentifier:
23
20
  return tagName.name;
24
- case utils_1.TSESTree.AST_NODE_TYPES.JSXMemberExpression:
21
+ case TSESTree.AST_NODE_TYPES.JSXMemberExpression:
25
22
  return `${stringifyJsxTagName(tagName.object)}.${tagName.property.name}`;
26
- case utils_1.TSESTree.AST_NODE_TYPES.JSXNamespacedName:
23
+ case TSESTree.AST_NODE_TYPES.JSXNamespacedName:
27
24
  return `${tagName.namespace.name}:${tagName.name.name}`;
28
25
  }
29
26
  }
30
27
  function compilePropMatcher(propMatcher) {
31
28
  return propMatcher.map(([tagNamePattern, propNamePattern]) => {
32
29
  return [
33
- picomatch_1.default.makeRe(tagNamePattern, { contains: false }),
34
- picomatch_1.default.makeRe(propNamePattern, { contains: false }),
30
+ picomatch.makeRe(tagNamePattern, { contains: false }),
31
+ picomatch.makeRe(propNamePattern, { contains: false }),
35
32
  ];
36
33
  });
37
34
  }
38
- exports.name = 'no-literal-string-in-jsx';
39
- exports.rule = {
35
+ export const name = 'no-literal-string-in-jsx';
36
+ export const rule = {
40
37
  meta: {
41
38
  type: 'problem',
42
39
  docs: {
@@ -46,9 +43,11 @@ exports.rule = {
46
43
  schema: [
47
44
  {
48
45
  type: 'object',
46
+ additionalProperties: false,
49
47
  properties: {
50
48
  props: {
51
49
  type: 'object',
50
+ additionalProperties: false,
52
51
  properties: {
53
52
  include: {
54
53
  ...propMatcherSchema,
@@ -78,6 +77,21 @@ exports.rule = {
78
77
  ...(userConfig.props?.exclude ?? []),
79
78
  ]);
80
79
  const lexicalJsxStack = [];
80
+ const shouldSkipCurrentJsxElement = () => {
81
+ const currentJsxNode = lexicalJsxStack[lexicalJsxStack.length - 1];
82
+ if (currentJsxNode.type === 'JSXFragment') {
83
+ return false;
84
+ }
85
+ const nameString = stringifyJsxTagName(currentJsxNode.openingElement.name);
86
+ // Check if children should be excluded
87
+ for (const [tagNamePattern, propNamePattern] of propExcludePattern) {
88
+ if (tagNamePattern.test(nameString) &&
89
+ propNamePattern.test('children')) {
90
+ return true;
91
+ }
92
+ }
93
+ return false;
94
+ };
81
95
  const shouldSkipCurrentJsxAttribute = (node) => {
82
96
  const currentJsxNode = lexicalJsxStack[lexicalJsxStack.length - 1];
83
97
  if (currentJsxNode.type === 'JSXFragment') {
@@ -167,6 +181,9 @@ exports.rule = {
167
181
  if (!node.value.replace(/\s*/gm, '')) {
168
182
  return;
169
183
  }
184
+ if (shouldSkipCurrentJsxElement()) {
185
+ return;
186
+ }
170
187
  context.report({
171
188
  node: node,
172
189
  messageId: 'noLiteralStringInJsx',
@@ -174,6 +191,9 @@ exports.rule = {
174
191
  },
175
192
  // Children expression container
176
193
  'JSXElement > JSXExpressionContainer': (node) => {
194
+ if (shouldSkipCurrentJsxElement()) {
195
+ return;
196
+ }
177
197
  if (node.expression.type !== 'JSXEmptyExpression') {
178
198
  checkJSXExpression(node.expression);
179
199
  }
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = void 0;
4
- const utils_1 = require("@typescript-eslint/utils");
5
- const context_compat_1 = require("../context-compat");
6
- exports.name = 'no-literal-string-in-object';
7
- exports.rule = {
1
+ import { TSESTree } from '@typescript-eslint/utils';
2
+ import { getParserServices } from '../context-compat.js';
3
+ export const name = 'no-literal-string-in-object';
4
+ export const rule = {
8
5
  meta: {
9
6
  type: 'problem',
10
7
  docs: {
@@ -33,7 +30,7 @@ exports.rule = {
33
30
  const propertyVisitor = (node) => {
34
31
  checkProperty(context, node);
35
32
  };
36
- const parserServices = (0, context_compat_1.getParserServices)(context);
33
+ const parserServices = getParserServices(context);
37
34
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
38
35
  if (parserServices?.defineTemplateBodyVisitor) {
39
36
  //@ts-expect-error
@@ -51,11 +48,11 @@ exports.rule = {
51
48
  function checkProperty(context, node) {
52
49
  const config = {
53
50
  include: ['label'],
54
- ...(context.options[0] || {}),
51
+ ...context.options[0],
55
52
  };
56
- const propertyKey = node.key.type === utils_1.TSESTree.AST_NODE_TYPES.Identifier
53
+ const propertyKey = node.key.type === TSESTree.AST_NODE_TYPES.Identifier
57
54
  ? node.key.name
58
- : node.key.type === utils_1.TSESTree.AST_NODE_TYPES.Literal &&
55
+ : node.key.type === TSESTree.AST_NODE_TYPES.Literal &&
59
56
  typeof node.key.value === 'string'
60
57
  ? node.key.value
61
58
  : null;
@@ -1,17 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rule = exports.name = void 0;
4
- const tslib_1 = require("tslib");
5
- const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
6
- const magic_string_1 = tslib_1.__importDefault(require("magic-string"));
7
- const context_compat_1 = require("../context-compat");
8
- const util_1 = require("../util");
9
- exports.name = 'no-missing-icu-plural-one-placeholders';
1
+ import { isLiteralElement, isPluralElement, isSelectElement, isTagElement, parse, } from '@formatjs/icu-messageformat-parser';
2
+ import MagicString from 'magic-string';
3
+ import { getParserServices } from '../context-compat.js';
4
+ import { extractMessages, patchMessage } from '../util.js';
5
+ export const name = 'no-missing-icu-plural-one-placeholders';
10
6
  function verifyAst(context, messageNode, ast) {
11
7
  const patches = [];
12
8
  _verifyAstAndReplace(ast);
13
9
  if (patches.length > 0) {
14
- const patchedMessage = (0, util_1.patchMessage)(messageNode, ast, content => {
10
+ const patchedMessage = patchMessage(messageNode, ast, content => {
15
11
  return patches
16
12
  .reduce((magicString, patch) => {
17
13
  switch (patch.type) {
@@ -22,7 +18,7 @@ function verifyAst(context, messageNode, ast) {
22
18
  case 'update':
23
19
  return magicString.update(patch.start, patch.end, patch.content);
24
20
  }
25
- }, new magic_string_1.default(content))
21
+ }, new MagicString(content))
26
22
  .toString();
27
23
  });
28
24
  context.report({
@@ -35,18 +31,18 @@ function verifyAst(context, messageNode, ast) {
35
31
  }
36
32
  function _verifyAstAndReplace(ast, root = true) {
37
33
  for (const el of ast) {
38
- if ((0, icu_messageformat_parser_1.isPluralElement)(el) && el.options['one']) {
34
+ if (isPluralElement(el) && el.options['one']) {
39
35
  _verifyAstAndReplace(el.options['one'].value, false);
40
36
  }
41
- else if ((0, icu_messageformat_parser_1.isSelectElement)(el)) {
37
+ else if (isSelectElement(el)) {
42
38
  for (const { value } of Object.values(el.options)) {
43
39
  _verifyAstAndReplace(value, root);
44
40
  }
45
41
  }
46
- else if ((0, icu_messageformat_parser_1.isTagElement)(el)) {
42
+ else if (isTagElement(el)) {
47
43
  _verifyAstAndReplace(el.children, root);
48
44
  }
49
- else if (!root && (0, icu_messageformat_parser_1.isLiteralElement)(el)) {
45
+ else if (!root && isLiteralElement(el)) {
50
46
  const match = el.value.match(/\b1\b/);
51
47
  if (match && el.location) {
52
48
  patches.push({
@@ -61,15 +57,15 @@ function verifyAst(context, messageNode, ast) {
61
57
  }
62
58
  }
63
59
  function checkNode(context, node) {
64
- const msgs = (0, util_1.extractMessages)(node);
60
+ const msgs = extractMessages(node);
65
61
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
66
62
  if (!defaultMessage || !messageNode) {
67
63
  continue;
68
64
  }
69
- verifyAst(context, messageNode, (0, icu_messageformat_parser_1.parse)(defaultMessage, { captureLocation: true }));
65
+ verifyAst(context, messageNode, parse(defaultMessage, { captureLocation: true }));
70
66
  }
71
67
  }
72
- exports.rule = {
68
+ export const rule = {
73
69
  meta: {
74
70
  type: 'problem',
75
71
  docs: {
@@ -85,7 +81,7 @@ exports.rule = {
85
81
  defaultOptions: [],
86
82
  create(context) {
87
83
  const callExpressionVisitor = (node) => checkNode(context, node);
88
- const parserServices = (0, context_compat_1.getParserServices)(context);
84
+ const parserServices = getParserServices(context);
89
85
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
90
86
  if (parserServices?.defineTemplateBodyVisitor) {
91
87
  //@ts-expect-error
@@ -1,13 +1,10 @@
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
  function verifyAst(ast, pluralCount = { count: 0 }) {
8
5
  const errors = [];
9
6
  for (const el of ast) {
10
- if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
7
+ if (isPluralElement(el)) {
11
8
  pluralCount.count++;
12
9
  if (pluralCount.count > 1) {
13
10
  errors.push({ messageId: 'noMultiplePlurals', data: {} });
@@ -21,13 +18,13 @@ function verifyAst(ast, pluralCount = { count: 0 }) {
21
18
  return errors;
22
19
  }
23
20
  function checkNode(context, node) {
24
- const settings = (0, util_1.getSettings)(context);
25
- const msgs = (0, util_1.extractMessages)(node, settings);
21
+ const settings = getSettings(context);
22
+ const msgs = extractMessages(node, settings);
26
23
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
27
24
  if (!defaultMessage || !messageNode) {
28
25
  continue;
29
26
  }
30
- const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
27
+ const errors = verifyAst(parse(defaultMessage, {
31
28
  ignoreTag: settings.ignoreTag,
32
29
  }));
33
30
  for (const error of errors) {
@@ -38,8 +35,8 @@ function checkNode(context, node) {
38
35
  }
39
36
  }
40
37
  }
41
- exports.name = 'no-multiple-plurals';
42
- exports.rule = {
38
+ export const name = 'no-multiple-plurals';
39
+ export const rule = {
43
40
  meta: {
44
41
  type: 'problem',
45
42
  docs: {
@@ -55,7 +52,7 @@ exports.rule = {
55
52
  defaultOptions: [],
56
53
  create(context) {
57
54
  const callExpressionVisitor = (node) => checkNode(context, node);
58
- const parserServices = (0, context_compat_1.getParserServices)(context);
55
+ const parserServices = getParserServices(context);
59
56
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
60
57
  if (parserServices?.defineTemplateBodyVisitor) {
61
58
  //@ts-expect-error