All files / src/utils Utils.ts

100% Statements 64/64
95.83% Branches 23/24
100% Functions 2/2
100% Lines 62/62
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 1871x   1x   1x       1x         1x             499x   499x 2507x     499x                 732x 1x     731x 17x     714x   714x   714x 231306x 231306x     714x               496x   496x 2502x   2502x     496x               101742x   101742x               10x   10x 7x   3x     10x   10x               14687x               2x                 11031x 1x     11030x 11029x     11030x               1x     6x                   34003x 34003x   34003x 26554x     7449x 7449x 7449x 7449x   7449x 7449x   7449x 25028x 106x     24922x 24908x 24908x   14x 14x     24922x     7449x   7449x      
import { JSFuck } from '../enums/JSFuck';
 
import { RandomGeneratorUtils } from './RandomGeneratorUtils';
 
export class Utils {
    /**
     * @type {string}
     */
    public static readonly hexadecimalPrefix: string = '0x';
 
    /**
     * @type {Map<string, string>}
     */
    private static readonly stringToUnicodeEscapeSequenceCache: Map <string, string> = new Map();
 
    /**
     * @param length
     * @return {number[]}
     */
    public static arrayRange (length: number): number[] {
        const range: number[] = [];
 
        for (let i: number = 0; i < length; i++) {
            range.push(i);
        }
 
        return range;
    }
 
    /**
     * @param array
     * @param times
     * @returns {T[]}
     */
    public static arrayRotate <T> (array: T[], times: number): T[] {
        if (!array.length) {
            throw new ReferenceError(`Cannot rotate empty array.`);
        }
 
        if (times <= 0) {
            return array;
        }
 
        const newArray: T[] = array;
 
        let temp: T | undefined;
 
        while (times--) {
            temp = newArray.pop()!;
            newArray.unshift(temp);
        }
 
        return newArray;
    }
 
    /**
     * @param array
     * @return {T[]}
     */
    public static arrayShuffle <T> (array: T[]): T[] {
        const shuffledArray: T[] = [...array];
 
        for (let i: number = shuffledArray.length; i; i--) {
            const j: number = Math.floor(RandomGeneratorUtils.getMathRandom() * i);
 
            [shuffledArray[i - 1], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i - 1]];
        }
 
        return shuffledArray;
    }
 
    /**
     * @param dec
     * @returns {string}
     */
    public static decToHex (dec: number): string {
        const radix: number = 16;
 
        return dec.toString(radix);
    }
 
    /**
     * @param url
     * @returns {string}
     */
    public static extractDomainFromUrl (url: string): string {
        let domain: string;
 
        if (url.indexOf('://') > -1 || url.indexOf('//') === 0) {
            domain = url.split('/')[2];
        } else {
            domain = url.split('/')[0];
        }
 
        domain = domain.split(':')[0];
 
        return domain;
    }
 
    /**
     * @param number
     * @returns {boolean}
     */
    public static isCeilNumber (number: number): boolean {
        return number % 1 === 0;
    }
 
    /**
     * @param obj
     * @returns {T}
     */
    public static strEnumify <T extends {[prop: string]: ''|string}> (obj: T): T {
        return obj;
    }
 
    /**
     * @param string
     * @param times
     * @returns {string}
     */
    public static stringRotate (string: string, times: number): string {
        if (!string) {
            throw new ReferenceError(`Cannot rotate empty string.`);
        }
 
        for (let i: number = 0; i < times; i++) {
            string = string[string.length - 1] + string.substring(0, string.length - 1);
        }
 
        return string;
    }
 
    /**
     * @param string
     * @returns {string}
     */
    public static stringToJSFuck (string: string): string {
        return Array
            .from(string)
            .map((character: string): string => {
                return JSFuck[character] || character;
            })
            .join(' + ');
    }
 
    /**
     * @param string
     * @param nonLatinAndNonDigitsOnly
     * @returns {string}
     */
    public static stringToUnicodeEscapeSequence (string: string, nonLatinAndNonDigitsOnly: boolean = false): string {
        const cacheKey: string = `${string}-${String(nonLatinAndNonDigitsOnly)}`;
 
        if (Utils.stringToUnicodeEscapeSequenceCache.has(cacheKey)) {
            return <string>Utils.stringToUnicodeEscapeSequenceCache.get(cacheKey);
        }
 
        const radix: number = 16;
        const replaceRegExp: RegExp = new RegExp('[\\s\\S]', 'g');
        const escapeRegExp: RegExp = new RegExp('[^a-zA-Z0-9]');
        const regexp: RegExp = new RegExp('[\\x00-\\x7F]');
 
        let prefix: string,
            template: string;
 
        const result: string = string.replace(replaceRegExp, (escape: string): string => {
            if (nonLatinAndNonDigitsOnly && !escapeRegExp.exec(escape)) {
                return escape;
            }
 
            if (regexp.exec(escape)) {
                prefix = '\\x';
                template = '00';
            } else {
                prefix = '\\u';
                template = '0000';
            }
 
            return `${prefix}${(template + escape.charCodeAt(0).toString(radix)).slice(-template.length)}`;
        });
 
        Utils.stringToUnicodeEscapeSequenceCache.set(cacheKey, result);
 
        return result;
    }
}