Skip to content
This repository was archived by the owner on May 4, 2020. It is now read-only.

Commit f20a2d4

Browse files
author
Long Ho
committed
feat(eslint-plugin-formatjs): Add literal option to enforce-description & enforce-default-message
1 parent 68acfaf commit f20a2d4

File tree

5 files changed

+98
-11
lines changed

5 files changed

+98
-11
lines changed

packages/eslint-plugin-formatjs/README.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,26 @@ const messages = defineMessages({
123123
});
124124
```
125125

126+
#### Options
127+
128+
```json
129+
{
130+
"plugins": ["formatjs"],
131+
"rules": {
132+
"formatjs/enforce-description": ["error", "literal"]
133+
}
134+
}
135+
```
136+
137+
Setting `literal` forces `description` to always be a string literal instead of function calls or variables. This is helpful for extraction tools that expects `description` to always be a literal
138+
126139
### `enforce-default-message`
127140

128141
This enforces `defaultMessage` in the message descriptor.
129142

130143
#### Why
131144

132-
- Can be usefull in case we want to extract messages for translations from source code. This way can make sure people won't forget about defaultMessage
145+
- Can be useful in case we want to extract messages for translations from source code. This way can make sure people won't forget about defaultMessage
133146

134147
```tsx
135148
import {defineMessages} from 'react-intl';
@@ -147,6 +160,19 @@ const messages = defineMessages({
147160
});
148161
```
149162

163+
#### Options
164+
165+
```json
166+
{
167+
"plugins": ["formatjs"],
168+
"rules": {
169+
"formatjs/enforce-default-message": ["error", "literal"]
170+
}
171+
}
172+
```
173+
174+
Setting `literal` forces `defaultMessage` to always be a string literal instead of function calls or variables. This is helpful for extraction tools that expects `defaultMessage` to always be a literal
175+
150176
### `enforce-placeholders`
151177

152178
Makes sure all values are passed in if message has placeholders (number/date/time/plural/select/selectordinal). This requires values to be passed in as literal object (not a variable).

packages/eslint-plugin-formatjs/src/rules/enforce-default-message.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,28 @@ function checkNode(
99
importedMacroVars: Scope.Variable[]
1010
) {
1111
const msgs = extractMessages(node as TSESTree.Node, importedMacroVars);
12+
const {
13+
options: [type],
14+
} = context;
1215
for (const [
1316
{
1417
message: {defaultMessage},
1518
messageNode,
1619
},
1720
] of msgs) {
18-
if (!defaultMessage && !messageNode) {
19-
context.report({
20-
node,
21-
message: '`defaultMessage` has to be specified in message descriptor',
22-
});
21+
if (!defaultMessage) {
22+
if (type === 'literal' && messageNode) {
23+
context.report({
24+
node,
25+
message:
26+
'`defaultMessage` must be a string literal (not function call or variable)',
27+
});
28+
} else if (!messageNode) {
29+
context.report({
30+
node,
31+
message: '`defaultMessage` has to be specified in message descriptor',
32+
});
33+
}
2334
}
2435
}
2536
}
@@ -35,6 +46,11 @@ const rule: Rule.RuleModule = {
3546
'https://github.com/formatjs/formatjs/tree/master/packages/eslint-plugin-formatjs#enforce-default-message',
3647
},
3748
fixable: 'code',
49+
schema: [
50+
{
51+
enum: ['literal', 'anything'],
52+
},
53+
],
3854
},
3955
create(context) {
4056
let importedMacroVars: Scope.Variable[] = [];

packages/eslint-plugin-formatjs/src/rules/enforce-description.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,28 @@ function checkNode(
99
importedMacroVars: Scope.Variable[]
1010
) {
1111
const msgs = extractMessages(node as TSESTree.Node, importedMacroVars);
12+
const {
13+
options: [type],
14+
} = context;
1215
for (const [
1316
{
1417
message: {description},
1518
descriptionNode,
1619
},
1720
] of msgs) {
18-
if (!description && !descriptionNode) {
19-
context.report({
20-
node,
21-
message: '`description` has to be specified in message descriptor',
22-
});
21+
if (!description) {
22+
if (type === 'literal' && descriptionNode) {
23+
context.report({
24+
node,
25+
message:
26+
'`description` has to be a string literal (not function call or variable)',
27+
});
28+
} else if (!descriptionNode) {
29+
context.report({
30+
node,
31+
message: '`description` has to be specified in message descriptor',
32+
});
33+
}
2334
}
2435
}
2536
}
@@ -35,6 +46,11 @@ export default {
3546
'https://github.com/formatjs/formatjs/tree/master/packages/eslint-plugin-formatjs#enforce-description',
3647
},
3748
fixable: 'code',
49+
schema: [
50+
{
51+
enum: ['literal', 'anything'],
52+
},
53+
],
3854
},
3955
create(context) {
4056
let importedMacroVars: Scope.Variable[] = [];

packages/eslint-plugin-formatjs/tests/enforce-default-message.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,20 @@ _({
3131
},
3232
],
3333
},
34+
{
35+
code: `
36+
import {_} from '@formatjs/macro'
37+
_({
38+
defaultMessage: foo
39+
})`,
40+
errors: [
41+
{
42+
message:
43+
'`defaultMessage` must be a string literal (not function call or variable)',
44+
},
45+
],
46+
options: ['literal'],
47+
},
3448
{
3549
code: `
3650
intl.formatMessage({

packages/eslint-plugin-formatjs/tests/enforce-description.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ _({
3131
},
3232
],
3333
},
34+
{
35+
code: `
36+
import {_} from '@formatjs/macro'
37+
_({
38+
defaultMessage: '{count, plural, one {#} other {# more}}',
39+
description: foo
40+
})`,
41+
errors: [
42+
{
43+
message:
44+
'`description` has to be a string literal (not function call or variable)',
45+
},
46+
],
47+
options: ['literal'],
48+
},
3449
{
3550
code: `
3651
intl.formatMessage({

0 commit comments

Comments
 (0)