@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.
@@ -1,97 +1,53 @@
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.
16
- **************************************************************************/
17
- /**
18
- * https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
19
- * Credit: https://git.corp.adobe.com/dc/dfl/blob/master/src/patterns/parseDateTimeSkeleton.js
20
- * Created a separate library to be used elsewhere as well.
21
- */
22
- const DATE_TIME_REGEX =
23
- // eslint-disable-next-line max-len
24
- /(?:[Eec]{1,6}|G{1,5}|[Qq]{1,5}|(?:[yYur]+|U{1,5})|[ML]{1,5}|d{1,2}|D{1,3}|F{1}|[abB]{1,5}|[hkHK]{1,2}|w{1,2}|W{1}|m{1,2}|s{1,2}|[zZOvV]{1,5}|[zZOvVxX]{1,3}|S{1,3}|'(?:[^']|'')*')|[^a-zA-Z']+/g;
25
-
26
- export const ShorthandStyles = ["full", "long", "medium", "short"]
27
-
28
- const testDate = new Date(2000, 2, 1, 2, 3, 4);
29
-
30
- /**
31
- * Since the formatted month names are different than standalone month names, we need to identify the correct option
32
- * to pass for formatting
33
- * @param value {string} formatted value of the month
34
- * @param language {string} language in which the month is formatted
35
- * @param isMediumFormatStyle {boolean} if shorthand style used for formatting was medium
36
- */
37
- function deduceMonthOption(value,
38
- language,
39
- isMediumFormatStyle) {
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.
40
16
 
41
- const formattedMarch = value;
42
- const longMarch = new Intl.DateTimeFormat(language, {month: 'long'}).formatToParts(testDate)[0].value;
43
- const shortMarch = new Intl.DateTimeFormat(language, {month: 'short'}).formatToParts(testDate)[0].value;
44
-
45
- const monthOptions = {
46
- [longMarch]: 'long',
47
- [shortMarch]: 'short',
48
- '03': '2-digit',
49
- '3': 'numeric'
50
- }
51
- if (formattedMarch !== undefined) {
52
- monthOptions[formattedMarch] = isMediumFormatStyle ? 'short' : 'long'
53
- }
54
- return monthOptions[value];
55
- }
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
+ *************************************************************************/
56
20
 
57
- export function getSkeleton(skeleton, language) {
21
+ const DATE_TIME_REGEX =
22
+ /(?:[Eec]{1,6}|G{1,5}|[Qq]{1,5}|(?:[yYur]+|U{1,5})|[ML]{1,5}|d{1,2}|D{1,3}|F{1}|[abB]{1,5}|[hkHK]{1,2}|w{1,2}|W{1}|m{1,2}|s{1,2}|[zZOvV]{1,5}|[zZOvVxX]{1,3}|S{1,3}|'(?:[^']|'')*')|[^a-zA-Z']+/g;
23
+ const ShorthandStyles = ["full", "long", "medium", "short"];
24
+ function getSkeleton(skeleton, language) {
58
25
  if (ShorthandStyles.find(type => skeleton.includes(type))) {
59
26
  const parsed = parseDateStyle(skeleton, language);
60
- const result = []
27
+ const result = [];
61
28
  const symbols = {
62
29
  month : 'M',
63
30
  year : 'Y',
64
31
  day : 'd'
65
- }
32
+ };
66
33
  parsed.forEach(([type, option, length]) => {
67
34
  if (type in symbols) {
68
- result.push(Array(length).fill(symbols[type]).join(''))
35
+ result.push(Array(length).fill(symbols[type]).join(''));
69
36
  } else if (type === 'literal') {
70
- result.push(option)
37
+ result.push(option);
71
38
  }
72
- })
39
+ });
73
40
  return result.join('');
74
41
  }
75
42
  return skeleton;
76
43
  }
77
-
78
- /**
79
- *
80
- * @param skeleton shorthand style for the date concatenated with shorthand style of time. The
81
- * Shorthand style for both date and time is one of ['full', 'long', 'medium', 'short'].
82
- * @param language {string} language to parse the date shorthand style
83
- * @returns {[*,string][]}
84
- */
85
44
  function parseDateStyle(skeleton, language) {
86
45
  const options = {};
87
- // the skeleton could have two keywords -- one for date, one for time
88
46
  const styles = skeleton.split(/\s/).filter(s => s.length);
89
47
  options.dateStyle = styles[0];
90
48
  if (styles.length > 1) options.timeStyle = styles[1];
91
-
92
49
  const testDate = new Date(2000, 2, 1, 2, 3, 4);
93
50
  const parts = new Intl.DateTimeFormat(language, options).formatToParts(testDate);
94
- // oddly, the formatted month name can be different from the standalone month name
95
51
  const formattedMarch = parts.find(p => p.type === 'month').value;
96
52
  const longMarch = new Intl.DateTimeFormat(language, {month: 'long'}).formatToParts(testDate)[0].value;
97
53
  const shortMarch = new Intl.DateTimeFormat(language, {month: 'short'}).formatToParts(testDate)[0].value;
@@ -115,12 +71,7 @@ function parseDateStyle(skeleton, language) {
115
71
  });
116
72
  return result;
117
73
  }
118
-
119
- /**
120
- * Parse Date time skeleton into Intl.DateTimeFormatOptions parts
121
- * Ref: https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
122
- */
123
- export function parseDateTimeSkeleton(skeleton, language) {
74
+ function parseDateTimeSkeleton(skeleton, language) {
124
75
  if (ShorthandStyles.find(type => skeleton.includes(type))) {
125
76
  return parseDateStyle(skeleton, language);
126
77
  }
@@ -128,11 +79,9 @@ export function parseDateTimeSkeleton(skeleton, language) {
128
79
  skeleton.replace(DATE_TIME_REGEX, match => {
129
80
  const len = match.length;
130
81
  switch (match[0]) {
131
- // Era
132
82
  case 'G':
133
83
  result.push(['era', len === 4 ? 'long' : len === 5 ? 'narrow' : 'short', len]);
134
84
  break;
135
- // Year
136
85
  case 'y':
137
86
  result.push(['year', len === 2 ? '2-digit' : 'numeric', len]);
138
87
  break;
@@ -143,16 +92,13 @@ export function parseDateTimeSkeleton(skeleton, language) {
143
92
  throw new RangeError(
144
93
  '`Y/u/U/r` (year) patterns are not supported, use `y` instead'
145
94
  );
146
- // Quarter
147
95
  case 'q':
148
96
  case 'Q':
149
97
  throw new RangeError('`q/Q` (quarter) patterns are not supported');
150
- // Month
151
98
  case 'M':
152
99
  case 'L':
153
100
  result.push(['month', ['numeric', '2-digit', 'short', 'long', 'narrow'][len - 1], len]);
154
101
  break;
155
- // Week
156
102
  case 'w':
157
103
  case 'W':
158
104
  throw new RangeError('`w/W` (week) patterns are not supported');
@@ -165,7 +111,6 @@ export function parseDateTimeSkeleton(skeleton, language) {
165
111
  throw new RangeError(
166
112
  '`D/F/g` (day) patterns are not supported, use `d` instead'
167
113
  );
168
- // Weekday
169
114
  case 'E':
170
115
  result.push(['weekday', ['short', 'short', 'short', 'long', 'narrow', 'narrow'][len - 1], len]);
171
116
  break;
@@ -181,16 +126,14 @@ export function parseDateTimeSkeleton(skeleton, language) {
181
126
  }
182
127
  result.push(['weekday', ['short', 'long', 'narrow', 'short'][len - 3], len]);
183
128
  break;
184
- // Period
185
- case 'a': // AM, PM
129
+ case 'a':
186
130
  result.push(['hour12', true, 1]);
187
131
  break;
188
- case 'b': // am, pm, noon, midnight
189
- case 'B': // flexible day periods
132
+ case 'b':
133
+ case 'B':
190
134
  throw new RangeError(
191
135
  '`b/B` (period) patterns are not supported, use `a` instead'
192
136
  );
193
- // Hour
194
137
  case 'h':
195
138
  result.push(['hourCycle', 'h12']);
196
139
  result.push(['hour', ['numeric', '2-digit'][len - 1], len]);
@@ -213,11 +156,9 @@ export function parseDateTimeSkeleton(skeleton, language) {
213
156
  throw new RangeError(
214
157
  '`j/J/C` (hour) patterns are not supported, use `h/H/K/k` instead'
215
158
  );
216
- // Minute
217
159
  case 'm':
218
160
  result.push(['minute', ['numeric', '2-digit'][len - 1], len]);
219
161
  break;
220
- // Second
221
162
  case 's':
222
163
  result.push(['second', ['numeric', '2-digit'][len - 1], len]);
223
164
  break;
@@ -228,23 +169,19 @@ export function parseDateTimeSkeleton(skeleton, language) {
228
169
  throw new RangeError(
229
170
  '`S/A` (millisecond) patterns are not supported, use `s` instead'
230
171
  );
231
- // Zone
232
- case 'O': // timeZone GMT-8 or GMT-08:00
172
+ case 'O':
233
173
  result.push(['timeZoneName', len < 4 ? 'shortOffset' : 'longOffset', len]);
234
174
  result.push(['x-timeZoneName', len < 4 ? 'O' : 'OOOO', len]);
235
175
  break;
236
- case 'X': // 1, 2, 3, 4: The ISO8601 varios formats
237
- case 'x': // 1, 2, 3, 4: The ISO8601 varios formats
238
- case 'Z': // 1..3, 4, 5: The ISO8601 varios formats
239
- // Z, ZZ, ZZZ should produce -0800
240
- // ZZZZ should produce GMT-08:00
241
- // ZZZZZ should produce -8:00 or -07:52:58
176
+ case 'X':
177
+ case 'x':
178
+ case 'Z':
242
179
  result.push(['timeZoneName', 'longOffset', 1]);
243
180
  result.push(['x-timeZoneName', match, 1]);
244
181
  break;
245
- case 'z': // 1..3, 4: specific non-location format
246
- case 'v': // 1, 4: generic non-location format
247
- case 'V': // 1, 2, 3, 4: time zone ID or city
182
+ case 'z':
183
+ case 'v':
184
+ case 'V':
248
185
  throw new RangeError(
249
186
  'z/v/V` (timeZone) patterns are not supported, use `X/x/Z/O` instead'
250
187
  );
@@ -258,3 +195,5 @@ export function parseDateTimeSkeleton(skeleton, language) {
258
195
  });
259
196
  return result;
260
197
  }
198
+
199
+ export { ShorthandStyles, getSkeleton, parseDateTimeSkeleton };
@@ -1,20 +1,22 @@
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.
16
- **************************************************************************/
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.
17
16
 
18
- import { parseDate, formatDate } from './DateParser.js';
19
- import {getSkeleton} from "./SkeletonParser.js";
20
- export {parseDate, formatDate, getSkeleton}
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
+
21
+ export { formatDate, parseDate } from './DateParser.js';
22
+ export { getSkeleton } from './SkeletonParser.js';
package/lib/esm/index.js CHANGED
@@ -1,17 +1,39 @@
1
- import {parseDate, formatDate, getSkeleton as parseDateSkeleton} from "./date/index.js";
2
- import {parseNumber, formatNumber} from "./number/NumberParser.js"
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
+
21
+ import { formatDate, parseDate } from './date/DateParser.js';
22
+ export { getSkeleton as parseDateSkeleton } from './date/SkeletonParser.js';
23
+ import { formatNumber, parseNumber } from './number/NumberParser.js';
24
+ import './number/SkeletonParser.js';
25
+ import './number/currencies.js';
3
26
 
4
27
  const getCategory = function (skeleton) {
5
28
  const chkCategory = skeleton?.match(/^(?:(num|date)\|)?(.+)/);
6
29
  return [chkCategory?.[1], chkCategory?.[2]]
7
- }
8
-
9
- export const format = function (value, locale, skeleton, timezone) {
10
- const [category, skelton] = getCategory(skeleton)
30
+ };
31
+ const format = function (value, locale, skeleton, timezone) {
32
+ const [category, skelton] = getCategory(skeleton);
11
33
  switch (category) {
12
34
  case 'date':
13
35
  if (!(value instanceof Date)) {
14
- value = new Date(value)
36
+ value = new Date(value);
15
37
  }
16
38
  return formatDate(value, locale, skelton, timezone)
17
39
  case 'num':
@@ -19,10 +41,9 @@ export const format = function (value, locale, skeleton, timezone) {
19
41
  default:
20
42
  throw `unable to deduce the format. The skeleton should be date|<format> for date formats and num|<format> for numbers`
21
43
  }
22
- }
23
-
24
- export const parse = function (value, locale, skeleton, timezone) {
25
- const [category, skelton] = getCategory(skeleton)
44
+ };
45
+ const parse = function (value, locale, skeleton, timezone) {
46
+ const [category, skelton] = getCategory(skeleton);
26
47
  switch (category) {
27
48
  case 'date':
28
49
  return parseDate(value, locale, skelton, timezone)
@@ -31,6 +52,6 @@ export const parse = function (value, locale, skeleton, timezone) {
31
52
  default:
32
53
  throw `unable to deduce the format. The skeleton should be date|<format> for date formats and num|<format> for numbers`
33
54
  }
34
- }
55
+ };
35
56
 
36
- export {parseDate, formatDate, parseDateSkeleton, parseNumber, formatNumber}
57
+ export { format, formatDate, formatNumber, parse, parseDate, parseNumber };
@@ -1,34 +1,51 @@
1
- import {parseNumberSkeleton} from "./SkeletonParser.js";
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
- export function formatNumber(numberValue, language, skeletn) {
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
+
21
+ import { parseNumberSkeleton } from './SkeletonParser.js';
22
+ import './currencies.js';
23
+
24
+ function formatNumber(numberValue, language, skeletn) {
25
+ if (skeletn.startsWith('num|')) {
26
+ skeletn = skel.split('|')[1];
27
+ }
4
28
  if (!skeletn) return numberValue
5
- language = language || "en"
29
+ language = language || "en";
6
30
  const {options, order} = parseNumberSkeleton(skeletn, language);
7
31
  return new Intl.NumberFormat(language, options).format(numberValue);
8
32
  }
9
-
10
33
  function getMetaInfo(language, skel) {
11
34
  const parts = {};
12
- // gather digits and radix symbol
13
35
  let options = new Intl.NumberFormat(language, {style:'decimal', useGrouping:false}).formatToParts(9876543210.1);
14
36
  parts.digits = options.find(p => p.type === 'integer').value.split('').reverse();
15
37
  parts.decimal = options.find(p => p.type === 'decimal').value;
16
-
17
- // extract type values from the parts
18
38
  const gather = type => {
19
39
  const find = options.find(p => p.type === type);
20
40
  if (find) parts[type] = find.value;
21
41
  };
22
- // now gather the localized parts that correspond to the provided skeleton.
23
42
  const parsed = parseNumberSkeleton(skel);
24
43
  const nf = new Intl.NumberFormat(language, parsed);
25
44
  options = nf.formatToParts(-987654321);
26
45
  gather('group');
27
46
  gather('minusSign');
28
47
  gather('percentSign');
29
- // it's possible to have multiple currency representations in a single value
30
48
  parts.currency = options.filter(p => p.type === 'currency').map(p => p.value);
31
- // collect all literals. Most likely a literal is an accounting bracket
32
49
  parts.literal = options.filter(p => p.type === 'literal').map(p => p.value);
33
50
  options = nf.formatToParts(987654321);
34
51
  gather('plusSign');
@@ -36,10 +53,11 @@ function getMetaInfo(language, skel) {
36
53
  gather('unit');
37
54
  return parts;
38
55
  }
39
-
40
- export function parseNumber(numberString, language, skel) {
56
+ function parseNumber(numberString, language, skel) {
41
57
  try {
42
- // factor will be updated to reflect: negative, percent, exponent etc.
58
+ if (skel.startsWith('num|')) {
59
+ skel = skel.split('|')[1];
60
+ }
43
61
  let factor = 1;
44
62
  let number = numberString;
45
63
  const meta = getMetaInfo(language, skel);
@@ -74,8 +92,9 @@ export function parseNumber(numberString, language, skel) {
74
92
  return numberString;
75
93
  }
76
94
  }
77
-
78
- export function parseDefaultNumber(numberString, language) {
95
+ function parseDefaultNumber(numberString, language) {
79
96
  const currency = currencies[language] || 'USD';
80
97
  return parseNumber(numberString, language, `currency/${currency}`);
81
98
  }
99
+
100
+ export { formatNumber, parseDefaultNumber, parseNumber };