-
-
Notifications
You must be signed in to change notification settings - Fork 627
/
Formatter.js
116 lines (98 loc) · 3.38 KB
/
Formatter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import baseLogger from './logger.js';
function parseFormatStr(formatStr) {
let formatName = formatStr.toLowerCase().trim();
let formatOptions = {};
if (formatStr.indexOf('(') > -1) {
const p = formatStr.split('(');
formatName = p[0].toLowerCase().trim();
const optStr = p[1].substring(0, p[1].length - 1);
// extra for currency
if (formatName === 'currency' && optStr.indexOf(':') < 0) {
if (!formatOptions.currency) formatOptions.currency = optStr.trim();
} else if (formatName === 'relativetime' && optStr.indexOf(':') < 0) {
if (!formatOptions.range) formatOptions.range = optStr.trim();
} else {
const opts = optStr.split(';');
opts.forEach((opt) => {
if (!opt) return;
const [key, ...rest] = opt.split(':');
const val = rest
.join(':')
.trim()
.replace(/^'+|'+$/g, ''); // trim and replace ''
if (!formatOptions[key.trim()]) formatOptions[key.trim()] = val;
if (val === 'false') formatOptions[key.trim()] = false;
if (val === 'true') formatOptions[key.trim()] = true;
if (!isNaN(val)) formatOptions[key.trim()] = parseInt(val, 10);
});
}
}
return {
formatName,
formatOptions,
};
}
class Formatter {
constructor(options = {}) {
this.logger = baseLogger.create('formatter');
this.options = options;
this.formats = {
number: (val, lng, options) => {
return new Intl.NumberFormat(lng, options).format(val);
},
currency: (val, lng, options) => {
return new Intl.NumberFormat(lng, { ...options, style: 'currency' }).format(val);
},
datetime: (val, lng, options) => {
return new Intl.DateTimeFormat(lng, { ...options }).format(val);
},
relativetime: (val, lng, options) => {
return new Intl.RelativeTimeFormat(lng, { ...options }).format(val, options.range || 'day');
},
list: (val, lng, options) => {
return new Intl.ListFormat(lng, { ...options }).format(val);
},
};
this.init(options);
}
/* eslint no-param-reassign: 0 */
init(services, options = { interpolation: {} }) {
const iOpts = options.interpolation;
this.formatSeparator = iOpts.formatSeparator
? iOpts.formatSeparator
: iOpts.formatSeparator || ',';
}
add(name, fc) {
this.formats[name.toLowerCase().trim()] = fc;
}
format(value, format, lng, options) {
const formats = format.split(this.formatSeparator);
const result = formats.reduce((mem, f) => {
const { formatName, formatOptions } = parseFormatStr(f);
if (this.formats[formatName]) {
let formatted = mem;
try {
// options passed explicit for that formatted value
const valOptions =
(options && options.formatParams && options.formatParams[options.interpolationkey]) ||
{};
// language
const l = valOptions.locale || valOptions.lng || options.locale || options.lng || lng;
formatted = this.formats[formatName](mem, l, {
...formatOptions,
...options,
...valOptions,
});
} catch (error) {
this.logger.warn(error);
}
return formatted;
} else {
this.logger.warn(`there was no format function for ${formatName}`);
}
return mem;
}, value);
return result;
}
}
export default Formatter;