-
Notifications
You must be signed in to change notification settings - Fork 9
/
format.ts
112 lines (99 loc) · 3.97 KB
/
format.ts
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
import {get} from './object';
/** Converts string to kebab-case notation */
export const toKebabCase = (str: string): string => {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/[\s_]+/g, '-').toLowerCase();
};
/** Converts string to camelCase notation */
export const toCamelCase = (str: string): string => {
return str.trim().replace(/[\s-,_]+([a-zA-Z0-9]?)/g, (match: string, word: string) => word.toUpperCase());
};
/** Makes the first non-indent (space, tab, newline) letter in the string capitalized */
export const capitalize = (str: string): string => {
let i = 0;
while (i < str.length && (str[i] === ' ' || str[i] === '\t' || str[i] === '\n')) i++;
return str.slice(0, i) + str.charAt(i).toUpperCase() + str.slice(i + 1);
};
/** Unwraps string from parenthesis */
export const unwrapParenthesis = (str: string): string => {
return str.trim().replace(/^\((.*)\)$/, '$1').trim();
};
/**
* Serialize to boolean string (`'true'|'false'`)
* Preserve null, undefined and empty string
*/
export const toBooleanAttribute = (val: any): string | null => {
if (val === null || val === undefined) return val;
return String(!!val && val !== 'false' && val !== '0');
};
/** Parses `null` and `undefined` as an empty string */
export const parseString = (val: string | null): string => String(val ?? '');
/** Parses string representation of the boolean value */
export const parseBoolean = (val: string | null): boolean => val !== null && val !== 'false' && val !== '0';
/**
* Parses number with the ability to pass an alternative fallback for NaN.
* Note: falsy values except 0 are treated as NaN
*/
export function parseNumber(str: string | number): number | undefined;
/**
* Parses number with the ability to pass an alternative fallback for NaN.
* Note: falsy values except 0 are treated as NaN
*/
export function parseNumber(str: string | number, nanValue: number): number;
export function parseNumber(str: string | number, nanValue?: number): number | undefined {
if (str === 0) return 0;
const value = +(str || NaN);
return isNaN(value) ? nanValue : value;
}
/**
* Common function that returns coefficient aspect ratio
* Supported formats: w:h, w/h, coefficient
* @example
* `16:9`, `16/9`, `1.77`
* @param str - string to parse
* @returns aspect ratio coefficient
*/
export function parseAspectRatio(str: string): number {
const [w, h] = str.split(/[:/]/);
if (typeof h !== 'undefined') return +w / +h;
return +w || 0;
}
/** Evaluates passed string or returns `defaultValue` */
export function evaluate(str: string, defaultValue?: any): any {
try {
// eslint-disable-next-line @typescript-eslint/no-implied-eval
return str ? (new Function(`return ${str}`))() : defaultValue;
} catch (e) {
console.warn('[ESL]: Cannot parse value ', str, e);
return defaultValue;
}
}
/** Default RegExp to match replacements in the string for the {@link format} function */
export const DEF_FORMAT_MATCHER = /{[{%]?([\w.]+)[%}]?}/g;
/** Replaces `{key}` patterns in the string from the source object */
export function format(str: string, source: Record<string, any>, matcher: RegExp = DEF_FORMAT_MATCHER): string {
return str.replace(matcher, (match, key) => {
const val = get(source, key);
return val === undefined ? match : val;
});
}
/**
* Parses time string ([CSS style](https://developer.mozilla.org/en-US/docs/Web/CSS/time))
* @example
* `.3s`, `4.5s`, `1000ms`
* @returns number - time in milliseconds
*/
export function parseCSSTime(timeStr: string): number {
const str = timeStr.trim().toLowerCase();
if (!/\dm?s$/.test(str)) return NaN;
if (str.endsWith('ms')) return +str.slice(0, -2);
return +str.slice(0, -1) * 1000;
}
/**
* Parses string of times ([CSS style](https://developer.mozilla.org/en-US/docs/Web/CSS/time))
* @example
* `.3s`, `4.5s,1000ms`, `1s, 5s`
* @returns number[] - array of times in milliseconds
*/
export function parseCSSTimeSet(timeStr: string): number[] {
return timeStr.split(',').map((timeSubstr) => parseCSSTime(timeSubstr));
}