@aemforms/af-formatters 0.22.26 → 0.22.30
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/lib/cjs/index.cjs +62 -239
- package/lib/esm/date/DateParser.js +52 -189
- package/lib/esm/date/SkeletonParser.js +39 -100
- package/lib/esm/date/index.js +20 -18
- package/lib/esm/index.js +34 -13
- package/lib/esm/number/NumberParser.js +34 -15
- package/lib/esm/number/SkeletonParser.js +75 -74
- package/lib/esm/number/currencies.js +24 -6
- package/package.json +11 -1
- package/lib/browser/afb-formatters.js +0 -950
|
@@ -1,61 +1,54 @@
|
|
|
1
|
-
|
|
1
|
+
/*************************************************************************
|
|
2
|
+
* ADOBE CONFIDENTIAL
|
|
3
|
+
* ___________________
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2022 Adobe
|
|
6
|
+
* All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* NOTICE: All information contained herein is, and remains
|
|
9
|
+
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
+
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
+
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
+
* property laws, including trade secret and copyright laws.
|
|
13
|
+
* Dissemination of this information or reproduction of this material
|
|
14
|
+
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
+
* from Adobe.
|
|
2
16
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
17
|
+
* Adobe permits you to use and modify this file solely in accordance with
|
|
18
|
+
* the terms of the Adobe license agreement accompanying it.
|
|
19
|
+
*************************************************************************/
|
|
6
20
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
currencySign : ['accounting', 'standard'],
|
|
12
|
-
localeMatcher : ['lookup', 'best fit'],
|
|
13
|
-
notation : ['standard', 'scientific', 'engineering', 'compact'],
|
|
14
|
-
numberingSystem :'' ,
|
|
15
|
-
signDisplay : ['auto', 'always', 'exceptZero', 'negative', 'never'],
|
|
16
|
-
style : ['decimal', 'currency', 'percent', 'unit'],
|
|
17
|
-
unit: '', //https://tc39.es/proposal-unified-intl-numberformat/section6/locales-currencies-tz_proposed_out.html#sec-issanctionedsimpleunitidentifier
|
|
18
|
-
unitDisplay : ['long', 'short', 'narrow'],
|
|
19
|
-
useGrouping : ['always', 'auto', 'min2', false, true],
|
|
20
|
-
roundingMode : '',
|
|
21
|
-
roundingPriority : '',
|
|
22
|
-
roundingIncrement : '',
|
|
23
|
-
trailingZeroDisplay : ['auto', 'stripIfInteger'],
|
|
24
|
-
minimumIntegerDigits : '',
|
|
25
|
-
minimumFractionDigits : '',
|
|
26
|
-
maximumFractionDigits : '',
|
|
27
|
-
minimumSignificantDigits : '',
|
|
28
|
-
maximumSignificantDigits : ''
|
|
29
|
-
}
|
|
21
|
+
import { getCurrency } from './currencies.js';
|
|
22
|
+
|
|
23
|
+
const NUMBER_REGEX =
|
|
24
|
+
/(?:[#]+|[@]+(#+)?|[0]+|[,]|[.]|[-]|[+]|[%]|[¤]{1,4}(?:\/([a-zA-Z]{3}))?|[;]|[K]{1,2}|E{1,2}[+]?|'(?:[^']|'')*')|[^a-zA-Z']+/g;
|
|
30
25
|
const supportedUnits = ['acre', 'bit', 'byte', 'celsius', 'centimeter', 'day',
|
|
31
26
|
'degree', 'fahrenheit', 'fluid-ounce', 'foot', 'gallon', 'gigabit',
|
|
32
27
|
'gigabyte', 'gram', 'hectare', 'hour', 'inch', 'kilobit', 'kilobyte',
|
|
33
28
|
'kilogram', 'kilometer', 'liter', 'megabit', 'megabyte', 'meter', 'mile',
|
|
34
29
|
'mile-scandinavian', 'milliliter', 'millimeter', 'millisecond', 'minute', 'month',
|
|
35
|
-
'ounce', 'percent', 'petabyte', 'pound', 'second', 'stone', 'terabit', 'terabyte', 'week', 'yard', 'year'].join('|')
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
export function parseNumberSkeleton(skeleton, language) {
|
|
40
|
-
const options = {}
|
|
30
|
+
'ounce', 'percent', 'petabyte', 'pound', 'second', 'stone', 'terabit', 'terabyte', 'week', 'yard', 'year'].join('|');
|
|
31
|
+
const ShorthandStyles = [/^currency(?:\/([a-zA-Z]{3}))?$/, /^decimal$/, /^integer$/, /^percent$/, new RegExp(`^unit\/(${supportedUnits})$`)];
|
|
32
|
+
function parseNumberSkeleton(skeleton, language) {
|
|
33
|
+
const options = {};
|
|
41
34
|
const order = [];
|
|
42
|
-
let match, index
|
|
35
|
+
let match, index;
|
|
43
36
|
for (index = 0; index < ShorthandStyles.length && match == null; index++) {
|
|
44
|
-
match = ShorthandStyles[index].exec(skeleton)
|
|
37
|
+
match = ShorthandStyles[index].exec(skeleton);
|
|
45
38
|
}
|
|
46
39
|
if (match) {
|
|
47
40
|
switch(index) {
|
|
48
41
|
case 1:
|
|
49
|
-
options.style = 'currency'
|
|
50
|
-
options.currencyDisplay = 'narrowSymbol'
|
|
42
|
+
options.style = 'currency';
|
|
43
|
+
options.currencyDisplay = 'narrowSymbol';
|
|
51
44
|
if (match[1]) {
|
|
52
|
-
options.currency = match[1]
|
|
45
|
+
options.currency = match[1];
|
|
53
46
|
} else {
|
|
54
|
-
options.currency = getCurrency(language)
|
|
47
|
+
options.currency = getCurrency(language);
|
|
55
48
|
}
|
|
56
49
|
break;
|
|
57
50
|
case 2:
|
|
58
|
-
|
|
51
|
+
new Intl.NumberFormat(language, {}).resolvedOptions();
|
|
59
52
|
options.minimumFractionDigits = options.minimumFractionDigits || 2;
|
|
60
53
|
break;
|
|
61
54
|
case 3:
|
|
@@ -63,7 +56,8 @@ export function parseNumberSkeleton(skeleton, language) {
|
|
|
63
56
|
options.maximumFractionDigits = 0;
|
|
64
57
|
break;
|
|
65
58
|
case 4:
|
|
66
|
-
options.style = 'percent'
|
|
59
|
+
options.style = 'percent';
|
|
60
|
+
options.maximumFractionDigits = 2;
|
|
67
61
|
break;
|
|
68
62
|
case 5:
|
|
69
63
|
options.style = "unit";
|
|
@@ -76,97 +70,104 @@ export function parseNumberSkeleton(skeleton, language) {
|
|
|
76
70
|
order
|
|
77
71
|
}
|
|
78
72
|
}
|
|
79
|
-
options.useGrouping = false
|
|
80
|
-
options.minimumIntegerDigits = 1
|
|
81
|
-
options.maximumFractionDigits = 0
|
|
82
|
-
options.minimumFractionDigits = 0
|
|
83
|
-
skeleton.replace(NUMBER_REGEX, (match, offset) => {
|
|
73
|
+
options.useGrouping = false;
|
|
74
|
+
options.minimumIntegerDigits = 1;
|
|
75
|
+
options.maximumFractionDigits = 0;
|
|
76
|
+
options.minimumFractionDigits = 0;
|
|
77
|
+
skeleton.replace(NUMBER_REGEX, (match, maxSignificantDigits, currencySymbol, offset) => {
|
|
84
78
|
const len = match.length;
|
|
85
79
|
switch(match[0]) {
|
|
86
80
|
case '#':
|
|
87
|
-
order.push(['digit', len])
|
|
81
|
+
order.push(['digit', len]);
|
|
88
82
|
if (options?.decimal === true) {
|
|
89
|
-
options.maximumFractionDigits = options.minimumFractionDigits + len
|
|
83
|
+
options.maximumFractionDigits = options.minimumFractionDigits + len;
|
|
90
84
|
}
|
|
91
85
|
break;
|
|
92
86
|
case '@':
|
|
93
87
|
if (options?.minimumSignificantDigits) {
|
|
94
88
|
throw "@ symbol should occur together"
|
|
95
89
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
options.maximumSignificantDigits = len
|
|
100
|
-
order.push(['digit', hashes.length])
|
|
90
|
+
const hashes = maxSignificantDigits || "";
|
|
91
|
+
order.push(['@', len - hashes.length]);
|
|
92
|
+
options.minimumSignificantDigits = len - hashes.length;
|
|
93
|
+
options.maximumSignificantDigits = len;
|
|
94
|
+
order.push(['digit', hashes.length]);
|
|
101
95
|
break;
|
|
102
96
|
case ',':
|
|
103
97
|
if (options?.decimal === true) {
|
|
104
98
|
throw "grouping character not supporting for fractions"
|
|
105
99
|
}
|
|
106
|
-
order.push(['group', 1])
|
|
100
|
+
order.push(['group', 1]);
|
|
107
101
|
options.useGrouping = 'auto';
|
|
108
102
|
break;
|
|
109
103
|
case '.':
|
|
110
104
|
if (options?.decimal) {
|
|
111
105
|
console.error("only one decimal symbol is allowed");
|
|
112
106
|
} else {
|
|
113
|
-
order.push(['decimal', 1])
|
|
107
|
+
order.push(['decimal', 1]);
|
|
114
108
|
options.decimal = true;
|
|
115
109
|
}
|
|
116
110
|
break;
|
|
117
111
|
case '0':
|
|
118
|
-
order.push('0', len)
|
|
112
|
+
order.push('0', len);
|
|
119
113
|
if(options.minimumSignificantDigits || options.maximumSignificantDigits) {
|
|
120
114
|
throw "0 is not supported with @"
|
|
121
115
|
}
|
|
122
116
|
if (options?.decimal === true) {
|
|
123
117
|
options.minimumFractionDigits = len;
|
|
118
|
+
if (!options.maximumFractionDigits) {
|
|
119
|
+
options.maximumFractionDigits = len;
|
|
120
|
+
}
|
|
124
121
|
} else {
|
|
125
|
-
options.minimumIntegerDigits = len
|
|
122
|
+
options.minimumIntegerDigits = len;
|
|
126
123
|
}
|
|
127
124
|
break;
|
|
128
125
|
case '-':
|
|
129
126
|
if (offset !== 0) {
|
|
130
|
-
console.error("sign display is always in the beginning")
|
|
127
|
+
console.error("sign display is always in the beginning");
|
|
131
128
|
}
|
|
132
|
-
options.signDisplay = 'negative'
|
|
133
|
-
order.push(['signDisplay', 1, '-'])
|
|
129
|
+
options.signDisplay = 'negative';
|
|
130
|
+
order.push(['signDisplay', 1, '-']);
|
|
134
131
|
break;
|
|
135
132
|
case '+':
|
|
136
133
|
if (offset !== 0 && order[order.length - 1][0] === 'E') {
|
|
137
|
-
console.error("sign display is always in the beginning")
|
|
134
|
+
console.error("sign display is always in the beginning");
|
|
138
135
|
}
|
|
139
136
|
if (offset === 0) {
|
|
140
|
-
options.signDisplay = 'always'
|
|
137
|
+
options.signDisplay = 'always';
|
|
141
138
|
}
|
|
142
|
-
order.push(['signDisplay', 1, '+'])
|
|
139
|
+
order.push(['signDisplay', 1, '+']);
|
|
143
140
|
break;
|
|
144
141
|
case '¤':
|
|
145
142
|
if (offset !== 0 && offset !== skeleton.length - 1) {
|
|
146
|
-
console.error("currency display should be either in the beginning or at the end")
|
|
143
|
+
console.error("currency display should be either in the beginning or at the end");
|
|
144
|
+
} else {
|
|
145
|
+
options.style = 'currency';
|
|
146
|
+
options.currencyDisplay = ['symbol', 'code', 'name', 'narrowSymbol'][len - 1];
|
|
147
|
+
options.currency = currencySymbol || getCurrency(language);
|
|
148
|
+
order.push(['currency', len]);
|
|
147
149
|
}
|
|
148
|
-
options.style = 'currency'
|
|
149
|
-
options.currencyDisplay = ['symbol', 'code', 'name', 'narrowSymbol'][len -1]
|
|
150
|
-
options.currency = getCurrency(language)
|
|
151
|
-
order.push(['currency', len])
|
|
152
150
|
break;
|
|
153
151
|
case '%':
|
|
154
152
|
if (offset !== 0 && offset !== skeleton.length - 1) {
|
|
155
|
-
console.error("percent display should be either in the beginning or at the end")
|
|
153
|
+
console.error("percent display should be either in the beginning or at the end");
|
|
154
|
+
} else {
|
|
155
|
+
order.push(['%', 1]);
|
|
156
|
+
options.style = 'percent';
|
|
156
157
|
}
|
|
157
|
-
order.push(['%', 1])
|
|
158
|
-
options.style = 'percent'
|
|
159
158
|
break;
|
|
160
159
|
case 'E':
|
|
161
|
-
order.push(['E', len])
|
|
162
|
-
options.style = ['scientific','engineering'](len - 1)
|
|
160
|
+
order.push(['E', len]);
|
|
161
|
+
options.style = ['scientific','engineering'](len - 1);
|
|
163
162
|
break;
|
|
164
163
|
default:
|
|
165
164
|
console.error("unknown chars" + match);
|
|
166
165
|
}
|
|
167
|
-
})
|
|
166
|
+
});
|
|
168
167
|
return {
|
|
169
168
|
options,
|
|
170
169
|
order
|
|
171
170
|
};
|
|
172
171
|
}
|
|
172
|
+
|
|
173
|
+
export { ShorthandStyles, parseNumberSkeleton };
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
/*************************************************************************
|
|
2
|
+
* ADOBE CONFIDENTIAL
|
|
3
|
+
* ___________________
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2022 Adobe
|
|
6
|
+
* All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* NOTICE: All information contained herein is, and remains
|
|
9
|
+
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
+
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
+
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
+
* property laws, including trade secret and copyright laws.
|
|
13
|
+
* Dissemination of this information or reproduction of this material
|
|
14
|
+
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
+
* from Adobe.
|
|
16
|
+
|
|
17
|
+
* Adobe permits you to use and modify this file solely in accordance with
|
|
18
|
+
* the terms of the Adobe license agreement accompanying it.
|
|
19
|
+
*************************************************************************/
|
|
20
|
+
|
|
1
21
|
const currencies = {
|
|
2
22
|
'da-DK': 'DKK',
|
|
3
23
|
'de-DE': 'EUR',
|
|
@@ -20,19 +40,17 @@ const currencies = {
|
|
|
20
40
|
'ru-RU': 'RUB',
|
|
21
41
|
'tr-TR': 'TRY'
|
|
22
42
|
};
|
|
23
|
-
|
|
24
|
-
const locales = Object.keys(currencies)
|
|
25
|
-
|
|
43
|
+
const locales = Object.keys(currencies);
|
|
26
44
|
const getCurrency = function (locale) {
|
|
27
45
|
if (locales.indexOf(locale) > -1) {
|
|
28
46
|
return currencies[locale]
|
|
29
47
|
} else {
|
|
30
|
-
const matchingLocale = locales.find(x => x.startsWith(locale))
|
|
48
|
+
const matchingLocale = locales.find(x => x.startsWith(locale));
|
|
31
49
|
if (matchingLocale) {
|
|
32
50
|
return currencies[matchingLocale]
|
|
33
51
|
}
|
|
34
52
|
}
|
|
35
53
|
return ''
|
|
36
|
-
}
|
|
54
|
+
};
|
|
37
55
|
|
|
38
|
-
export {getCurrency}
|
|
56
|
+
export { getCurrency };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aemforms/af-formatters",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.30",
|
|
4
4
|
"description": "Formatting Module for Forms Runtime",
|
|
5
5
|
"author": "Adobe Systems",
|
|
6
6
|
"license": "Adobe Proprietary",
|
|
@@ -27,6 +27,16 @@
|
|
|
27
27
|
"lib",
|
|
28
28
|
"LICENSE"
|
|
29
29
|
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"test": "NODE_OPTIONS=--experimental-vm-modules jest --silent",
|
|
32
|
+
"eslint": "npx eslint src/**",
|
|
33
|
+
"eslint:fix": "npx eslint --fix src/**",
|
|
34
|
+
"test:ci": "NODE_OPTIONS=--experimental-vm-modules jest --silent --coverage",
|
|
35
|
+
"build": "npm run clean && mkdir -p lib/esm && cp -R src/* lib/esm/ && rollup -c rollup.config.js",
|
|
36
|
+
"clean": "rm -rf lib target",
|
|
37
|
+
"prepublishOnly": "npm run build && npm run test",
|
|
38
|
+
"docs": "npx typedoc --options .typedoc.cjs"
|
|
39
|
+
},
|
|
30
40
|
"devDependencies": {
|
|
31
41
|
"@babel/cli": "^7.18.10",
|
|
32
42
|
"@babel/core": "^7.19.0",
|