eslint-plugin-formatjs 2.17.7
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.
- package/LICENSE.md +9 -0
- package/README.md +3 -0
- package/index.d.ts +20 -0
- package/index.d.ts.map +1 -0
- package/index.js +34 -0
- package/package.json +34 -0
- package/rules/blacklist-elements.d.ts +4 -0
- package/rules/blacklist-elements.d.ts.map +1 -0
- package/rules/blacklist-elements.js +135 -0
- package/rules/enforce-default-message.d.ts +4 -0
- package/rules/enforce-default-message.d.ts.map +1 -0
- package/rules/enforce-default-message.js +58 -0
- package/rules/enforce-description.d.ts +4 -0
- package/rules/enforce-description.d.ts.map +1 -0
- package/rules/enforce-description.js +57 -0
- package/rules/enforce-id.d.ts +4 -0
- package/rules/enforce-id.d.ts.map +1 -0
- package/rules/enforce-id.js +104 -0
- package/rules/enforce-placeholders.d.ts +4 -0
- package/rules/enforce-placeholders.d.ts.map +1 -0
- package/rules/enforce-placeholders.js +120 -0
- package/rules/enforce-plural-rules.d.ts +4 -0
- package/rules/enforce-plural-rules.d.ts.map +1 -0
- package/rules/enforce-plural-rules.js +113 -0
- package/rules/no-camel-case.d.ts +4 -0
- package/rules/no-camel-case.d.ts.map +1 -0
- package/rules/no-camel-case.js +85 -0
- package/rules/no-complex-selectors.d.ts +4 -0
- package/rules/no-complex-selectors.d.ts.map +1 -0
- package/rules/no-complex-selectors.js +80 -0
- package/rules/no-emoji.d.ts +4 -0
- package/rules/no-emoji.d.ts.map +1 -0
- package/rules/no-emoji.js +50 -0
- package/rules/no-id.d.ts +4 -0
- package/rules/no-id.d.ts.map +1 -0
- package/rules/no-id.js +58 -0
- package/rules/no-multiple-plurals.d.ts +4 -0
- package/rules/no-multiple-plurals.d.ts.map +1 -0
- package/rules/no-multiple-plurals.js +80 -0
- package/rules/no-multiple-whitespaces.d.ts +4 -0
- package/rules/no-multiple-whitespaces.d.ts.map +1 -0
- package/rules/no-multiple-whitespaces.js +57 -0
- package/rules/no-offset.d.ts +4 -0
- package/rules/no-offset.d.ts.map +1 -0
- package/rules/no-offset.js +78 -0
- package/util.d.ts +22 -0
- package/util.d.ts.map +1 -0
- package/util.js +232 -0
package/util.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/typescript-estree';
|
|
2
|
+
export interface MessageDescriptor {
|
|
3
|
+
id?: string;
|
|
4
|
+
defaultMessage?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface Settings {
|
|
8
|
+
excludeMessageDeclCalls?: boolean;
|
|
9
|
+
additionalFunctionNames?: string[];
|
|
10
|
+
additionalComponentNames?: string[];
|
|
11
|
+
ignoreTag?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface MessageDescriptorNodeInfo {
|
|
14
|
+
message: MessageDescriptor;
|
|
15
|
+
messageNode?: TSESTree.Property['value'] | TSESTree.JSXAttribute['value'];
|
|
16
|
+
messagePropNode?: TSESTree.Property | TSESTree.JSXAttribute;
|
|
17
|
+
descriptionNode?: TSESTree.Property['value'] | TSESTree.JSXAttribute['value'];
|
|
18
|
+
idValueNode?: TSESTree.Property['value'] | TSESTree.JSXAttribute['value'];
|
|
19
|
+
idPropNode?: TSESTree.Property | TSESTree.JSXAttribute;
|
|
20
|
+
}
|
|
21
|
+
export declare function extractMessages(node: TSESTree.Node, { additionalComponentNames, additionalFunctionNames, excludeMessageDeclCalls, }?: Settings): Array<[MessageDescriptorNodeInfo, TSESTree.Expression | undefined]>;
|
|
22
|
+
//# sourceMappingURL=util.d.ts.map
|
package/util.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../../packages/eslint-plugin-formatjs/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sCAAsC,CAAA;AAE7D,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAMD,MAAM,WAAW,QAAQ;IACvB,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAA;IAClC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAA;IACnC,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AACD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,iBAAiB,CAAA;IAC1B,WAAW,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IACzE,eAAe,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAA;IAC3D,eAAe,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IAC7E,WAAW,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IACzE,UAAU,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAA;CACvD;AAsND,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,CAAC,IAAI,EACnB,EACE,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,GACxB,GAAE,QAAa,GACf,KAAK,CAAC,CAAC,yBAAyB,EAAE,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC,CAiDrE"}
|
package/util.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractMessages = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var FORMAT_FUNCTION_NAMES = new Set(['$formatMessage', 'formatMessage']);
|
|
6
|
+
var COMPONENT_NAMES = new Set(['FormattedMessage']);
|
|
7
|
+
var DECLARATION_FUNCTION_NAMES = new Set(['defineMessage']);
|
|
8
|
+
function isStringLiteral(node) {
|
|
9
|
+
return node.type === 'Literal' && typeof node.value === 'string';
|
|
10
|
+
}
|
|
11
|
+
function isTemplateLiteralWithoutVar(node) {
|
|
12
|
+
return node.type === 'TemplateLiteral' && node.quasis.length === 1;
|
|
13
|
+
}
|
|
14
|
+
function staticallyEvaluateStringConcat(node) {
|
|
15
|
+
if (!isStringLiteral(node.right)) {
|
|
16
|
+
return ['', false];
|
|
17
|
+
}
|
|
18
|
+
if (isStringLiteral(node.left)) {
|
|
19
|
+
return [String(node.left.value) + node.right.value, true];
|
|
20
|
+
}
|
|
21
|
+
if (node.left.type === 'BinaryExpression') {
|
|
22
|
+
var _a = staticallyEvaluateStringConcat(node.left), result = _a[0], isStaticallyEvaluatable = _a[1];
|
|
23
|
+
return [result + node.right.value, isStaticallyEvaluatable];
|
|
24
|
+
}
|
|
25
|
+
return ['', false];
|
|
26
|
+
}
|
|
27
|
+
function isIntlFormatMessageCall(node) {
|
|
28
|
+
return (node.type === 'CallExpression' &&
|
|
29
|
+
node.callee.type === 'MemberExpression' &&
|
|
30
|
+
node.callee.object.type === 'Identifier' &&
|
|
31
|
+
node.callee.object.name === 'intl' &&
|
|
32
|
+
node.callee.property.type === 'Identifier' &&
|
|
33
|
+
node.callee.property.name === 'formatMessage' &&
|
|
34
|
+
node.arguments.length >= 1 &&
|
|
35
|
+
node.arguments[0].type === 'ObjectExpression');
|
|
36
|
+
}
|
|
37
|
+
function isSingleMessageDescriptorDeclaration(node, functionNames) {
|
|
38
|
+
return (node.type === 'CallExpression' &&
|
|
39
|
+
node.callee.type === 'Identifier' &&
|
|
40
|
+
functionNames.has(node.callee.name));
|
|
41
|
+
}
|
|
42
|
+
function isMultipleMessageDescriptorDeclaration(node) {
|
|
43
|
+
return (node.type === 'CallExpression' &&
|
|
44
|
+
node.callee.type === 'Identifier' &&
|
|
45
|
+
node.callee.name === 'defineMessages');
|
|
46
|
+
}
|
|
47
|
+
function extractMessageDescriptor(node) {
|
|
48
|
+
if (!node || node.type !== 'ObjectExpression') {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
var result = {
|
|
52
|
+
message: {},
|
|
53
|
+
messageNode: undefined,
|
|
54
|
+
messagePropNode: undefined,
|
|
55
|
+
descriptionNode: undefined,
|
|
56
|
+
idValueNode: undefined,
|
|
57
|
+
};
|
|
58
|
+
for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
|
|
59
|
+
var prop = _a[_i];
|
|
60
|
+
if (prop.type !== 'Property' || prop.key.type !== 'Identifier') {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
var valueNode = prop.value;
|
|
64
|
+
var value = undefined;
|
|
65
|
+
if (isStringLiteral(valueNode)) {
|
|
66
|
+
value = valueNode.value;
|
|
67
|
+
}
|
|
68
|
+
else if (isTemplateLiteralWithoutVar(valueNode)) {
|
|
69
|
+
value = valueNode.quasis[0].value.cooked;
|
|
70
|
+
}
|
|
71
|
+
else if (valueNode.type === 'BinaryExpression') {
|
|
72
|
+
var _b = staticallyEvaluateStringConcat(valueNode), result_1 = _b[0], isStatic = _b[1];
|
|
73
|
+
if (isStatic) {
|
|
74
|
+
value = result_1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
switch (prop.key.name) {
|
|
78
|
+
case 'defaultMessage':
|
|
79
|
+
result.messagePropNode = prop;
|
|
80
|
+
result.messageNode = valueNode;
|
|
81
|
+
result.message.defaultMessage = value;
|
|
82
|
+
break;
|
|
83
|
+
case 'description':
|
|
84
|
+
result.descriptionNode = valueNode;
|
|
85
|
+
result.message.description = value;
|
|
86
|
+
break;
|
|
87
|
+
case 'id':
|
|
88
|
+
result.message.id = value;
|
|
89
|
+
result.idValueNode = valueNode;
|
|
90
|
+
result.idPropNode = prop;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function extractMessageDescriptorFromJSXElement(node) {
|
|
97
|
+
if (!node || !node.attributes) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
var values;
|
|
101
|
+
var result = {
|
|
102
|
+
message: {},
|
|
103
|
+
messageNode: undefined,
|
|
104
|
+
messagePropNode: undefined,
|
|
105
|
+
descriptionNode: undefined,
|
|
106
|
+
idValueNode: undefined,
|
|
107
|
+
idPropNode: undefined,
|
|
108
|
+
};
|
|
109
|
+
for (var _i = 0, _a = node.attributes; _i < _a.length; _i++) {
|
|
110
|
+
var prop = _a[_i];
|
|
111
|
+
if (prop.type !== 'JSXAttribute' || prop.name.type !== 'JSXIdentifier') {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
var key = prop.name;
|
|
115
|
+
var valueNode = prop.value;
|
|
116
|
+
var value = undefined;
|
|
117
|
+
if (valueNode) {
|
|
118
|
+
if (isStringLiteral(valueNode)) {
|
|
119
|
+
value = valueNode.value;
|
|
120
|
+
}
|
|
121
|
+
else if ((valueNode === null || valueNode === void 0 ? void 0 : valueNode.type) === 'JSXExpressionContainer') {
|
|
122
|
+
var expression = valueNode.expression;
|
|
123
|
+
if (expression.type === 'BinaryExpression') {
|
|
124
|
+
var _b = staticallyEvaluateStringConcat(expression), result_2 = _b[0], isStatic = _b[1];
|
|
125
|
+
if (isStatic) {
|
|
126
|
+
value = result_2;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else if (isTemplateLiteralWithoutVar(expression)) {
|
|
130
|
+
value = expression.quasis[0].value.cooked;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
switch (key.name) {
|
|
135
|
+
case 'defaultMessage':
|
|
136
|
+
result.messagePropNode = prop;
|
|
137
|
+
result.messageNode = valueNode;
|
|
138
|
+
if (value) {
|
|
139
|
+
result.message.defaultMessage = value;
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
case 'description':
|
|
143
|
+
result.descriptionNode = valueNode;
|
|
144
|
+
if (value) {
|
|
145
|
+
result.message.description = value;
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
case 'id':
|
|
149
|
+
result.idValueNode = valueNode;
|
|
150
|
+
result.idPropNode = prop;
|
|
151
|
+
if (value) {
|
|
152
|
+
result.message.id = value;
|
|
153
|
+
}
|
|
154
|
+
break;
|
|
155
|
+
case 'values':
|
|
156
|
+
if ((valueNode === null || valueNode === void 0 ? void 0 : valueNode.type) === 'JSXExpressionContainer' &&
|
|
157
|
+
valueNode.expression.type === 'ObjectExpression') {
|
|
158
|
+
values = valueNode.expression;
|
|
159
|
+
}
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (!result.messagePropNode &&
|
|
164
|
+
!result.descriptionNode &&
|
|
165
|
+
!result.idPropNode) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
return [result, values];
|
|
169
|
+
}
|
|
170
|
+
function extractMessageDescriptors(node) {
|
|
171
|
+
if (!node || node.type !== 'ObjectExpression' || !node.properties.length) {
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
var msgs = [];
|
|
175
|
+
for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
|
|
176
|
+
var prop = _a[_i];
|
|
177
|
+
if (prop.type !== 'Property') {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
var msg = prop.value;
|
|
181
|
+
if (msg.type !== 'ObjectExpression') {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
var nodeInfo = extractMessageDescriptor(msg);
|
|
185
|
+
if (nodeInfo) {
|
|
186
|
+
msgs.push(nodeInfo);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return msgs;
|
|
190
|
+
}
|
|
191
|
+
function extractMessages(node, _a) {
|
|
192
|
+
var _b = _a === void 0 ? {} : _a, additionalComponentNames = _b.additionalComponentNames, additionalFunctionNames = _b.additionalFunctionNames, excludeMessageDeclCalls = _b.excludeMessageDeclCalls;
|
|
193
|
+
var allFormatFunctionNames = Array.isArray(additionalFunctionNames)
|
|
194
|
+
? new Set(tslib_1.__spreadArray(tslib_1.__spreadArray([], Array.from(FORMAT_FUNCTION_NAMES)), additionalFunctionNames))
|
|
195
|
+
: FORMAT_FUNCTION_NAMES;
|
|
196
|
+
var allComponentNames = Array.isArray(additionalComponentNames)
|
|
197
|
+
? new Set(tslib_1.__spreadArray(tslib_1.__spreadArray([], Array.from(COMPONENT_NAMES)), additionalComponentNames))
|
|
198
|
+
: COMPONENT_NAMES;
|
|
199
|
+
if (node.type === 'CallExpression') {
|
|
200
|
+
var expr = node;
|
|
201
|
+
var args0 = expr.arguments[0];
|
|
202
|
+
var args1 = expr.arguments[1];
|
|
203
|
+
// We can't really analyze spread element
|
|
204
|
+
if (!args0 || args0.type === 'SpreadElement') {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
if ((!excludeMessageDeclCalls &&
|
|
208
|
+
isSingleMessageDescriptorDeclaration(node, DECLARATION_FUNCTION_NAMES)) ||
|
|
209
|
+
isIntlFormatMessageCall(node) ||
|
|
210
|
+
isSingleMessageDescriptorDeclaration(node, allFormatFunctionNames)) {
|
|
211
|
+
var msgDescriptorNodeInfo = extractMessageDescriptor(args0);
|
|
212
|
+
if (msgDescriptorNodeInfo && (!args1 || args1.type !== 'SpreadElement')) {
|
|
213
|
+
return [[msgDescriptorNodeInfo, args1]];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else if (!excludeMessageDeclCalls &&
|
|
217
|
+
isMultipleMessageDescriptorDeclaration(node)) {
|
|
218
|
+
return extractMessageDescriptors(args0).map(function (msg) { return [msg, undefined]; });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else if (node.type === 'JSXOpeningElement' &&
|
|
222
|
+
node.name &&
|
|
223
|
+
node.name.type === 'JSXIdentifier' &&
|
|
224
|
+
allComponentNames.has(node.name.name)) {
|
|
225
|
+
var msgDescriptorNodeInfo = extractMessageDescriptorFromJSXElement(node);
|
|
226
|
+
if (msgDescriptorNodeInfo) {
|
|
227
|
+
return [msgDescriptorNodeInfo];
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
exports.extractMessages = extractMessages;
|