@lingui/core 5.1.1 → 5.2.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/dist/index.cjs CHANGED
@@ -14,12 +14,59 @@ function normalizeLocales(locales) {
14
14
  }
15
15
  function date(locales, value, format) {
16
16
  const _locales = normalizeLocales(locales);
17
+ if (!format) {
18
+ format = "default";
19
+ }
20
+ let o;
21
+ if (typeof format === "string") {
22
+ o = {
23
+ day: "numeric",
24
+ month: "short",
25
+ year: "numeric"
26
+ };
27
+ switch (format) {
28
+ case "full":
29
+ o.weekday = "long";
30
+ case "long":
31
+ o.month = "long";
32
+ break;
33
+ case "short":
34
+ o.month = "numeric";
35
+ break;
36
+ }
37
+ } else {
38
+ o = format;
39
+ }
17
40
  const formatter = getMemoized(
18
41
  () => cacheKey("date", _locales, format),
19
- () => new Intl.DateTimeFormat(_locales, format)
42
+ () => new Intl.DateTimeFormat(_locales, o)
20
43
  );
21
44
  return formatter.format(isString(value) ? new Date(value) : value);
22
45
  }
46
+ function time(locales, value, format) {
47
+ let o;
48
+ if (!format) {
49
+ format = "default";
50
+ }
51
+ if (typeof format === "string") {
52
+ o = {
53
+ second: "numeric",
54
+ minute: "numeric",
55
+ hour: "numeric"
56
+ };
57
+ switch (format) {
58
+ case "full":
59
+ case "long":
60
+ o.timeZoneName = "short";
61
+ break;
62
+ case "short":
63
+ delete o.second;
64
+ }
65
+ } else {
66
+ o = format;
67
+ }
68
+ return date(locales, value, o);
69
+ }
23
70
  function number(locales, value, format) {
24
71
  const _locales = normalizeLocales(locales);
25
72
  const formatter = getMemoized(
@@ -58,7 +105,8 @@ const formats = {
58
105
  date: date,
59
106
  defaultLocale: defaultLocale,
60
107
  number: number,
61
- plural: plural
108
+ plural: plural,
109
+ time: time
62
110
  };
63
111
 
64
112
  const UNICODE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/;
@@ -66,7 +114,9 @@ const OCTOTHORPE_PH = "%__lingui_octothorpe__%";
66
114
  const getDefaultFormats = (locale, passedLocales, formats = {}) => {
67
115
  const locales = passedLocales || locale;
68
116
  const style = (format) => {
69
- return typeof format === "object" ? format : formats[format] || { style: format };
117
+ if (typeof format === "object")
118
+ return format;
119
+ return formats[format];
70
120
  };
71
121
  const replaceOctothorpe = (value, message) => {
72
122
  const numberFormat = Object.keys(formats).length ? style("number") : void 0;
@@ -85,8 +135,13 @@ const getDefaultFormats = (locale, passedLocales, formats = {}) => {
85
135
  return replaceOctothorpe(value - offset, message);
86
136
  },
87
137
  select: selectFormatter,
88
- number: (value, format) => number(locales, value, style(format)),
89
- date: (value, format) => date(locales, value, style(format))
138
+ number: (value, format) => number(
139
+ locales,
140
+ value,
141
+ style(format) || { style: format }
142
+ ),
143
+ date: (value, format) => date(locales, value, style(format) || format),
144
+ time: (value, format) => time(locales, value, style(format) || format)
90
145
  };
91
146
  };
92
147
  const selectFormatter = (value, rules) => rules[value] ?? rules.other;
@@ -132,10 +187,10 @@ function interpolate(translation, locale, locales) {
132
187
  };
133
188
  const result = formatMessage(translation);
134
189
  if (isString(result) && UNICODE_REGEX.test(result)) {
135
- return unraw.unraw(result.trim());
190
+ return unraw.unraw(result);
136
191
  }
137
192
  if (isString(result))
138
- return result.trim();
193
+ return result;
139
194
  return result ? String(result) : "";
140
195
  };
141
196
  }
@@ -253,9 +308,8 @@ class I18n extends EventEmitter {
253
308
  /**
254
309
  * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
255
310
  */
256
- // @ts-ignore deprecated, so ignore the reported error
257
311
  loadLocaleData(localeOrAllData, localeData) {
258
- if (localeData != null) {
312
+ if (typeof localeOrAllData === "string") {
259
313
  this._loadLocaleData(localeOrAllData, localeData);
260
314
  } else {
261
315
  Object.keys(localeOrAllData).forEach(
@@ -302,6 +356,11 @@ class I18n extends EventEmitter {
302
356
  this.emit("change");
303
357
  }
304
358
  _(id, values, options) {
359
+ if (!this.locale) {
360
+ throw new Error(
361
+ "Lingui: Attempted to call a translation function without setting a locale.\nMake sure to call `i18n.activate(locale)` before using Lingui functions.\nThis issue may also occur due to a race condition in your initialization logic."
362
+ );
363
+ }
305
364
  let message = options?.message;
306
365
  if (!id) {
307
366
  id = "";
package/dist/index.d.cts CHANGED
@@ -127,7 +127,9 @@ declare class I18n extends EventEmitter<Events> {
127
127
  declare function setupI18n(params?: I18nProps): I18n;
128
128
 
129
129
  declare const defaultLocale = "en";
130
- declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions): string;
130
+ type DateTimeFormatSize = "short" | "default" | "long" | "full";
131
+ declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions | DateTimeFormatSize): string;
132
+ declare function time(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions | DateTimeFormatSize): string;
131
133
  declare function number(locales: Locales, value: number, format?: Intl.NumberFormatOptions): string;
132
134
  type PluralOptions = {
133
135
  [key: string]: Intl.LDMLPluralRule;
@@ -137,13 +139,15 @@ type PluralOptions = {
137
139
  };
138
140
  declare function plural(locales: Locales, ordinal: boolean, value: number, { offset, ...rules }: PluralOptions): string;
139
141
 
142
+ type formats_DateTimeFormatSize = DateTimeFormatSize;
140
143
  type formats_PluralOptions = PluralOptions;
141
144
  declare const formats_date: typeof date;
142
145
  declare const formats_defaultLocale: typeof defaultLocale;
143
146
  declare const formats_number: typeof number;
144
147
  declare const formats_plural: typeof plural;
148
+ declare const formats_time: typeof time;
145
149
  declare namespace formats {
146
- export { type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural };
150
+ export { type formats_DateTimeFormatSize as DateTimeFormatSize, type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural, formats_time as time };
147
151
  }
148
152
 
149
153
  declare const i18n: I18n;
package/dist/index.d.mts CHANGED
@@ -127,7 +127,9 @@ declare class I18n extends EventEmitter<Events> {
127
127
  declare function setupI18n(params?: I18nProps): I18n;
128
128
 
129
129
  declare const defaultLocale = "en";
130
- declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions): string;
130
+ type DateTimeFormatSize = "short" | "default" | "long" | "full";
131
+ declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions | DateTimeFormatSize): string;
132
+ declare function time(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions | DateTimeFormatSize): string;
131
133
  declare function number(locales: Locales, value: number, format?: Intl.NumberFormatOptions): string;
132
134
  type PluralOptions = {
133
135
  [key: string]: Intl.LDMLPluralRule;
@@ -137,13 +139,15 @@ type PluralOptions = {
137
139
  };
138
140
  declare function plural(locales: Locales, ordinal: boolean, value: number, { offset, ...rules }: PluralOptions): string;
139
141
 
142
+ type formats_DateTimeFormatSize = DateTimeFormatSize;
140
143
  type formats_PluralOptions = PluralOptions;
141
144
  declare const formats_date: typeof date;
142
145
  declare const formats_defaultLocale: typeof defaultLocale;
143
146
  declare const formats_number: typeof number;
144
147
  declare const formats_plural: typeof plural;
148
+ declare const formats_time: typeof time;
145
149
  declare namespace formats {
146
- export { type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural };
150
+ export { type formats_DateTimeFormatSize as DateTimeFormatSize, type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural, formats_time as time };
147
151
  }
148
152
 
149
153
  declare const i18n: I18n;
package/dist/index.d.ts CHANGED
@@ -127,7 +127,9 @@ declare class I18n extends EventEmitter<Events> {
127
127
  declare function setupI18n(params?: I18nProps): I18n;
128
128
 
129
129
  declare const defaultLocale = "en";
130
- declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions): string;
130
+ type DateTimeFormatSize = "short" | "default" | "long" | "full";
131
+ declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions | DateTimeFormatSize): string;
132
+ declare function time(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions | DateTimeFormatSize): string;
131
133
  declare function number(locales: Locales, value: number, format?: Intl.NumberFormatOptions): string;
132
134
  type PluralOptions = {
133
135
  [key: string]: Intl.LDMLPluralRule;
@@ -137,13 +139,15 @@ type PluralOptions = {
137
139
  };
138
140
  declare function plural(locales: Locales, ordinal: boolean, value: number, { offset, ...rules }: PluralOptions): string;
139
141
 
142
+ type formats_DateTimeFormatSize = DateTimeFormatSize;
140
143
  type formats_PluralOptions = PluralOptions;
141
144
  declare const formats_date: typeof date;
142
145
  declare const formats_defaultLocale: typeof defaultLocale;
143
146
  declare const formats_number: typeof number;
144
147
  declare const formats_plural: typeof plural;
148
+ declare const formats_time: typeof time;
145
149
  declare namespace formats {
146
- export { type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural };
150
+ export { type formats_DateTimeFormatSize as DateTimeFormatSize, type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural, formats_time as time };
147
151
  }
148
152
 
149
153
  declare const i18n: I18n;
package/dist/index.mjs CHANGED
@@ -12,12 +12,59 @@ function normalizeLocales(locales) {
12
12
  }
13
13
  function date(locales, value, format) {
14
14
  const _locales = normalizeLocales(locales);
15
+ if (!format) {
16
+ format = "default";
17
+ }
18
+ let o;
19
+ if (typeof format === "string") {
20
+ o = {
21
+ day: "numeric",
22
+ month: "short",
23
+ year: "numeric"
24
+ };
25
+ switch (format) {
26
+ case "full":
27
+ o.weekday = "long";
28
+ case "long":
29
+ o.month = "long";
30
+ break;
31
+ case "short":
32
+ o.month = "numeric";
33
+ break;
34
+ }
35
+ } else {
36
+ o = format;
37
+ }
15
38
  const formatter = getMemoized(
16
39
  () => cacheKey("date", _locales, format),
17
- () => new Intl.DateTimeFormat(_locales, format)
40
+ () => new Intl.DateTimeFormat(_locales, o)
18
41
  );
19
42
  return formatter.format(isString(value) ? new Date(value) : value);
20
43
  }
44
+ function time(locales, value, format) {
45
+ let o;
46
+ if (!format) {
47
+ format = "default";
48
+ }
49
+ if (typeof format === "string") {
50
+ o = {
51
+ second: "numeric",
52
+ minute: "numeric",
53
+ hour: "numeric"
54
+ };
55
+ switch (format) {
56
+ case "full":
57
+ case "long":
58
+ o.timeZoneName = "short";
59
+ break;
60
+ case "short":
61
+ delete o.second;
62
+ }
63
+ } else {
64
+ o = format;
65
+ }
66
+ return date(locales, value, o);
67
+ }
21
68
  function number(locales, value, format) {
22
69
  const _locales = normalizeLocales(locales);
23
70
  const formatter = getMemoized(
@@ -56,7 +103,8 @@ const formats = {
56
103
  date: date,
57
104
  defaultLocale: defaultLocale,
58
105
  number: number,
59
- plural: plural
106
+ plural: plural,
107
+ time: time
60
108
  };
61
109
 
62
110
  const UNICODE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/;
@@ -64,7 +112,9 @@ const OCTOTHORPE_PH = "%__lingui_octothorpe__%";
64
112
  const getDefaultFormats = (locale, passedLocales, formats = {}) => {
65
113
  const locales = passedLocales || locale;
66
114
  const style = (format) => {
67
- return typeof format === "object" ? format : formats[format] || { style: format };
115
+ if (typeof format === "object")
116
+ return format;
117
+ return formats[format];
68
118
  };
69
119
  const replaceOctothorpe = (value, message) => {
70
120
  const numberFormat = Object.keys(formats).length ? style("number") : void 0;
@@ -83,8 +133,13 @@ const getDefaultFormats = (locale, passedLocales, formats = {}) => {
83
133
  return replaceOctothorpe(value - offset, message);
84
134
  },
85
135
  select: selectFormatter,
86
- number: (value, format) => number(locales, value, style(format)),
87
- date: (value, format) => date(locales, value, style(format))
136
+ number: (value, format) => number(
137
+ locales,
138
+ value,
139
+ style(format) || { style: format }
140
+ ),
141
+ date: (value, format) => date(locales, value, style(format) || format),
142
+ time: (value, format) => time(locales, value, style(format) || format)
88
143
  };
89
144
  };
90
145
  const selectFormatter = (value, rules) => rules[value] ?? rules.other;
@@ -130,10 +185,10 @@ function interpolate(translation, locale, locales) {
130
185
  };
131
186
  const result = formatMessage(translation);
132
187
  if (isString(result) && UNICODE_REGEX.test(result)) {
133
- return unraw(result.trim());
188
+ return unraw(result);
134
189
  }
135
190
  if (isString(result))
136
- return result.trim();
191
+ return result;
137
192
  return result ? String(result) : "";
138
193
  };
139
194
  }
@@ -251,9 +306,8 @@ class I18n extends EventEmitter {
251
306
  /**
252
307
  * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
253
308
  */
254
- // @ts-ignore deprecated, so ignore the reported error
255
309
  loadLocaleData(localeOrAllData, localeData) {
256
- if (localeData != null) {
310
+ if (typeof localeOrAllData === "string") {
257
311
  this._loadLocaleData(localeOrAllData, localeData);
258
312
  } else {
259
313
  Object.keys(localeOrAllData).forEach(
@@ -300,6 +354,11 @@ class I18n extends EventEmitter {
300
354
  this.emit("change");
301
355
  }
302
356
  _(id, values, options) {
357
+ if (!this.locale) {
358
+ throw new Error(
359
+ "Lingui: Attempted to call a translation function without setting a locale.\nMake sure to call `i18n.activate(locale)` before using Lingui functions.\nThis issue may also occur due to a race condition in your initialization logic."
360
+ );
361
+ }
303
362
  let message = options?.message;
304
363
  if (!id) {
305
364
  id = "";
package/macro/index.d.ts CHANGED
@@ -38,7 +38,7 @@ type MacroMessageDescriptor = (
38
38
  * const message = t({
39
39
  * id: "msg.hello",
40
40
  * comment: "Greetings at the homepage",
41
- * message: `Hello ${name}`,
41
+ * message: `Hello ${{name}}`,
42
42
  * });
43
43
  * ```
44
44
  *
@@ -55,18 +55,24 @@ type MacroMessageDescriptor = (
55
55
  */
56
56
  export function t(descriptor: MacroMessageDescriptor): string
57
57
 
58
+ export type LabeledExpression<T> = Record<string, T>
59
+ export type MessagePlaceholder =
60
+ | string
61
+ | number
62
+ | LabeledExpression<string | number>
63
+
58
64
  /**
59
65
  * Translates a template string using the global I18n instance
60
66
  *
61
67
  * @example
62
68
  * ```
63
69
  * import { t } from "@lingui/core/macro";
64
- * const message = t`Hello ${name}`;
70
+ * const message = t`Hello ${{name}}`;
65
71
  * ```
66
72
  */
67
73
  export function t(
68
74
  literals: TemplateStringsArray,
69
- ...placeholders: any[]
75
+ ...placeholders: MessagePlaceholder[]
70
76
  ): string
71
77
 
72
78
  /**
@@ -78,9 +84,9 @@ export function t(
78
84
  * import { I18n } from "@lingui/core";
79
85
  * const i18n = new I18n({
80
86
  * locale: "nl",
81
- * messages: { "Hello {name}": "Hallo {name}" },
87
+ * messages: { "Hello {{name}}": "Hallo {{name}}" },
82
88
  * });
83
- * const message = t(i18n)`Hello ${name}`;
89
+ * const message = t(i18n)`Hello ${{name}}`;
84
90
  * ```
85
91
  *
86
92
  * @example
@@ -89,13 +95,13 @@ export function t(
89
95
  * import { I18n } from "@lingui/core";
90
96
  * const i18n = new I18n({
91
97
  * locale: "nl",
92
- * messages: { "Hello {name}": "Hallo {name}" },
98
+ * messages: { "Hello {{name}}": "Hallo {{name}}" },
93
99
  * });
94
- * const message = t(i18n)({ message: `Hello ${name}` });
100
+ * const message = t(i18n)({ message: `Hello ${{name}}` });
95
101
  * ```
96
102
  *
97
103
  * @deprecated in v5, would be removed in v6.
98
- * Please use `` i18n._(msg`Hello ${name}`) `` instead
104
+ * Please use `` i18n._(msg`Hello ${{name}}`) `` instead
99
105
  *
100
106
  */
101
107
  export function t(i18n: I18n): {
@@ -109,7 +115,7 @@ export function t(i18n: I18n): {
109
115
  * @example
110
116
  * ```
111
117
  * import { plural } from "@lingui/core/macro";
112
- * const message = plural(count, {
118
+ * const message = plural({count}, {
113
119
  * one: "# Book",
114
120
  * other: "# Books",
115
121
  * });
@@ -118,7 +124,10 @@ export function t(i18n: I18n): {
118
124
  * @param value Determines the plural form
119
125
  * @param options Object with available plural forms
120
126
  */
121
- export function plural(value: number | string, options: ChoiceOptions): string
127
+ export function plural(
128
+ value: number | string | LabeledExpression<number | string>,
129
+ options: ChoiceOptions
130
+ ): string
122
131
 
123
132
  /**
124
133
  * Pluralize a message using ordinal forms
@@ -129,7 +138,7 @@ export function plural(value: number | string, options: ChoiceOptions): string
129
138
  * @example
130
139
  * ```
131
140
  * import { selectOrdinal } from "@lingui/core/macro";
132
- * const message = selectOrdinal(count, {
141
+ * const message = selectOrdinal({count}, {
133
142
  * one: "#st",
134
143
  * two: "#nd",
135
144
  * few: "#rd",
@@ -141,7 +150,7 @@ export function plural(value: number | string, options: ChoiceOptions): string
141
150
  * @param options Object with available plural forms
142
151
  */
143
152
  export function selectOrdinal(
144
- value: number | string,
153
+ value: number | string | LabeledExpression<number | string>,
145
154
  options: ChoiceOptions
146
155
  ): string
147
156
 
@@ -161,7 +170,7 @@ type SelectOptions = {
161
170
  * @example
162
171
  * ```
163
172
  * import { select } from "@lingui/core/macro";
164
- * const message = select(gender, {
173
+ * const message = select({gender}, {
165
174
  * male: "he",
166
175
  * female: "she",
167
176
  * other: "they",
@@ -171,7 +180,10 @@ type SelectOptions = {
171
180
  * @param value The key of choices to use
172
181
  * @param choices
173
182
  */
174
- export function select(value: string, choices: SelectOptions): string
183
+ export function select(
184
+ value: string | LabeledExpression<string>,
185
+ choices: SelectOptions
186
+ ): string
175
187
 
176
188
  /**
177
189
  * Define a message for later use
@@ -184,7 +196,7 @@ export function select(value: string, choices: SelectOptions): string
184
196
  * import { defineMessage } from "@lingui/core/macro";
185
197
  * const message = defineMessage({
186
198
  * comment: "Greetings on the welcome page",
187
- * message: `Welcome, ${name}!`,
199
+ * message: `Welcome, ${{name}}!`,
188
200
  * });
189
201
  * ```
190
202
  *
@@ -200,15 +212,15 @@ export function defineMessage(
200
212
  * @example
201
213
  * ```
202
214
  * import { defineMessage, msg } from "@lingui/core/macro";
203
- * const message = defineMessage`Hello ${name}`;
215
+ * const message = defineMessage`Hello ${{name}}`;
204
216
  *
205
217
  * // or using shorter version
206
- * const message = msg`Hello ${name}`;
218
+ * const message = msg`Hello ${{name}}`;
207
219
  * ```
208
220
  */
209
221
  export function defineMessage(
210
222
  literals: TemplateStringsArray,
211
- ...placeholders: any[]
223
+ ...placeholders: MessagePlaceholder[]
212
224
  ): MessageDescriptor
213
225
 
214
226
  /**
@@ -216,3 +228,8 @@ export function defineMessage(
216
228
  * Alias for {@link defineMessage}
217
229
  */
218
230
  export const msg: typeof defineMessage
231
+
232
+ /**
233
+ * Helps to define a name for a variable in the message
234
+ */
235
+ export function ph(def: LabeledExpression<string | number>): string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingui/core",
3
- "version": "5.1.1",
3
+ "version": "5.2.0",
4
4
  "sideEffects": false,
5
5
  "description": "I18n tools for javascript",
6
6
  "main": "./dist/index.cjs",
@@ -60,7 +60,7 @@
60
60
  ],
61
61
  "dependencies": {
62
62
  "@babel/runtime": "^7.20.13",
63
- "@lingui/message-utils": "5.1.1",
63
+ "@lingui/message-utils": "5.2.0",
64
64
  "unraw": "^3.0.0"
65
65
  },
66
66
  "devDependencies": {
@@ -69,7 +69,7 @@
69
69
  "unbuild": "2.0.0"
70
70
  },
71
71
  "peerDependencies": {
72
- "@lingui/babel-plugin-lingui-macro": "5.1.0",
72
+ "@lingui/babel-plugin-lingui-macro": "5.2.0",
73
73
  "babel-plugin-macros": "2 || 3"
74
74
  },
75
75
  "peerDependenciesMeta": {
@@ -80,5 +80,5 @@
80
80
  "optional": true
81
81
  }
82
82
  },
83
- "gitHead": "de0517677882f1900a052018e396b94f406963d6"
83
+ "gitHead": "9c50b4877ca8b134d0d96c09a8055221ca70b095"
84
84
  }