@lingui/macro 3.14.0 → 3.16.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.
- package/CHANGELOG.md +406 -0
- package/build/LICENSE +21 -0
- package/{constants.js → build/constants.js} +5 -5
- package/{global.d.ts → build/global.d.ts} +0 -0
- package/build/icu.js +113 -0
- package/{index.d.ts → build/index.d.ts} +1 -0
- package/build/index.js +158 -0
- package/build/macroJs.js +345 -0
- package/build/macroJsx.js +328 -0
- package/build/utils.js +25 -0
- package/package.json +11 -9
- package/icu.js +0 -118
- package/index.js +0 -168
- package/macroJs.js +0 -384
- package/macroJsx.js +0 -360
- package/utils.js +0 -30
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.normalizeWhitespace = normalizeWhitespace;
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
|
|
9
|
+
var R = _interopRequireWildcard(require("ramda"));
|
|
10
|
+
|
|
11
|
+
var _icu = _interopRequireDefault(require("./icu"));
|
|
12
|
+
|
|
13
|
+
var _utils = require("./utils");
|
|
14
|
+
|
|
15
|
+
var _constants = require("./constants");
|
|
16
|
+
|
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
+
|
|
19
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
20
|
+
|
|
21
|
+
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
22
|
+
|
|
23
|
+
const pluralRuleRe = /(_[\d\w]+|zero|one|two|few|many|other)/;
|
|
24
|
+
|
|
25
|
+
const jsx2icuExactChoice = value => value.replace(/_(\d+)/, "=$1").replace(/_(\w+)/, "$1"); // replace whitespace before/after newline with single space
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
const keepSpaceRe = /\s*(?:\r\n|\r|\n)+\s*/g; // remove whitespace before/after tag or expression
|
|
29
|
+
|
|
30
|
+
const stripAroundTagsRe = /(?:([>}])(?:\r\n|\r|\n)+\s*|(?:\r\n|\r|\n)+\s*(?=[<{]))/g;
|
|
31
|
+
|
|
32
|
+
function maybeNodeValue(node) {
|
|
33
|
+
if (!node) return null;
|
|
34
|
+
if (node.type === "StringLiteral") return node.value;
|
|
35
|
+
if (node.type === "JSXAttribute") return maybeNodeValue(node.value);
|
|
36
|
+
if (node.type === "JSXExpressionContainer") return maybeNodeValue(node.expression);
|
|
37
|
+
if (node.type === "TemplateLiteral" && node.expressions.length === 0) return node.quasis[0].value.raw;
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function normalizeWhitespace(text) {
|
|
42
|
+
return text.replace(stripAroundTagsRe, "$1").replace(keepSpaceRe, " ") // keep escaped newlines
|
|
43
|
+
.replace(/\\n/g, "\n").replace(/\\s/g, " ") // we remove trailing whitespace inside Plural
|
|
44
|
+
.replace(/(\s+})/gm, "}").trim();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
class MacroJSX {
|
|
48
|
+
expressionIndex = (0, _utils.makeCounter)();
|
|
49
|
+
elementIndex = (0, _utils.makeCounter)();
|
|
50
|
+
|
|
51
|
+
constructor({
|
|
52
|
+
types
|
|
53
|
+
}) {
|
|
54
|
+
this.types = types;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
safeJsxAttribute = (name, value) => {
|
|
58
|
+
// This handles quoted JSX attributes and html entities.
|
|
59
|
+
return this.types.jsxAttribute(this.types.jsxIdentifier(name), this.types.jsxExpressionContainer(this.types.stringLiteral(value)));
|
|
60
|
+
};
|
|
61
|
+
replacePath = path => {
|
|
62
|
+
const tokens = this.tokenizeNode(path.node);
|
|
63
|
+
const messageFormat = new _icu.default();
|
|
64
|
+
const {
|
|
65
|
+
message: messageRaw,
|
|
66
|
+
values,
|
|
67
|
+
jsxElements
|
|
68
|
+
} = messageFormat.fromTokens(tokens);
|
|
69
|
+
const message = normalizeWhitespace(messageRaw);
|
|
70
|
+
const {
|
|
71
|
+
attributes,
|
|
72
|
+
id,
|
|
73
|
+
comment,
|
|
74
|
+
context
|
|
75
|
+
} = this.stripMacroAttributes(path.node);
|
|
76
|
+
|
|
77
|
+
if (!id && !message) {
|
|
78
|
+
return;
|
|
79
|
+
} else if (id && id !== message) {
|
|
80
|
+
// If `id` prop already exists and generated ID is different,
|
|
81
|
+
// add it as a `default` prop
|
|
82
|
+
attributes.push(this.types.jsxAttribute(this.types.jsxIdentifier(_constants.ID), this.types.stringLiteral(id)));
|
|
83
|
+
|
|
84
|
+
if (process.env.NODE_ENV !== "production") {
|
|
85
|
+
if (message) {
|
|
86
|
+
attributes.push(this.safeJsxAttribute(_constants.MESSAGE, message));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
attributes.push(this.safeJsxAttribute(_constants.ID, message));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (process.env.NODE_ENV !== "production") {
|
|
94
|
+
if (comment) {
|
|
95
|
+
attributes.push(this.types.jsxAttribute(this.types.jsxIdentifier(_constants.COMMENT), this.types.stringLiteral(comment)));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (context) {
|
|
100
|
+
attributes.push(this.types.jsxAttribute(this.types.jsxIdentifier(_constants.CONTEXT), this.types.stringLiteral(context)));
|
|
101
|
+
} // Parameters for variable substitution
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
const valuesObject = Object.keys(values).map(key => this.types.objectProperty(this.types.identifier(key), values[key]));
|
|
105
|
+
|
|
106
|
+
if (valuesObject.length) {
|
|
107
|
+
attributes.push(this.types.jsxAttribute(this.types.jsxIdentifier("values"), this.types.jsxExpressionContainer(this.types.objectExpression(valuesObject))));
|
|
108
|
+
} // Inline elements
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if (Object.keys(jsxElements).length) {
|
|
112
|
+
attributes.push(this.types.jsxAttribute(this.types.jsxIdentifier("components"), this.types.jsxExpressionContainer(this.types.objectExpression(Object.keys(jsxElements).map(key => this.types.objectProperty(this.types.identifier(key), jsxElements[key]))))));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const newNode = this.types.jsxElement(this.types.jsxOpeningElement(this.types.jsxIdentifier("Trans"), attributes,
|
|
116
|
+
/*selfClosing*/
|
|
117
|
+
true),
|
|
118
|
+
/*closingElement*/
|
|
119
|
+
null,
|
|
120
|
+
/*children*/
|
|
121
|
+
[],
|
|
122
|
+
/*selfClosing*/
|
|
123
|
+
true);
|
|
124
|
+
newNode.loc = path.node.loc;
|
|
125
|
+
path.replaceWith(newNode);
|
|
126
|
+
};
|
|
127
|
+
attrName = (names, exclude = false) => {
|
|
128
|
+
const namesRe = new RegExp("^(" + names.join("|") + ")$");
|
|
129
|
+
return attr => {
|
|
130
|
+
const name = attr.name.name;
|
|
131
|
+
return exclude ? !namesRe.test(name) : namesRe.test(name);
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
stripMacroAttributes = node => {
|
|
135
|
+
const {
|
|
136
|
+
attributes
|
|
137
|
+
} = node.openingElement;
|
|
138
|
+
const id = attributes.filter(this.attrName([_constants.ID]))[0];
|
|
139
|
+
const message = attributes.filter(this.attrName([_constants.MESSAGE]))[0];
|
|
140
|
+
const comment = attributes.filter(this.attrName([_constants.COMMENT]))[0];
|
|
141
|
+
const context = attributes.filter(this.attrName([_constants.CONTEXT]))[0];
|
|
142
|
+
let reserved = [_constants.ID, _constants.MESSAGE, _constants.COMMENT, _constants.CONTEXT];
|
|
143
|
+
|
|
144
|
+
if (this.isI18nComponent(node)) {// no reserved prop names
|
|
145
|
+
} else if (this.isChoiceComponent(node)) {
|
|
146
|
+
reserved = [...reserved, "_\\w+", "_\\d+", "zero", "one", "two", "few", "many", "other", "value", "offset"];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
id: maybeNodeValue(id),
|
|
151
|
+
message: maybeNodeValue(message),
|
|
152
|
+
comment: maybeNodeValue(comment),
|
|
153
|
+
context: maybeNodeValue(context),
|
|
154
|
+
attributes: attributes.filter(this.attrName(reserved, true))
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
tokenizeNode = node => {
|
|
158
|
+
if (this.isI18nComponent(node)) {
|
|
159
|
+
// t
|
|
160
|
+
return this.tokenizeTrans(node);
|
|
161
|
+
} else if (this.isChoiceComponent(node)) {
|
|
162
|
+
// plural, select and selectOrdinal
|
|
163
|
+
return this.tokenizeChoiceComponent(node);
|
|
164
|
+
} else if (this.types.isJSXElement(node)) {
|
|
165
|
+
return this.tokenizeElement(node);
|
|
166
|
+
} else {
|
|
167
|
+
return this.tokenizeExpression(node);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
tokenizeTrans = node => {
|
|
171
|
+
return R.flatten(node.children.map(child => this.tokenizeChildren(child)).filter(Boolean));
|
|
172
|
+
};
|
|
173
|
+
tokenizeChildren = node => {
|
|
174
|
+
if (this.types.isJSXExpressionContainer(node)) {
|
|
175
|
+
const exp = node.expression;
|
|
176
|
+
|
|
177
|
+
if (this.types.isStringLiteral(exp)) {
|
|
178
|
+
// Escape forced newlines to keep them in message.
|
|
179
|
+
return {
|
|
180
|
+
type: "text",
|
|
181
|
+
value: exp.value.replace(/\n/g, "\\n")
|
|
182
|
+
};
|
|
183
|
+
} else if (this.types.isTemplateLiteral(exp)) {
|
|
184
|
+
const tokenize = R.pipe( // Don"t output tokens without text.
|
|
185
|
+
R.evolve({
|
|
186
|
+
quasis: R.map(text => {
|
|
187
|
+
// if it's an unicode we keep the cooked value because it's the parsed value by babel (without unicode chars)
|
|
188
|
+
// This regex will detect if a string contains unicode chars, when they're we should interpolate them
|
|
189
|
+
// why? because platforms like react native doesn't parse them, just doing a JSON.parse makes them UTF-8 friendly
|
|
190
|
+
const value = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/g.test(text.value.raw) ? text.value.cooked : text.value.raw;
|
|
191
|
+
if (value === "") return null;
|
|
192
|
+
return this.tokenizeText(this.clearBackslashes(value));
|
|
193
|
+
}),
|
|
194
|
+
expressions: R.map(exp => this.types.isCallExpression(exp) ? this.tokenizeNode(exp) : this.tokenizeExpression(exp))
|
|
195
|
+
}), exp => (0, _utils.zip)(exp.quasis, exp.expressions), R.flatten, R.filter(Boolean));
|
|
196
|
+
return tokenize(exp);
|
|
197
|
+
} else if (this.types.isJSXElement(exp)) {
|
|
198
|
+
return this.tokenizeNode(exp);
|
|
199
|
+
} else {
|
|
200
|
+
return this.tokenizeExpression(exp);
|
|
201
|
+
}
|
|
202
|
+
} else if (this.types.isJSXElement(node)) {
|
|
203
|
+
return this.tokenizeNode(node);
|
|
204
|
+
} else if (this.types.isJSXSpreadChild(node)) {// just do nothing
|
|
205
|
+
} else if (this.types.isJSXText(node)) {
|
|
206
|
+
return this.tokenizeText(node.value);
|
|
207
|
+
} else {// impossible path
|
|
208
|
+
// return this.tokenizeText(node.value)
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
tokenizeChoiceComponent = node => {
|
|
212
|
+
const element = node.openingElement;
|
|
213
|
+
const format = this.getJsxTagName(node).toLowerCase();
|
|
214
|
+
const props = element.attributes.filter(this.attrName([_constants.ID, _constants.COMMENT, _constants.MESSAGE, _constants.CONTEXT, "key", // we remove <Trans /> react props that are not useful for translation
|
|
215
|
+
"render", "component", "components"], true));
|
|
216
|
+
const token = {
|
|
217
|
+
type: "arg",
|
|
218
|
+
format,
|
|
219
|
+
name: null,
|
|
220
|
+
value: undefined,
|
|
221
|
+
options: {
|
|
222
|
+
offset: undefined
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
for (const attr of props) {
|
|
227
|
+
if (this.types.isJSXSpreadAttribute(attr)) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (this.types.isJSXNamespacedName(attr.name)) {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const name = attr.name.name;
|
|
236
|
+
|
|
237
|
+
if (name === "value") {
|
|
238
|
+
const exp = this.types.isLiteral(attr.value) ? attr.value : attr.value.expression;
|
|
239
|
+
token.name = this.expressionToArgument(exp);
|
|
240
|
+
token.value = exp;
|
|
241
|
+
} else if (format !== "select" && name === "offset") {
|
|
242
|
+
// offset is static parameter, so it must be either string or number
|
|
243
|
+
token.options.offset = this.types.isStringLiteral(attr.value) ? attr.value.value : attr.value.expression.value;
|
|
244
|
+
} else {
|
|
245
|
+
let value;
|
|
246
|
+
|
|
247
|
+
if (this.types.isStringLiteral(attr.value)) {
|
|
248
|
+
value = attr.value.extra.raw.replace(/(["'])(.*)\1/, "$2");
|
|
249
|
+
} else {
|
|
250
|
+
value = this.tokenizeChildren(attr.value);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (pluralRuleRe.test(name)) {
|
|
254
|
+
token.options[jsx2icuExactChoice(name)] = value;
|
|
255
|
+
} else {
|
|
256
|
+
token.options[name] = value;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return token;
|
|
262
|
+
};
|
|
263
|
+
tokenizeElement = node => {
|
|
264
|
+
// !!! Important: Calculate element index before traversing children.
|
|
265
|
+
// That way outside elements are numbered before inner elements. (...and it looks pretty).
|
|
266
|
+
const name = this.elementIndex();
|
|
267
|
+
const children = R.flatten(node.children.map(child => this.tokenizeChildren(child)).filter(Boolean));
|
|
268
|
+
node.children = [];
|
|
269
|
+
node.openingElement.selfClosing = true;
|
|
270
|
+
return {
|
|
271
|
+
type: "element",
|
|
272
|
+
name,
|
|
273
|
+
value: node,
|
|
274
|
+
children
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
tokenizeExpression = node => {
|
|
278
|
+
return {
|
|
279
|
+
type: "arg",
|
|
280
|
+
name: this.expressionToArgument(node),
|
|
281
|
+
value: node
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
tokenizeText = value => {
|
|
285
|
+
return {
|
|
286
|
+
type: "text",
|
|
287
|
+
value
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
expressionToArgument(exp) {
|
|
292
|
+
return this.types.isIdentifier(exp) ? exp.name : String(this.expressionIndex());
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* We clean '//\` ' to just '`'
|
|
296
|
+
**/
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
clearBackslashes(value) {
|
|
300
|
+
// if not we replace the extra scaped literals
|
|
301
|
+
return value.replace(/\\`/g, "`");
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Custom matchers
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
isIdentifier = (node, name) => {
|
|
309
|
+
return this.types.isIdentifier(node, {
|
|
310
|
+
name
|
|
311
|
+
});
|
|
312
|
+
};
|
|
313
|
+
isI18nComponent = (node, name = "Trans") => {
|
|
314
|
+
return this.types.isJSXElement(node) && this.types.isJSXIdentifier(node.openingElement.name, {
|
|
315
|
+
name
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
isChoiceComponent = node => {
|
|
319
|
+
return this.isI18nComponent(node, "Plural") || this.isI18nComponent(node, "Select") || this.isI18nComponent(node, "SelectOrdinal");
|
|
320
|
+
};
|
|
321
|
+
getJsxTagName = node => {
|
|
322
|
+
if (this.types.isJSXIdentifier(node.openingElement.name)) {
|
|
323
|
+
return node.openingElement.name.name;
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
exports.default = MacroJSX;
|
package/build/utils.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.zip = zip;
|
|
7
|
+
exports.makeCounter = void 0;
|
|
8
|
+
|
|
9
|
+
var R = _interopRequireWildcard(require("ramda"));
|
|
10
|
+
|
|
11
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
12
|
+
|
|
13
|
+
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Custom zip method which takes length of the larger array
|
|
17
|
+
* (usually zip functions use the `smaller` length, discarding values in larger array)
|
|
18
|
+
*/
|
|
19
|
+
function zip(a, b) {
|
|
20
|
+
return R.range(0, Math.max(a.length, b.length)).map(index => [a[index], b[index]]);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const makeCounter = (index = 0) => () => index++;
|
|
24
|
+
|
|
25
|
+
exports.makeCounter = makeCounter;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingui/macro",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
4
4
|
"description": "Macro for generating messages in ICU MessageFormat syntax",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "./build/index.js",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Tomáš Ehrlich",
|
|
8
8
|
"email": "tomas.ehrlich@gmail.com"
|
|
@@ -19,23 +19,25 @@
|
|
|
19
19
|
"url": "https://github.com/lingui/js-lingui/issues"
|
|
20
20
|
},
|
|
21
21
|
"engines": {
|
|
22
|
-
"node": ">=
|
|
22
|
+
"node": ">=14.0.0"
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"LICENSE",
|
|
26
26
|
"README.md",
|
|
27
|
-
"
|
|
28
|
-
"global.d.ts",
|
|
29
|
-
"index.d.ts"
|
|
27
|
+
"build/"
|
|
30
28
|
],
|
|
31
29
|
"dependencies": {
|
|
32
30
|
"@babel/runtime": "^7.11.2",
|
|
33
|
-
"@lingui/conf": "
|
|
31
|
+
"@lingui/conf": "3.16.0",
|
|
34
32
|
"ramda": "^0.27.1"
|
|
35
33
|
},
|
|
36
34
|
"peerDependencies": {
|
|
37
35
|
"@lingui/core": "^3.13.0",
|
|
38
36
|
"@lingui/react": "^3.13.0",
|
|
39
|
-
"babel-plugin-macros": "2 ||
|
|
40
|
-
}
|
|
37
|
+
"babel-plugin-macros": "2 || 3"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/babel-plugin-macros": "^2.8.5"
|
|
41
|
+
},
|
|
42
|
+
"gitHead": "e8c1f518b988f45f3f6da84333550b215dcde94b"
|
|
41
43
|
}
|
package/icu.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", {
|
|
6
|
-
value: true
|
|
7
|
-
});
|
|
8
|
-
exports.default = ICUMessageFormat;
|
|
9
|
-
|
|
10
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
-
|
|
12
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
13
|
-
|
|
14
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
15
|
-
|
|
16
|
-
var metaOptions = ["id", "comment", "props"];
|
|
17
|
-
var escapedMetaOptionsRe = new RegExp("^_(".concat(metaOptions.join("|"), ")$"));
|
|
18
|
-
|
|
19
|
-
function ICUMessageFormat() {}
|
|
20
|
-
|
|
21
|
-
ICUMessageFormat.prototype.fromTokens = function (tokens) {
|
|
22
|
-
var _this = this;
|
|
23
|
-
|
|
24
|
-
return (Array.isArray(tokens) ? tokens : [tokens]).map(function (token) {
|
|
25
|
-
return _this.processToken(token);
|
|
26
|
-
}).filter(Boolean).reduce(function (props, message) {
|
|
27
|
-
return _objectSpread(_objectSpread({}, message), {}, {
|
|
28
|
-
message: props.message + message.message,
|
|
29
|
-
values: _objectSpread(_objectSpread({}, props.values), message.values),
|
|
30
|
-
jsxElements: _objectSpread(_objectSpread({}, props.jsxElements), message.jsxElements)
|
|
31
|
-
});
|
|
32
|
-
}, {
|
|
33
|
-
message: "",
|
|
34
|
-
values: {},
|
|
35
|
-
jsxElements: {}
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
ICUMessageFormat.prototype.processToken = function (token) {
|
|
40
|
-
var _this2 = this;
|
|
41
|
-
|
|
42
|
-
var jsxElements = {};
|
|
43
|
-
|
|
44
|
-
if (token.type === "text") {
|
|
45
|
-
return {
|
|
46
|
-
message: token.value
|
|
47
|
-
};
|
|
48
|
-
} else if (token.type === "arg") {
|
|
49
|
-
if (token.value !== undefined && token.value.type === 'JSXEmptyExpression') {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
var values = token.value !== undefined ? (0, _defineProperty2.default)({}, token.name, token.value) : {};
|
|
54
|
-
|
|
55
|
-
switch (token.format) {
|
|
56
|
-
case "plural":
|
|
57
|
-
case "select":
|
|
58
|
-
case "selectordinal":
|
|
59
|
-
var formatOptions = Object.keys(token.options).filter(function (key) {
|
|
60
|
-
return token.options[key] != null;
|
|
61
|
-
}).map(function (key) {
|
|
62
|
-
var value = token.options[key];
|
|
63
|
-
key = key.replace(escapedMetaOptionsRe, "$1");
|
|
64
|
-
|
|
65
|
-
if (key === "offset") {
|
|
66
|
-
// offset has special syntax `offset:number`
|
|
67
|
-
return "offset:".concat(value);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (typeof value !== "string") {
|
|
71
|
-
// process tokens from nested formatters
|
|
72
|
-
var _this2$fromTokens = _this2.fromTokens(value),
|
|
73
|
-
message = _this2$fromTokens.message,
|
|
74
|
-
childValues = _this2$fromTokens.values,
|
|
75
|
-
childJsxElements = _this2$fromTokens.jsxElements;
|
|
76
|
-
|
|
77
|
-
Object.assign(values, childValues);
|
|
78
|
-
Object.assign(jsxElements, childJsxElements);
|
|
79
|
-
value = message;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return "".concat(key, " {").concat(value, "}");
|
|
83
|
-
}).join(" ");
|
|
84
|
-
return {
|
|
85
|
-
message: "{".concat(token.name, ", ").concat(token.format, ", ").concat(formatOptions, "}"),
|
|
86
|
-
values: values,
|
|
87
|
-
jsxElements: jsxElements
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
default:
|
|
91
|
-
return {
|
|
92
|
-
message: "{".concat(token.name, "}"),
|
|
93
|
-
values: values
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
} else if (token.type === "element") {
|
|
97
|
-
var message = "";
|
|
98
|
-
var elementValues = {};
|
|
99
|
-
Object.assign(jsxElements, (0, _defineProperty2.default)({}, token.name, token.value));
|
|
100
|
-
token.children.forEach(function (child) {
|
|
101
|
-
var _this2$fromTokens2 = _this2.fromTokens(child),
|
|
102
|
-
childMessage = _this2$fromTokens2.message,
|
|
103
|
-
childValues = _this2$fromTokens2.values,
|
|
104
|
-
childJsxElements = _this2$fromTokens2.jsxElements;
|
|
105
|
-
|
|
106
|
-
message += childMessage;
|
|
107
|
-
Object.assign(elementValues, childValues);
|
|
108
|
-
Object.assign(jsxElements, childJsxElements);
|
|
109
|
-
});
|
|
110
|
-
return {
|
|
111
|
-
message: token.children.length ? "<".concat(token.name, ">").concat(message, "</").concat(token.name, ">") : "<".concat(token.name, "/>"),
|
|
112
|
-
values: elementValues,
|
|
113
|
-
jsxElements: jsxElements
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
throw new Error("Unknown token type ".concat(token.type));
|
|
118
|
-
};
|
package/index.js
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", {
|
|
6
|
-
value: true
|
|
7
|
-
});
|
|
8
|
-
exports.default = void 0;
|
|
9
|
-
|
|
10
|
-
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
11
|
-
|
|
12
|
-
var _babelPluginMacros = require("babel-plugin-macros");
|
|
13
|
-
|
|
14
|
-
var _conf = require("@lingui/conf");
|
|
15
|
-
|
|
16
|
-
var _macroJs = _interopRequireDefault(require("./macroJs"));
|
|
17
|
-
|
|
18
|
-
var _macroJsx = _interopRequireDefault(require("./macroJsx"));
|
|
19
|
-
|
|
20
|
-
var config = (0, _conf.getConfig)({
|
|
21
|
-
configPath: process.env.LINGUI_CONFIG
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
var getSymbolSource = function getSymbolSource(name) {
|
|
25
|
-
if (Array.isArray(config.runtimeConfigModule)) {
|
|
26
|
-
if (name === "i18n") {
|
|
27
|
-
return config.runtimeConfigModule;
|
|
28
|
-
} else {
|
|
29
|
-
return ["@lingui/react", name];
|
|
30
|
-
}
|
|
31
|
-
} else {
|
|
32
|
-
if (Object.prototype.hasOwnProperty.call(config.runtimeConfigModule, name)) {
|
|
33
|
-
return config.runtimeConfigModule[name];
|
|
34
|
-
} else {
|
|
35
|
-
return ["@lingui/react", name];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
var _getSymbolSource = getSymbolSource("i18n"),
|
|
41
|
-
_getSymbolSource2 = (0, _slicedToArray2.default)(_getSymbolSource, 2),
|
|
42
|
-
i18nImportModule = _getSymbolSource2[0],
|
|
43
|
-
_getSymbolSource2$ = _getSymbolSource2[1],
|
|
44
|
-
i18nImportName = _getSymbolSource2$ === void 0 ? "i18n" : _getSymbolSource2$;
|
|
45
|
-
|
|
46
|
-
var _getSymbolSource3 = getSymbolSource("Trans"),
|
|
47
|
-
_getSymbolSource4 = (0, _slicedToArray2.default)(_getSymbolSource3, 2),
|
|
48
|
-
TransImportModule = _getSymbolSource4[0],
|
|
49
|
-
_getSymbolSource4$ = _getSymbolSource4[1],
|
|
50
|
-
TransImportName = _getSymbolSource4$ === void 0 ? "Trans" : _getSymbolSource4$;
|
|
51
|
-
|
|
52
|
-
function macro(_ref) {
|
|
53
|
-
var references = _ref.references,
|
|
54
|
-
state = _ref.state,
|
|
55
|
-
babel = _ref.babel;
|
|
56
|
-
var jsxNodes = [];
|
|
57
|
-
var jsNodes = [];
|
|
58
|
-
var needsI18nImport = false;
|
|
59
|
-
Object.keys(references).forEach(function (tagName) {
|
|
60
|
-
var nodes = references[tagName];
|
|
61
|
-
var macroType = getMacroType(tagName);
|
|
62
|
-
|
|
63
|
-
if (macroType == null) {
|
|
64
|
-
throw nodes[0].buildCodeFrameError("Unknown macro ".concat(tagName));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (macroType === "js") {
|
|
68
|
-
nodes.forEach(function (node) {
|
|
69
|
-
jsNodes.push(node.parentPath);
|
|
70
|
-
});
|
|
71
|
-
} else {
|
|
72
|
-
nodes.forEach(function (node) {
|
|
73
|
-
// identifier.openingElement.jsxElement
|
|
74
|
-
jsxNodes.push(node.parentPath.parentPath);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
jsNodes.filter(isRootPath(jsNodes)).forEach(function (path) {
|
|
79
|
-
if (alreadyVisited(path)) return;
|
|
80
|
-
var macro = new _macroJs.default(babel, {
|
|
81
|
-
i18nImportName: i18nImportName
|
|
82
|
-
});
|
|
83
|
-
if (macro.replacePath(path)) needsI18nImport = true;
|
|
84
|
-
});
|
|
85
|
-
jsxNodes.filter(isRootPath(jsxNodes)).forEach(function (path) {
|
|
86
|
-
if (alreadyVisited(path)) return;
|
|
87
|
-
var macro = new _macroJsx.default(babel);
|
|
88
|
-
macro.replacePath(path);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
if (needsI18nImport) {
|
|
92
|
-
addImport(babel, state, i18nImportModule, i18nImportName);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (jsxNodes.length) {
|
|
96
|
-
addImport(babel, state, TransImportModule, TransImportName);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (process.env.LINGUI_EXTRACT === "1") {
|
|
100
|
-
return {
|
|
101
|
-
keepImports: true
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function addImport(babel, state, module, importName) {
|
|
107
|
-
var t = babel.types;
|
|
108
|
-
var linguiImport = state.file.path.node.body.find(function (importNode) {
|
|
109
|
-
return t.isImportDeclaration(importNode) && importNode.source.value === module && // https://github.com/lingui/js-lingui/issues/777
|
|
110
|
-
importNode.importKind !== "type";
|
|
111
|
-
});
|
|
112
|
-
var tIdentifier = t.identifier(importName); // Handle adding the import or altering the existing import
|
|
113
|
-
|
|
114
|
-
if (linguiImport) {
|
|
115
|
-
if (linguiImport.specifiers.findIndex(function (specifier) {
|
|
116
|
-
return specifier.imported && specifier.imported.name === importName;
|
|
117
|
-
}) === -1) {
|
|
118
|
-
linguiImport.specifiers.push(t.importSpecifier(tIdentifier, tIdentifier));
|
|
119
|
-
}
|
|
120
|
-
} else {
|
|
121
|
-
state.file.path.node.body.unshift(t.importDeclaration([t.importSpecifier(tIdentifier, tIdentifier)], t.stringLiteral(module)));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function isRootPath(allPath) {
|
|
126
|
-
return function (node) {
|
|
127
|
-
return function traverse(path) {
|
|
128
|
-
if (!path.parentPath) {
|
|
129
|
-
return true;
|
|
130
|
-
} else {
|
|
131
|
-
return !allPath.includes(path.parentPath) && traverse(path.parentPath);
|
|
132
|
-
}
|
|
133
|
-
}(node);
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
var alreadyVisitedCache = [];
|
|
138
|
-
|
|
139
|
-
function alreadyVisited(path) {
|
|
140
|
-
if (alreadyVisitedCache.includes(path)) {
|
|
141
|
-
return true;
|
|
142
|
-
} else {
|
|
143
|
-
alreadyVisitedCache.push(path);
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function getMacroType(tagName) {
|
|
149
|
-
switch (tagName) {
|
|
150
|
-
case "defineMessage":
|
|
151
|
-
case "arg":
|
|
152
|
-
case "t":
|
|
153
|
-
case "plural":
|
|
154
|
-
case "select":
|
|
155
|
-
case "selectOrdinal":
|
|
156
|
-
return "js";
|
|
157
|
-
|
|
158
|
-
case "Trans":
|
|
159
|
-
case "Plural":
|
|
160
|
-
case "Select":
|
|
161
|
-
case "SelectOrdinal":
|
|
162
|
-
return "jsx";
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
var _default = (0, _babelPluginMacros.createMacro)(macro);
|
|
167
|
-
|
|
168
|
-
exports.default = _default;
|