i18next 21.2.6 → 21.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 21.3.3
2
+
3
+ - apply default interpolation formatter when interpolation options don't specify one [1680](https://github.com/i18next/i18next/issues/1680)
4
+
5
+ ## 21.3.2
6
+
7
+ - formatter typescript declarations [1679](https://github.com/i18next/i18next/pull/1679)
8
+
9
+ ## 21.3.1
10
+
11
+ - get rid of internal isDummy check to prevent react-native issue [1675](https://github.com/i18next/i18next/issues/1675)
12
+
13
+ ## 21.3.0
14
+
15
+ - adds support for formats provided by Intl API (number, currency, datetime, relativedate, list)
16
+
1
17
  ## 21.2.6
2
18
 
3
19
  - optimize do skip natural language detection also if user provided nsSeparator option is passed via direct options
@@ -8,6 +8,7 @@ var _possibleConstructorReturn = require('@babel/runtime/helpers/possibleConstru
8
8
  var _getPrototypeOf = require('@babel/runtime/helpers/getPrototypeOf');
9
9
  var _assertThisInitialized = require('@babel/runtime/helpers/assertThisInitialized');
10
10
  var _inherits = require('@babel/runtime/helpers/inherits');
11
+ var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
11
12
 
12
13
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
14
 
@@ -19,6 +20,7 @@ var _possibleConstructorReturn__default = /*#__PURE__*/_interopDefaultLegacy(_po
19
20
  var _getPrototypeOf__default = /*#__PURE__*/_interopDefaultLegacy(_getPrototypeOf);
20
21
  var _assertThisInitialized__default = /*#__PURE__*/_interopDefaultLegacy(_assertThisInitialized);
21
22
  var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits);
23
+ var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray);
22
24
 
23
25
  var consoleLogger = {
24
26
  type: 'logger',
@@ -1627,6 +1629,124 @@ var Interpolator = function () {
1627
1629
  return Interpolator;
1628
1630
  }();
1629
1631
 
1632
+ function parseFormatStr(formatStr) {
1633
+ var formatName = formatStr.toLowerCase();
1634
+ var formatOptions = {};
1635
+
1636
+ if (formatStr.indexOf('(') > -1) {
1637
+ var p = formatStr.split('(');
1638
+ formatName = p[0].toLowerCase();
1639
+ var optStr = p[1].substring(0, p[1].length - 1);
1640
+
1641
+ if (formatName === 'currency' && optStr.indexOf(':') < 0) {
1642
+ if (!formatOptions.currency) formatOptions.currency = optStr.trim();
1643
+ } else if (formatName === 'relativetime' && optStr.indexOf(':') < 0) {
1644
+ if (!formatOptions.range) formatOptions.range = optStr.trim();
1645
+ } else {
1646
+ var opts = optStr.split(';');
1647
+ opts.forEach(function (opt) {
1648
+ if (!opt) return;
1649
+
1650
+ var _opt$split = opt.split(':'),
1651
+ _opt$split2 = _slicedToArray__default['default'](_opt$split, 2),
1652
+ key = _opt$split2[0],
1653
+ val = _opt$split2[1];
1654
+
1655
+ if (val.trim() === 'false') formatOptions[key.trim()] = false;
1656
+ if (val.trim() === 'true') formatOptions[key.trim()] = true;
1657
+ if (!isNaN(val.trim())) formatOptions[key.trim()] = parseInt(val.trim(), 10);
1658
+ if (!formatOptions[key.trim()]) formatOptions[key.trim()] = val.trim();
1659
+ });
1660
+ }
1661
+ }
1662
+
1663
+ return {
1664
+ formatName: formatName,
1665
+ formatOptions: formatOptions
1666
+ };
1667
+ }
1668
+
1669
+ var Formatter = function () {
1670
+ function Formatter() {
1671
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1672
+
1673
+ _classCallCheck__default['default'](this, Formatter);
1674
+
1675
+ this.logger = baseLogger.create('formatter');
1676
+ this.options = options;
1677
+ this.formats = {
1678
+ number: function number(val, lng, options) {
1679
+ return new Intl.NumberFormat(lng, options).format(val);
1680
+ },
1681
+ currency: function currency(val, lng, options) {
1682
+ return new Intl.NumberFormat(lng, _objectSpread__default['default']({}, options, {
1683
+ style: 'currency'
1684
+ })).format(val);
1685
+ },
1686
+ datetime: function datetime(val, lng, options) {
1687
+ return new Intl.DateTimeFormat(lng, _objectSpread__default['default']({}, options)).format(val);
1688
+ },
1689
+ relativetime: function relativetime(val, lng, options) {
1690
+ return new Intl.RelativeTimeFormat(lng, _objectSpread__default['default']({}, options)).format(val, options.range || 'day');
1691
+ },
1692
+ list: function list(val, lng, options) {
1693
+ return new Intl.ListFormat(lng, _objectSpread__default['default']({}, options)).format(val);
1694
+ }
1695
+ };
1696
+ this.init(options);
1697
+ }
1698
+
1699
+ _createClass__default['default'](Formatter, [{
1700
+ key: "init",
1701
+ value: function init(services) {
1702
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
1703
+ interpolation: {}
1704
+ };
1705
+ var iOpts = options.interpolation;
1706
+ this.formatSeparator = iOpts.formatSeparator ? iOpts.formatSeparator : iOpts.formatSeparator || ',';
1707
+ }
1708
+ }, {
1709
+ key: "add",
1710
+ value: function add(name, fc) {
1711
+ this.formats[name] = fc;
1712
+ }
1713
+ }, {
1714
+ key: "format",
1715
+ value: function format(value, _format, lng, options) {
1716
+ var _this = this;
1717
+
1718
+ var formats = _format.split(this.formatSeparator);
1719
+
1720
+ var result = formats.reduce(function (mem, f) {
1721
+ var _parseFormatStr = parseFormatStr(f),
1722
+ formatName = _parseFormatStr.formatName,
1723
+ formatOptions = _parseFormatStr.formatOptions;
1724
+
1725
+ if (_this.formats[formatName]) {
1726
+ var formatted = mem;
1727
+
1728
+ try {
1729
+ var valOptions = options && options.formatParams && options.formatParams[options.interpolationkey] || {};
1730
+ var l = valOptions.locale || valOptions.lng || options.locale || options.lng || lng;
1731
+ formatted = _this.formats[formatName](mem, l, _objectSpread__default['default']({}, formatOptions, options, valOptions));
1732
+ } catch (error) {
1733
+ _this.logger.warn(error);
1734
+ }
1735
+
1736
+ return formatted;
1737
+ } else {
1738
+ _this.logger.warn("there was no format function for ".concat(formatName));
1739
+ }
1740
+
1741
+ return mem;
1742
+ }, value);
1743
+ return result;
1744
+ }
1745
+ }]);
1746
+
1747
+ return Formatter;
1748
+ }();
1749
+
1630
1750
  function remove(arr, what) {
1631
1751
  var found = arr.indexOf(what);
1632
1752
 
@@ -1996,7 +2116,8 @@ var I18n = function (_EventEmitter) {
1996
2116
  }
1997
2117
  }
1998
2118
 
1999
- this.options = _objectSpread__default['default']({}, get(), this.options, transformOptions(options));
2119
+ var defOpts = get();
2120
+ this.options = _objectSpread__default['default']({}, defOpts, this.options, transformOptions(options));
2000
2121
 
2001
2122
  if (options.keySeparator !== undefined) {
2002
2123
  this.options.userDefinedKeySeparator = options.keySeparator;
@@ -2006,9 +2127,6 @@ var I18n = function (_EventEmitter) {
2006
2127
  this.options.userDefinedNsSeparator = options.nsSeparator;
2007
2128
  }
2008
2129
 
2009
- this.format = this.options.interpolation.format;
2010
- if (!callback) callback = noop;
2011
-
2012
2130
  function createClassOnDemand(ClassOrObject) {
2013
2131
  if (!ClassOrObject) return null;
2014
2132
  if (typeof ClassOrObject === 'function') return new ClassOrObject();
@@ -2022,6 +2140,14 @@ var I18n = function (_EventEmitter) {
2022
2140
  baseLogger.init(null, this.options);
2023
2141
  }
2024
2142
 
2143
+ var formatter;
2144
+
2145
+ if (this.modules.formatter) {
2146
+ formatter = this.modules.formatter;
2147
+ } else if (typeof Intl !== 'undefined') {
2148
+ formatter = Formatter;
2149
+ }
2150
+
2025
2151
  var lu = new LanguageUtil(this.options);
2026
2152
  this.store = new ResourceStore(this.options.resources, this.options);
2027
2153
  var s = this.services;
@@ -2033,6 +2159,13 @@ var I18n = function (_EventEmitter) {
2033
2159
  compatibilityJSON: this.options.compatibilityJSON,
2034
2160
  simplifyPluralSuffix: this.options.simplifyPluralSuffix
2035
2161
  });
2162
+
2163
+ if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
2164
+ s.formatter = createClassOnDemand(formatter);
2165
+ s.formatter.init(s, this.options);
2166
+ this.options.interpolation.format = s.formatter.format.bind(s.formatter);
2167
+ }
2168
+
2036
2169
  s.interpolator = new Interpolator(this.options);
2037
2170
  s.utils = {
2038
2171
  hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
@@ -2069,6 +2202,9 @@ var I18n = function (_EventEmitter) {
2069
2202
  });
2070
2203
  }
2071
2204
 
2205
+ this.format = this.options.interpolation.format;
2206
+ if (!callback) callback = noop;
2207
+
2072
2208
  if (this.options.fallbackLng && !this.services.languageDetector && !this.options.lng) {
2073
2209
  var codes = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
2074
2210
  if (codes.length > 0 && codes[0] !== 'dev') this.options.lng = codes[0];
@@ -2206,6 +2342,10 @@ var I18n = function (_EventEmitter) {
2206
2342
  postProcessor.addPostProcessor(module);
2207
2343
  }
2208
2344
 
2345
+ if (module.type === 'formatter') {
2346
+ this.modules.formatter = module;
2347
+ }
2348
+
2209
2349
  if (module.type === '3rdParty') {
2210
2350
  this.modules.external.push(module);
2211
2351
  }
@@ -117,6 +117,62 @@ function _possibleConstructorReturn(self, call) {
117
117
  return _assertThisInitialized(self);
118
118
  }
119
119
 
120
+ function _slicedToArray(arr, i) {
121
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
122
+ }
123
+
124
+ function _arrayWithHoles(arr) {
125
+ if (Array.isArray(arr)) return arr;
126
+ }
127
+
128
+ function _iterableToArrayLimit(arr, i) {
129
+ if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
130
+ var _arr = [];
131
+ var _n = true;
132
+ var _d = false;
133
+ var _e = undefined;
134
+
135
+ try {
136
+ for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
137
+ _arr.push(_s.value);
138
+
139
+ if (i && _arr.length === i) break;
140
+ }
141
+ } catch (err) {
142
+ _d = true;
143
+ _e = err;
144
+ } finally {
145
+ try {
146
+ if (!_n && _i["return"] != null) _i["return"]();
147
+ } finally {
148
+ if (_d) throw _e;
149
+ }
150
+ }
151
+
152
+ return _arr;
153
+ }
154
+
155
+ function _unsupportedIterableToArray(o, minLen) {
156
+ if (!o) return;
157
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
158
+ var n = Object.prototype.toString.call(o).slice(8, -1);
159
+ if (n === "Object" && o.constructor) n = o.constructor.name;
160
+ if (n === "Map" || n === "Set") return Array.from(o);
161
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
162
+ }
163
+
164
+ function _arrayLikeToArray(arr, len) {
165
+ if (len == null || len > arr.length) len = arr.length;
166
+
167
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
168
+
169
+ return arr2;
170
+ }
171
+
172
+ function _nonIterableRest() {
173
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
174
+ }
175
+
120
176
  var consoleLogger = {
121
177
  type: 'logger',
122
178
  log: function log(args) {
@@ -1724,6 +1780,124 @@ var Interpolator = function () {
1724
1780
  return Interpolator;
1725
1781
  }();
1726
1782
 
1783
+ function parseFormatStr(formatStr) {
1784
+ var formatName = formatStr.toLowerCase();
1785
+ var formatOptions = {};
1786
+
1787
+ if (formatStr.indexOf('(') > -1) {
1788
+ var p = formatStr.split('(');
1789
+ formatName = p[0].toLowerCase();
1790
+ var optStr = p[1].substring(0, p[1].length - 1);
1791
+
1792
+ if (formatName === 'currency' && optStr.indexOf(':') < 0) {
1793
+ if (!formatOptions.currency) formatOptions.currency = optStr.trim();
1794
+ } else if (formatName === 'relativetime' && optStr.indexOf(':') < 0) {
1795
+ if (!formatOptions.range) formatOptions.range = optStr.trim();
1796
+ } else {
1797
+ var opts = optStr.split(';');
1798
+ opts.forEach(function (opt) {
1799
+ if (!opt) return;
1800
+
1801
+ var _opt$split = opt.split(':'),
1802
+ _opt$split2 = _slicedToArray(_opt$split, 2),
1803
+ key = _opt$split2[0],
1804
+ val = _opt$split2[1];
1805
+
1806
+ if (val.trim() === 'false') formatOptions[key.trim()] = false;
1807
+ if (val.trim() === 'true') formatOptions[key.trim()] = true;
1808
+ if (!isNaN(val.trim())) formatOptions[key.trim()] = parseInt(val.trim(), 10);
1809
+ if (!formatOptions[key.trim()]) formatOptions[key.trim()] = val.trim();
1810
+ });
1811
+ }
1812
+ }
1813
+
1814
+ return {
1815
+ formatName: formatName,
1816
+ formatOptions: formatOptions
1817
+ };
1818
+ }
1819
+
1820
+ var Formatter = function () {
1821
+ function Formatter() {
1822
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1823
+
1824
+ _classCallCheck(this, Formatter);
1825
+
1826
+ this.logger = baseLogger.create('formatter');
1827
+ this.options = options;
1828
+ this.formats = {
1829
+ number: function number(val, lng, options) {
1830
+ return new Intl.NumberFormat(lng, options).format(val);
1831
+ },
1832
+ currency: function currency(val, lng, options) {
1833
+ return new Intl.NumberFormat(lng, _objectSpread({}, options, {
1834
+ style: 'currency'
1835
+ })).format(val);
1836
+ },
1837
+ datetime: function datetime(val, lng, options) {
1838
+ return new Intl.DateTimeFormat(lng, _objectSpread({}, options)).format(val);
1839
+ },
1840
+ relativetime: function relativetime(val, lng, options) {
1841
+ return new Intl.RelativeTimeFormat(lng, _objectSpread({}, options)).format(val, options.range || 'day');
1842
+ },
1843
+ list: function list(val, lng, options) {
1844
+ return new Intl.ListFormat(lng, _objectSpread({}, options)).format(val);
1845
+ }
1846
+ };
1847
+ this.init(options);
1848
+ }
1849
+
1850
+ _createClass(Formatter, [{
1851
+ key: "init",
1852
+ value: function init(services) {
1853
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
1854
+ interpolation: {}
1855
+ };
1856
+ var iOpts = options.interpolation;
1857
+ this.formatSeparator = iOpts.formatSeparator ? iOpts.formatSeparator : iOpts.formatSeparator || ',';
1858
+ }
1859
+ }, {
1860
+ key: "add",
1861
+ value: function add(name, fc) {
1862
+ this.formats[name] = fc;
1863
+ }
1864
+ }, {
1865
+ key: "format",
1866
+ value: function format(value, _format, lng, options) {
1867
+ var _this = this;
1868
+
1869
+ var formats = _format.split(this.formatSeparator);
1870
+
1871
+ var result = formats.reduce(function (mem, f) {
1872
+ var _parseFormatStr = parseFormatStr(f),
1873
+ formatName = _parseFormatStr.formatName,
1874
+ formatOptions = _parseFormatStr.formatOptions;
1875
+
1876
+ if (_this.formats[formatName]) {
1877
+ var formatted = mem;
1878
+
1879
+ try {
1880
+ var valOptions = options && options.formatParams && options.formatParams[options.interpolationkey] || {};
1881
+ var l = valOptions.locale || valOptions.lng || options.locale || options.lng || lng;
1882
+ formatted = _this.formats[formatName](mem, l, _objectSpread({}, formatOptions, options, valOptions));
1883
+ } catch (error) {
1884
+ _this.logger.warn(error);
1885
+ }
1886
+
1887
+ return formatted;
1888
+ } else {
1889
+ _this.logger.warn("there was no format function for ".concat(formatName));
1890
+ }
1891
+
1892
+ return mem;
1893
+ }, value);
1894
+ return result;
1895
+ }
1896
+ }]);
1897
+
1898
+ return Formatter;
1899
+ }();
1900
+
1727
1901
  function remove(arr, what) {
1728
1902
  var found = arr.indexOf(what);
1729
1903
 
@@ -2093,7 +2267,8 @@ var I18n = function (_EventEmitter) {
2093
2267
  }
2094
2268
  }
2095
2269
 
2096
- this.options = _objectSpread({}, get(), this.options, transformOptions(options));
2270
+ var defOpts = get();
2271
+ this.options = _objectSpread({}, defOpts, this.options, transformOptions(options));
2097
2272
 
2098
2273
  if (options.keySeparator !== undefined) {
2099
2274
  this.options.userDefinedKeySeparator = options.keySeparator;
@@ -2103,9 +2278,6 @@ var I18n = function (_EventEmitter) {
2103
2278
  this.options.userDefinedNsSeparator = options.nsSeparator;
2104
2279
  }
2105
2280
 
2106
- this.format = this.options.interpolation.format;
2107
- if (!callback) callback = noop;
2108
-
2109
2281
  function createClassOnDemand(ClassOrObject) {
2110
2282
  if (!ClassOrObject) return null;
2111
2283
  if (typeof ClassOrObject === 'function') return new ClassOrObject();
@@ -2119,6 +2291,14 @@ var I18n = function (_EventEmitter) {
2119
2291
  baseLogger.init(null, this.options);
2120
2292
  }
2121
2293
 
2294
+ var formatter;
2295
+
2296
+ if (this.modules.formatter) {
2297
+ formatter = this.modules.formatter;
2298
+ } else if (typeof Intl !== 'undefined') {
2299
+ formatter = Formatter;
2300
+ }
2301
+
2122
2302
  var lu = new LanguageUtil(this.options);
2123
2303
  this.store = new ResourceStore(this.options.resources, this.options);
2124
2304
  var s = this.services;
@@ -2130,6 +2310,13 @@ var I18n = function (_EventEmitter) {
2130
2310
  compatibilityJSON: this.options.compatibilityJSON,
2131
2311
  simplifyPluralSuffix: this.options.simplifyPluralSuffix
2132
2312
  });
2313
+
2314
+ if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
2315
+ s.formatter = createClassOnDemand(formatter);
2316
+ s.formatter.init(s, this.options);
2317
+ this.options.interpolation.format = s.formatter.format.bind(s.formatter);
2318
+ }
2319
+
2133
2320
  s.interpolator = new Interpolator(this.options);
2134
2321
  s.utils = {
2135
2322
  hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
@@ -2166,6 +2353,9 @@ var I18n = function (_EventEmitter) {
2166
2353
  });
2167
2354
  }
2168
2355
 
2356
+ this.format = this.options.interpolation.format;
2357
+ if (!callback) callback = noop;
2358
+
2169
2359
  if (this.options.fallbackLng && !this.services.languageDetector && !this.options.lng) {
2170
2360
  var codes = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
2171
2361
  if (codes.length > 0 && codes[0] !== 'dev') this.options.lng = codes[0];
@@ -2303,6 +2493,10 @@ var I18n = function (_EventEmitter) {
2303
2493
  postProcessor.addPostProcessor(module);
2304
2494
  }
2305
2495
 
2496
+ if (module.type === 'formatter') {
2497
+ this.modules.formatter = module;
2498
+ }
2499
+
2306
2500
  if (module.type === '3rdParty') {
2307
2501
  this.modules.external.push(module);
2308
2502
  }
@@ -6,6 +6,7 @@ import _possibleConstructorReturn from '@babel/runtime/helpers/esm/possibleConst
6
6
  import _getPrototypeOf from '@babel/runtime/helpers/esm/getPrototypeOf';
7
7
  import _assertThisInitialized from '@babel/runtime/helpers/esm/assertThisInitialized';
8
8
  import _inherits from '@babel/runtime/helpers/esm/inherits';
9
+ import _slicedToArray from '@babel/runtime/helpers/esm/slicedToArray';
9
10
 
10
11
  var consoleLogger = {
11
12
  type: 'logger',
@@ -1614,6 +1615,124 @@ var Interpolator = function () {
1614
1615
  return Interpolator;
1615
1616
  }();
1616
1617
 
1618
+ function parseFormatStr(formatStr) {
1619
+ var formatName = formatStr.toLowerCase();
1620
+ var formatOptions = {};
1621
+
1622
+ if (formatStr.indexOf('(') > -1) {
1623
+ var p = formatStr.split('(');
1624
+ formatName = p[0].toLowerCase();
1625
+ var optStr = p[1].substring(0, p[1].length - 1);
1626
+
1627
+ if (formatName === 'currency' && optStr.indexOf(':') < 0) {
1628
+ if (!formatOptions.currency) formatOptions.currency = optStr.trim();
1629
+ } else if (formatName === 'relativetime' && optStr.indexOf(':') < 0) {
1630
+ if (!formatOptions.range) formatOptions.range = optStr.trim();
1631
+ } else {
1632
+ var opts = optStr.split(';');
1633
+ opts.forEach(function (opt) {
1634
+ if (!opt) return;
1635
+
1636
+ var _opt$split = opt.split(':'),
1637
+ _opt$split2 = _slicedToArray(_opt$split, 2),
1638
+ key = _opt$split2[0],
1639
+ val = _opt$split2[1];
1640
+
1641
+ if (val.trim() === 'false') formatOptions[key.trim()] = false;
1642
+ if (val.trim() === 'true') formatOptions[key.trim()] = true;
1643
+ if (!isNaN(val.trim())) formatOptions[key.trim()] = parseInt(val.trim(), 10);
1644
+ if (!formatOptions[key.trim()]) formatOptions[key.trim()] = val.trim();
1645
+ });
1646
+ }
1647
+ }
1648
+
1649
+ return {
1650
+ formatName: formatName,
1651
+ formatOptions: formatOptions
1652
+ };
1653
+ }
1654
+
1655
+ var Formatter = function () {
1656
+ function Formatter() {
1657
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1658
+
1659
+ _classCallCheck(this, Formatter);
1660
+
1661
+ this.logger = baseLogger.create('formatter');
1662
+ this.options = options;
1663
+ this.formats = {
1664
+ number: function number(val, lng, options) {
1665
+ return new Intl.NumberFormat(lng, options).format(val);
1666
+ },
1667
+ currency: function currency(val, lng, options) {
1668
+ return new Intl.NumberFormat(lng, _objectSpread({}, options, {
1669
+ style: 'currency'
1670
+ })).format(val);
1671
+ },
1672
+ datetime: function datetime(val, lng, options) {
1673
+ return new Intl.DateTimeFormat(lng, _objectSpread({}, options)).format(val);
1674
+ },
1675
+ relativetime: function relativetime(val, lng, options) {
1676
+ return new Intl.RelativeTimeFormat(lng, _objectSpread({}, options)).format(val, options.range || 'day');
1677
+ },
1678
+ list: function list(val, lng, options) {
1679
+ return new Intl.ListFormat(lng, _objectSpread({}, options)).format(val);
1680
+ }
1681
+ };
1682
+ this.init(options);
1683
+ }
1684
+
1685
+ _createClass(Formatter, [{
1686
+ key: "init",
1687
+ value: function init(services) {
1688
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
1689
+ interpolation: {}
1690
+ };
1691
+ var iOpts = options.interpolation;
1692
+ this.formatSeparator = iOpts.formatSeparator ? iOpts.formatSeparator : iOpts.formatSeparator || ',';
1693
+ }
1694
+ }, {
1695
+ key: "add",
1696
+ value: function add(name, fc) {
1697
+ this.formats[name] = fc;
1698
+ }
1699
+ }, {
1700
+ key: "format",
1701
+ value: function format(value, _format, lng, options) {
1702
+ var _this = this;
1703
+
1704
+ var formats = _format.split(this.formatSeparator);
1705
+
1706
+ var result = formats.reduce(function (mem, f) {
1707
+ var _parseFormatStr = parseFormatStr(f),
1708
+ formatName = _parseFormatStr.formatName,
1709
+ formatOptions = _parseFormatStr.formatOptions;
1710
+
1711
+ if (_this.formats[formatName]) {
1712
+ var formatted = mem;
1713
+
1714
+ try {
1715
+ var valOptions = options && options.formatParams && options.formatParams[options.interpolationkey] || {};
1716
+ var l = valOptions.locale || valOptions.lng || options.locale || options.lng || lng;
1717
+ formatted = _this.formats[formatName](mem, l, _objectSpread({}, formatOptions, options, valOptions));
1718
+ } catch (error) {
1719
+ _this.logger.warn(error);
1720
+ }
1721
+
1722
+ return formatted;
1723
+ } else {
1724
+ _this.logger.warn("there was no format function for ".concat(formatName));
1725
+ }
1726
+
1727
+ return mem;
1728
+ }, value);
1729
+ return result;
1730
+ }
1731
+ }]);
1732
+
1733
+ return Formatter;
1734
+ }();
1735
+
1617
1736
  function remove(arr, what) {
1618
1737
  var found = arr.indexOf(what);
1619
1738
 
@@ -1983,7 +2102,8 @@ var I18n = function (_EventEmitter) {
1983
2102
  }
1984
2103
  }
1985
2104
 
1986
- this.options = _objectSpread({}, get(), this.options, transformOptions(options));
2105
+ var defOpts = get();
2106
+ this.options = _objectSpread({}, defOpts, this.options, transformOptions(options));
1987
2107
 
1988
2108
  if (options.keySeparator !== undefined) {
1989
2109
  this.options.userDefinedKeySeparator = options.keySeparator;
@@ -1993,9 +2113,6 @@ var I18n = function (_EventEmitter) {
1993
2113
  this.options.userDefinedNsSeparator = options.nsSeparator;
1994
2114
  }
1995
2115
 
1996
- this.format = this.options.interpolation.format;
1997
- if (!callback) callback = noop;
1998
-
1999
2116
  function createClassOnDemand(ClassOrObject) {
2000
2117
  if (!ClassOrObject) return null;
2001
2118
  if (typeof ClassOrObject === 'function') return new ClassOrObject();
@@ -2009,6 +2126,14 @@ var I18n = function (_EventEmitter) {
2009
2126
  baseLogger.init(null, this.options);
2010
2127
  }
2011
2128
 
2129
+ var formatter;
2130
+
2131
+ if (this.modules.formatter) {
2132
+ formatter = this.modules.formatter;
2133
+ } else if (typeof Intl !== 'undefined') {
2134
+ formatter = Formatter;
2135
+ }
2136
+
2012
2137
  var lu = new LanguageUtil(this.options);
2013
2138
  this.store = new ResourceStore(this.options.resources, this.options);
2014
2139
  var s = this.services;
@@ -2020,6 +2145,13 @@ var I18n = function (_EventEmitter) {
2020
2145
  compatibilityJSON: this.options.compatibilityJSON,
2021
2146
  simplifyPluralSuffix: this.options.simplifyPluralSuffix
2022
2147
  });
2148
+
2149
+ if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
2150
+ s.formatter = createClassOnDemand(formatter);
2151
+ s.formatter.init(s, this.options);
2152
+ this.options.interpolation.format = s.formatter.format.bind(s.formatter);
2153
+ }
2154
+
2023
2155
  s.interpolator = new Interpolator(this.options);
2024
2156
  s.utils = {
2025
2157
  hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
@@ -2056,6 +2188,9 @@ var I18n = function (_EventEmitter) {
2056
2188
  });
2057
2189
  }
2058
2190
 
2191
+ this.format = this.options.interpolation.format;
2192
+ if (!callback) callback = noop;
2193
+
2059
2194
  if (this.options.fallbackLng && !this.services.languageDetector && !this.options.lng) {
2060
2195
  var codes = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
2061
2196
  if (codes.length > 0 && codes[0] !== 'dev') this.options.lng = codes[0];
@@ -2193,6 +2328,10 @@ var I18n = function (_EventEmitter) {
2193
2328
  postProcessor.addPostProcessor(module);
2194
2329
  }
2195
2330
 
2331
+ if (module.type === 'formatter') {
2332
+ this.modules.formatter = module;
2333
+ }
2334
+
2196
2335
  if (module.type === '3rdParty') {
2197
2336
  this.modules.external.push(module);
2198
2337
  }