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             534x   534x 2684x     534x                 732x 1x     731x 17x     714x   714x   714x 229372x 229372x     714x               531x   531x 2679x   2679x     531x               101548x   101548x               10x   10x 7x   3x     10x   10x               14687x               2x                 10987x 1x     10986x 10985x     10986x               1x     6x                   33855x 33855x   33855x 26489x     7366x 7366x 7366x 7366x   7366x 7366x   7366x 24636x 106x     24530x 24516x 24516x   14x 14x     24530x     7366x   7366x      
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;
    }
}