@automattic/number-formatters 1.0.0-alpha.1

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.
@@ -0,0 +1,317 @@
1
+ import debugFactory from 'debug';
2
+ import { FALLBACK_CURRENCY } from '../constants.js';
3
+ import { getCachedFormatter } from '../get-cached-formatter.js';
4
+ import { defaultCurrencyOverrides } from './currencies.js';
5
+ const debug = debugFactory('number-formatters:number-format-currency');
6
+ /**
7
+ * Retrieves the currency override for a given currency.
8
+ * If the currency is USD and the user is not in the US, it will return `US$`.
9
+ * @param currency - The currency to get the override for.
10
+ * @param geoLocation - The geo location of the user.
11
+ * @return {CurrencyOverride | undefined} The currency override.
12
+ */
13
+ function getCurrencyOverride(currency, geoLocation) {
14
+ if (currency === 'USD' && geoLocation && geoLocation !== '' && geoLocation !== 'US') {
15
+ return { symbol: 'US$' };
16
+ }
17
+ return defaultCurrencyOverrides[currency];
18
+ }
19
+ /**
20
+ * Returns a valid currency code based on a shortlist of currency codes.
21
+ * Only currencies from the shortlist are allowed. Everything else will fall back to `FALLBACK_CURRENCY`.
22
+ * @param currency - The currency to get the valid currency for.
23
+ * @param geoLocation - The geo location of the user.
24
+ * @return {string} The valid currency.
25
+ */
26
+ function getValidCurrency(currency, geoLocation) {
27
+ if (!getCurrencyOverride(currency, geoLocation)) {
28
+ debug(`getValidCurrency was called with a non-existent currency "${currency}"; falling back to ${FALLBACK_CURRENCY}`);
29
+ return FALLBACK_CURRENCY;
30
+ }
31
+ return currency;
32
+ }
33
+ /**
34
+ * Returns a currency formatter for a given currency.
35
+ * @param params - The parameters for the currency formatter.
36
+ * @param params.number - The number to format.
37
+ * @param params.currency - The currency to format.
38
+ * @param params.browserSafeLocale - The browser safe locale.
39
+ * @param params.forceLatin - Whether to force the latin locale.
40
+ * @param params.stripZeros - Whether to strip zeros.
41
+ * @param params.signForPositive - Whether to show the sign for positive numbers.
42
+ * @return {Intl.NumberFormat} The currency formatter.
43
+ */
44
+ function getCurrencyFormatter({ number, currency, browserSafeLocale, forceLatin = true, stripZeros, signForPositive, }) {
45
+ /**
46
+ * `numberingSystem` is an option to `Intl.NumberFormat` and is available
47
+ * in all major browsers according to
48
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
49
+ * but is not part of the TypeScript types in `es2020`:
50
+ *
51
+ * https://github.com/microsoft/TypeScript/blob/cfd472f7aa5a2010a3115263bf457b30c5b489f3/src/lib/es2020.intl.d.ts#L272
52
+ *
53
+ * However, it is part of the TypeScript types in `es5`:
54
+ *
55
+ * https://github.com/microsoft/TypeScript/blob/cfd472f7aa5a2010a3115263bf457b30c5b489f3/src/lib/es5.d.ts#L4310
56
+ *
57
+ * Apparently calypso uses `es2020` so we cannot use that option here right
58
+ * now. Instead, we will use the unicode extension to the locale, documented
59
+ * here:
60
+ *
61
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/numberingSystem#adding_a_numbering_system_via_the_locale_string
62
+ */
63
+ const locale = `${browserSafeLocale}${forceLatin ? '-u-nu-latn' : ''}`;
64
+ const numberFormatOptions = {
65
+ style: 'currency',
66
+ currency,
67
+ ...(stripZeros &&
68
+ Number.isInteger(number) && {
69
+ /**
70
+ * There's an option called `trailingZeroDisplay` but it does not yet work
71
+ * in FF so we have to strip zeros manually.
72
+ */
73
+ maximumFractionDigits: 0,
74
+ minimumFractionDigits: 0,
75
+ }),
76
+ ...(signForPositive && { signDisplay: 'exceptZero' }),
77
+ };
78
+ return getCachedFormatter({
79
+ locale,
80
+ options: numberFormatOptions,
81
+ });
82
+ }
83
+ /**
84
+ * Returns the precision for a given locale and currency.
85
+ * @param browserSafeLocale - The browser safe locale.
86
+ * @param currency - The currency to get the precision for.
87
+ * @param forceLatin - Whether to force the latin locale.
88
+ * @return {number | undefined} The precision.
89
+ */
90
+ function getPrecisionForLocaleAndCurrency(browserSafeLocale, currency, forceLatin) {
91
+ const formatter = getCurrencyFormatter({ number: 0, currency, browserSafeLocale, forceLatin });
92
+ /**
93
+ * For regular numbers, the default is 3 if neither `minimumFractionDigits` or `maximumFractionDigits` are set,
94
+ * otherwise the greatest betweem `minimumFractionDigits` and 3.
95
+ *
96
+ * For currencies, the default is dependent on the currency.
97
+ *
98
+ * This may also result in undefined, for several reasons:
99
+ * see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#significantdigitsfractiondigits_default_values
100
+ */
101
+ return formatter.resolvedOptions().maximumFractionDigits;
102
+ }
103
+ /**
104
+ * Scales a number to a specified precision and rounds it to that precision.
105
+ * It ensures that all currency values are consistently rounded to the desired precision,
106
+ * avoiding issues with floating-point arithmetic.
107
+ * @param number - The number to scale.
108
+ * @param currencyPrecision - The precision to scale the number to.
109
+ * @return {number} The scaled number.
110
+ */
111
+ function scaleNumberForPrecision(number, currencyPrecision) {
112
+ const scale = Math.pow(10, currencyPrecision);
113
+ return Math.round(number * scale) / scale;
114
+ }
115
+ /**
116
+ * Prepares a number for formatting.
117
+ * @param number - The number to prepare.
118
+ * @param currencyPrecision - The precision to prepare the number for.
119
+ * @param isSmallestUnit - Whether the number is the smallest unit of a currency.
120
+ * @return {number} The prepared number.
121
+ */
122
+ function prepareNumberForFormatting(number,
123
+ // currencyPrecision here must be the precision of the currency, regardless
124
+ // of what precision is requested for display!
125
+ currencyPrecision, isSmallestUnit) {
126
+ if (isNaN(number)) {
127
+ debug('formatCurrency was called with NaN');
128
+ return 0;
129
+ }
130
+ if (isSmallestUnit) {
131
+ if (!Number.isInteger(number)) {
132
+ debug('formatCurrency was called with isSmallestUnit and a float which will be rounded', number);
133
+ }
134
+ const smallestUnitDivisor = 10 ** currencyPrecision;
135
+ return scaleNumberForPrecision(Math.round(number) / smallestUnitDivisor, currencyPrecision);
136
+ }
137
+ return scaleNumberForPrecision(number, currencyPrecision);
138
+ }
139
+ /**
140
+ * Formats money with a given currency code.
141
+ *
142
+ * The currency will define the properties to use for this formatting, but
143
+ * those properties can be overridden using the options. Be careful when doing
144
+ * this.
145
+ *
146
+ * For currencies that include decimals, this will always return the amount
147
+ * with decimals included, even if those decimals are zeros. To exclude the
148
+ * zeros, use the `stripZeros` option. For example, the function will normally
149
+ * format `10.00` in `USD` as `$10.00` but when this option is true, it will
150
+ * return `$10` instead.
151
+ *
152
+ * Since rounding errors are common in floating point math, sometimes a price
153
+ * is provided as an integer in the smallest unit of a currency (eg: cents in
154
+ * USD or yen in JPY). Set the `isSmallestUnit` to change the function to
155
+ * operate on integer numbers instead. If this option is not set or false, the
156
+ * function will format the amount `1025` in `USD` as `$1,025.00`, but when the
157
+ * option is true, it will return `$10.25` instead.
158
+ *
159
+ * If the number is NaN, it will be treated as 0.
160
+ *
161
+ * If the currency code is not known, this will assume a default currency
162
+ * similar to USD.
163
+ *
164
+ * If `isSmallestUnit` is set and the number is not an integer, it will be
165
+ * rounded to an integer.
166
+ *
167
+ * @param params - The parameters for the currency formatter.
168
+ * @param params.number - The number to format.
169
+ * @param params.browserSafeLocale - The browser safe locale.
170
+ * @param params.currency - The currency to format.
171
+ * @param params.stripZeros - Whether to strip zeros.
172
+ * @param params.isSmallestUnit - Whether the number is the smallest unit of a currency.
173
+ * @param params.signForPositive - Whether to show the sign for positive numbers.
174
+ * @param params.geoLocation - The geo location of the user.
175
+ * @param params.forceLatin - Whether to force the latin locale.
176
+ * @return {string} A formatted string.
177
+ */
178
+ const numberFormatCurrency = ({ number, browserSafeLocale, currency, stripZeros, isSmallestUnit, signForPositive, geoLocation, forceLatin, }) => {
179
+ const validCurrency = getValidCurrency(currency, geoLocation);
180
+ const currencyOverride = getCurrencyOverride(validCurrency, geoLocation);
181
+ const currencyPrecision = getPrecisionForLocaleAndCurrency(browserSafeLocale, validCurrency, forceLatin);
182
+ if (isSmallestUnit && typeof currencyPrecision === 'undefined') {
183
+ throw new Error(`Could not determine currency precision for ${validCurrency} in ${browserSafeLocale}`);
184
+ }
185
+ const numberAsFloat = prepareNumberForFormatting(number, currencyPrecision ?? 0, isSmallestUnit);
186
+ const formatter = getCurrencyFormatter({
187
+ number: numberAsFloat,
188
+ currency: validCurrency,
189
+ browserSafeLocale,
190
+ forceLatin,
191
+ stripZeros,
192
+ signForPositive,
193
+ });
194
+ const parts = formatter.formatToParts(numberAsFloat);
195
+ return parts.reduce((formatted, part) => {
196
+ switch (part.type) {
197
+ case 'currency':
198
+ if (currencyOverride?.symbol) {
199
+ return formatted + currencyOverride.symbol;
200
+ }
201
+ return formatted + part.value;
202
+ default:
203
+ return formatted + part.value;
204
+ }
205
+ }, '');
206
+ };
207
+ /**
208
+ * Returns a formatted price object which can be used to manually render a
209
+ * formatted currency (eg: if you wanted to render the currency symbol in a
210
+ * different font size).
211
+ *
212
+ * The currency will define the properties to use for this formatting, but
213
+ * those properties can be overridden using the options. Be careful when doing
214
+ * this.
215
+ *
216
+ * For currencies that include decimals, this will always return the amount
217
+ * with decimals included, even if those decimals are zeros. To exclude the
218
+ * zeros, use the `stripZeros` option. For example, the function will normally
219
+ * format `10.00` in `USD` as `$10.00` but when this option is true, it will
220
+ * return `$10` instead.
221
+ *
222
+ * Since rounding errors are common in floating point math, sometimes a price
223
+ * is provided as an integer in the smallest unit of a currency (eg: cents in
224
+ * USD or yen in JPY). Set the `isSmallestUnit` to change the function to
225
+ * operate on integer numbers instead. If this option is not set or false, the
226
+ * function will format the amount `1025` in `USD` as `$1,025.00`, but when the
227
+ * option is true, it will return `$10.25` instead.
228
+ *
229
+ * Note that the `integer` return value of this function is not a number, but a
230
+ * locale-formatted string which may include symbols like spaces, commas, or
231
+ * periods as group separators. Similarly, the `fraction` property is a string
232
+ * that contains the decimal separator.
233
+ *
234
+ * If the number is NaN, it will be treated as 0.
235
+ *
236
+ * If the currency code is not known, this will assume a default currency
237
+ * similar to USD.
238
+ *
239
+ * If `isSmallestUnit` is set and the number is not an integer, it will be
240
+ * rounded to an integer.
241
+ *
242
+ * @param params - The parameters for the currency formatter.
243
+ * @param params.number - The number to format.
244
+ * @param params.browserSafeLocale - The browser safe locale.
245
+ * @param params.currency - The currency to format.
246
+ * @param params.stripZeros - Whether to strip zeros.
247
+ * @param params.isSmallestUnit - Whether the number is the smallest unit of a currency.
248
+ * @param params.signForPositive - Whether to show the sign for positive numbers.
249
+ * @param params.geoLocation - The geo location of the user.
250
+ * @param params.forceLatin - Whether to force the latin locale.
251
+ * @return {CurrencyObject} A formatted string e.g. { symbol:'$', integer: '$99', fraction: '.99', sign: '-' }
252
+ */
253
+ const getCurrencyObject = ({ number, browserSafeLocale, currency, stripZeros, isSmallestUnit, signForPositive, geoLocation, forceLatin, }) => {
254
+ const validCurrency = getValidCurrency(currency, geoLocation);
255
+ const currencyOverride = getCurrencyOverride(validCurrency, geoLocation);
256
+ const currencyPrecision = getPrecisionForLocaleAndCurrency(browserSafeLocale, validCurrency, forceLatin);
257
+ const numberAsFloat = prepareNumberForFormatting(number, currencyPrecision ?? 0, isSmallestUnit);
258
+ const formatter = getCurrencyFormatter({
259
+ number: numberAsFloat,
260
+ currency: validCurrency,
261
+ browserSafeLocale,
262
+ forceLatin,
263
+ stripZeros,
264
+ signForPositive,
265
+ });
266
+ const parts = formatter.formatToParts(numberAsFloat);
267
+ let sign = '';
268
+ let symbol = '$';
269
+ let symbolPosition = 'before';
270
+ let hasAmountBeenSet = false;
271
+ let hasDecimalBeenSet = false;
272
+ let integer = '';
273
+ let fraction = '';
274
+ parts.forEach(part => {
275
+ switch (part.type) {
276
+ case 'currency':
277
+ symbol = currencyOverride?.symbol ?? part.value;
278
+ if (hasAmountBeenSet) {
279
+ symbolPosition = 'after';
280
+ }
281
+ return;
282
+ case 'group':
283
+ integer += part.value;
284
+ hasAmountBeenSet = true;
285
+ return;
286
+ case 'decimal':
287
+ fraction += part.value;
288
+ hasAmountBeenSet = true;
289
+ hasDecimalBeenSet = true;
290
+ return;
291
+ case 'integer':
292
+ integer += part.value;
293
+ hasAmountBeenSet = true;
294
+ return;
295
+ case 'fraction':
296
+ fraction += part.value;
297
+ hasAmountBeenSet = true;
298
+ hasDecimalBeenSet = true;
299
+ return;
300
+ case 'minusSign':
301
+ sign = '-';
302
+ return;
303
+ case 'plusSign':
304
+ sign = '+';
305
+ }
306
+ });
307
+ const hasNonZeroFraction = !Number.isInteger(numberAsFloat) && hasDecimalBeenSet;
308
+ return {
309
+ sign,
310
+ symbol,
311
+ symbolPosition,
312
+ integer,
313
+ fraction,
314
+ hasNonZeroFraction,
315
+ };
316
+ };
317
+ export { numberFormatCurrency, getCurrencyObject };
@@ -0,0 +1,22 @@
1
+ import type { NumberFormatParams } from './types.js';
2
+ /**
3
+ * Formats numbers using locale settings and/or passed options.
4
+ * @param params - The parameters for the number formatter.
5
+ * @param params.browserSafeLocale - The browser safe locale.
6
+ * @param params.decimals - The number of decimal places to use.
7
+ * @param params.forceLatin - Whether to force the latin locale.
8
+ * @param params.numberFormatOptions - The options for the number formatter.
9
+ * @return {Intl.NumberFormat} The number formatter.
10
+ */
11
+ declare const numberFormat: ({ browserSafeLocale, decimals, forceLatin, numberFormatOptions, }: NumberFormatParams) => Intl.NumberFormat;
12
+ /**
13
+ * Convenience method for formatting numbers in a compact notation e.g. 1K, 1M, etc.
14
+ * Basically sets `notation: 'compact'` and `maximumFractionDigits: 1` in the options.
15
+ * Everything is overridable by passing the `numberFormatOptions` option.
16
+ * If you want more digits, pass `maximumFractionDigits: 2`.
17
+ * @param params - The parameters for the number formatter.
18
+ * @param params.numberFormatOptions - The options for the number formatter.
19
+ * @return {Intl.NumberFormat} The number formatter.
20
+ */
21
+ declare const numberFormatCompact: typeof numberFormat;
22
+ export { numberFormat, numberFormatCompact };
@@ -0,0 +1,55 @@
1
+ import { getCachedFormatter } from './get-cached-formatter.js';
2
+ /**
3
+ * Formats numbers using locale settings and/or passed options.
4
+ * @param params - The parameters for the number formatter.
5
+ * @param params.browserSafeLocale - The browser safe locale.
6
+ * @param params.decimals - The number of decimal places to use.
7
+ * @param params.forceLatin - Whether to force the latin locale.
8
+ * @param params.numberFormatOptions - The options for the number formatter.
9
+ * @return {Intl.NumberFormat} The number formatter.
10
+ */
11
+ const numberFormat = ({ browserSafeLocale, decimals = 0, forceLatin = true, numberFormatOptions = {}, }) => {
12
+ /**
13
+ * `numberingSystem` is an option to `Intl.NumberFormat` and is available
14
+ * in all major browsers according to
15
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
16
+ * but is not part of the TypeScript types in `es2020`:
17
+ *
18
+ * https://github.com/microsoft/TypeScript/blob/cfd472f7aa5a2010a3115263bf457b30c5b489f3/src/lib/es2020.intl.d.ts#L272
19
+ *
20
+ * However, it is part of the TypeScript types in `es5`:
21
+ *
22
+ * https://github.com/microsoft/TypeScript/blob/cfd472f7aa5a2010a3115263bf457b30c5b489f3/src/lib/es5.d.ts#L4310
23
+ *
24
+ * Apparently calypso uses `es2020` so we cannot use that option here right
25
+ * now. Instead, we will use the unicode extension to the locale, documented
26
+ * here:
27
+ *
28
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/numberingSystem#adding_a_numbering_system_via_the_locale_string
29
+ */
30
+ const locale = `${browserSafeLocale}${forceLatin ? '-u-nu-latn' : ''}`;
31
+ const options = {
32
+ minimumFractionDigits: decimals, // minimumFractionDigits default is 0
33
+ maximumFractionDigits: decimals, // maximumFractionDigits default is the greater between minimumFractionDigits and 3
34
+ ...numberFormatOptions,
35
+ };
36
+ return getCachedFormatter({ locale, options });
37
+ };
38
+ /**
39
+ * Convenience method for formatting numbers in a compact notation e.g. 1K, 1M, etc.
40
+ * Basically sets `notation: 'compact'` and `maximumFractionDigits: 1` in the options.
41
+ * Everything is overridable by passing the `numberFormatOptions` option.
42
+ * If you want more digits, pass `maximumFractionDigits: 2`.
43
+ * @param params - The parameters for the number formatter.
44
+ * @param params.numberFormatOptions - The options for the number formatter.
45
+ * @return {Intl.NumberFormat} The number formatter.
46
+ */
47
+ const numberFormatCompact = ({ numberFormatOptions = {}, ...params }) => numberFormat({
48
+ ...params,
49
+ numberFormatOptions: {
50
+ notation: 'compact',
51
+ maximumFractionDigits: 1,
52
+ ...numberFormatOptions,
53
+ },
54
+ });
55
+ export { numberFormat, numberFormatCompact };
@@ -0,0 +1,109 @@
1
+ export interface NumberFormatParams {
2
+ /**
3
+ * Browser-safe locale string that works with Intl.NumberFormat e.g. 'en-US' (not 'en_US').
4
+ */
5
+ browserSafeLocale: string;
6
+ /**
7
+ * Number of decimal places to use.
8
+ * This is just convenience over setting `minimumFractionDigits`, `maximumFractionDigits` to the same value.
9
+ * ( default = 0 )
10
+ */
11
+ decimals?: number;
12
+ /**
13
+ * Whether to use latin numbers by default ( default = true ).
14
+ */
15
+ forceLatin?: boolean;
16
+ /**
17
+ * `Intl.NumberFormat` options to pass through.
18
+ * `minimumFractionDigits` & `maximumFractionDigits` will override `decimals` if set.
19
+ */
20
+ numberFormatOptions?: Intl.NumberFormatOptions;
21
+ }
22
+ export interface CurrencyOverride {
23
+ symbol?: string;
24
+ }
25
+ export interface NumberFormatCurrencyParams {
26
+ /**
27
+ * Number to format.
28
+ */
29
+ number: number;
30
+ /**
31
+ * Browser-safe locale string that works with Intl.NumberFormat e.g. 'en-US' (not 'en_US').
32
+ */
33
+ browserSafeLocale: string;
34
+ /**
35
+ * Currency code.
36
+ */
37
+ currency: string;
38
+ /**
39
+ * Whether to use latin numbers by default ( default = true ).
40
+ */
41
+ forceLatin?: boolean;
42
+ /**
43
+ * The user's geo location if available.
44
+ */
45
+ geoLocation?: string;
46
+ /**
47
+ * Forces any decimal zeros to be hidden if set.
48
+ *
49
+ * For example, the function will normally format `10.00` in `USD` as
50
+ * `$10.00` but when this option is true, it will return `$10` instead.
51
+ *
52
+ * For currencies without decimals (eg: JPY), this has no effect.
53
+ */
54
+ stripZeros?: boolean;
55
+ /**
56
+ * Changes function to treat number as an integer in the currency's smallest unit.
57
+ *
58
+ * Since rounding errors are common in floating point math, sometimes a price
59
+ * is provided as an integer in the smallest unit of a currency (eg: cents in
60
+ * USD or yen in JPY). If this option is false, the function will format the
61
+ * amount `1025` in `USD` as `$1,025.00`, but when the option is true, it
62
+ * will return `$10.25` instead.
63
+ */
64
+ isSmallestUnit?: boolean;
65
+ /**
66
+ * If the number is greater than 0, setting this to true will include its
67
+ * sign (eg: `+$35.00`). Has no effect on negative numbers or 0.
68
+ */
69
+ signForPositive?: boolean;
70
+ }
71
+ export interface CurrencyObject {
72
+ /**
73
+ * The negative sign for the price, if it is negative, or the positive sign
74
+ * if `signForPositive` is set.
75
+ */
76
+ sign: '-' | '+' | '';
77
+ /**
78
+ * The currency symbol for the formatted price.
79
+ *
80
+ * Note that the symbol's position depends on the `symbolPosition` property,
81
+ * and keep RTL locales in mind.
82
+ */
83
+ symbol: string;
84
+ /**
85
+ * The position of the currency symbol relative to the formatted price.
86
+ */
87
+ symbolPosition: 'before' | 'after';
88
+ /**
89
+ * The section of the formatted price before the decimal.
90
+ *
91
+ * Note that this is not a number, but a locale-formatted string which may
92
+ * include symbols like spaces, commas, or periods as group separators.
93
+ */
94
+ integer: string;
95
+ /**
96
+ * The section of the formatted price after and including the decimal.
97
+ *
98
+ * Note that this is not a number, but a locale-formatted string which may
99
+ * include symbols like spaces, commas, or periods as the decimal separator.
100
+ */
101
+ fraction: string;
102
+ /**
103
+ * True if the formatted number has a non-0 decimal part.
104
+ */
105
+ hasNonZeroFraction: boolean;
106
+ }
107
+ export type FormatNumber = (number: number, options?: Omit<NumberFormatParams, 'browserSafeLocale'>) => string;
108
+ export type FormatCurrency = (number: number, currency: string, options?: Omit<NumberFormatCurrencyParams, 'number' | 'currency' | 'browserSafeLocale' | 'geoLocation'>) => string;
109
+ export type GetCurrencyObject = (number: number, currency: string, options?: Omit<NumberFormatCurrencyParams, 'number' | 'currency' | 'browserSafeLocale' | 'geoLocation'>) => CurrencyObject;
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@automattic/number-formatters",
3
+ "version": "1.0.0-alpha.1",
4
+ "description": "Number formatting utilities",
5
+ "author": "Automattic",
6
+ "license": "GPL-2.0-or-later",
7
+ "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/number-formatters/#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/Automattic/jetpack.git",
11
+ "directory": "projects/js-packages/number-formatters"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Automattic/jetpack/labels/[JS Package] Number Formatters"
15
+ },
16
+ "dependencies": {
17
+ "@babel/runtime": "^7",
18
+ "@wordpress/date": "5.19.0",
19
+ "debug": "4.4.0"
20
+ },
21
+ "devDependencies": {
22
+ "@babel/core": "7.26.10",
23
+ "@babel/preset-react": "7.26.3",
24
+ "@jest/globals": "29.4.3",
25
+ "@types/jest": "29.5.14",
26
+ "jest": "29.7.0",
27
+ "jest-environment-jsdom": "29.7.0",
28
+ "typescript": "5.8.2"
29
+ },
30
+ "type": "module",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "default": "./dist/index.js"
35
+ }
36
+ },
37
+ "scripts": {
38
+ "build": "pnpm run clean && pnpm run compile-ts",
39
+ "clean": "rm -rf dist/",
40
+ "compile-ts": "tsc --pretty",
41
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest",
42
+ "test-coverage": "pnpm run test --coverage",
43
+ "typecheck": "tsc --noEmit"
44
+ }
45
+ }
@@ -0,0 +1,2 @@
1
+ export const FALLBACK_LOCALE = 'en';
2
+ export const FALLBACK_CURRENCY = 'USD';