@qrvey/utils 1.3.1 → 1.3.2

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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/dates/helpers/isValidDateObject.d.ts +6 -0
  3. package/dist/cjs/dates/helpers/isValidDateObject.js +12 -0
  4. package/dist/cjs/dates/range/getDateRange.js +10 -3
  5. package/dist/cjs/filters/helpers/common/mergeFilters.js +2 -2
  6. package/dist/cjs/format/definition.d.ts +62 -0
  7. package/dist/cjs/format/definition.js +18 -1
  8. package/dist/cjs/format/duration/addDurationFormat.d.ts +13 -0
  9. package/dist/cjs/format/duration/addDurationFormat.js +20 -0
  10. package/dist/cjs/format/duration/durationFormatter.d.ts +79 -0
  11. package/dist/cjs/format/duration/durationFormatter.js +156 -0
  12. package/dist/cjs/format/duration/index.d.ts +2 -0
  13. package/dist/cjs/format/duration/index.js +18 -0
  14. package/dist/cjs/format/index.d.ts +1 -0
  15. package/dist/cjs/format/index.js +1 -0
  16. package/dist/dates/helpers/isValidDateObject.d.ts +6 -0
  17. package/dist/dates/helpers/isValidDateObject.js +8 -0
  18. package/dist/dates/range/getDateRange.js +10 -3
  19. package/dist/filters/helpers/common/mergeFilters.js +2 -2
  20. package/dist/format/definition.d.ts +62 -0
  21. package/dist/format/definition.js +17 -0
  22. package/dist/format/duration/addDurationFormat.d.ts +13 -0
  23. package/dist/format/duration/addDurationFormat.js +16 -0
  24. package/dist/format/duration/durationFormatter.d.ts +79 -0
  25. package/dist/format/duration/durationFormatter.js +152 -0
  26. package/dist/format/duration/index.d.ts +2 -0
  27. package/dist/format/duration/index.js +2 -0
  28. package/dist/format/index.d.ts +1 -0
  29. package/dist/format/index.js +1 -0
  30. package/package.json +1 -1
  31. package/src/dates/helpers/isValidDateObject.ts +9 -0
  32. package/src/dates/range/getDateRange.ts +13 -3
  33. package/src/filters/helpers/common/mergeFilters.ts +2 -2
  34. package/src/format/definition.ts +19 -0
  35. package/src/format/duration/addDurationFormat.ts +17 -0
  36. package/src/format/duration/durationFormatter.ts +169 -0
  37. package/src/format/duration/index.ts +2 -0
  38. package/src/format/index.ts +1 -0
  39. package/test/format/addDurationFormat.test.js +39 -0
  40. package/test/format/addDurationFormatWithLocale.test.js +11 -0
  41. package/test/format/durationFormatterClass.test.js +45 -0
@@ -0,0 +1,79 @@
1
+ export declare class DurationFormatter {
2
+ private options;
3
+ private parts;
4
+ private valueFormatter;
5
+ private numberFactor;
6
+ private template;
7
+ private numberFormatOptions;
8
+ /**
9
+ * The constructor function takes in a template string and an options object. It then sets the
10
+ * options object to the default options object if no options object is passed in. It then parses
11
+ * the template string and sets the parts to the parsed template string. It then tries to set the
12
+ * valueFormatter to a new Intl.NumberFormat object with the locale and fractionDigits options. If
13
+ * it fails, it sets the valueFormatter to a new Intl.NumberFormat object with the default locale
14
+ * and fractionDigits options. It then sets the numberFactor to the duration parts object with the
15
+ * name of the unit option. If it can't find the unit option, it sets the numberFactor to 1
16
+ * @param [template] - The template string that will be used to format the duration.
17
+ * @param options - This is an object that contains the following properties: unit, locale and fractionDigits
18
+ */
19
+ constructor(options: {
20
+ template: string;
21
+ options?: {
22
+ unit?: string;
23
+ locale?: string;
24
+ fractionDigits?: number;
25
+ };
26
+ intlNumberFormat?: Intl.NumberFormat;
27
+ });
28
+ private setOptions;
29
+ /**
30
+ * It sets the locale formatter for the number.
31
+ */
32
+ private setLocaleFormatter;
33
+ /**
34
+ * It returns a new instance of the Intl.NumberFormat class, which is a built-in JavaScript class
35
+ * that formats numbers
36
+ * @param {string | string[]} locale - string | string[]
37
+ * @returns A new instance of the Intl.NumberFormat class.
38
+ */
39
+ private getNewNumberFormat;
40
+ /**
41
+ * It takes a template string and sets the parts property to the result of calling the
42
+ * parseFormatTemplate function with the template string as an argument
43
+ * @param {string} template - The format template string.
44
+ */
45
+ private setParts;
46
+ /**
47
+ * It replaces the H and D characters in the template with h and d respectively
48
+ * @param {string} template - The template string to be used for the date format.
49
+ * @returns The template string with all instances of H replaced with h and all instances of D
50
+ * replaced with d.
51
+ */
52
+ private matchFormatsReplace;
53
+ /**
54
+ * It sets the numberFactor to the value of the duration part that matches the unit.
55
+ */
56
+ private setNumberFactor;
57
+ /**
58
+ * It takes a string, splits it into an array of strings, then maps each string to a config object,
59
+ * then filters out any falsy values, then reverses the array
60
+ * @param {string} template - string - the template string that we want to parse
61
+ * @returns An array of objects that have the order and the name of the part of the duration.
62
+ */
63
+ private parseFormatTemplate;
64
+ /**
65
+ * It takes a number, multiplies it by a factor, then uses the parts array to calculate the number
66
+ * of each part in the number, then uses the template to format the number
67
+ * @param {number} number - The number of milliseconds to format.
68
+ * @returns The template string with the values replaced.
69
+ */
70
+ format(number: number): string;
71
+ /**
72
+ * It takes a dictionary of values and a list of keys, and returns a formatted string
73
+ * @param parts - { [x: string]: any; }
74
+ * @param {string | (string | number)[]} part - This is the part of the date that we're
75
+ * formatting.
76
+ * @returns The value of the part of the date that is being formatted.
77
+ */
78
+ private formatValue;
79
+ }
@@ -0,0 +1,152 @@
1
+ import { isEmpty } from "../../general/mix/isEmpty";
2
+ import { DEFAULT_OPTIONS, DURATION_PARTS, PARTS_REGEX } from "../definition";
3
+ /* It takes a template string and a number of milliseconds and returns a string that is formatted to
4
+ the user's preference
5
+ this class is based on moment format:
6
+ years: Y or y
7
+ months: M
8
+ weeks: W or w
9
+ days: D or d
10
+ hours: H or h
11
+ minutes: m
12
+ seconds: s
13
+ ms: S
14
+ */
15
+ export class DurationFormatter {
16
+ /**
17
+ * The constructor function takes in a template string and an options object. It then sets the
18
+ * options object to the default options object if no options object is passed in. It then parses
19
+ * the template string and sets the parts to the parsed template string. It then tries to set the
20
+ * valueFormatter to a new Intl.NumberFormat object with the locale and fractionDigits options. If
21
+ * it fails, it sets the valueFormatter to a new Intl.NumberFormat object with the default locale
22
+ * and fractionDigits options. It then sets the numberFactor to the duration parts object with the
23
+ * name of the unit option. If it can't find the unit option, it sets the numberFactor to 1
24
+ * @param [template] - The template string that will be used to format the duration.
25
+ * @param options - This is an object that contains the following properties: unit, locale and fractionDigits
26
+ */
27
+ constructor(options) {
28
+ this.numberFormatOptions = {
29
+ minimumFractionDigits: DEFAULT_OPTIONS.fractionDigits,
30
+ maximumFractionDigits: DEFAULT_OPTIONS.fractionDigits
31
+ };
32
+ this.setOptions(options.options);
33
+ this.setParts(options.template);
34
+ this.setLocaleFormatter(options.intlNumberFormat);
35
+ this.setNumberFactor();
36
+ }
37
+ setOptions(options) {
38
+ this.options = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
39
+ }
40
+ /**
41
+ * It sets the locale formatter for the number.
42
+ */
43
+ setLocaleFormatter(intlNumberFormat) {
44
+ try {
45
+ if (intlNumberFormat) {
46
+ console.log(intlNumberFormat.resolvedOptions());
47
+ this.valueFormatter = intlNumberFormat;
48
+ }
49
+ else {
50
+ this.valueFormatter = this.getNewNumberFormat(this.options.locale);
51
+ }
52
+ }
53
+ catch (e) {
54
+ if (intlNumberFormat) {
55
+ this.valueFormatter = intlNumberFormat;
56
+ }
57
+ else {
58
+ this.valueFormatter = this.getNewNumberFormat(DEFAULT_OPTIONS.locale);
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * It returns a new instance of the Intl.NumberFormat class, which is a built-in JavaScript class
64
+ * that formats numbers
65
+ * @param {string | string[]} locale - string | string[]
66
+ * @returns A new instance of the Intl.NumberFormat class.
67
+ */
68
+ getNewNumberFormat(locale) {
69
+ return new Intl.NumberFormat(locale, this.numberFormatOptions);
70
+ }
71
+ /**
72
+ * It takes a template string and sets the parts property to the result of calling the
73
+ * parseFormatTemplate function with the template string as an argument
74
+ * @param {string} template - The format template string.
75
+ */
76
+ setParts(template) {
77
+ this.template = this.matchFormatsReplace(template);
78
+ this.parts = this.parseFormatTemplate(template);
79
+ }
80
+ /**
81
+ * It replaces the H and D characters in the template with h and d respectively
82
+ * @param {string} template - The template string to be used for the date format.
83
+ * @returns The template string with all instances of H replaced with h and all instances of D
84
+ * replaced with d.
85
+ */
86
+ matchFormatsReplace(template) {
87
+ return isEmpty(template) ? template : template.replace(/H/g, 'h');
88
+ }
89
+ /**
90
+ * It sets the numberFactor to the value of the duration part that matches the unit.
91
+ */
92
+ setNumberFactor() {
93
+ var _a;
94
+ this.numberFactor = ((_a = Object.values(DURATION_PARTS).find((d) => d.name === this.options.unit)) === null || _a === void 0 ? void 0 : _a.ms) || 1;
95
+ }
96
+ /**
97
+ * It takes a string, splits it into an array of strings, then maps each string to a config object,
98
+ * then filters out any falsy values, then reverses the array
99
+ * @param {string} template - string - the template string that we want to parse
100
+ * @returns An array of objects that have the order and the name of the part of the duration.
101
+ */
102
+ parseFormatTemplate(template) {
103
+ this.template = isEmpty(template) ? '' : template;
104
+ return (this.template.match(PARTS_REGEX) || [])
105
+ .reduce((store, part) => {
106
+ const config = DURATION_PARTS[part[0]];
107
+ if (config)
108
+ store[config.order] = config;
109
+ return store;
110
+ }, [])
111
+ .filter(Boolean)
112
+ .reverse();
113
+ }
114
+ /**
115
+ * It takes a number, multiplies it by a factor, then uses the parts array to calculate the number
116
+ * of each part in the number, then uses the template to format the number
117
+ * @param {number} number - The number of milliseconds to format.
118
+ * @returns The template string with the values replaced.
119
+ */
120
+ format(number) {
121
+ if (number === null)
122
+ return null;
123
+ if (number === undefined || this.template === undefined || isNaN(number))
124
+ return undefined;
125
+ if (isEmpty(number))
126
+ return "";
127
+ number *= this.numberFactor;
128
+ const durationParts = this.parts.reduce((store, part) => {
129
+ store[part.symbol] = number / part.ms;
130
+ number %= part.ms;
131
+ return store;
132
+ }, {});
133
+ if (!Number.isInteger(number))
134
+ return number === null ? null : this.valueFormatter.format(number).padStart(this.parts.length, "0");
135
+ if (isEmpty(this.template))
136
+ return this.valueFormatter.format(number).padStart(this.parts.length, "0");
137
+ return this.template.replace(PARTS_REGEX, (match, $1) => {
138
+ return $1 || this.formatValue(durationParts, match);
139
+ });
140
+ }
141
+ /**
142
+ * It takes a dictionary of values and a list of keys, and returns a formatted string
143
+ * @param parts - { [x: string]: any; }
144
+ * @param {string | (string | number)[]} part - This is the part of the date that we're
145
+ * formatting.
146
+ * @returns The value of the part of the date that is being formatted.
147
+ */
148
+ formatValue(parts, part) {
149
+ const value = parts[part[0]];
150
+ return this.valueFormatter.format(value).padStart(part.length, "0");
151
+ }
152
+ }
@@ -0,0 +1,2 @@
1
+ export * from './durationFormatter';
2
+ export * from './addDurationFormat';
@@ -0,0 +1,2 @@
1
+ export * from './durationFormatter';
2
+ export * from './addDurationFormat';
@@ -1,2 +1,3 @@
1
1
  export * from './format';
2
2
  export * from './localization';
3
+ export * from './duration/index';
@@ -1,2 +1,3 @@
1
1
  export * from './format';
2
2
  export * from './localization';
3
+ export * from './duration/index';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qrvey/utils",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Helper, Utils for all Qrvey Projects",
5
5
  "homepage": "https://bitbucket.org/qrvey/qrvey_utils/wiki/Home",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,9 @@
1
+
2
+ /**
3
+ * If the date is a valid Date object, return true, otherwise return false.
4
+ * @param {Date} date - The date object to check.
5
+ * @returns A boolean value.
6
+ */
7
+ export function isValidDateObject(date: Date): boolean {
8
+ return date instanceof Date && !isNaN(date.getTime());
9
+ }
@@ -1,5 +1,6 @@
1
1
  import { capitalize } from "../../general/string/capitalize";
2
2
  import { isTokenLabel } from "../../tokens/isTokenLabel";
3
+ import { isValidDateObject } from "../helpers/isValidDateObject";
3
4
 
4
5
  /**
5
6
  * Get date range object from a string date value
@@ -107,9 +108,18 @@ function getStringTimeRange(value: string, dateGroupLabel: string) {
107
108
  }
108
109
  }
109
110
 
110
- function getStringDate(dt: Date) {
111
- if (dt.getTime() !== dt.getTime()) return '01/01/0000';
112
- return `${('0' + (dt.getMonth() + 1)).slice(-2)}/${('0' + dt.getDate()).slice(-2)}/${dt.getFullYear()}`;
111
+
112
+ /**
113
+ * It takes a Date object as an argument and returns a string in the format of MM/DD/YYYY
114
+ * @param {Date} dt - Date - The date object to convert to a string
115
+ * @returns A string in the format of MM/DD/YYYY
116
+ */
117
+ function getStringDate(dt: Date):string {
118
+ if(isValidDateObject(dt)){
119
+ return `${('0' + (dt.getMonth() + 1)).slice(-2)}/${('0' + dt.getDate()).slice(-2)}/${dt.getFullYear()}`;
120
+ }
121
+
122
+ return '01/01/0000';
113
123
  }
114
124
 
115
125
  function getYearRange(value: string) {
@@ -52,7 +52,7 @@ function mergeScopes(scopes1: IFSScope[] = [], scopes2: IFSScope[] = [], setting
52
52
  const scope2Index = scopes2.findIndex(scope2 => resolveScopeConditions(scope2, { scope: scope1.scope, scopeid: scope1.scopeid }));
53
53
  if (scope2Index > -1) {
54
54
  scope1 = {
55
- ...scope1,
55
+ ...scopes2[scope2Index],
56
56
  datasets: mergeDatasets(scope1.datasets, scopes2[scope2Index].datasets, settings)
57
57
  };
58
58
  scopes2.splice(scope2Index, 1);
@@ -77,7 +77,7 @@ function mergeDatasets(datasets1: IFSDataset[] = [], datasets2: IFSDataset[] = [
77
77
  const dataset2Index = datasets2.findIndex(dataset2 => resolveDatasetConditions(dataset2, { qrveyid: dataset1.qrveyid, linkid: dataset1.linkid }));
78
78
  if (dataset2Index > -1) {
79
79
  dataset1 = {
80
- ...dataset1,
80
+ ...datasets2[dataset2Index],
81
81
  filters: mergeFilterss(dataset1.filters, datasets2[dataset2Index].filters, settings)
82
82
  };
83
83
  datasets2.splice(dataset2Index, 1);
@@ -105,3 +105,22 @@ export const LANG_DEFAULT = 'en-US';
105
105
  export const CURRENCY_DEFAULT = { text: '$ (USD)', label: 'USD' };
106
106
  export const DATETIME_OPTIONS = { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' };
107
107
 
108
+ export const PARTS_REGEX = /\[([^\]]+)]|Y{1,2}|M{1,2}|W{1,2}|D{1,2}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}/g;
109
+
110
+ export const DURATION_PARTS = {
111
+ S: { order: 1, symbol: "S", name: "milliseconds", ms: 1 },
112
+ s: { order: 2, symbol: "s", name: "seconds", ms: 1000 },
113
+ m: { order: 3, symbol: "m", name: "minutes", ms: 1000 * 60 },
114
+ h: { order: 4, symbol: "h", name: "hours", ms: 1000 * 60 * 60 },
115
+ H: { order: 5, symbol: "H", name: "hours", ms: 1000 * 60 * 60 },
116
+ D: { order: 6, symbol: "D", name: "days", ms: 1000 * 60 * 60 * 24 },
117
+ W: { order: 7, symbol: "W", name: "weeks", ms: 1000 * 60 * 60 * 24 * 7 },
118
+ M: { order: 8, symbol: "M", name: "months", ms: 1000 * 60 * 60 * 24 * 30 },
119
+ Y: { order: 9, symbol: "Y", name: "years", ms: 1000 * 60 * 60 * 24 * 365 },
120
+ };
121
+
122
+ export const DEFAULT_OPTIONS = {
123
+ unit: "seconds",
124
+ locale: "en-EN",
125
+ fractionDigits: 0
126
+ };
@@ -0,0 +1,17 @@
1
+ import { DurationFormatter } from "./durationFormatter";
2
+
3
+ /**[TODO: The decimals dots are not working correctly, we need to reviewing (fractionDigits)]
4
+ * "Convert a number of seconds to a human readable string."
5
+ *
6
+ * `addDurationFormat` is a function that takes a number, a format, an optional locale, and an optional
7
+ * number of fraction digits, and returns a string
8
+ * @param {number} number - The number of milliseconds to format.
9
+ * @param {string} format - The format string.
10
+ * @param {string} [locale] - The locale to use for formatting. If not specified, the default locale is
11
+ * used.
12
+ * @param {number} [fractionDigits] - The number of digits to show after the decimal point.
13
+ * @returns A string
14
+ */
15
+ export function addDurationFormat(number: number, format: string, locale?: string, fractionDigits?: number): string {
16
+ return new DurationFormatter( { template: format, options: { locale: locale, fractionDigits: fractionDigits } }).format(number);
17
+ }
@@ -0,0 +1,169 @@
1
+ import { isEmpty } from "../../general/mix/isEmpty";
2
+ import { DEFAULT_OPTIONS, DURATION_PARTS, PARTS_REGEX } from "../definition";
3
+
4
+ /* It takes a template string and a number of milliseconds and returns a string that is formatted to
5
+ the user's preference
6
+ this class is based on moment format:
7
+ years: Y or y
8
+ months: M
9
+ weeks: W or w
10
+ days: D or d
11
+ hours: H or h
12
+ minutes: m
13
+ seconds: s
14
+ ms: S
15
+ */
16
+ export class DurationFormatter {
17
+
18
+ private options: { unit?: string; locale?: string; fractionDigits?: number; };
19
+ private parts: any;
20
+ private valueFormatter: Intl.NumberFormat;
21
+ private numberFactor: number;
22
+ private template: string;
23
+ private numberFormatOptions = {
24
+ minimumFractionDigits: DEFAULT_OPTIONS.fractionDigits,
25
+ maximumFractionDigits: DEFAULT_OPTIONS.fractionDigits
26
+ };
27
+
28
+ /**
29
+ * The constructor function takes in a template string and an options object. It then sets the
30
+ * options object to the default options object if no options object is passed in. It then parses
31
+ * the template string and sets the parts to the parsed template string. It then tries to set the
32
+ * valueFormatter to a new Intl.NumberFormat object with the locale and fractionDigits options. If
33
+ * it fails, it sets the valueFormatter to a new Intl.NumberFormat object with the default locale
34
+ * and fractionDigits options. It then sets the numberFactor to the duration parts object with the
35
+ * name of the unit option. If it can't find the unit option, it sets the numberFactor to 1
36
+ * @param [template] - The template string that will be used to format the duration.
37
+ * @param options - This is an object that contains the following properties: unit, locale and fractionDigits
38
+ */
39
+ constructor(options:{ template: string, options?: { unit?: string; locale?: string; fractionDigits?: number; }, intlNumberFormat?: Intl.NumberFormat }) {
40
+ this.setOptions(options.options);
41
+ this.setParts(options.template);
42
+ this.setLocaleFormatter(options.intlNumberFormat);
43
+ this.setNumberFactor();
44
+ }
45
+
46
+ private setOptions(options: { unit?: string; locale?: string; fractionDigits?: number; }){
47
+ this.options = { ...DEFAULT_OPTIONS, ...options };
48
+ }
49
+
50
+ /**
51
+ * It sets the locale formatter for the number.
52
+ */
53
+ private setLocaleFormatter(intlNumberFormat: Intl.NumberFormat){
54
+
55
+ try{
56
+ if(intlNumberFormat){
57
+ console.log(intlNumberFormat.resolvedOptions());
58
+ this.valueFormatter = intlNumberFormat;
59
+ }else{
60
+ this.valueFormatter = this.getNewNumberFormat(this.options.locale);
61
+ }
62
+ }catch(e){
63
+ if(intlNumberFormat){
64
+ this.valueFormatter = intlNumberFormat;
65
+ }else{
66
+ this.valueFormatter = this.getNewNumberFormat(DEFAULT_OPTIONS.locale);
67
+ }
68
+
69
+ }
70
+ }
71
+
72
+ /**
73
+ * It returns a new instance of the Intl.NumberFormat class, which is a built-in JavaScript class
74
+ * that formats numbers
75
+ * @param {string | string[]} locale - string | string[]
76
+ * @returns A new instance of the Intl.NumberFormat class.
77
+ */
78
+ private getNewNumberFormat(locale: string | string[]){
79
+ return new Intl.NumberFormat(locale, this.numberFormatOptions);
80
+ }
81
+
82
+ /**
83
+ * It takes a template string and sets the parts property to the result of calling the
84
+ * parseFormatTemplate function with the template string as an argument
85
+ * @param {string} template - The format template string.
86
+ */
87
+ private setParts(template: string){
88
+ this.template = this.matchFormatsReplace(template);
89
+ this.parts = this.parseFormatTemplate(template);
90
+ }
91
+
92
+ /**
93
+ * It replaces the H and D characters in the template with h and d respectively
94
+ * @param {string} template - The template string to be used for the date format.
95
+ * @returns The template string with all instances of H replaced with h and all instances of D
96
+ * replaced with d.
97
+ */
98
+ private matchFormatsReplace(template: string){
99
+ return isEmpty(template) ? template: template.replace(/H/g, 'h');
100
+ }
101
+
102
+ /**
103
+ * It sets the numberFactor to the value of the duration part that matches the unit.
104
+ */
105
+ private setNumberFactor(){
106
+ this.numberFactor = Object.values(DURATION_PARTS).find((d) => d.name === this.options.unit)?.ms || 1;
107
+ }
108
+
109
+ /**
110
+ * It takes a string, splits it into an array of strings, then maps each string to a config object,
111
+ * then filters out any falsy values, then reverses the array
112
+ * @param {string} template - string - the template string that we want to parse
113
+ * @returns An array of objects that have the order and the name of the part of the duration.
114
+ */
115
+ private parseFormatTemplate(template: string) {
116
+ this.template = isEmpty(template)? '': template;
117
+ return (this.template.match(PARTS_REGEX) || [])
118
+ .reduce((store, part) => {
119
+ const config = DURATION_PARTS[part[0]];
120
+ if (config) store[config.order] = config;
121
+ return store;
122
+ }, [])
123
+ .filter(Boolean)
124
+ .reverse();
125
+ }
126
+
127
+
128
+
129
+ /**
130
+ * It takes a number, multiplies it by a factor, then uses the parts array to calculate the number
131
+ * of each part in the number, then uses the template to format the number
132
+ * @param {number} number - The number of milliseconds to format.
133
+ * @returns The template string with the values replaced.
134
+ */
135
+ public format(number: number): string {
136
+ if(number === null) return null;
137
+ if(number === undefined || this.template === undefined || isNaN(number)) return undefined;
138
+ if(isEmpty(number)) return "";
139
+
140
+ number *= this.numberFactor;
141
+
142
+ const durationParts = this.parts.reduce((store, part) => {
143
+ store[part.symbol] = number / part.ms;
144
+ number %= part.ms;
145
+ return store;
146
+ }, {});
147
+
148
+ if(!Number.isInteger(number)) return number === null? null: this.valueFormatter.format(number).padStart(this.parts.length, "0");
149
+ if(isEmpty(this.template)) return this.valueFormatter.format(number).padStart(this.parts.length, "0");
150
+
151
+ return this.template.replace(PARTS_REGEX, (match, $1) => {
152
+ return $1 || this.formatValue(durationParts, match);
153
+ });
154
+ }
155
+
156
+
157
+
158
+ /**
159
+ * It takes a dictionary of values and a list of keys, and returns a formatted string
160
+ * @param parts - { [x: string]: any; }
161
+ * @param {string | (string | number)[]} part - This is the part of the date that we're
162
+ * formatting.
163
+ * @returns The value of the part of the date that is being formatted.
164
+ */
165
+ private formatValue(parts: { [x: string]: any; }, part: string | (string | number)[]): string {
166
+ const value = parts[part[0]];
167
+ return this.valueFormatter.format(value).padStart(part.length, "0");
168
+ }
169
+ }
@@ -0,0 +1,2 @@
1
+ export * from './durationFormatter';
2
+ export * from './addDurationFormat';
@@ -1,2 +1,3 @@
1
1
  export * from './format';
2
2
  export * from './localization';
3
+ export * from './duration/index';
@@ -0,0 +1,39 @@
1
+ const { addDurationFormat } = require('../../dist/cjs');
2
+
3
+ describe('Validating the duration format function', function () {
4
+ const seconds = 105243;
5
+
6
+ test("validating addDurationFormat function", () => {
7
+ let value = addDurationFormat(seconds, "HH:mm")
8
+ expect(value).toEqual("29:14");
9
+
10
+ const text = 'seconds';
11
+ value = addDurationFormat(text, "HH:mm");
12
+ expect(value).toEqual(undefined);
13
+
14
+ value = addDurationFormat(null, "HH:mm")
15
+ expect(value).toBeNull();
16
+
17
+ value = addDurationFormat("", "HH:mm")
18
+ expect(value).toEqual("");
19
+
20
+ value = addDurationFormat(seconds, "")
21
+ expect(value).toEqual("105,243,000");
22
+
23
+ value = addDurationFormat(seconds, "TEXTO")
24
+ expect(value).toEqual("TEXTO");
25
+
26
+ value = addDurationFormat(seconds, null)
27
+ expect(value).toEqual("105,243,000");
28
+
29
+ value = addDurationFormat(seconds, undefined)
30
+ expect(value).toEqual("105,243,000");
31
+
32
+ value = addDurationFormat(undefined, undefined)
33
+ expect(value).toEqual(undefined);
34
+
35
+ value = addDurationFormat(null, null)
36
+ expect(value).toEqual(null);
37
+
38
+ })
39
+ });
@@ -0,0 +1,11 @@
1
+ const { addDurationFormat } = require('../../dist/cjs');
2
+
3
+ describe('Validating the duration format function', function () {
4
+ const seconds = 105243;
5
+
6
+ test('Duration Format With Locale', function () {
7
+ value = addDurationFormat(seconds, "ss",'pl')
8
+ expect(value).toEqual("105\xa0243");
9
+ });
10
+
11
+ });
@@ -0,0 +1,45 @@
1
+ const { DurationFormatter } = require('../../dist/cjs');
2
+
3
+ describe('Validating the duration format function', function () {
4
+ const seconds = 105243;
5
+
6
+ test('Duration Format', function () {
7
+
8
+ const intNumberFormat = new Intl.NumberFormat('en', {
9
+ maximumFractionDigits: 0
10
+ })
11
+
12
+ let duration = new DurationFormatter({template: 'D[d] HH[h] mm[m] ss[s]', intlNumberFormat: intNumberFormat});
13
+ value = duration.format(seconds);
14
+ expect(value).toEqual("1d 05h 14m 03s");
15
+
16
+ duration = new DurationFormatter({template: 'HH:mm:ss', intlNumberFormat: intNumberFormat});
17
+ value = duration.format(seconds);
18
+ expect(value).toEqual("29:14:03");
19
+
20
+ duration = new DurationFormatter({template: 'HH:mm', intlNumberFormat: intNumberFormat});
21
+ value = duration.format(seconds);
22
+ expect(value).toEqual("29:14");
23
+
24
+ duration = new DurationFormatter({template: 'HH', intlNumberFormat: intNumberFormat});
25
+ value = duration.format(seconds);
26
+ expect(value).toEqual("29");
27
+
28
+ duration = new DurationFormatter({template: 'mm', intlNumberFormat: intNumberFormat});
29
+ value = duration.format(seconds);
30
+ expect(value).toEqual("1,754");
31
+
32
+ duration = new DurationFormatter({template: 'ss', intlNumberFormat: intNumberFormat});
33
+ value = duration.format(seconds);
34
+ expect(value).toEqual("105,243");
35
+
36
+ duration = new DurationFormatter({template: 'SSS', intlNumberFormat: intNumberFormat});
37
+ value = duration.format(seconds);
38
+ expect(value).toEqual("105,243,000");
39
+
40
+ duration = new DurationFormatter({template: '', intlNumberFormat: intNumberFormat});
41
+ value = duration.format(seconds);
42
+ expect(value).toEqual("105,243,000");
43
+
44
+ });
45
+ });