@lingui/core 4.4.2 → 4.6.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
@@ -3,13 +3,18 @@
3
3
  const unraw = require('unraw');
4
4
  const compileMessage = require('@lingui/message-utils/compileMessage');
5
5
 
6
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
7
+
8
+ const unraw__default = /*#__PURE__*/_interopDefaultCompat(unraw);
9
+
6
10
  const isString = (s) => typeof s === "string";
7
11
  const isFunction = (f) => typeof f === "function";
8
12
 
9
13
  const cache = /* @__PURE__ */ new Map();
14
+ const defaultLocale = "en";
10
15
  function normalizeLocales(locales) {
11
16
  const out = Array.isArray(locales) ? locales : [locales];
12
- return [...out, "en"];
17
+ return [...out, defaultLocale];
13
18
  }
14
19
  function date(locales, value, format) {
15
20
  const _locales = normalizeLocales(locales);
@@ -55,16 +60,19 @@ function cacheKey(type, locales, options) {
55
60
  const formats = {
56
61
  __proto__: null,
57
62
  date: date,
63
+ defaultLocale: defaultLocale,
58
64
  number: number,
59
65
  plural: plural
60
66
  };
61
67
 
62
68
  const UNICODE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/g;
63
- const getDefaultFormats = (locale, locales, formats = {}) => {
64
- locales = locales || locale;
65
- const style = (format) => isString(format) ? formats[format] || { style: format } : format;
69
+ const getDefaultFormats = (locale, passedLocales, formats = {}) => {
70
+ const locales = passedLocales || locale;
71
+ const style = (format) => {
72
+ return typeof format === "object" ? format : formats[format] || { style: format };
73
+ };
66
74
  const replaceOctothorpe = (value, message) => {
67
- const numberFormat = Object.keys(formats).length ? style("number") : {};
75
+ const numberFormat = Object.keys(formats).length ? style("number") : void 0;
68
76
  const valueStr = number(locales, value, numberFormat);
69
77
  return message.replace("#", valueStr);
70
78
  };
@@ -79,14 +87,16 @@ const getDefaultFormats = (locale, locales, formats = {}) => {
79
87
  const message = plural(locales, true, value, cases);
80
88
  return replaceOctothorpe(value - offset, message);
81
89
  },
82
- select: (value, rules) => rules[value] ?? rules.other,
90
+ select: selectFormatter,
83
91
  number: (value, format) => number(locales, value, style(format)),
84
92
  date: (value, format) => date(locales, value, style(format)),
85
- undefined: (value) => value
93
+ undefined: undefinedFormatter
86
94
  };
87
95
  };
96
+ const selectFormatter = (value, rules) => rules[value] ?? rules.other;
97
+ const undefinedFormatter = (value) => value;
88
98
  function interpolate(translation, locale, locales) {
89
- return (values, formats = {}) => {
99
+ return (values = {}, formats) => {
90
100
  const formatters = getDefaultFormats(locale, locales, formats);
91
101
  const formatMessage = (message) => {
92
102
  if (!Array.isArray(message))
@@ -96,14 +106,15 @@ function interpolate(translation, locale, locales) {
96
106
  return message2 + token;
97
107
  const [name, type, format] = token;
98
108
  let interpolatedFormat = {};
99
- if (format != null && !isString(format)) {
100
- Object.keys(format).forEach((key) => {
101
- interpolatedFormat[key] = formatMessage(format[key]);
109
+ if (format != null && typeof format === "object") {
110
+ Object.entries(format).forEach(([key, value2]) => {
111
+ interpolatedFormat[key] = formatMessage(value2);
102
112
  });
103
113
  } else {
104
114
  interpolatedFormat = format;
105
115
  }
106
- const value = formatters[type](values[name], interpolatedFormat);
116
+ const formatter = formatters[type];
117
+ const value = formatter(values[name], interpolatedFormat);
107
118
  if (value == null)
108
119
  return message2;
109
120
  return message2 + value;
@@ -111,58 +122,76 @@ function interpolate(translation, locale, locales) {
111
122
  };
112
123
  const result = formatMessage(translation);
113
124
  if (isString(result) && UNICODE_REGEX.test(result)) {
114
- return unraw(result.trim());
125
+ return unraw__default(result.trim());
115
126
  }
116
127
  if (isString(result))
117
128
  return result.trim();
118
- return result;
129
+ return result ? String(result) : "";
119
130
  };
120
131
  }
121
132
 
133
+ var __defProp$1 = Object.defineProperty;
134
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
135
+ var __publicField$1 = (obj, key, value) => {
136
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
137
+ return value;
138
+ };
122
139
  class EventEmitter {
123
140
  constructor() {
124
- this._events = {};
141
+ __publicField$1(this, "_events", {});
125
142
  }
126
143
  on(event, listener) {
127
- if (!this._hasEvent(event))
128
- this._events[event] = [];
144
+ var _a;
145
+ (_a = this._events)[event] ?? (_a[event] = []);
129
146
  this._events[event].push(listener);
130
147
  return () => this.removeListener(event, listener);
131
148
  }
132
149
  removeListener(event, listener) {
133
- if (!this._hasEvent(event))
150
+ const maybeListeners = this._getListeners(event);
151
+ if (!maybeListeners)
134
152
  return;
135
- const index = this._events[event].indexOf(listener);
153
+ const index = maybeListeners.indexOf(listener);
136
154
  if (~index)
137
- this._events[event].splice(index, 1);
155
+ maybeListeners.splice(index, 1);
138
156
  }
139
157
  emit(event, ...args) {
140
- if (!this._hasEvent(event))
158
+ const maybeListeners = this._getListeners(event);
159
+ if (!maybeListeners)
141
160
  return;
142
- this._events[event].map((listener) => listener.apply(this, args));
161
+ maybeListeners.map((listener) => listener.apply(this, args));
143
162
  }
144
- _hasEvent(event) {
145
- return Array.isArray(this._events[event]);
163
+ _getListeners(event) {
164
+ const maybeListeners = this._events[event];
165
+ return Array.isArray(maybeListeners) ? maybeListeners : false;
146
166
  }
147
167
  }
148
168
 
169
+ var __defProp = Object.defineProperty;
170
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
171
+ var __publicField = (obj, key, value) => {
172
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
173
+ return value;
174
+ };
149
175
  class I18n extends EventEmitter {
150
176
  constructor(params) {
151
177
  super();
178
+ __publicField(this, "_locale", "");
179
+ __publicField(this, "_locales");
180
+ __publicField(this, "_localeData", {});
181
+ __publicField(this, "_messages", {});
182
+ __publicField(this, "_missing");
152
183
  /**
153
184
  * Alias for {@see I18n._}
154
185
  */
155
- this.t = this._.bind(this);
156
- this._messages = {};
157
- this._localeData = {};
186
+ __publicField(this, "t", this._.bind(this));
158
187
  if (params.missing != null)
159
188
  this._missing = params.missing;
160
189
  if (params.messages != null)
161
190
  this.load(params.messages);
162
191
  if (params.localeData != null)
163
192
  this.loadLocaleData(params.localeData);
164
- if (params.locale != null || params.locales != null) {
165
- this.activate(params.locale, params.locales);
193
+ if (typeof params.locale === "string" || params.locales) {
194
+ this.activate(params.locale ?? defaultLocale, params.locales);
166
195
  }
167
196
  }
168
197
  get locale() {
@@ -181,15 +210,17 @@ class I18n extends EventEmitter {
181
210
  return this._localeData[this._locale] ?? {};
182
211
  }
183
212
  _loadLocaleData(locale, localeData) {
184
- if (this._localeData[locale] == null) {
213
+ const maybeLocaleData = this._localeData[locale];
214
+ if (!maybeLocaleData) {
185
215
  this._localeData[locale] = localeData;
186
216
  } else {
187
- Object.assign(this._localeData[locale], localeData);
217
+ Object.assign(maybeLocaleData, localeData);
188
218
  }
189
219
  }
190
220
  /**
191
221
  * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
192
222
  */
223
+ // @ts-ignore deprecated, so ignore the reported error
193
224
  loadLocaleData(localeOrAllData, localeData) {
194
225
  if (localeData != null) {
195
226
  this._loadLocaleData(localeOrAllData, localeData);
@@ -201,18 +232,19 @@ class I18n extends EventEmitter {
201
232
  this.emit("change");
202
233
  }
203
234
  _load(locale, messages) {
204
- if (this._messages[locale] == null) {
235
+ const maybeMessages = this._messages[locale];
236
+ if (!maybeMessages) {
205
237
  this._messages[locale] = messages;
206
238
  } else {
207
- Object.assign(this._messages[locale], messages);
239
+ Object.assign(maybeMessages, messages);
208
240
  }
209
241
  }
210
242
  load(localeOrMessages, messages) {
211
- if (messages != null) {
243
+ if (typeof localeOrMessages == "string" && typeof messages === "object") {
212
244
  this._load(localeOrMessages, messages);
213
245
  } else {
214
- Object.keys(localeOrMessages).forEach(
215
- (locale) => this._load(locale, localeOrMessages[locale])
246
+ Object.entries(localeOrMessages).forEach(
247
+ ([locale, messages2]) => this._load(locale, messages2)
216
248
  );
217
249
  }
218
250
  this.emit("change");
@@ -236,13 +268,15 @@ class I18n extends EventEmitter {
236
268
  this._locales = locales;
237
269
  this.emit("change");
238
270
  }
239
- _(id, values = {}, { message, formats } = {}) {
271
+ _(id, values, options) {
272
+ let message = options?.message;
240
273
  if (!isString(id)) {
241
274
  values = id.values || values;
242
275
  message = id.message;
243
276
  id = id.id;
244
277
  }
245
- const messageMissing = !this.messages[id];
278
+ const messageForId = this.messages[id];
279
+ const messageMissing = messageForId === void 0;
246
280
  const missing = this._missing;
247
281
  if (missing && messageMissing) {
248
282
  return isFunction(missing) ? missing(this._locale, id) : missing;
@@ -250,7 +284,7 @@ class I18n extends EventEmitter {
250
284
  if (messageMissing) {
251
285
  this.emit("missing", { id, locale: this._locale });
252
286
  }
253
- let translation = this.messages[id] || message || id;
287
+ let translation = messageForId || message || id;
254
288
  if (process.env.NODE_ENV !== "production") {
255
289
  translation = isString(translation) ? compileMessage.compileMessage(translation) : translation;
256
290
  }
@@ -262,7 +296,7 @@ class I18n extends EventEmitter {
262
296
  translation,
263
297
  this._locale,
264
298
  this._locales
265
- )(values, formats);
299
+ )(values, options?.formats);
266
300
  }
267
301
  date(value, format) {
268
302
  return date(this._locales || this._locale, value, format);
@@ -0,0 +1,132 @@
1
+ import { CompiledMessage } from '@lingui/message-utils/compileMessage';
2
+
3
+ declare class EventEmitter<Events extends {
4
+ [name: string]: (...args: any[]) => any;
5
+ }> {
6
+ private readonly _events;
7
+ on(event: keyof Events, listener: Events[typeof event]): () => void;
8
+ removeListener(event: keyof Events, listener: Events[typeof event]): void;
9
+ emit(event: keyof Events, ...args: Parameters<Events[typeof event]>): void;
10
+ private _getListeners;
11
+ }
12
+
13
+ type MessageOptions = {
14
+ message?: string;
15
+ formats?: Formats;
16
+ comment?: string;
17
+ };
18
+
19
+ type Locale = string;
20
+ type Locales = Locale | Locale[];
21
+ type Formats = Record<string, Intl.DateTimeFormatOptions | Intl.NumberFormatOptions>;
22
+ type Values = Record<string, unknown>;
23
+ /**
24
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
25
+ */
26
+ type LocaleData = {
27
+ plurals?: (n: number, ordinal?: boolean) => ReturnType<Intl.PluralRules["select"]>;
28
+ };
29
+ /**
30
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
31
+ */
32
+ type AllLocaleData = Record<Locale, LocaleData>;
33
+ type Messages = Record<string, CompiledMessage>;
34
+ type AllMessages = Record<Locale, Messages>;
35
+ type MessageDescriptor = {
36
+ id: string;
37
+ comment?: string;
38
+ message?: string;
39
+ values?: Record<string, unknown>;
40
+ };
41
+ type MissingMessageEvent = {
42
+ locale: Locale;
43
+ id: string;
44
+ };
45
+ type MissingHandler = string | ((locale: string, id: string) => string);
46
+ type setupI18nProps = {
47
+ locale?: Locale;
48
+ locales?: Locales;
49
+ messages?: AllMessages;
50
+ /**
51
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
52
+ */
53
+ localeData?: AllLocaleData;
54
+ missing?: MissingHandler;
55
+ };
56
+ type Events = {
57
+ change: () => void;
58
+ missing: (event: MissingMessageEvent) => void;
59
+ };
60
+ type LoadAndActivateOptions = {
61
+ /** initial active locale */
62
+ locale: Locale;
63
+ /** list of alternative locales (BCP 47 language tags) which are used for number and date formatting */
64
+ locales?: Locales;
65
+ /** compiled message catalog */
66
+ messages: Messages;
67
+ };
68
+ declare class I18n extends EventEmitter<Events> {
69
+ private _locale;
70
+ private _locales?;
71
+ private _localeData;
72
+ private _messages;
73
+ private _missing?;
74
+ constructor(params: setupI18nProps);
75
+ get locale(): string;
76
+ get locales(): Locales | undefined;
77
+ get messages(): Messages;
78
+ /**
79
+ * @deprecated this has no effect. Please remove this from the code. Deprecated in v4
80
+ */
81
+ get localeData(): LocaleData;
82
+ private _loadLocaleData;
83
+ /**
84
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
85
+ */
86
+ loadLocaleData(allLocaleData: AllLocaleData): void;
87
+ /**
88
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
89
+ */
90
+ loadLocaleData(locale: Locale, localeData: LocaleData): void;
91
+ private _load;
92
+ load(allMessages: AllMessages): void;
93
+ load(locale: Locale, messages: Messages): void;
94
+ /**
95
+ * @param options {@link LoadAndActivateOptions}
96
+ */
97
+ loadAndActivate({ locale, locales, messages }: LoadAndActivateOptions): void;
98
+ activate(locale: Locale, locales?: Locales): void;
99
+ _(descriptor: MessageDescriptor): string;
100
+ _(id: string, values?: Values, options?: MessageOptions): string;
101
+ /**
102
+ * Alias for {@see I18n._}
103
+ */
104
+ t: I18n["_"];
105
+ date(value: string | Date, format?: Intl.DateTimeFormatOptions): string;
106
+ number(value: number, format?: Intl.NumberFormatOptions): string;
107
+ }
108
+ declare function setupI18n(params?: setupI18nProps): I18n;
109
+
110
+ declare const defaultLocale = "en";
111
+ declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions): string;
112
+ declare function number(locales: Locales, value: number, format?: Intl.NumberFormatOptions): string;
113
+ type PluralOptions = {
114
+ [key: string]: Intl.LDMLPluralRule;
115
+ } & {
116
+ offset: number;
117
+ other: string;
118
+ };
119
+ declare function plural(locales: Locales, ordinal: boolean, value: number, { offset, ...rules }: PluralOptions): string;
120
+
121
+ type formats_PluralOptions = PluralOptions;
122
+ declare const formats_date: typeof date;
123
+ declare const formats_defaultLocale: typeof defaultLocale;
124
+ declare const formats_number: typeof number;
125
+ declare const formats_plural: typeof plural;
126
+ declare namespace formats {
127
+ export { type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural };
128
+ }
129
+
130
+ declare const i18n: I18n;
131
+
132
+ export { type AllLocaleData, type AllMessages, I18n, type Locale, type LocaleData, type Locales, type MessageDescriptor, type MessageOptions, type Messages, formats, i18n, setupI18n };
@@ -0,0 +1,132 @@
1
+ import { CompiledMessage } from '@lingui/message-utils/compileMessage';
2
+
3
+ declare class EventEmitter<Events extends {
4
+ [name: string]: (...args: any[]) => any;
5
+ }> {
6
+ private readonly _events;
7
+ on(event: keyof Events, listener: Events[typeof event]): () => void;
8
+ removeListener(event: keyof Events, listener: Events[typeof event]): void;
9
+ emit(event: keyof Events, ...args: Parameters<Events[typeof event]>): void;
10
+ private _getListeners;
11
+ }
12
+
13
+ type MessageOptions = {
14
+ message?: string;
15
+ formats?: Formats;
16
+ comment?: string;
17
+ };
18
+
19
+ type Locale = string;
20
+ type Locales = Locale | Locale[];
21
+ type Formats = Record<string, Intl.DateTimeFormatOptions | Intl.NumberFormatOptions>;
22
+ type Values = Record<string, unknown>;
23
+ /**
24
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
25
+ */
26
+ type LocaleData = {
27
+ plurals?: (n: number, ordinal?: boolean) => ReturnType<Intl.PluralRules["select"]>;
28
+ };
29
+ /**
30
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
31
+ */
32
+ type AllLocaleData = Record<Locale, LocaleData>;
33
+ type Messages = Record<string, CompiledMessage>;
34
+ type AllMessages = Record<Locale, Messages>;
35
+ type MessageDescriptor = {
36
+ id: string;
37
+ comment?: string;
38
+ message?: string;
39
+ values?: Record<string, unknown>;
40
+ };
41
+ type MissingMessageEvent = {
42
+ locale: Locale;
43
+ id: string;
44
+ };
45
+ type MissingHandler = string | ((locale: string, id: string) => string);
46
+ type setupI18nProps = {
47
+ locale?: Locale;
48
+ locales?: Locales;
49
+ messages?: AllMessages;
50
+ /**
51
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
52
+ */
53
+ localeData?: AllLocaleData;
54
+ missing?: MissingHandler;
55
+ };
56
+ type Events = {
57
+ change: () => void;
58
+ missing: (event: MissingMessageEvent) => void;
59
+ };
60
+ type LoadAndActivateOptions = {
61
+ /** initial active locale */
62
+ locale: Locale;
63
+ /** list of alternative locales (BCP 47 language tags) which are used for number and date formatting */
64
+ locales?: Locales;
65
+ /** compiled message catalog */
66
+ messages: Messages;
67
+ };
68
+ declare class I18n extends EventEmitter<Events> {
69
+ private _locale;
70
+ private _locales?;
71
+ private _localeData;
72
+ private _messages;
73
+ private _missing?;
74
+ constructor(params: setupI18nProps);
75
+ get locale(): string;
76
+ get locales(): Locales | undefined;
77
+ get messages(): Messages;
78
+ /**
79
+ * @deprecated this has no effect. Please remove this from the code. Deprecated in v4
80
+ */
81
+ get localeData(): LocaleData;
82
+ private _loadLocaleData;
83
+ /**
84
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
85
+ */
86
+ loadLocaleData(allLocaleData: AllLocaleData): void;
87
+ /**
88
+ * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
89
+ */
90
+ loadLocaleData(locale: Locale, localeData: LocaleData): void;
91
+ private _load;
92
+ load(allMessages: AllMessages): void;
93
+ load(locale: Locale, messages: Messages): void;
94
+ /**
95
+ * @param options {@link LoadAndActivateOptions}
96
+ */
97
+ loadAndActivate({ locale, locales, messages }: LoadAndActivateOptions): void;
98
+ activate(locale: Locale, locales?: Locales): void;
99
+ _(descriptor: MessageDescriptor): string;
100
+ _(id: string, values?: Values, options?: MessageOptions): string;
101
+ /**
102
+ * Alias for {@see I18n._}
103
+ */
104
+ t: I18n["_"];
105
+ date(value: string | Date, format?: Intl.DateTimeFormatOptions): string;
106
+ number(value: number, format?: Intl.NumberFormatOptions): string;
107
+ }
108
+ declare function setupI18n(params?: setupI18nProps): I18n;
109
+
110
+ declare const defaultLocale = "en";
111
+ declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions): string;
112
+ declare function number(locales: Locales, value: number, format?: Intl.NumberFormatOptions): string;
113
+ type PluralOptions = {
114
+ [key: string]: Intl.LDMLPluralRule;
115
+ } & {
116
+ offset: number;
117
+ other: string;
118
+ };
119
+ declare function plural(locales: Locales, ordinal: boolean, value: number, { offset, ...rules }: PluralOptions): string;
120
+
121
+ type formats_PluralOptions = PluralOptions;
122
+ declare const formats_date: typeof date;
123
+ declare const formats_defaultLocale: typeof defaultLocale;
124
+ declare const formats_number: typeof number;
125
+ declare const formats_plural: typeof plural;
126
+ declare namespace formats {
127
+ export { type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural };
128
+ }
129
+
130
+ declare const i18n: I18n;
131
+
132
+ export { type AllLocaleData, type AllMessages, I18n, type Locale, type LocaleData, type Locales, type MessageDescriptor, type MessageOptions, type Messages, formats, i18n, setupI18n };
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ declare class EventEmitter<Events extends {
7
7
  on(event: keyof Events, listener: Events[typeof event]): () => void;
8
8
  removeListener(event: keyof Events, listener: Events[typeof event]): void;
9
9
  emit(event: keyof Events, ...args: Parameters<Events[typeof event]>): void;
10
- private _hasEvent;
10
+ private _getListeners;
11
11
  }
12
12
 
13
13
  type MessageOptions = {
@@ -67,13 +67,13 @@ type LoadAndActivateOptions = {
67
67
  };
68
68
  declare class I18n extends EventEmitter<Events> {
69
69
  private _locale;
70
- private _locales;
70
+ private _locales?;
71
71
  private _localeData;
72
72
  private _messages;
73
- private _missing;
73
+ private _missing?;
74
74
  constructor(params: setupI18nProps);
75
75
  get locale(): string;
76
- get locales(): Locales;
76
+ get locales(): Locales | undefined;
77
77
  get messages(): Messages;
78
78
  /**
79
79
  * @deprecated this has no effect. Please remove this from the code. Deprecated in v4
@@ -107,24 +107,26 @@ declare class I18n extends EventEmitter<Events> {
107
107
  }
108
108
  declare function setupI18n(params?: setupI18nProps): I18n;
109
109
 
110
+ declare const defaultLocale = "en";
110
111
  declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions): string;
111
112
  declare function number(locales: Locales, value: number, format?: Intl.NumberFormatOptions): string;
112
- declare function plural(locales: Locales, ordinal: boolean, value: number, { offset, ...rules }: {
113
- [x: string]: any;
114
- offset?: number;
115
- }): string;
113
+ type PluralOptions = {
114
+ [key: string]: Intl.LDMLPluralRule;
115
+ } & {
116
+ offset: number;
117
+ other: string;
118
+ };
119
+ declare function plural(locales: Locales, ordinal: boolean, value: number, { offset, ...rules }: PluralOptions): string;
116
120
 
121
+ type formats_PluralOptions = PluralOptions;
117
122
  declare const formats_date: typeof date;
123
+ declare const formats_defaultLocale: typeof defaultLocale;
118
124
  declare const formats_number: typeof number;
119
125
  declare const formats_plural: typeof plural;
120
126
  declare namespace formats {
121
- export {
122
- formats_date as date,
123
- formats_number as number,
124
- formats_plural as plural,
125
- };
127
+ export { type formats_PluralOptions as PluralOptions, formats_date as date, formats_defaultLocale as defaultLocale, formats_number as number, formats_plural as plural };
126
128
  }
127
129
 
128
130
  declare const i18n: I18n;
129
131
 
130
- export { AllLocaleData, AllMessages, I18n, Locale, LocaleData, Locales, MessageDescriptor, MessageOptions, Messages, formats, i18n, setupI18n };
132
+ export { type AllLocaleData, type AllMessages, I18n, type Locale, type LocaleData, type Locales, type MessageDescriptor, type MessageOptions, type Messages, formats, i18n, setupI18n };
package/dist/index.mjs CHANGED
@@ -5,9 +5,10 @@ const isString = (s) => typeof s === "string";
5
5
  const isFunction = (f) => typeof f === "function";
6
6
 
7
7
  const cache = /* @__PURE__ */ new Map();
8
+ const defaultLocale = "en";
8
9
  function normalizeLocales(locales) {
9
10
  const out = Array.isArray(locales) ? locales : [locales];
10
- return [...out, "en"];
11
+ return [...out, defaultLocale];
11
12
  }
12
13
  function date(locales, value, format) {
13
14
  const _locales = normalizeLocales(locales);
@@ -53,16 +54,19 @@ function cacheKey(type, locales, options) {
53
54
  const formats = {
54
55
  __proto__: null,
55
56
  date: date,
57
+ defaultLocale: defaultLocale,
56
58
  number: number,
57
59
  plural: plural
58
60
  };
59
61
 
60
62
  const UNICODE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/g;
61
- const getDefaultFormats = (locale, locales, formats = {}) => {
62
- locales = locales || locale;
63
- const style = (format) => isString(format) ? formats[format] || { style: format } : format;
63
+ const getDefaultFormats = (locale, passedLocales, formats = {}) => {
64
+ const locales = passedLocales || locale;
65
+ const style = (format) => {
66
+ return typeof format === "object" ? format : formats[format] || { style: format };
67
+ };
64
68
  const replaceOctothorpe = (value, message) => {
65
- const numberFormat = Object.keys(formats).length ? style("number") : {};
69
+ const numberFormat = Object.keys(formats).length ? style("number") : void 0;
66
70
  const valueStr = number(locales, value, numberFormat);
67
71
  return message.replace("#", valueStr);
68
72
  };
@@ -77,14 +81,16 @@ const getDefaultFormats = (locale, locales, formats = {}) => {
77
81
  const message = plural(locales, true, value, cases);
78
82
  return replaceOctothorpe(value - offset, message);
79
83
  },
80
- select: (value, rules) => rules[value] ?? rules.other,
84
+ select: selectFormatter,
81
85
  number: (value, format) => number(locales, value, style(format)),
82
86
  date: (value, format) => date(locales, value, style(format)),
83
- undefined: (value) => value
87
+ undefined: undefinedFormatter
84
88
  };
85
89
  };
90
+ const selectFormatter = (value, rules) => rules[value] ?? rules.other;
91
+ const undefinedFormatter = (value) => value;
86
92
  function interpolate(translation, locale, locales) {
87
- return (values, formats = {}) => {
93
+ return (values = {}, formats) => {
88
94
  const formatters = getDefaultFormats(locale, locales, formats);
89
95
  const formatMessage = (message) => {
90
96
  if (!Array.isArray(message))
@@ -94,14 +100,15 @@ function interpolate(translation, locale, locales) {
94
100
  return message2 + token;
95
101
  const [name, type, format] = token;
96
102
  let interpolatedFormat = {};
97
- if (format != null && !isString(format)) {
98
- Object.keys(format).forEach((key) => {
99
- interpolatedFormat[key] = formatMessage(format[key]);
103
+ if (format != null && typeof format === "object") {
104
+ Object.entries(format).forEach(([key, value2]) => {
105
+ interpolatedFormat[key] = formatMessage(value2);
100
106
  });
101
107
  } else {
102
108
  interpolatedFormat = format;
103
109
  }
104
- const value = formatters[type](values[name], interpolatedFormat);
110
+ const formatter = formatters[type];
111
+ const value = formatter(values[name], interpolatedFormat);
105
112
  if (value == null)
106
113
  return message2;
107
114
  return message2 + value;
@@ -113,54 +120,72 @@ function interpolate(translation, locale, locales) {
113
120
  }
114
121
  if (isString(result))
115
122
  return result.trim();
116
- return result;
123
+ return result ? String(result) : "";
117
124
  };
118
125
  }
119
126
 
127
+ var __defProp$1 = Object.defineProperty;
128
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
129
+ var __publicField$1 = (obj, key, value) => {
130
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
131
+ return value;
132
+ };
120
133
  class EventEmitter {
121
134
  constructor() {
122
- this._events = {};
135
+ __publicField$1(this, "_events", {});
123
136
  }
124
137
  on(event, listener) {
125
- if (!this._hasEvent(event))
126
- this._events[event] = [];
138
+ var _a;
139
+ (_a = this._events)[event] ?? (_a[event] = []);
127
140
  this._events[event].push(listener);
128
141
  return () => this.removeListener(event, listener);
129
142
  }
130
143
  removeListener(event, listener) {
131
- if (!this._hasEvent(event))
144
+ const maybeListeners = this._getListeners(event);
145
+ if (!maybeListeners)
132
146
  return;
133
- const index = this._events[event].indexOf(listener);
147
+ const index = maybeListeners.indexOf(listener);
134
148
  if (~index)
135
- this._events[event].splice(index, 1);
149
+ maybeListeners.splice(index, 1);
136
150
  }
137
151
  emit(event, ...args) {
138
- if (!this._hasEvent(event))
152
+ const maybeListeners = this._getListeners(event);
153
+ if (!maybeListeners)
139
154
  return;
140
- this._events[event].map((listener) => listener.apply(this, args));
155
+ maybeListeners.map((listener) => listener.apply(this, args));
141
156
  }
142
- _hasEvent(event) {
143
- return Array.isArray(this._events[event]);
157
+ _getListeners(event) {
158
+ const maybeListeners = this._events[event];
159
+ return Array.isArray(maybeListeners) ? maybeListeners : false;
144
160
  }
145
161
  }
146
162
 
163
+ var __defProp = Object.defineProperty;
164
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
165
+ var __publicField = (obj, key, value) => {
166
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
167
+ return value;
168
+ };
147
169
  class I18n extends EventEmitter {
148
170
  constructor(params) {
149
171
  super();
172
+ __publicField(this, "_locale", "");
173
+ __publicField(this, "_locales");
174
+ __publicField(this, "_localeData", {});
175
+ __publicField(this, "_messages", {});
176
+ __publicField(this, "_missing");
150
177
  /**
151
178
  * Alias for {@see I18n._}
152
179
  */
153
- this.t = this._.bind(this);
154
- this._messages = {};
155
- this._localeData = {};
180
+ __publicField(this, "t", this._.bind(this));
156
181
  if (params.missing != null)
157
182
  this._missing = params.missing;
158
183
  if (params.messages != null)
159
184
  this.load(params.messages);
160
185
  if (params.localeData != null)
161
186
  this.loadLocaleData(params.localeData);
162
- if (params.locale != null || params.locales != null) {
163
- this.activate(params.locale, params.locales);
187
+ if (typeof params.locale === "string" || params.locales) {
188
+ this.activate(params.locale ?? defaultLocale, params.locales);
164
189
  }
165
190
  }
166
191
  get locale() {
@@ -179,15 +204,17 @@ class I18n extends EventEmitter {
179
204
  return this._localeData[this._locale] ?? {};
180
205
  }
181
206
  _loadLocaleData(locale, localeData) {
182
- if (this._localeData[locale] == null) {
207
+ const maybeLocaleData = this._localeData[locale];
208
+ if (!maybeLocaleData) {
183
209
  this._localeData[locale] = localeData;
184
210
  } else {
185
- Object.assign(this._localeData[locale], localeData);
211
+ Object.assign(maybeLocaleData, localeData);
186
212
  }
187
213
  }
188
214
  /**
189
215
  * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4
190
216
  */
217
+ // @ts-ignore deprecated, so ignore the reported error
191
218
  loadLocaleData(localeOrAllData, localeData) {
192
219
  if (localeData != null) {
193
220
  this._loadLocaleData(localeOrAllData, localeData);
@@ -199,18 +226,19 @@ class I18n extends EventEmitter {
199
226
  this.emit("change");
200
227
  }
201
228
  _load(locale, messages) {
202
- if (this._messages[locale] == null) {
229
+ const maybeMessages = this._messages[locale];
230
+ if (!maybeMessages) {
203
231
  this._messages[locale] = messages;
204
232
  } else {
205
- Object.assign(this._messages[locale], messages);
233
+ Object.assign(maybeMessages, messages);
206
234
  }
207
235
  }
208
236
  load(localeOrMessages, messages) {
209
- if (messages != null) {
237
+ if (typeof localeOrMessages == "string" && typeof messages === "object") {
210
238
  this._load(localeOrMessages, messages);
211
239
  } else {
212
- Object.keys(localeOrMessages).forEach(
213
- (locale) => this._load(locale, localeOrMessages[locale])
240
+ Object.entries(localeOrMessages).forEach(
241
+ ([locale, messages2]) => this._load(locale, messages2)
214
242
  );
215
243
  }
216
244
  this.emit("change");
@@ -234,13 +262,15 @@ class I18n extends EventEmitter {
234
262
  this._locales = locales;
235
263
  this.emit("change");
236
264
  }
237
- _(id, values = {}, { message, formats } = {}) {
265
+ _(id, values, options) {
266
+ let message = options?.message;
238
267
  if (!isString(id)) {
239
268
  values = id.values || values;
240
269
  message = id.message;
241
270
  id = id.id;
242
271
  }
243
- const messageMissing = !this.messages[id];
272
+ const messageForId = this.messages[id];
273
+ const messageMissing = messageForId === void 0;
244
274
  const missing = this._missing;
245
275
  if (missing && messageMissing) {
246
276
  return isFunction(missing) ? missing(this._locale, id) : missing;
@@ -248,7 +278,7 @@ class I18n extends EventEmitter {
248
278
  if (messageMissing) {
249
279
  this.emit("missing", { id, locale: this._locale });
250
280
  }
251
- let translation = this.messages[id] || message || id;
281
+ let translation = messageForId || message || id;
252
282
  if (process.env.NODE_ENV !== "production") {
253
283
  translation = isString(translation) ? compileMessage(translation) : translation;
254
284
  }
@@ -260,7 +290,7 @@ class I18n extends EventEmitter {
260
290
  translation,
261
291
  this._locale,
262
292
  this._locales
263
- )(values, formats);
293
+ )(values, options?.formats);
264
294
  }
265
295
  date(value, format) {
266
296
  return date(this._locales || this._locale, value, format);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingui/core",
3
- "version": "4.4.2",
3
+ "version": "4.6.0",
4
4
  "sideEffects": false,
5
5
  "description": "I18n tools for javascript",
6
6
  "main": "./dist/index.cjs",
@@ -37,11 +37,11 @@
37
37
  "exports": {
38
38
  ".": {
39
39
  "require": {
40
- "types": "./dist/index.d.ts",
40
+ "types": "./dist/index.d.cts",
41
41
  "default": "./dist/index.cjs"
42
42
  },
43
43
  "import": {
44
- "types": "./dist/index.d.ts",
44
+ "types": "./dist/index.d.mts",
45
45
  "default": "./dist/index.mjs"
46
46
  }
47
47
  },
@@ -54,12 +54,12 @@
54
54
  ],
55
55
  "dependencies": {
56
56
  "@babel/runtime": "^7.20.13",
57
- "@lingui/message-utils": "4.4.2",
58
- "unraw": "^2.0.1"
57
+ "@lingui/message-utils": "4.6.0",
58
+ "unraw": "^3.0.0"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@lingui/jest-mocks": "*",
62
- "unbuild": "^1.1.2"
62
+ "unbuild": "2.0.0"
63
63
  },
64
- "gitHead": "316a004ec82721fcceb8f3c4a5aeb4a48d367927"
64
+ "gitHead": "2afa0efb2d0cd1d47adc76e1eec9f5e57e34ae18"
65
65
  }