use-intl 2.7.5 → 2.7.7-alpha.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.
Files changed (121) hide show
  1. package/dist/{AbstractIntlMessages.d.ts → core/AbstractIntlMessages.d.ts} +0 -0
  2. package/dist/{DateTimeFormatOptions.d.ts → core/DateTimeFormatOptions.d.ts} +0 -0
  3. package/dist/{Formats.d.ts → core/Formats.d.ts} +0 -0
  4. package/dist/{IntlError.d.ts → core/IntlError.d.ts} +0 -0
  5. package/dist/{IntlMessages.d.ts → core/IntlMessages.d.ts} +0 -0
  6. package/dist/{NumberFormatOptions.d.ts → core/NumberFormatOptions.d.ts} +0 -0
  7. package/dist/{TranslationValues.d.ts → core/TranslationValues.d.ts} +2 -2
  8. package/dist/core/config.d.ts +6 -0
  9. package/dist/{convertFormatsToIntlMessageFormat.d.ts → core/convertFormatsToIntlMessageFormat.d.ts} +0 -0
  10. package/dist/core/createBaseTranslator.d.ts +34 -0
  11. package/dist/{useIntl.d.ts → core/createIntl.d.ts} +11 -1
  12. package/dist/core/createTranslator.d.ts +47 -0
  13. package/dist/core/createTranslatorImpl.d.ts +21 -0
  14. package/dist/core/index.d.ts +8 -0
  15. package/dist/core/resolveNamespace.d.ts +5 -0
  16. package/dist/core/use-intl.esm.js +32 -0
  17. package/dist/core/use-intl.esm.js.map +1 -0
  18. package/dist/{use-intl.esm8.js → core/use-intl.esm2.js} +2 -2
  19. package/dist/core/use-intl.esm2.js.map +1 -0
  20. package/dist/{use-intl.esm4.js → core/use-intl.esm3.js} +12 -12
  21. package/dist/core/use-intl.esm3.js.map +1 -0
  22. package/dist/core/use-intl.esm4.js +61 -0
  23. package/dist/core/use-intl.esm4.js.map +1 -0
  24. package/dist/core/use-intl.esm5.js +13 -0
  25. package/dist/core/use-intl.esm5.js.map +1 -0
  26. package/dist/{use-intl.esm10.js → core/use-intl.esm6.js} +2 -2
  27. package/dist/core/use-intl.esm6.js.map +1 -0
  28. package/dist/core/use-intl.esm7.js +213 -0
  29. package/dist/core/use-intl.esm7.js.map +1 -0
  30. package/dist/core/use-intl.esm8.js +10 -0
  31. package/dist/core/use-intl.esm8.js.map +1 -0
  32. package/dist/{use-intl.esm13.js → core/use-intl.esm9.js} +2 -2
  33. package/dist/core/use-intl.esm9.js.map +1 -0
  34. package/dist/{utils → core/utils}/MessageKeys.d.ts +0 -0
  35. package/dist/{utils → core/utils}/NamespaceKeys.d.ts +0 -0
  36. package/dist/{utils → core/utils}/NestedKeyOf.d.ts +0 -0
  37. package/dist/{utils → core/utils}/NestedValueOf.d.ts +0 -0
  38. package/dist/{validateMessages.d.ts → core/validateMessages.d.ts} +0 -0
  39. package/dist/index.d.ts +2 -12
  40. package/dist/{IntlContext.d.ts → react/IntlContext.d.ts} +4 -4
  41. package/dist/{IntlProvider.d.ts → react/IntlProvider.d.ts} +4 -4
  42. package/dist/react/index.d.ts +6 -0
  43. package/dist/react/use-intl.esm.js +25 -0
  44. package/dist/react/use-intl.esm.js.map +1 -0
  45. package/dist/{use-intl.esm3.js → react/use-intl.esm2.js} +4 -4
  46. package/dist/react/use-intl.esm2.js.map +1 -0
  47. package/dist/{use-intl.esm7.js → react/use-intl.esm3.js} +2 -2
  48. package/dist/react/use-intl.esm3.js.map +1 -0
  49. package/dist/{use-intl.esm6.js → react/use-intl.esm4.js} +2 -2
  50. package/dist/react/use-intl.esm4.js.map +1 -0
  51. package/dist/react/use-intl.esm5.js +36 -0
  52. package/dist/react/use-intl.esm5.js.map +1 -0
  53. package/dist/{use-intl.esm5.js → react/use-intl.esm6.js} +2 -2
  54. package/dist/react/use-intl.esm6.js.map +1 -0
  55. package/dist/{use-intl.esm11.js → react/use-intl.esm7.js} +1 -1
  56. package/dist/react/use-intl.esm7.js.map +1 -0
  57. package/dist/react/use-intl.esm8.js +44 -0
  58. package/dist/react/use-intl.esm8.js.map +1 -0
  59. package/dist/{use-intl.esm9.js → react/use-intl.esm9.js} +0 -0
  60. package/dist/react/use-intl.esm9.js.map +1 -0
  61. package/dist/react/useIntl.d.ts +5 -0
  62. package/dist/{useIntlContext.d.ts → react/useIntlContext.d.ts} +0 -0
  63. package/dist/{useLocale.d.ts → react/useLocale.d.ts} +0 -0
  64. package/dist/{useNow.d.ts → react/useNow.d.ts} +0 -0
  65. package/dist/{useTimeZone.d.ts → react/useTimeZone.d.ts} +0 -0
  66. package/dist/{useTranslations.d.ts → react/useTranslations.d.ts} +6 -6
  67. package/dist/react/useTranslationsImpl.d.ts +8 -0
  68. package/dist/use-intl.cjs.development.js +363 -218
  69. package/dist/use-intl.cjs.development.js.map +1 -1
  70. package/dist/use-intl.cjs.production.min.js +1 -1
  71. package/dist/use-intl.cjs.production.min.js.map +1 -1
  72. package/dist/use-intl.esm.js +9 -7
  73. package/dist/use-intl.esm.js.map +1 -1
  74. package/package.json +3 -2
  75. package/src/{AbstractIntlMessages.tsx → core/AbstractIntlMessages.tsx} +0 -0
  76. package/src/{DateTimeFormatOptions.tsx → core/DateTimeFormatOptions.tsx} +0 -0
  77. package/src/{Formats.tsx → core/Formats.tsx} +0 -0
  78. package/src/{IntlError.tsx → core/IntlError.tsx} +0 -0
  79. package/src/{IntlMessages.tsx → core/IntlMessages.tsx} +0 -0
  80. package/src/{NumberFormatOptions.tsx → core/NumberFormatOptions.tsx} +0 -0
  81. package/src/{TranslationValues.tsx → core/TranslationValues.tsx} +8 -2
  82. package/src/core/config.tsx +15 -0
  83. package/src/{convertFormatsToIntlMessageFormat.tsx → core/convertFormatsToIntlMessageFormat.tsx} +0 -0
  84. package/src/core/createBaseTranslator.tsx +323 -0
  85. package/src/{useIntl.tsx → core/createIntl.tsx} +17 -4
  86. package/src/core/createTranslator.tsx +110 -0
  87. package/src/core/createTranslatorImpl.tsx +95 -0
  88. package/src/core/index.tsx +11 -0
  89. package/src/core/resolveNamespace.tsx +12 -0
  90. package/src/{utils → core/utils}/MessageKeys.tsx +0 -0
  91. package/src/{utils → core/utils}/NamespaceKeys.tsx +0 -0
  92. package/src/{utils → core/utils}/NestedKeyOf.tsx +0 -0
  93. package/src/{utils → core/utils}/NestedValueOf.tsx +0 -0
  94. package/src/{validateMessages.tsx → core/validateMessages.tsx} +0 -0
  95. package/src/index.tsx +2 -15
  96. package/src/{IntlContext.tsx → react/IntlContext.tsx} +4 -4
  97. package/src/{IntlProvider.tsx → react/IntlProvider.tsx} +6 -19
  98. package/src/react/index.tsx +6 -0
  99. package/src/react/useIntl.tsx +19 -0
  100. package/src/{useIntlContext.tsx → react/useIntlContext.tsx} +0 -0
  101. package/src/{useLocale.tsx → react/useLocale.tsx} +0 -0
  102. package/src/{useNow.tsx → react/useNow.tsx} +0 -0
  103. package/src/{useTimeZone.tsx → react/useTimeZone.tsx} +0 -0
  104. package/src/{useTranslations.tsx → react/useTranslations.tsx} +9 -7
  105. package/src/react/useTranslationsImpl.tsx +64 -0
  106. package/dist/use-intl.esm10.js.map +0 -1
  107. package/dist/use-intl.esm11.js.map +0 -1
  108. package/dist/use-intl.esm12.js +0 -213
  109. package/dist/use-intl.esm12.js.map +0 -1
  110. package/dist/use-intl.esm13.js.map +0 -1
  111. package/dist/use-intl.esm2.js +0 -48
  112. package/dist/use-intl.esm2.js.map +0 -1
  113. package/dist/use-intl.esm3.js.map +0 -1
  114. package/dist/use-intl.esm4.js.map +0 -1
  115. package/dist/use-intl.esm5.js.map +0 -1
  116. package/dist/use-intl.esm6.js.map +0 -1
  117. package/dist/use-intl.esm7.js.map +0 -1
  118. package/dist/use-intl.esm8.js.map +0 -1
  119. package/dist/use-intl.esm9.js.map +0 -1
  120. package/dist/useTranslationsImpl.d.ts +0 -12
  121. package/src/useTranslationsImpl.tsx +0 -328
@@ -2,11 +2,12 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var IntlMessageFormat = require('intl-messageformat');
5
6
  var React = require('react');
6
- var intlMessageformat = require('intl-messageformat');
7
7
 
8
8
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
9
 
10
+ var IntlMessageFormat__default = /*#__PURE__*/_interopDefaultLegacy(IntlMessageFormat);
10
11
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
11
12
 
12
13
  function _extends() {
@@ -133,8 +134,6 @@ function _objectWithoutPropertiesLoose(source, excluded) {
133
134
  return target;
134
135
  }
135
136
 
136
- var IntlContext = /*#__PURE__*/React.createContext(undefined);
137
-
138
137
  exports.IntlErrorCode = void 0;
139
138
 
140
139
  (function (IntlErrorCode) {
@@ -173,36 +172,6 @@ var IntlError = /*#__PURE__*/function (_Error) {
173
172
  return IntlError;
174
173
  }( /*#__PURE__*/_wrapNativeSuper(Error));
175
174
 
176
- function validateMessagesSegment(messages, invalidKeyLabels, parentPath) {
177
- Object.entries(messages).forEach(function (_ref) {
178
- var key = _ref[0],
179
- messageOrMessages = _ref[1];
180
-
181
- if (key.includes('.')) {
182
- var keyLabel = key;
183
- if (parentPath) keyLabel += " (at " + parentPath + ")";
184
- invalidKeyLabels.push(keyLabel);
185
- }
186
-
187
- if (messageOrMessages != null && typeof messageOrMessages === 'object') {
188
- validateMessagesSegment(messageOrMessages, invalidKeyLabels, [parentPath, key].filter(function (part) {
189
- return part != null;
190
- }).join('.'));
191
- }
192
- });
193
- }
194
-
195
- function validateMessages(messages, onError) {
196
- var invalidKeyLabels = [];
197
- validateMessagesSegment(messages, invalidKeyLabels);
198
-
199
- if (invalidKeyLabels.length > 0) {
200
- onError(new IntlError(exports.IntlErrorCode.INVALID_KEY, "Namespace keys can not contain the character \".\" as this is used to express nesting. Please remove it or replace it with another character.\n\nInvalid " + (invalidKeyLabels.length === 1 ? 'key' : 'keys') + ": " + invalidKeyLabels.join(', ')));
201
- }
202
- }
203
-
204
- var _excluded = ["children", "onError", "getMessageFallback", "messages"];
205
-
206
175
  function defaultGetMessageFallback(_ref) {
207
176
  var key = _ref.key,
208
177
  namespace = _ref.namespace;
@@ -210,48 +179,10 @@ function defaultGetMessageFallback(_ref) {
210
179
  return part != null;
211
180
  }).join('.');
212
181
  }
213
-
214
182
  function defaultOnError(error) {
215
183
  console.error(error);
216
184
  }
217
185
 
218
- function IntlProvider(_ref2) {
219
- var children = _ref2.children,
220
- _ref2$onError = _ref2.onError,
221
- onError = _ref2$onError === void 0 ? defaultOnError : _ref2$onError,
222
- _ref2$getMessageFallb = _ref2.getMessageFallback,
223
- getMessageFallback = _ref2$getMessageFallb === void 0 ? defaultGetMessageFallback : _ref2$getMessageFallb,
224
- messages = _ref2.messages,
225
- contextValues = _objectWithoutPropertiesLoose(_ref2, _excluded);
226
-
227
- {
228
- // eslint-disable-next-line react-hooks/rules-of-hooks
229
- React.useEffect(function () {
230
- if (messages) {
231
- validateMessages(messages, onError);
232
- }
233
- }, [messages, onError]);
234
- }
235
-
236
- return React__default["default"].createElement(IntlContext.Provider, {
237
- value: _extends({}, contextValues, {
238
- messages: messages,
239
- onError: onError,
240
- getMessageFallback: getMessageFallback
241
- })
242
- }, children);
243
- }
244
-
245
- function useIntlContext() {
246
- var context = React.useContext(IntlContext);
247
-
248
- if (!context) {
249
- throw new Error('No intl context found. Have you configured the provider?' );
250
- }
251
-
252
- return context;
253
- }
254
-
255
186
  function setTimeZoneInFormats(formats, timeZone) {
256
187
  if (!formats) return formats; // The only way to set a time zone with `intl-messageformat` is to merge it into the formats
257
188
  // https://github.com/formatjs/formatjs/blob/8256c5271505cf2606e48e3c97ecdd16ede4f1b5/packages/intl/src/message.ts#L15
@@ -282,17 +213,17 @@ function convertFormatsToIntlMessageFormat(formats, timeZone) {
282
213
  });
283
214
  }
284
215
 
285
- function resolvePath(messages, idPath, namespace) {
216
+ function resolvePath(messages, key, namespace) {
286
217
  if (!messages) {
287
218
  throw new Error("No messages available at `" + namespace + "`." );
288
219
  }
289
220
 
290
221
  var message = messages;
291
- idPath.split('.').forEach(function (part) {
222
+ key.split('.').forEach(function (part) {
292
223
  var next = message[part];
293
224
 
294
225
  if (part == null || next == null) {
295
- throw new Error("Could not resolve `" + idPath + "` in " + (namespace ? "`" + namespace + "`" : 'messages') + "." );
226
+ throw new Error("Could not resolve `" + key + "` in " + (namespace ? "`" + namespace + "`" : 'messages') + "." );
296
227
  }
297
228
 
298
229
  message = next;
@@ -310,8 +241,8 @@ function prepareTranslationValues(values) {
310
241
  var transformed;
311
242
 
312
243
  if (typeof value === 'function') {
313
- transformed = function transformed(children) {
314
- var result = value(children);
244
+ transformed = function transformed(chunks) {
245
+ var result = value(chunks);
315
246
  return React.isValidElement(result) ? React.cloneElement(result, {
316
247
  key: key + index++
317
248
  }) : result;
@@ -325,167 +256,229 @@ function prepareTranslationValues(values) {
325
256
  return transformedValues;
326
257
  }
327
258
 
328
- function useTranslationsImpl(allMessages, namespace, namespacePrefix) {
329
- var _useIntlContext = useIntlContext(),
330
- defaultTranslationValues = _useIntlContext.defaultTranslationValues,
331
- globalFormats = _useIntlContext.formats,
332
- getMessageFallback = _useIntlContext.getMessageFallback,
333
- locale = _useIntlContext.locale,
334
- onError = _useIntlContext.onError,
335
- timeZone = _useIntlContext.timeZone; // The `namespacePrefix` is part of the type system.
336
- // See the comment in the hook invocation.
259
+ function getMessagesOrError(_ref) {
260
+ var messages = _ref.messages,
261
+ namespace = _ref.namespace,
262
+ _ref$onError = _ref.onError,
263
+ onError = _ref$onError === void 0 ? defaultOnError : _ref$onError;
337
264
 
265
+ try {
266
+ if (!messages) {
267
+ throw new Error("development" !== "production" ? "No messages were configured on the provider." : undefined);
268
+ }
338
269
 
339
- allMessages = allMessages[namespacePrefix];
340
- namespace = namespace === namespacePrefix ? undefined : namespace.slice((namespacePrefix + '.').length);
341
- var cachedFormatsByLocaleRef = React.useRef({});
342
- var messagesOrError = React.useMemo(function () {
343
- try {
344
- if (!allMessages) {
345
- throw new Error("development" !== "production" ? "No messages were configured on the provider." : undefined);
346
- }
270
+ var retrievedMessages = namespace ? resolvePath(messages, namespace) : messages;
347
271
 
348
- var retrievedMessages = namespace ? resolvePath(allMessages, namespace) : allMessages;
272
+ if (!retrievedMessages) {
273
+ throw new Error("development" !== "production" ? "No messages for namespace `" + namespace + "` found." : undefined);
274
+ }
349
275
 
350
- if (!retrievedMessages) {
351
- throw new Error("development" !== "production" ? "No messages for namespace `" + namespace + "` found." : undefined);
352
- }
276
+ return retrievedMessages;
277
+ } catch (error) {
278
+ var intlError = new IntlError(exports.IntlErrorCode.MISSING_MESSAGE, error.message);
279
+ onError(intlError);
280
+ return intlError;
281
+ }
282
+ }
283
+ function createBaseTranslator(_ref2) {
284
+ var cachedFormatsByLocale = _ref2.cachedFormatsByLocale,
285
+ defaultTranslationValues = _ref2.defaultTranslationValues,
286
+ globalFormats = _ref2.formats,
287
+ _ref2$getMessageFallb = _ref2.getMessageFallback,
288
+ getMessageFallback = _ref2$getMessageFallb === void 0 ? defaultGetMessageFallback : _ref2$getMessageFallb,
289
+ locale = _ref2.locale,
290
+ messagesOrError = _ref2.messagesOrError,
291
+ namespace = _ref2.namespace,
292
+ onError = _ref2.onError,
293
+ timeZone = _ref2.timeZone;
294
+
295
+ function getFallbackFromErrorAndNotify(key, code, message) {
296
+ var error = new IntlError(code, message);
297
+ onError(error);
298
+ return getMessageFallback({
299
+ error: error,
300
+ key: key,
301
+ namespace: namespace
302
+ });
303
+ }
353
304
 
354
- return retrievedMessages;
355
- } catch (error) {
356
- var intlError = new IntlError(exports.IntlErrorCode.MISSING_MESSAGE, error.message);
357
- onError(intlError);
358
- return intlError;
359
- }
360
- }, [allMessages, namespace, onError]);
361
- var translate = React.useMemo(function () {
362
- function getFallbackFromErrorAndNotify(key, code, message) {
363
- var error = new IntlError(code, message);
364
- onError(error);
305
+ function translateBaseFn(
306
+ /** Use a dot to indicate a level of nesting (e.g. `namespace.nestedLabel`). */
307
+ key,
308
+ /** Key value pairs for values to interpolate into the message. */
309
+ values,
310
+ /** Provide custom formats for numbers, dates and times. */
311
+ formats) {
312
+ var _cachedFormatsByLocal;
313
+
314
+ if (messagesOrError instanceof IntlError) {
315
+ // We have already warned about this during render
365
316
  return getMessageFallback({
366
- error: error,
317
+ error: messagesOrError,
367
318
  key: key,
368
319
  namespace: namespace
369
320
  });
370
321
  }
371
322
 
372
- function translateBaseFn(
373
- /** Use a dot to indicate a level of nesting (e.g. `namespace.nestedLabel`). */
374
- key,
375
- /** Key value pairs for values to interpolate into the message. */
376
- values,
377
- /** Provide custom formats for numbers, dates and times. */
378
- formats) {
379
- var _cachedFormatsByLocal;
380
-
381
- var cachedFormatsByLocale = cachedFormatsByLocaleRef.current;
382
-
383
- if (messagesOrError instanceof IntlError) {
384
- // We have already warned about this during render
385
- return getMessageFallback({
386
- error: messagesOrError,
387
- key: key,
388
- namespace: namespace
389
- });
390
- }
323
+ var messages = messagesOrError;
324
+ var cacheKey = [namespace, key].filter(function (part) {
325
+ return part != null;
326
+ }).join('.');
327
+ var messageFormat;
391
328
 
392
- var messages = messagesOrError;
393
- var cacheKey = [namespace, key].filter(function (part) {
394
- return part != null;
395
- }).join('.');
396
- var messageFormat;
397
-
398
- if ((_cachedFormatsByLocal = cachedFormatsByLocale[locale]) != null && _cachedFormatsByLocal[cacheKey]) {
399
- messageFormat = cachedFormatsByLocale[locale][cacheKey];
400
- } else {
401
- var message;
402
-
403
- try {
404
- message = resolvePath(messages, key, namespace);
405
- } catch (error) {
406
- return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.MISSING_MESSAGE, error.message);
407
- }
329
+ if (cachedFormatsByLocale != null && (_cachedFormatsByLocal = cachedFormatsByLocale[locale]) != null && _cachedFormatsByLocal[cacheKey]) {
330
+ messageFormat = cachedFormatsByLocale == null ? void 0 : cachedFormatsByLocale[locale][cacheKey];
331
+ } else {
332
+ var message;
408
333
 
409
- if (typeof message === 'object') {
410
- return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.INSUFFICIENT_PATH, "Insufficient path specified for `" + key + "` in `" + (namespace ? "`" + namespace + "`" : 'messages') + "`." );
411
- }
334
+ try {
335
+ message = resolvePath(messages, key, namespace);
336
+ } catch (error) {
337
+ return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.MISSING_MESSAGE, error.message);
338
+ }
412
339
 
413
- try {
414
- messageFormat = new intlMessageformat.IntlMessageFormat(message, locale, convertFormatsToIntlMessageFormat(_extends({}, globalFormats, formats), timeZone));
415
- } catch (error) {
416
- return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.INVALID_MESSAGE, error.message);
417
- }
340
+ if (typeof message === 'object') {
341
+ return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.INSUFFICIENT_PATH, "Insufficient path specified for `" + key + "` in `" + (namespace ? "`" + namespace + "`" : 'messages') + "`." );
342
+ }
343
+
344
+ try {
345
+ messageFormat = new IntlMessageFormat__default["default"](message, locale, convertFormatsToIntlMessageFormat(_extends({}, globalFormats, formats), timeZone));
346
+ } catch (error) {
347
+ return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.INVALID_MESSAGE, error.message);
348
+ }
418
349
 
350
+ if (cachedFormatsByLocale) {
419
351
  if (!cachedFormatsByLocale[locale]) {
420
352
  cachedFormatsByLocale[locale] = {};
421
353
  }
422
354
 
423
355
  cachedFormatsByLocale[locale][cacheKey] = messageFormat;
424
356
  }
357
+ }
425
358
 
426
- try {
427
- var formattedMessage = messageFormat.format( // @ts-ignore `intl-messageformat` expects a different format
428
- // for rich text elements since a recent minor update. This
429
- // needs to be evaluated in detail, possibly also in regards
430
- // to be able to format to parts.
431
- prepareTranslationValues(_extends({}, defaultTranslationValues, values)));
359
+ try {
360
+ var formattedMessage = messageFormat.format( // @ts-ignore `intl-messageformat` expects a different format
361
+ // for rich text elements since a recent minor update. This
362
+ // needs to be evaluated in detail, possibly also in regards
363
+ // to be able to format to parts.
364
+ prepareTranslationValues(_extends({}, defaultTranslationValues, values)));
432
365
 
433
- if (formattedMessage == null) {
434
- throw new Error("development" !== "production" ? "Unable to format `" + key + "` in " + (namespace ? "namespace `" + namespace + "`" : 'messages') : undefined);
435
- } // Limit the function signature to return strings or React elements
366
+ if (formattedMessage == null) {
367
+ throw new Error("development" !== "production" ? "Unable to format `" + key + "` in " + (namespace ? "namespace `" + namespace + "`" : 'messages') : undefined);
368
+ } // Limit the function signature to return strings or React elements
436
369
 
437
370
 
438
- return React.isValidElement(formattedMessage) || // Arrays of React elements
439
- Array.isArray(formattedMessage) || typeof formattedMessage === 'string' ? formattedMessage : String(formattedMessage);
440
- } catch (error) {
441
- return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.FORMATTING_ERROR, error.message);
442
- }
371
+ return React.isValidElement(formattedMessage) || // Arrays of React elements
372
+ Array.isArray(formattedMessage) || typeof formattedMessage === 'string' ? formattedMessage : String(formattedMessage);
373
+ } catch (error) {
374
+ return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.FORMATTING_ERROR, error.message);
443
375
  }
376
+ }
444
377
 
445
- function translateFn(
446
- /** Use a dot to indicate a level of nesting (e.g. `namespace.nestedLabel`). */
447
- key,
448
- /** Key value pairs for values to interpolate into the message. */
449
- values,
450
- /** Provide custom formats for numbers, dates and times. */
451
- formats) {
452
- var message = translateBaseFn(key, values, formats);
453
-
454
- if (typeof message !== 'string') {
455
- return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.INVALID_MESSAGE, "The message `" + key + "` in " + (namespace ? "namespace `" + namespace + "`" : 'messages') + " didn't resolve to a string. If you want to format rich text, use `t.rich` instead." );
456
- }
378
+ function translateFn(
379
+ /** Use a dot to indicate a level of nesting (e.g. `namespace.nestedLabel`). */
380
+ key,
381
+ /** Key value pairs for values to interpolate into the message. */
382
+ values,
383
+ /** Provide custom formats for numbers, dates and times. */
384
+ formats) {
385
+ var result = translateBaseFn(key, values, formats);
386
+
387
+ if (typeof result !== 'string') {
388
+ return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.INVALID_MESSAGE, "The message `" + key + "` in " + (namespace ? "namespace `" + namespace + "`" : 'messages') + " didn't resolve to a string. If you want to format rich text, use `t.rich` instead." );
389
+ }
457
390
 
458
- return message;
391
+ return result;
392
+ }
393
+
394
+ translateFn.rich = translateBaseFn;
395
+
396
+ translateFn.raw = function (
397
+ /** Use a dot to indicate a level of nesting (e.g. `namespace.nestedLabel`). */
398
+ key) {
399
+ if (messagesOrError instanceof IntlError) {
400
+ // We have already warned about this during render
401
+ return getMessageFallback({
402
+ error: messagesOrError,
403
+ key: key,
404
+ namespace: namespace
405
+ });
459
406
  }
460
407
 
461
- translateFn.rich = translateBaseFn;
462
-
463
- translateFn.raw = function (
464
- /** Use a dot to indicate a level of nesting (e.g. `namespace.nestedLabel`). */
465
- key) {
466
- if (messagesOrError instanceof IntlError) {
467
- // We have already warned about this during render
468
- return getMessageFallback({
469
- error: messagesOrError,
470
- key: key,
471
- namespace: namespace
472
- });
473
- }
408
+ var messages = messagesOrError;
474
409
 
475
- var messages = messagesOrError;
410
+ try {
411
+ return resolvePath(messages, key, namespace);
412
+ } catch (error) {
413
+ return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.MISSING_MESSAGE, error.message);
414
+ }
415
+ };
476
416
 
477
- try {
478
- return resolvePath(messages, key, namespace);
479
- } catch (error) {
480
- return getFallbackFromErrorAndNotify(key, exports.IntlErrorCode.MISSING_MESSAGE, error.message);
481
- }
482
- };
417
+ return translateFn;
418
+ }
483
419
 
484
- return translateFn;
485
- }, [onError, getMessageFallback, namespace, messagesOrError, locale, globalFormats, timeZone, defaultTranslationValues]);
486
- return translate;
420
+ /**
421
+ * For the strictly typed messages to work we have to wrap the namespace into
422
+ * a mandatory prefix. See https://stackoverflow.com/a/71529575/343045
423
+ */
424
+ function resolveNamespace(namespace, namespacePrefix) {
425
+ return namespace === namespacePrefix ? undefined : namespace.slice((namespacePrefix + '.').length);
487
426
  }
488
427
 
428
+ var _excluded$2 = ["messages", "namespace", "onError", "getMessageFallback"];
429
+ function createTranslatorImpl(_ref, namespacePrefix) {
430
+ var messages = _ref.messages,
431
+ namespace = _ref.namespace,
432
+ _ref$onError = _ref.onError,
433
+ onError = _ref$onError === void 0 ? defaultOnError : _ref$onError,
434
+ _ref$getMessageFallba = _ref.getMessageFallback,
435
+ getMessageFallback = _ref$getMessageFallba === void 0 ? defaultGetMessageFallback : _ref$getMessageFallba,
436
+ rest = _objectWithoutPropertiesLoose(_ref, _excluded$2);
437
+
438
+ // The `namespacePrefix` is part of the type system.
439
+ // See the comment in the function invocation.
440
+ messages = messages[namespacePrefix];
441
+ namespace = resolveNamespace(namespace, namespacePrefix);
442
+ var translator = createBaseTranslator(_extends({}, rest, {
443
+ onError: onError,
444
+ messagesOrError: getMessagesOrError({
445
+ messages: messages,
446
+ namespace: namespace,
447
+ onError: onError
448
+ })
449
+ }));
450
+ var originalRich = translator.rich;
451
+
452
+ function base() {
453
+ return translator.apply(void 0, arguments);
454
+ } // Augment `t.rich` to return plain strings
455
+
456
+
457
+ base.rich = function (key,
458
+ /** Key value pairs for values to interpolate into the message. */
459
+ values, formats) {
460
+ // `chunks` is returned as a string when no React element
461
+ // is used, therefore it's safe to cast this type.
462
+ var result = originalRich(key, values, formats); // When only string chunks are provided to the parser, only strings should be returned here.
463
+
464
+ if (typeof result !== 'string') {
465
+ var error = new IntlError(exports.IntlErrorCode.FORMATTING_ERROR, "`createTranslator` only accepts functions for rich text formatting that receive and return strings.\n\nE.g. t.rich('rich', {b: (chunks) => `<b>${chunks}</b>`})" );
466
+ onError(error);
467
+ return getMessageFallback({
468
+ error: error,
469
+ key: key,
470
+ namespace: namespace
471
+ });
472
+ }
473
+
474
+ return result;
475
+ };
476
+
477
+ base.raw = translator.raw;
478
+ return base;
479
+ }
480
+
481
+ var _excluded$1 = ["messages", "namespace"];
489
482
  /**
490
483
  * Translates messages from the given namespace by using the ICU syntax.
491
484
  * See https://formatjs.io/docs/core-concepts/icu-syntax.
@@ -495,16 +488,21 @@ function useTranslationsImpl(allMessages, namespace, namespacePrefix) {
495
488
  * (e.g. `namespace.Component`).
496
489
  */
497
490
 
498
- function useTranslations(namespace) {
499
- var context = useIntlContext();
500
- var messages = context.messages; // We have to wrap the actual hook so the type inference for the optional
501
- // namespace works correctly. See https://stackoverflow.com/a/71529575/343045
502
- // The prefix ("!"") is arbitrary, but we have to use some.
491
+ function createTranslator(_ref) {
492
+ var messages = _ref.messages,
493
+ namespace = _ref.namespace,
494
+ rest = _objectWithoutPropertiesLoose(_ref, _excluded$1);
503
495
 
504
- return useTranslationsImpl({
505
- '!': messages
506
- }, // @ts-ignore
507
- namespace ? "!." + namespace : '!', '!');
496
+ // We have to wrap the actual function so the type inference for the optional
497
+ // namespace works correctly. See https://stackoverflow.com/a/71529575/343045
498
+ // The prefix ("!") is arbitrary.
499
+ return createTranslatorImpl(_extends({}, rest, {
500
+ messages: {
501
+ '!': messages
502
+ },
503
+ // @ts-ignore
504
+ namespace: namespace ? "!." + namespace : '!'
505
+ }), '!');
508
506
  }
509
507
 
510
508
  var MINUTE = 60;
@@ -549,13 +547,13 @@ function getRelativeTimeFormatConfig(seconds) {
549
547
  };
550
548
  }
551
549
 
552
- function useIntl() {
553
- var _useIntlContext = useIntlContext(),
554
- formats = _useIntlContext.formats,
555
- locale = _useIntlContext.locale,
556
- globalNow = _useIntlContext.now,
557
- onError = _useIntlContext.onError,
558
- timeZone = _useIntlContext.timeZone;
550
+ function createIntl(_ref) {
551
+ var formats = _ref.formats,
552
+ locale = _ref.locale,
553
+ globalNow = _ref.now,
554
+ _ref$onError = _ref.onError,
555
+ onError = _ref$onError === void 0 ? defaultOnError : _ref$onError,
556
+ timeZone = _ref.timeZone;
559
557
 
560
558
  function resolveFormatOrOptions(typeFormats, formatOrOptions) {
561
559
  var options;
@@ -656,6 +654,151 @@ function useIntl() {
656
654
  };
657
655
  }
658
656
 
657
+ function validateMessagesSegment(messages, invalidKeyLabels, parentPath) {
658
+ Object.entries(messages).forEach(function (_ref) {
659
+ var key = _ref[0],
660
+ messageOrMessages = _ref[1];
661
+
662
+ if (key.includes('.')) {
663
+ var keyLabel = key;
664
+ if (parentPath) keyLabel += " (at " + parentPath + ")";
665
+ invalidKeyLabels.push(keyLabel);
666
+ }
667
+
668
+ if (messageOrMessages != null && typeof messageOrMessages === 'object') {
669
+ validateMessagesSegment(messageOrMessages, invalidKeyLabels, [parentPath, key].filter(function (part) {
670
+ return part != null;
671
+ }).join('.'));
672
+ }
673
+ });
674
+ }
675
+
676
+ function validateMessages(messages, onError) {
677
+ var invalidKeyLabels = [];
678
+ validateMessagesSegment(messages, invalidKeyLabels);
679
+
680
+ if (invalidKeyLabels.length > 0) {
681
+ onError(new IntlError(exports.IntlErrorCode.INVALID_KEY, "Namespace keys can not contain the character \".\" as this is used to express nesting. Please remove it or replace it with another character.\n\nInvalid " + (invalidKeyLabels.length === 1 ? 'key' : 'keys') + ": " + invalidKeyLabels.join(', ')));
682
+ }
683
+ }
684
+
685
+ var IntlContext = /*#__PURE__*/React.createContext(undefined);
686
+
687
+ var _excluded = ["children", "onError", "getMessageFallback", "messages"];
688
+ function IntlProvider(_ref) {
689
+ var children = _ref.children,
690
+ _ref$onError = _ref.onError,
691
+ onError = _ref$onError === void 0 ? defaultOnError : _ref$onError,
692
+ _ref$getMessageFallba = _ref.getMessageFallback,
693
+ getMessageFallback = _ref$getMessageFallba === void 0 ? defaultGetMessageFallback : _ref$getMessageFallba,
694
+ messages = _ref.messages,
695
+ contextValues = _objectWithoutPropertiesLoose(_ref, _excluded);
696
+
697
+ {
698
+ // eslint-disable-next-line react-hooks/rules-of-hooks
699
+ React.useEffect(function () {
700
+ if (messages) {
701
+ validateMessages(messages, onError);
702
+ }
703
+ }, [messages, onError]);
704
+ }
705
+
706
+ return React__default["default"].createElement(IntlContext.Provider, {
707
+ value: _extends({}, contextValues, {
708
+ messages: messages,
709
+ onError: onError,
710
+ getMessageFallback: getMessageFallback
711
+ })
712
+ }, children);
713
+ }
714
+
715
+ function useIntlContext() {
716
+ var context = React.useContext(IntlContext);
717
+
718
+ if (!context) {
719
+ throw new Error('No intl context found. Have you configured the provider?' );
720
+ }
721
+
722
+ return context;
723
+ }
724
+
725
+ function useTranslationsImpl(allMessages, namespace, namespacePrefix) {
726
+ var _useIntlContext = useIntlContext(),
727
+ defaultTranslationValues = _useIntlContext.defaultTranslationValues,
728
+ globalFormats = _useIntlContext.formats,
729
+ getMessageFallback = _useIntlContext.getMessageFallback,
730
+ locale = _useIntlContext.locale,
731
+ onError = _useIntlContext.onError,
732
+ timeZone = _useIntlContext.timeZone; // The `namespacePrefix` is part of the type system.
733
+ // See the comment in the hook invocation.
734
+
735
+
736
+ allMessages = allMessages[namespacePrefix];
737
+ namespace = resolveNamespace(namespace, namespacePrefix);
738
+ var cachedFormatsByLocaleRef = React.useRef({});
739
+ var messagesOrError = React.useMemo(function () {
740
+ return getMessagesOrError({
741
+ messages: allMessages,
742
+ namespace: namespace,
743
+ onError: onError
744
+ });
745
+ }, [allMessages, namespace, onError]);
746
+ var translate = React.useMemo(function () {
747
+ return createBaseTranslator({
748
+ cachedFormatsByLocale: cachedFormatsByLocaleRef.current,
749
+ getMessageFallback: getMessageFallback,
750
+ messagesOrError: messagesOrError,
751
+ defaultTranslationValues: defaultTranslationValues,
752
+ namespace: namespace,
753
+ onError: onError,
754
+ formats: globalFormats,
755
+ locale: locale,
756
+ timeZone: timeZone
757
+ });
758
+ }, [getMessageFallback, messagesOrError, defaultTranslationValues, namespace, onError, globalFormats, locale, timeZone]);
759
+ return translate;
760
+ }
761
+
762
+ /**
763
+ * Translates messages from the given namespace by using the ICU syntax.
764
+ * See https://formatjs.io/docs/core-concepts/icu-syntax.
765
+ *
766
+ * If no namespace is provided, all available messages are returned.
767
+ * The namespace can also indicate nesting by using a dot
768
+ * (e.g. `namespace.Component`).
769
+ */
770
+
771
+ function useTranslations(namespace) {
772
+ var context = useIntlContext();
773
+ var messages = context.messages; // We have to wrap the actual hook so the type inference for the optional
774
+ // namespace works correctly. See https://stackoverflow.com/a/71529575/343045
775
+ // The prefix ("!") is arbitrary.
776
+
777
+ return useTranslationsImpl({
778
+ '!': messages
779
+ }, // @ts-ignore
780
+ namespace ? "!." + namespace : '!', '!');
781
+ }
782
+
783
+ function useIntl() {
784
+ var _useIntlContext = useIntlContext(),
785
+ formats = _useIntlContext.formats,
786
+ locale = _useIntlContext.locale,
787
+ globalNow = _useIntlContext.now,
788
+ onError = _useIntlContext.onError,
789
+ timeZone = _useIntlContext.timeZone;
790
+
791
+ return React.useMemo(function () {
792
+ return createIntl({
793
+ formats: formats,
794
+ locale: locale,
795
+ now: globalNow,
796
+ onError: onError,
797
+ timeZone: timeZone
798
+ });
799
+ }, [formats, globalNow, locale, onError, timeZone]);
800
+ }
801
+
659
802
  function useLocale() {
660
803
  return useIntlContext().locale;
661
804
  }
@@ -711,6 +854,8 @@ function useTimeZone() {
711
854
 
712
855
  exports.IntlError = IntlError;
713
856
  exports.IntlProvider = IntlProvider;
857
+ exports.createIntl = createIntl;
858
+ exports.createTranslator = createTranslator;
714
859
  exports.useIntl = useIntl;
715
860
  exports.useLocale = useLocale;
716
861
  exports.useNow = useNow;