All files / src utils.ts

91.3% Statements 63/69
84.21% Branches 32/38
100% Functions 7/7
90.62% Lines 58/64

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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        216x 216x 3x   213x 2081x 14x     199x       6x 6x 1x   5x 5x 1x     4x     1x   1x 1x 1x 256x 256x 256x         241x     241x 241x 241x 7620x   241x       285x 1x   285x     285x     285x 285x 285x 285x 14683x 14683x     14683x   285x         5x       1x             9895x 1456x   8439x 4116x       4323x 4323x 19x   4304x 4304x 4304x 4768x 4768x 4304x   464x 464x   4304x             4304x    
import {ABISerializableObject} from './serializer/serializable'
import rand from 'brorand'
 
export function arrayEquals(a: ArrayLike<number>, b: ArrayLike<number>) {
    const len = a.length
    if (len !== b.length) {
        return false
    }
    for (let i = 0; i < len; i++) {
        if (a[i] !== b[i]) {
            return false
        }
    }
    return true
}
 
export function arrayEquatableEquals(a: ABISerializableObject[], b: ABISerializableObject[]) {
    const len = a.length
    if (len !== b.length) {
        return false
    }
    for (let i = 0; i < len; i++) {
        if (!a[i].equals(b[i])) {
            return false
        }
    }
    return true
}
 
const hexLookup: {enc?: Array<string>; dec?: Record<string, number>} = {}
function buildHexLookup() {
    hexLookup.enc = new Array<string>(0xff)
    hexLookup.dec = {}
    for (let i = 0; i <= 0xff; ++i) {
        const b = i.toString(16).padStart(2, '0')
        hexLookup.enc[i] = b
        hexLookup.dec[b] = i
    }
}
 
export function arrayToHex(array: ArrayLike<number>) {
    Iif (!hexLookup.enc) {
        buildHexLookup()
    }
    const len = array.length
    const rv = new Array<string>(len)
    for (let i = 0; i < len; ++i) {
        rv[i] = hexLookup.enc![array[i]]
    }
    return rv.join('')
}
 
export function hexToArray(hex: string) {
    if (!hexLookup.dec) {
        buildHexLookup()
    }
    Iif (typeof hex !== 'string') {
        throw new Error('Expected string containing hex digits')
    }
    Iif (hex.length % 2) {
        throw new Error('Odd number of hex digits')
    }
    hex = hex.toLowerCase()
    const len = hex.length / 2
    const result = new Uint8Array(len)
    for (let i = 0; i < len; i++) {
        const b = hexLookup.dec![hex[i * 2] + hex[i * 2 + 1]]
        Iif (b === undefined) {
            throw new Error('Expected hex string')
        }
        result[i] = b
    }
    return result
}
 
/** Generate N random bytes, throws if a secure random source isn't available. */
export function secureRandom(length: number): Uint8Array {
    return rand(length)
}
 
/** Used in isInstanceOf checks so we don't spam with warnings. */
let didWarn = false
 
/** Check if object in instance of class. */
export function isInstanceOf<T extends {new (...args: any[]): InstanceType<T>}>(
    object: any,
    someClass: T
): object is InstanceType<T> {
    if (object instanceof someClass) {
        return true
    }
    if (object == null || typeof object !== 'object') {
        return false
    }
    // not an actual instance but since bundlers can fail to dedupe stuff or
    // multiple versions can be included we check for compatibility if possible
    const className = someClass['__className'] || someClass['abiName']
    if (!className) {
        return false
    }
    let instanceClass = object.constructor
    let isAlienInstance = false
    while (instanceClass && !isAlienInstance) {
        const instanceClassName = instanceClass['__className'] || instanceClass['abiName']
        if (!instanceClassName) {
            break
        }
        isAlienInstance = className == instanceClassName
        instanceClass = Object.getPrototypeOf(instanceClass)
    }
    Iif (isAlienInstance && !didWarn) {
        // eslint-disable-next-line no-console
        console.warn(
            `Detected alien instance of ${className}, this usually means more than one version of @wharfkit/antelope has been included in your bundle.`
        )
        didWarn = true
    }
    return isAlienInstance
}