@lingui/macro 4.0.0-next.0 → 4.0.0-next.2

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/build/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export type ChoiceOptions = {
13
13
  many?: string
14
14
 
15
15
  /** Catch-all option */
16
- other?: string
16
+ other: string
17
17
  /** Exact match form, corresponds to =N rule */
18
18
  [digit: `${number}`]: string
19
19
  }
@@ -193,6 +193,29 @@ export function defineMessage(
193
193
  descriptor: MacroMessageDescriptor
194
194
  ): MessageDescriptor
195
195
 
196
+ /**
197
+ * Define a message for later use
198
+ *
199
+ * @example
200
+ * ```
201
+ * import { defineMessage, msg } from "@lingui/macro";
202
+ * const message = defineMessage`Hello ${name}`;
203
+ *
204
+ * // or using shorter version
205
+ * const message = msg`Hello ${name}`;
206
+ * ```
207
+ */
208
+ export function defineMessage(
209
+ literals: TemplateStringsArray,
210
+ ...placeholders: any[]
211
+ ): MessageDescriptor
212
+
213
+ /**
214
+ * Define a message for later use
215
+ * Alias for {@see defineMessage}
216
+ */
217
+ export const msg: typeof defineMessage
218
+
196
219
  type CommonProps = {
197
220
  id?: string
198
221
  comment?: string
package/build/index.js CHANGED
@@ -10,7 +10,7 @@ var _macroJs = _interopRequireDefault(require("./macroJs"));
10
10
  var _macroJsx = _interopRequireDefault(require("./macroJsx"));
11
11
  var _types = require("@babel/types");
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
- const jsMacroTags = new Set(["defineMessage", "arg", "t", "plural", "select", "selectOrdinal"]);
13
+ const jsMacroTags = new Set(["defineMessage", "msg", "arg", "t", "plural", "select", "selectOrdinal"]);
14
14
  const jsxMacroTags = new Set(["Trans", "Plural", "Select", "SelectOrdinal"]);
15
15
  let config;
16
16
  function getConfig(_config) {
package/build/macroJs.js CHANGED
@@ -15,6 +15,17 @@ const keepNewLineRe = /(?:\r\n|\r|\n)+\s+/g;
15
15
  function normalizeWhitespace(text) {
16
16
  return text.replace(keepSpaceRe, " ").replace(keepNewLineRe, "\n").trim();
17
17
  }
18
+ function buildICUFromTokens(tokens) {
19
+ const messageFormat = new _icu.default();
20
+ const {
21
+ message,
22
+ values
23
+ } = messageFormat.fromTokens(tokens);
24
+ return {
25
+ message: normalizeWhitespace(message),
26
+ values
27
+ };
28
+ }
18
29
  class MacroJs {
19
30
  // Babel Types
20
31
 
@@ -31,14 +42,8 @@ class MacroJs {
31
42
  this.nameMap = opts.nameMap;
32
43
  this.nameMapReversed = Array.from(opts.nameMap.entries()).reduce((map, [key, value]) => map.set(value, key), new Map());
33
44
  }
34
- replacePathWithMessage = (path, {
35
- message,
36
- values
37
- }, linguiInstance) => {
38
- const properties = [this.createIdProperty(message), this.createObjectProperty(_constants.MESSAGE, this.types.stringLiteral(message)), this.createValuesProperty(values)];
39
- const newNode = this.createI18nCall(this.createMessageDescriptor(properties,
40
- // preserve line numbers for extractor
41
- path.node.loc), linguiInstance);
45
+ replacePathWithMessage = (path, tokens, linguiInstance) => {
46
+ const newNode = this.createI18nCall(this.createMessageDescriptorFromTokens(tokens, path.node.loc), linguiInstance);
42
47
  path.replaceWith(newNode);
43
48
  };
44
49
 
@@ -46,9 +51,20 @@ class MacroJs {
46
51
  replacePath = path => {
47
52
  // reset the expression counter
48
53
  this._expressionIndex = (0, _utils.makeCounter)();
49
- if (this.isDefineMessage(path.node)) {
50
- this.replaceDefineMessage(path);
51
- return true;
54
+
55
+ // defineMessage({ message: "Message", context: "My" }) -> {id: <hash + context>, message: "Message"}
56
+ if (this.types.isCallExpression(path.node) && this.isDefineMessage(path.node.callee)) {
57
+ let descriptor = this.processDescriptor(path.node.arguments[0]);
58
+ path.replaceWith(descriptor);
59
+ return false;
60
+ }
61
+
62
+ // defineMessage`Message` -> {id: <hash>, message: "Message"}
63
+ if (this.types.isTaggedTemplateExpression(path.node) && this.isDefineMessage(path.node.tag)) {
64
+ const tokens = this.tokenizeTemplateLiteral(path.node.quasi);
65
+ const descriptor = this.createMessageDescriptorFromTokens(tokens, path.node.loc);
66
+ path.replaceWith(descriptor);
67
+ return false;
52
68
  }
53
69
 
54
70
  // t(i18nInstance)`Message` -> i18nInstance._(messageDescriptor)
@@ -56,71 +72,27 @@ class MacroJs {
56
72
  // Use the first argument as i18n instance instead of the default i18n instance
57
73
  const i18nInstance = path.node.arguments[0];
58
74
  const tokens = this.tokenizeNode(path.parentPath.node);
59
- const messageFormat = new _icu.default();
60
- const {
61
- message: messageRaw,
62
- values
63
- } = messageFormat.fromTokens(tokens);
64
- const message = normalizeWhitespace(messageRaw);
65
- this.replacePathWithMessage(path.parentPath, {
66
- message,
67
- values
68
- }, i18nInstance);
75
+ this.replacePathWithMessage(path.parentPath, tokens, i18nInstance);
69
76
  return false;
70
77
  }
71
78
 
72
79
  // t(i18nInstance)(messageDescriptor) -> i18nInstance._(messageDescriptor)
73
- if (this.types.isCallExpression(path.node) && this.types.isCallExpression(path.parentPath.node) && this.types.isExpression(path.node.arguments[0]) && this.isLinguiIdentifier(path.node.callee, "t")) {
80
+ if (this.types.isCallExpression(path.node) && this.types.isCallExpression(path.parentPath.node) && this.types.isExpression(path.node.arguments[0]) && path.parentPath.node.callee === path.node && this.isLinguiIdentifier(path.node.callee, "t")) {
74
81
  const i18nInstance = path.node.arguments[0];
75
82
  this.replaceTAsFunction(path.parentPath, i18nInstance);
76
83
  return false;
77
84
  }
85
+
86
+ // t({...})
78
87
  if (this.types.isCallExpression(path.node) && this.isLinguiIdentifier(path.node.callee, "t")) {
79
88
  this.replaceTAsFunction(path);
80
89
  return true;
81
90
  }
82
91
  const tokens = this.tokenizeNode(path.node);
83
- const messageFormat = new _icu.default();
84
- const {
85
- message: messageRaw,
86
- values
87
- } = messageFormat.fromTokens(tokens);
88
- const message = normalizeWhitespace(messageRaw);
89
- this.replacePathWithMessage(path, {
90
- message,
91
- values
92
- });
92
+ this.replacePathWithMessage(path, tokens);
93
93
  return true;
94
94
  };
95
95
 
96
- /**
97
- * macro `defineMessage` is called with MessageDescriptor. The only
98
- * thing that happens is that any macros used in `message` property
99
- * are replaced with formatted message.
100
- *
101
- * import { defineMessage, plural } from '@lingui/macro';
102
- * const message = defineMessage({
103
- * id: "msg.id",
104
- * comment: "Description",
105
- * message: plural(value, { one: "book", other: "books" })
106
- * })
107
- *
108
- * ↓ ↓ ↓ ↓ ↓ ↓
109
- *
110
- * const message = {
111
- * id: "msg.id",
112
- * comment: "Description",
113
- * message: "{value, plural, one {book} other {books}}"
114
- * }
115
- *
116
- */
117
- replaceDefineMessage = path => {
118
- // reset the expression counter
119
- this._expressionIndex = (0, _utils.makeCounter)();
120
- let descriptor = this.processDescriptor(path.node.arguments[0]);
121
- path.replaceWith(descriptor);
122
- };
123
-
124
96
  /**
125
97
  * macro `t` is called with MessageDescriptor, after that
126
98
  * we create a new node to append it to i18n._
@@ -143,7 +115,8 @@ class MacroJs {
143
115
  *
144
116
  * {
145
117
  * comment: "Description",
146
- * id: "{value, plural, one {book} other {books}}"
118
+ * id: <hash>
119
+ * message: "{value, plural, one {book} other {books}}"
147
120
  * }
148
121
  *
149
122
  */
@@ -164,12 +137,10 @@ class MacroJs {
164
137
  const tokens = this.types.isTemplateLiteral(messageProperty.value) ? this.tokenizeTemplateLiteral(messageProperty.value) : this.tokenizeNode(messageProperty.value, true);
165
138
  let messageNode = messageProperty.value;
166
139
  if (tokens) {
167
- const messageFormat = new _icu.default();
168
140
  const {
169
- message: messageRaw,
141
+ message,
170
142
  values
171
- } = messageFormat.fromTokens(tokens);
172
- const message = normalizeWhitespace(messageRaw);
143
+ } = buildICUFromTokens(tokens);
173
144
  messageNode = this.types.stringLiteral(message);
174
145
  properties.push(this.createValuesProperty(values));
175
146
  }
@@ -263,6 +234,10 @@ class MacroJs {
263
234
  value = this.tokenizeTemplateLiteral(attrValue);
264
235
  } else if (this.types.isCallExpression(attrValue)) {
265
236
  value = this.tokenizeNode(attrValue);
237
+ } else if (this.types.isStringLiteral(attrValue)) {
238
+ value = attrValue.value;
239
+ } else if (this.types.isExpression(attrValue)) {
240
+ value = this.tokenizeExpression(attrValue);
266
241
  } else {
267
242
  value = attrValue.value;
268
243
  }
@@ -305,6 +280,16 @@ class MacroJs {
305
280
  createI18nCall(messageDescriptor, linguiInstance) {
306
281
  return this.types.callExpression(this.types.memberExpression(linguiInstance ?? this.types.identifier(this.i18nImportName), this.types.identifier("_")), [messageDescriptor]);
307
282
  }
283
+ createMessageDescriptorFromTokens(tokens, oldLoc) {
284
+ const {
285
+ message,
286
+ values
287
+ } = buildICUFromTokens(tokens);
288
+ const properties = [this.createIdProperty(message), !this.stripNonEssentialProps ? this.createObjectProperty(_constants.MESSAGE, this.types.stringLiteral(message)) : null, this.createValuesProperty(values)];
289
+ return this.createMessageDescriptor(properties,
290
+ // preserve line numbers for extractor
291
+ oldLoc);
292
+ }
308
293
  createMessageDescriptor(properties, oldLoc) {
309
294
  const newDescriptor = this.types.objectExpression(properties.filter(Boolean));
310
295
  this.types.addComment(newDescriptor, "leading", _constants.EXTRACT_MARK);
@@ -329,7 +314,7 @@ class MacroJs {
329
314
  });
330
315
  }
331
316
  isDefineMessage(node) {
332
- return this.types.isCallExpression(node) && this.isLinguiIdentifier(node.callee, "defineMessage");
317
+ return this.isLinguiIdentifier(node, "defineMessage") || this.isLinguiIdentifier(node, "msg");
333
318
  }
334
319
  isArg(node) {
335
320
  return this.types.isCallExpression(node) && this.isLinguiIdentifier(node.callee, "arg");
package/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export type ChoiceOptions = {
13
13
  many?: string
14
14
 
15
15
  /** Catch-all option */
16
- other?: string
16
+ other: string
17
17
  /** Exact match form, corresponds to =N rule */
18
18
  [digit: `${number}`]: string
19
19
  }
@@ -193,6 +193,29 @@ export function defineMessage(
193
193
  descriptor: MacroMessageDescriptor
194
194
  ): MessageDescriptor
195
195
 
196
+ /**
197
+ * Define a message for later use
198
+ *
199
+ * @example
200
+ * ```
201
+ * import { defineMessage, msg } from "@lingui/macro";
202
+ * const message = defineMessage`Hello ${name}`;
203
+ *
204
+ * // or using shorter version
205
+ * const message = msg`Hello ${name}`;
206
+ * ```
207
+ */
208
+ export function defineMessage(
209
+ literals: TemplateStringsArray,
210
+ ...placeholders: any[]
211
+ ): MessageDescriptor
212
+
213
+ /**
214
+ * Define a message for later use
215
+ * Alias for {@see defineMessage}
216
+ */
217
+ export const msg: typeof defineMessage
218
+
196
219
  type CommonProps = {
197
220
  id?: string
198
221
  comment?: string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingui/macro",
3
- "version": "4.0.0-next.0",
3
+ "version": "4.0.0-next.2",
4
4
  "description": "Macro for generating messages in ICU MessageFormat syntax",
5
5
  "main": "./build/index.js",
6
6
  "types": "./index.d.ts",
@@ -34,12 +34,12 @@
34
34
  "dependencies": {
35
35
  "@babel/runtime": "^7.20.13",
36
36
  "@babel/types": "^7.20.7",
37
- "@lingui/cli": "^4.0.0-next.0",
38
- "@lingui/conf": "^4.0.0-next.0"
37
+ "@lingui/cli": "^4.0.0-next.2",
38
+ "@lingui/conf": "^4.0.0-next.2"
39
39
  },
40
40
  "peerDependencies": {
41
- "@lingui/core": "4.0.0-next.0",
42
- "@lingui/react": "4.0.0-next.0",
41
+ "@lingui/core": "4.0.0-next.2",
42
+ "@lingui/react": "4.0.0-next.2",
43
43
  "babel-plugin-macros": "2 || 3"
44
44
  },
45
45
  "devDependencies": {
@@ -48,12 +48,7 @@
48
48
  "@babel/traverse": "7.20.12",
49
49
  "@types/babel-plugin-macros": "^2.8.5",
50
50
  "prettier": "2.8.3",
51
- "tsd": "^0.25.0"
51
+ "tsd": "^0.26.1"
52
52
  },
53
- "tsd": {
54
- "compilerOptions": {
55
- "strict": false
56
- }
57
- },
58
- "gitHead": "637f5cf6beda9d4ebce4e15cd9fdaa23e404b660"
53
+ "gitHead": "556ab57e20c2ac9d384a22424c6a90c2ba0dd133"
59
54
  }