1+ import { StringValue , compactUnitAnyCase , durationInterface } from '../@types/utils/formatter' ;
2+
13/**
24 * Turn text into colored text that supports MCBE
35 * @param {string } text The text you want to format to rainbow colors.
@@ -39,73 +41,65 @@ function formatNumber(value: number): string {
3941 if ( typeof value !== 'number' ) return ;
4042 return value . toString ( ) . replace ( / \B (? = ( \d { 3 } ) + (? ! \d ) ) / g, "," ) ;
4143} ;
44+
45+ export function MS ( value : StringValue ) : number ;
46+ export function MS ( value : number , { compactDuration, fullDuration } ?: { compactDuration ?: boolean , fullDuration ?: boolean } ) : string ;
47+ export function MS ( value : number , { fullDuration, avoidDuration } ?: { compactDuration ?: boolean , fullDuration : boolean , avoidDuration : Array < compactUnitAnyCase > } ) : string ;
48+ export function MS ( value : StringValue | number , { compactDuration, fullDuration, avoidDuration } : { compactDuration ?: boolean , fullDuration ?: boolean , avoidDuration ?: Array < compactUnitAnyCase > } = { } ) : string | number | undefined {
49+ try {
50+ if ( typeof value === 'string' ) {
51+ if ( / ^ \d + $ / . test ( value ) ) return Number ( value ) ;
52+ const durations = value . match ( / - ? \d * \. ? \d + \s * ?( y e a r s ? | y r s ? | w e e k s ? | d a y s ? | h o u r s ? | h r s ? | m i n u t e s ? | m i n s ? | s e c o n d s ? | s e c s ? | m i l l i s e c o n d s ? | m s e c s ? | m s | [ s m h d w y ] ) / gi) ;
53+ return durations ? durations . reduce ( ( a , b ) => a + toMS ( b ) , 0 ) : null ;
54+ } ;
55+ if ( typeof value === 'number' ) return toDuration ( value , { compactDuration, fullDuration, avoidDuration } ) ;
56+ throw new Error ( 'Value is not a string or a number' ) ;
57+ } catch ( err ) {
58+ const message = isError ( err )
59+ ? `${ err . message } . Value = ${ JSON . stringify ( value ) } `
60+ : 'An unknown error has occured.' ;
61+ throw new Error ( message ) ;
62+ } ;
63+ } ;
64+
4265/**
43- * Convert seconds, minutes, hours, days and week to milliseconds and vice versa
44- * @param {string | number } value string time support: second, minute, hour, day, week.
45- * @param {boolean } [compact] Return time string in a compact format
46- * @returns {string | number | undefined }
47- * @example MS('2 days') //Output: 172800000
48- * MS('1d') //Output: 86400000
49- * MS('10h') //Output: 36000000
50- * MS('2.5 hrs') //Output: 9000000
51- * MS('2h') //Output: 7200000
52- * MS('1m') //Output: 60000
53- * MS('5s') //Output: 5000
54- * MS('1y') //Output: 31557600000
55- * MS('100') //Output: 100
56- * MS('-3 days') //Output: -259200000
57- * MS('-1h') //Output: -3600000
58- * MS('-200') //Output: -200
59- *
60- * //Convert from Milliseconds
61- *
62- * MS(86400000, { compact: true }); //Output: 1d
63- * MS(86400000); //Output: 1 day
64- * MS(172800000, { compact: true }); //Output: 2d
65- * MS(172800000); //Output: 2 days
66+ * Convert Durations to milliseconds
6667 */
67- function MS ( value : string | number , { compact } : { compact ?: boolean } = { } ) : any {
68- if ( typeof value === 'string' ) return timeToMs ( value ) ;
69- if ( typeof value === 'number' ) return msToTime ( value , compact ? true : false ) ;
68+ function toMS ( value : string ) : number | undefined {
69+ const number = Number ( value . replace ( / [ ^ - . 0 - 9 ] + / g, '' ) ) ;
70+ value = value . replace ( / \s + / g, '' ) ;
71+ if ( / \d + (? = m s | m i l l i s e c o n d s ? ) / i. test ( value ) ) return number ;
72+ else if ( / \d + (? = s ) / i. test ( value ) ) return number * 1000 ;
73+ else if ( / \d + (? = m ) / i. test ( value ) ) return number * 60000 ;
74+ else if ( / \d + (? = h ) / i. test ( value ) ) return number * 3.6e+6 ;
75+ else if ( / \d + (? = d ) / i. test ( value ) ) return number * 8.64e+7 ;
76+ else if ( / \d + (? = w ) / i. test ( value ) ) return number * 6.048e+8 ;
77+ else if ( / \d + (? = y ) / i. test ( value ) ) return number * 3.154e+10 ;
7078} ;
79+
7180/**
72- *
73- * @param {string } string Time to ms
74- * @returns {number }
81+ * Convert milliseconds to durations
7582 */
76- function timeToMs ( value : string ) : number {
77- if ( ! / ^ - ? \s ? \d * \. ? \d * ?\s ? ( ( y e a r s * ?| y r s * ?) | ( w e e k s * ?) | ( d a y s * ?) | ( h o u r s * ?| h r s * ?) | ( m i n u t e s * ?| m i n s * ?) | ( s e c o n d s * ?| s e c s * ?) | ( m i l l i s e c o n d s * ?| m s e c s * ?| m s ) | [ s m h d w y ] ) $ / . test ( value ) ) return ;
78- const number = parseFloat ( value . replace ( / [ ^ - . 0 - 9 ] + / g, '' ) ) ;
79- if ( / \d + (? = \s ? ( m i l l i s e c o n d s ? | m s e c s ? | m s ) ) / . test ( value ) ) return number ;
80- else if ( / \d + (? = \s ? s ) / . test ( value ) ) return number * 1000 ;
81- else if ( / \d + (? = \s ? m ) / . test ( value ) ) return number * 60000 ;
82- else if ( / \d + (? = \s ? h ) / . test ( value ) ) return number * 3.6e+6 ;
83- else if ( / \d + (? = \s ? d ) / . test ( value ) ) return number * 8.64e+7 ;
84- else if ( / \d + (? = \s ? w ) / . test ( value ) ) return number * 6.048e+8 ;
85- else if ( / \d + (? = \s ? y ) / . test ( value ) ) return number * 3.154e+10 ;
83+ function toDuration ( value : number , { compactDuration, fullDuration, avoidDuration } : { compactDuration ?: boolean , fullDuration ?: boolean , avoidDuration ?: Array < compactUnitAnyCase > } = { } ) : string {
84+ const absMs = Math . abs ( value ) ;
85+ const duration : Array < durationInterface > = [
86+ { short : 'd' , long : 'day' , ms : absMs / 8.64e+7 } ,
87+ { short : 'h' , long : 'hour' , ms : absMs / 3.6e+6 % 24 } ,
88+ { short : 'm' , long : 'minute' , ms : absMs / 60000 % 60 } ,
89+ { short : 's' , long : 'second' , ms : absMs / 1000 % 60 } ,
90+ { short : 'ms' , long : 'millisecond' , ms : absMs % 1000 } ,
91+ ] ;
92+ const mappedDuration = duration
93+ . filter ( obj => obj . ms !== 0 && avoidDuration ? fullDuration && ! avoidDuration . map ( v => v . toLowerCase ( ) ) . includes ( obj . short ) : obj . ms )
94+ . map ( obj => `${ Math . sign ( value ) === - 1 ? '-' : '' } ${ compactDuration ? `${ Math . floor ( obj . ms ) } ${ obj . short } ` : `${ Math . floor ( obj . ms ) } ${ obj . long } ${ obj . ms === 1 ? '' : 's' } ` } ` ) ;
95+ return fullDuration ? mappedDuration . join ( compactDuration ? ' ' : ', ' ) : mappedDuration [ 0 ] ;
8696} ;
97+
8798/**
88- *
89- * @param {number } ms Ms to Time
90- * @param {boolean } [compact] Compact time format
91- * @returns {string }
99+ * A type guard for errors.
92100 */
93- function msToTime ( ms : number , compact ?: boolean ) : string {
94- let negative = Math . sign ( ms ) === - 1 , absMs = Math . abs ( ms ) ;
95- let seconds = absMs / 1000 , minutes = absMs / 60000 , hours = absMs / 3.6e+6 , days = absMs / 8.64e+7 , weeks = absMs / 6.048e+8 ;
96- if ( absMs < 1000 ) return plural ( 'ms' , 'millisecond' , negative , absMs , compact ) ;
97- else if ( seconds < 60 ) return plural ( 's' , 'second' , negative , seconds , compact ) ;
98- else if ( minutes < 60 ) return plural ( 'm' , 'minute' , negative , minutes , compact ) ;
99- else if ( hours < 24 ) return plural ( 'h' , 'hour' , negative , hours , compact ) ;
100- else if ( days < 7 ) return plural ( 'd' , 'day' , negative , days , compact ) ;
101- else return plural ( 'w' , 'week' , negative , weeks , compact ) ;
102- } ;
103- function plural ( shortType : string , type : string , negative : boolean , number : number , compact : boolean ) : string {
104- number = Math . round ( number ) ;
105- let origNumb = `${ negative ? '-' : '' } ${ number } ` ;
106- if ( compact ) return `${ origNumb } ${ shortType } ` ;
107- if ( number > 1 ) return `${ origNumb } ${ type } s` ;
108- else return `${ origNumb } ${ type } ` ;
101+ function isError ( error : unknown ) : error is Error {
102+ return typeof error === 'object' && error !== null && 'message' in error ;
109103} ;
110104
111- export { rainbowText , compressNumber , formatNumber , MS } ;
105+ export { rainbowText , compressNumber , formatNumber } ;
0 commit comments