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,26 +1,22 @@
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 { parse, TYPE, } from '@formatjs/icu-messageformat-parser';
2
+ import { getParserServices } from '../context-compat.js';
3
+ import { extractMessages, getSettings, patchMessage } from '../util.js';
7
4
  function isAstValid(ast) {
8
5
  for (const element of ast) {
9
6
  switch (element.type) {
10
- case icu_messageformat_parser_1.TYPE.literal:
7
+ case TYPE.literal:
11
8
  if (/\s{2,}/gm.test(element.value)) {
12
9
  return false;
13
10
  }
14
11
  break;
15
- case icu_messageformat_parser_1.TYPE.argument:
16
- case icu_messageformat_parser_1.TYPE.date:
17
- case icu_messageformat_parser_1.TYPE.literal:
18
- case icu_messageformat_parser_1.TYPE.number:
19
- case icu_messageformat_parser_1.TYPE.pound:
20
- case icu_messageformat_parser_1.TYPE.time:
12
+ case TYPE.argument:
13
+ case TYPE.date:
14
+ case TYPE.number:
15
+ case TYPE.pound:
16
+ case TYPE.time:
21
17
  break;
22
- case icu_messageformat_parser_1.TYPE.plural:
23
- case icu_messageformat_parser_1.TYPE.select: {
18
+ case TYPE.plural:
19
+ case TYPE.select: {
24
20
  for (const option of Object.values(element.options)) {
25
21
  if (!isAstValid(option.value)) {
26
22
  return false;
@@ -28,7 +24,7 @@ function isAstValid(ast) {
28
24
  }
29
25
  break;
30
26
  }
31
- case icu_messageformat_parser_1.TYPE.tag:
27
+ case TYPE.tag:
32
28
  return isAstValid(element.children);
33
29
  }
34
30
  }
@@ -39,24 +35,23 @@ function trimMultiWhitespaces(message, ast) {
39
35
  const collectLiteralElements = (elements) => {
40
36
  for (const element of elements) {
41
37
  switch (element.type) {
42
- case icu_messageformat_parser_1.TYPE.literal:
38
+ case TYPE.literal:
43
39
  literalElements.push(element);
44
40
  break;
45
- case icu_messageformat_parser_1.TYPE.argument:
46
- case icu_messageformat_parser_1.TYPE.date:
47
- case icu_messageformat_parser_1.TYPE.literal:
48
- case icu_messageformat_parser_1.TYPE.number:
49
- case icu_messageformat_parser_1.TYPE.pound:
50
- case icu_messageformat_parser_1.TYPE.time:
41
+ case TYPE.argument:
42
+ case TYPE.date:
43
+ case TYPE.number:
44
+ case TYPE.pound:
45
+ case TYPE.time:
51
46
  break;
52
- case icu_messageformat_parser_1.TYPE.plural:
53
- case icu_messageformat_parser_1.TYPE.select: {
47
+ case TYPE.plural:
48
+ case TYPE.select: {
54
49
  for (const option of Object.values(element.options)) {
55
50
  collectLiteralElements(option.value);
56
51
  }
57
52
  break;
58
53
  }
59
- case icu_messageformat_parser_1.TYPE.tag:
54
+ case TYPE.tag:
60
55
  collectLiteralElements(element.children);
61
56
  break;
62
57
  }
@@ -79,14 +74,14 @@ function trimMultiWhitespaces(message, ast) {
79
74
  return trimmedFragments.join('');
80
75
  }
81
76
  function checkNode(context, node) {
82
- const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
77
+ const msgs = extractMessages(node, getSettings(context));
83
78
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
84
79
  if (!defaultMessage || !messageNode) {
85
80
  continue;
86
81
  }
87
82
  let ast;
88
83
  try {
89
- ast = (0, icu_messageformat_parser_1.parse)(defaultMessage, { captureLocation: true });
84
+ ast = parse(defaultMessage, { captureLocation: true });
90
85
  }
91
86
  catch (e) {
92
87
  context.report({
@@ -97,7 +92,7 @@ function checkNode(context, node) {
97
92
  return;
98
93
  }
99
94
  if (!isAstValid(ast)) {
100
- const newMessage = (0, util_1.patchMessage)(messageNode, ast, trimMultiWhitespaces);
95
+ const newMessage = patchMessage(messageNode, ast, trimMultiWhitespaces);
101
96
  context.report({
102
97
  node: messageNode,
103
98
  messageId: 'noMultipleWhitespaces',
@@ -108,8 +103,8 @@ function checkNode(context, node) {
108
103
  }
109
104
  }
110
105
  }
111
- exports.name = 'no-multiple-whitespaces';
112
- exports.rule = {
106
+ export const name = 'no-multiple-whitespaces';
107
+ export const rule = {
113
108
  meta: {
114
109
  type: 'problem',
115
110
  docs: {
@@ -126,7 +121,7 @@ exports.rule = {
126
121
  defaultOptions: [],
127
122
  create(context) {
128
123
  const callExpressionVisitor = (node) => checkNode(context, node);
129
- const parserServices = (0, context_compat_1.getParserServices)(context);
124
+ const parserServices = getParserServices(context);
130
125
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
131
126
  if (parserServices?.defineTemplateBodyVisitor) {
132
127
  //@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) {
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
  if (el.offset) {
12
9
  errors.push({ messageId: 'noOffset', data: {} });
13
10
  }
@@ -20,13 +17,13 @@ function verifyAst(ast) {
20
17
  return errors;
21
18
  }
22
19
  function checkNode(context, node) {
23
- const settings = (0, util_1.getSettings)(context);
24
- const msgs = (0, util_1.extractMessages)(node, settings);
20
+ const settings = getSettings(context);
21
+ const msgs = extractMessages(node, settings);
25
22
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
26
23
  if (!defaultMessage || !messageNode) {
27
24
  continue;
28
25
  }
29
- const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
26
+ const errors = verifyAst(parse(defaultMessage, {
30
27
  ignoreTag: settings.ignoreTag,
31
28
  }));
32
29
  for (const error of errors) {
@@ -37,8 +34,8 @@ function checkNode(context, node) {
37
34
  }
38
35
  }
39
36
  }
40
- exports.name = 'no-offset';
41
- exports.rule = {
37
+ export const name = 'no-offset';
38
+ export const rule = {
42
39
  meta: {
43
40
  type: 'problem',
44
41
  docs: {
@@ -54,7 +51,7 @@ exports.rule = {
54
51
  defaultOptions: [],
55
52
  create(context) {
56
53
  const callExpressionVisitor = (node) => checkNode(context, node);
57
- const parserServices = (0, context_compat_1.getParserServices)(context);
54
+ const parserServices = getParserServices(context);
58
55
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
59
56
  if (parserServices?.defineTemplateBodyVisitor) {
60
57
  //@ts-expect-error
@@ -1,32 +1,29 @@
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 { parse, TYPE, } from '@formatjs/icu-messageformat-parser';
2
+ import { getParserServices } from '../context-compat.js';
3
+ import { extractMessages, getSettings } from '../util.js';
7
4
  function verifyAst(ast) {
8
5
  if (ast.length !== 1) {
9
6
  return;
10
7
  }
11
8
  switch (ast[0].type) {
12
- case icu_messageformat_parser_1.TYPE.argument:
9
+ case TYPE.argument:
13
10
  return 'unnecessaryFormat';
14
- case icu_messageformat_parser_1.TYPE.number:
11
+ case TYPE.number:
15
12
  return 'unnecessaryFormatNumber';
16
- case icu_messageformat_parser_1.TYPE.date:
13
+ case TYPE.date:
17
14
  return 'unnecessaryFormatDate';
18
- case icu_messageformat_parser_1.TYPE.time:
15
+ case TYPE.time:
19
16
  return 'unnecessaryFormatTime';
20
17
  }
21
18
  }
22
19
  function checkNode(context, node) {
23
- const settings = (0, util_1.getSettings)(context);
24
- const msgs = (0, util_1.extractMessages)(node, settings);
20
+ const settings = getSettings(context);
21
+ const msgs = extractMessages(node, settings);
25
22
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
26
23
  if (!defaultMessage || !messageNode) {
27
24
  continue;
28
25
  }
29
- const messageId = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
26
+ const messageId = verifyAst(parse(defaultMessage, {
30
27
  ignoreTag: settings.ignoreTag,
31
28
  }));
32
29
  if (messageId)
@@ -36,8 +33,8 @@ function checkNode(context, node) {
36
33
  });
37
34
  }
38
35
  }
39
- exports.name = 'no-useless-message';
40
- exports.rule = {
36
+ export const name = 'no-useless-message';
37
+ export const rule = {
41
38
  meta: {
42
39
  type: 'problem',
43
40
  docs: {
@@ -56,7 +53,7 @@ exports.rule = {
56
53
  defaultOptions: [],
57
54
  create(context) {
58
55
  const callExpressionVisitor = (node) => checkNode(context, node);
59
- const parserServices = (0, context_compat_1.getParserServices)(context);
56
+ const parserServices = getParserServices(context);
60
57
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
61
58
  if (parserServices?.defineTemplateBodyVisitor) {
62
59
  //@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 util_1 = require("../util");
5
- exports.name = 'prefer-formatted-message';
6
- exports.rule = {
1
+ import { isIntlFormatMessageCall } from '../util.js';
2
+ export const name = 'prefer-formatted-message';
3
+ export const rule = {
7
4
  meta: {
8
5
  type: 'suggestion',
9
6
  docs: {
@@ -22,7 +19,7 @@ exports.rule = {
22
19
  JSXElement: (node) => {
23
20
  node.children.forEach(child => {
24
21
  if (child.type !== 'JSXExpressionContainer' ||
25
- !(0, util_1.isIntlFormatMessageCall)(child.expression)) {
22
+ !isIntlFormatMessageCall(child.expression)) {
26
23
  return;
27
24
  }
28
25
  context.report({
@@ -1,16 +1,12 @@
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");
1
+ import { parse, TYPE, } from '@formatjs/icu-messageformat-parser';
2
+ import MagicString from 'magic-string';
3
+ import { getParserServices } from '../context-compat.js';
4
+ import { extractMessages, getSettings, patchMessage } from '../util.js';
9
5
  function verifyAst(context, messageNode, ast) {
10
6
  const patches = [];
11
7
  _verifyAst(ast);
12
8
  if (patches.length > 0) {
13
- const patchedMessage = (0, util_1.patchMessage)(messageNode, ast, content => {
9
+ const patchedMessage = patchMessage(messageNode, ast, content => {
14
10
  return patches
15
11
  .reduce((magicString, patch) => {
16
12
  switch (patch.type) {
@@ -21,7 +17,7 @@ function verifyAst(context, messageNode, ast) {
21
17
  case 'update':
22
18
  return magicString.update(patch.start, patch.end, patch.content);
23
19
  }
24
- }, new magic_string_1.default(content))
20
+ }, new MagicString(content))
25
21
  .toString();
26
22
  });
27
23
  context.report({
@@ -36,32 +32,32 @@ function verifyAst(context, messageNode, ast) {
36
32
  for (let i = 0; i < ast.length; i++) {
37
33
  const current = ast[i];
38
34
  switch (current.type) {
39
- case icu_messageformat_parser_1.TYPE.argument:
40
- case icu_messageformat_parser_1.TYPE.number: {
35
+ case TYPE.argument:
36
+ case TYPE.number: {
41
37
  // Applicable to only plain argument or number argument without any style
42
- if (current.type === icu_messageformat_parser_1.TYPE.number && current.style) {
38
+ if (current.type === TYPE.number && current.style) {
43
39
  break;
44
40
  }
45
41
  const next = ast[i + 1];
46
42
  const nextNext = ast[i + 2];
47
43
  if (next &&
48
44
  nextNext &&
49
- next.type === icu_messageformat_parser_1.TYPE.literal &&
45
+ next.type === TYPE.literal &&
50
46
  next.value === ' ' &&
51
- nextNext.type === icu_messageformat_parser_1.TYPE.plural &&
47
+ nextNext.type === TYPE.plural &&
52
48
  nextNext.value === current.value) {
53
49
  // `{A} {A, plural, one {B} other {Bs}}` => `{A, plural, one {# B} other {# Bs}}`
54
50
  _removeRangeAndPrependPluralClauses(current.location.start.offset, next.location.end.offset, nextNext, '# ');
55
51
  }
56
52
  else if (next &&
57
- next.type === icu_messageformat_parser_1.TYPE.plural &&
53
+ next.type === TYPE.plural &&
58
54
  next.value === current.value) {
59
55
  // `{A}{A, plural, one {B} other {Bs}}` => `{A, plural, one {#B} other {#Bs}}`
60
56
  _removeRangeAndPrependPluralClauses(current.location.start.offset, current.location.end.offset, next, '#');
61
57
  }
62
58
  break;
63
59
  }
64
- case icu_messageformat_parser_1.TYPE.plural: {
60
+ case TYPE.plural: {
65
61
  // `{A, plural, one {{A} B} other {{A} Bs}}` => `{A, plural, one {# B} other {# Bs}}`
66
62
  const name = current.value;
67
63
  for (const { value } of Object.values(current.options)) {
@@ -69,13 +65,13 @@ function verifyAst(context, messageNode, ast) {
69
65
  }
70
66
  break;
71
67
  }
72
- case icu_messageformat_parser_1.TYPE.select: {
68
+ case TYPE.select: {
73
69
  for (const { value } of Object.values(current.options)) {
74
70
  _verifyAst(value);
75
71
  }
76
72
  break;
77
73
  }
78
- case icu_messageformat_parser_1.TYPE.tag:
74
+ case TYPE.tag:
79
75
  _verifyAst(current.children);
80
76
  break;
81
77
  default:
@@ -88,11 +84,11 @@ function verifyAst(context, messageNode, ast) {
88
84
  function _replacementArgumentWithPound(name, ast) {
89
85
  for (const element of ast) {
90
86
  switch (element.type) {
91
- case icu_messageformat_parser_1.TYPE.argument:
92
- case icu_messageformat_parser_1.TYPE.number: {
87
+ case TYPE.argument:
88
+ case TYPE.number: {
93
89
  if (element.value === name &&
94
90
  // Either plain argument or number argument without any style
95
- (element.type !== icu_messageformat_parser_1.TYPE.number || !element.style)) {
91
+ (element.type !== TYPE.number || !element.style)) {
96
92
  patches.push({
97
93
  type: 'update',
98
94
  start: element.location.start.offset,
@@ -102,11 +98,11 @@ function verifyAst(context, messageNode, ast) {
102
98
  }
103
99
  break;
104
100
  }
105
- case icu_messageformat_parser_1.TYPE.tag: {
101
+ case TYPE.tag: {
106
102
  _replacementArgumentWithPound(name, element.children);
107
103
  break;
108
104
  }
109
- case icu_messageformat_parser_1.TYPE.select: {
105
+ case TYPE.select: {
110
106
  for (const { value } of Object.values(element.options)) {
111
107
  _replacementArgumentWithPound(name, value);
112
108
  }
@@ -138,14 +134,14 @@ function verifyAst(context, messageNode, ast) {
138
134
  }
139
135
  }
140
136
  function checkNode(context, node) {
141
- const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
137
+ const msgs = extractMessages(node, getSettings(context));
142
138
  for (const [{ message: { defaultMessage }, messageNode, },] of msgs) {
143
139
  if (!defaultMessage || !messageNode) {
144
140
  continue;
145
141
  }
146
142
  let ast;
147
143
  try {
148
- ast = (0, icu_messageformat_parser_1.parse)(defaultMessage, { captureLocation: true });
144
+ ast = parse(defaultMessage, { captureLocation: true });
149
145
  }
150
146
  catch (e) {
151
147
  context.report({
@@ -158,8 +154,8 @@ function checkNode(context, node) {
158
154
  verifyAst(context, messageNode, ast);
159
155
  }
160
156
  }
161
- exports.name = 'prefer-pound-in-plural';
162
- exports.rule = {
157
+ export const name = 'prefer-pound-in-plural';
158
+ export const rule = {
163
159
  meta: {
164
160
  type: 'suggestion',
165
161
  docs: {
@@ -177,7 +173,7 @@ exports.rule = {
177
173
  // TODO: Vue support
178
174
  create(context) {
179
175
  const callExpressionVisitor = (node) => checkNode(context, node);
180
- const parserServices = (0, context_compat_1.getParserServices)(context);
176
+ const parserServices = getParserServices(context);
181
177
  //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
182
178
  if (parserServices?.defineTemplateBodyVisitor) {
183
179
  //@ts-expect-error
package/util.js CHANGED
@@ -1,14 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSettings = getSettings;
4
- exports.isIntlFormatMessageCall = isIntlFormatMessageCall;
5
- exports.extractMessageDescriptor = extractMessageDescriptor;
6
- exports.extractMessages = extractMessages;
7
- exports.patchMessage = patchMessage;
8
1
  const FORMAT_FUNCTION_NAMES = new Set(['$formatMessage', 'formatMessage', '$t']);
9
2
  const COMPONENT_NAMES = new Set(['FormattedMessage']);
10
3
  const DECLARATION_FUNCTION_NAMES = new Set(['defineMessage']);
11
- function getSettings({ settings }) {
4
+ export function getSettings({ settings }) {
12
5
  return settings.formatjs ?? settings;
13
6
  }
14
7
  function isStringLiteral(node) {
@@ -30,7 +23,7 @@ function staticallyEvaluateStringConcat(node) {
30
23
  }
31
24
  return ['', false];
32
25
  }
33
- function isIntlFormatMessageCall(node) {
26
+ export function isIntlFormatMessageCall(node) {
34
27
  return (node.type === 'CallExpression' &&
35
28
  node.callee.type === 'MemberExpression' &&
36
29
  ((node.callee.object.type === 'Identifier' &&
@@ -54,7 +47,7 @@ function isMultipleMessageDescriptorDeclaration(node) {
54
47
  node.callee.type === 'Identifier' &&
55
48
  node.callee.name === 'defineMessages');
56
49
  }
57
- function extractMessageDescriptor(node) {
50
+ export function extractMessageDescriptor(node) {
58
51
  if (!node || node.type !== 'ObjectExpression') {
59
52
  return;
60
53
  }
@@ -220,7 +213,7 @@ function extractMessageDescriptors(node) {
220
213
  }
221
214
  return msgs;
222
215
  }
223
- function extractMessages(node, { additionalComponentNames, additionalFunctionNames, excludeMessageDeclCalls, } = {}) {
216
+ export function extractMessages(node, { additionalComponentNames, additionalFunctionNames, excludeMessageDeclCalls, } = {}) {
224
217
  const allFormatFunctionNames = Array.isArray(additionalFunctionNames)
225
218
  ? new Set([
226
219
  ...Array.from(FORMAT_FUNCTION_NAMES),
@@ -268,7 +261,7 @@ function extractMessages(node, { additionalComponentNames, additionalFunctionNam
268
261
  * `fixer.replaceText(messageNode, <return value>)`. If the return value is null,
269
262
  * it means that the patch cannot be applied.
270
263
  */
271
- function patchMessage(messageNode, ast, patcher) {
264
+ export function patchMessage(messageNode, ast, patcher) {
272
265
  if (messageNode.type === 'Literal' &&
273
266
  messageNode.value &&
274
267
  typeof messageNode.value === 'string') {
@@ -1,3 +0,0 @@
1
- import type { ParserServicesWithoutTypeInformation, ParserServicesWithTypeInformation } from '@typescript-eslint/utils';
2
- import { RuleContext } from '@typescript-eslint/utils/ts-eslint';
3
- export declare const getParserServices: <TRuleContext extends RuleContext<string, unknown[]>>(context: TRuleContext) => Partial<ParserServicesWithoutTypeInformation> | Partial<ParserServicesWithTypeInformation> | undefined;
@@ -1,6 +0,0 @@
1
- export const getParserServices = (context) => {
2
- if (context.parserServices) {
3
- return context.parserServices;
4
- }
5
- return context.sourceCode.parserServices;
6
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,146 +0,0 @@
1
- import { name as blocklistElementRuleName, rule as blocklistElements, } from './rules/blocklist-elements';
2
- import { rule as enforceDefaultMessage, name as enforceDefaultMessageName, } from './rules/enforce-default-message';
3
- import { rule as enforceDescription, name as enforceDescriptionName, } from './rules/enforce-description';
4
- import { rule as enforceId, name as enforceIdName } from './rules/enforce-id';
5
- import { rule as enforcePlaceholders, name as enforcePlaceholdersName, } from './rules/enforce-placeholders';
6
- import { rule as enforcePluralRules, name as enforcePluralRulesName, } from './rules/enforce-plural-rules';
7
- import { rule as noCamelCase, name as noCamelCaseName, } from './rules/no-camel-case';
8
- import { rule as noComplexSelectors, name as noComplexSelectorsName, } from './rules/no-complex-selectors';
9
- import { rule as noEmoji, name as noEmojiName } from './rules/no-emoji';
10
- import { rule as noId, name as noIdName } from './rules/no-id';
11
- import { rule as noInvalidICU, name as noInvalidICUName, } from './rules/no-invalid-icu';
12
- import { rule as noLiteralStringInJsx, name as noLiteralStringInJsxName, } from './rules/no-literal-string-in-jsx';
13
- import { rule as noMissingIcuPluralOnePlaceholders, name as noMissingIcuPluralOnePlaceholdersName, } from './rules/no-missing-icu-plural-one-placeholders';
14
- import { rule as noMultiplePlurals, name as noMultiplePluralsName, } from './rules/no-multiple-plurals';
15
- import { rule as noMultipleWhitespaces, name as noMultipleWhitespacesName, } from './rules/no-multiple-whitespaces';
16
- import { rule as noOffset, name as noOffsetName } from './rules/no-offset';
17
- import { rule as noUselessMessage, name as noUselessMessageName, } from './rules/no-useless-message';
18
- import { rule as preferFormattedMessage, name as preferFormattedMessageName, } from './rules/prefer-formatted-message';
19
- import { rule as preferPoundInPlural, name as preferPoundInPluralName, } from './rules/prefer-pound-in-plural';
20
- import { rule as noLiteralStringInObject, name as noLiteralStringInObjectName, } from './rules/no-literal-string-in-object';
21
- import { name, version } from './package.json';
22
- // All rules
23
- const rules = {
24
- // @ts-expect-error
25
- [blocklistElementRuleName]: blocklistElements,
26
- // @ts-expect-error
27
- [enforceDefaultMessageName]: enforceDefaultMessage,
28
- // @ts-expect-error
29
- [enforceDescriptionName]: enforceDescription,
30
- // @ts-expect-error
31
- [enforceIdName]: enforceId,
32
- // @ts-expect-error
33
- [enforcePlaceholdersName]: enforcePlaceholders,
34
- // @ts-expect-error
35
- [enforcePluralRulesName]: enforcePluralRules,
36
- // @ts-expect-error
37
- [noCamelCaseName]: noCamelCase,
38
- // @ts-expect-error
39
- [noComplexSelectorsName]: noComplexSelectors,
40
- // @ts-expect-error
41
- [noEmojiName]: noEmoji,
42
- // @ts-expect-error
43
- [noIdName]: noId,
44
- // @ts-expect-error
45
- [noInvalidICUName]: noInvalidICU,
46
- // @ts-expect-error
47
- [noLiteralStringInJsxName]: noLiteralStringInJsx,
48
- // @ts-expect-error
49
- [noMultiplePluralsName]: noMultiplePlurals,
50
- // @ts-expect-error
51
- [noMultipleWhitespacesName]: noMultipleWhitespaces,
52
- // @ts-expect-error
53
- [noOffsetName]: noOffset,
54
- // @ts-expect-error
55
- [noUselessMessageName]: noUselessMessage,
56
- // @ts-expect-error
57
- [preferFormattedMessageName]: preferFormattedMessage,
58
- // @ts-expect-error
59
- [preferPoundInPluralName]: preferPoundInPlural,
60
- // @ts-expect-error
61
- [noMissingIcuPluralOnePlaceholdersName]: noMissingIcuPluralOnePlaceholders,
62
- // @ts-expect-error
63
- [noLiteralStringInObjectName]: noLiteralStringInObject,
64
- };
65
- // Base plugin
66
- const plugin = {
67
- meta: { name, version },
68
- rules,
69
- };
70
- // Configs
71
- const configs = {
72
- strict: {
73
- name: 'formatjs/strict',
74
- plugins: { formatjs: plugin },
75
- rules: {
76
- 'formatjs/no-offset': 'error',
77
- 'formatjs/enforce-default-message': ['error', 'literal'],
78
- 'formatjs/enforce-description': ['error', 'literal'],
79
- 'formatjs/enforce-placeholders': 'error',
80
- 'formatjs/no-emoji': 'error',
81
- 'formatjs/no-multiple-whitespaces': 'error',
82
- 'formatjs/no-multiple-plurals': 'error',
83
- 'formatjs/no-complex-selectors': ['error', { limit: 20 }],
84
- 'formatjs/no-useless-message': 'error',
85
- 'formatjs/prefer-pound-in-plural': 'error',
86
- 'formatjs/no-missing-icu-plural-one-placeholders': 'error',
87
- 'formatjs/enforce-id': [
88
- 'error',
89
- {
90
- idInterpolationPattern: '[sha512:contenthash:base64:10]',
91
- },
92
- ],
93
- 'formatjs/enforce-plural-rules': [
94
- 'error',
95
- {
96
- one: true,
97
- other: true,
98
- },
99
- ],
100
- 'formatjs/no-literal-string-in-jsx': [
101
- 'error',
102
- {
103
- props: {
104
- include: [['*', '{label,placeholder,title}']],
105
- },
106
- },
107
- ],
108
- 'formatjs/blocklist-elements': ['error', ['selectordinal']],
109
- },
110
- },
111
- recommended: {
112
- name: 'formatjs/recommended',
113
- plugins: { formatjs: plugin },
114
- rules: {
115
- 'formatjs/no-offset': 'error',
116
- 'formatjs/enforce-default-message': ['error', 'literal'],
117
- 'formatjs/enforce-description': ['error', 'literal'],
118
- 'formatjs/enforce-placeholders': 'error',
119
- 'formatjs/no-emoji': 'error',
120
- 'formatjs/no-multiple-whitespaces': 'error',
121
- 'formatjs/no-multiple-plurals': 'error',
122
- 'formatjs/no-complex-selectors': ['error', { limit: 20 }],
123
- 'formatjs/no-useless-message': 'error',
124
- 'formatjs/prefer-pound-in-plural': 'error',
125
- 'formatjs/no-missing-icu-plural-one-placeholders': 'error',
126
- 'formatjs/enforce-plural-rules': [
127
- 'error',
128
- {
129
- one: true,
130
- other: true,
131
- },
132
- ],
133
- 'formatjs/no-literal-string-in-jsx': [
134
- 'warn',
135
- {
136
- props: {
137
- include: [['*', '{label,placeholder,title}']],
138
- },
139
- },
140
- ],
141
- 'formatjs/blocklist-elements': ['error', ['selectordinal']],
142
- },
143
- },
144
- };
145
- plugin.configs = configs;
146
- module.exports = plugin;
@@ -1,31 +0,0 @@
1
- {
2
- "name": "eslint-plugin-formatjs",
3
- "description": "ESLint plugin for formatjs",
4
- "version": "5.4.2",
5
- "license": "MIT",
6
- "author": "Long Ho <holevietlong@gmail.com>",
7
- "dependencies": {
8
- "@formatjs/icu-messageformat-parser": "workspace:*",
9
- "@formatjs/ts-transformer": "workspace:*",
10
- "@types/eslint": "^9.6.1",
11
- "@types/picomatch": "^3",
12
- "@typescript-eslint/utils": "^8.27.0",
13
- "magic-string": "^0.30.0",
14
- "picomatch": "2 || 3 || 4",
15
- "tslib": "^2.8.0",
16
- "unicode-emoji-utils": "^1.2.0"
17
- },
18
- "peerDependencies": {
19
- "eslint": "^9.23.0"
20
- },
21
- "bugs": "https://github.com/formatjs/formatjs/issues",
22
- "homepage": "https://github.com/formatjs/formatjs#readme",
23
- "keywords": [
24
- "eslint",
25
- "eslintplugin",
26
- "formatjs",
27
- "i18n"
28
- ],
29
- "main": "index.js",
30
- "repository": "formatjs/formatjs.git"
31
- }