All files / src utils.ts

98.21% Statements 55/56
92% Branches 46/50
100% Functions 13/13
98.18% Lines 54/55

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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 1411438x                           1x             1x 1x     2x         1x 2x 1x     1x     1x 4x 1x 3x 2x 1x 1x           1x 10x                           1x 501x 309x     192x             31x     161x 20x     141x       1x 124x       1x 39x 2x     37x 1x       36x 13x     23x 3x         20x     1x 2x 2x     1x 2x 2x     2x 6x 6x 3x 3x 3x   3x   3x 1x   2x    
import {
    ABI,
    API,
    Blob,
    Checksum160,
    Checksum256,
    Float64,
    isInstanceOf,
    Name,
    NameType,
    Serializer,
    UInt128,
    UInt64,
    UInt64Type,
} from '@wharfkit/antelope'
 
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
 
/** A table scope: a name, or any `uint64` value. Numeric scopes above 2^53 must be passed as a `UInt64`, since a `number` cannot hold them. */
export type TableScopeType = NameType | UInt64Type
 
export function pascalCase(value: string): string {
    return value
        .split(/_| /)
        .map((w) => {
            return w[0].toUpperCase() + w.slice(1).toLowerCase()
        })
        .join('')
}
 
export function capitalize(string) {
    if (typeof string !== 'string' || string.length === 0) {
        return ''
    }
 
    return string.charAt(0).toUpperCase() + string.slice(1)
}
 
export function singularize(word: string): string {
    if (word.endsWith('ies')) {
        return word.slice(0, -3) + 'y'
    } else if (word.endsWith('ches') || word.endsWith('ses')) {
        return word.slice(0, -2)
    } else if (word.endsWith('s') && word.length > 1 && word[word.length - 2] !== 's') {
        return word.slice(0, -1)
    } else E{
        return word
    }
}
 
export function indexPositionInWords(index: number): string {
    return [
        'primary',
        'secondary',
        'tertiary',
        'fourth',
        'fifth',
        'sixth',
        'seventh',
        'eighth',
        'ninth',
        'tenth',
    ][index]
}
 
export function wrapIndexValue(value): API.v1.TableIndexType | undefined {
    if (value === undefined || value === null) {
        return
    }
 
    if (
        isInstanceOf(value, UInt128) ||
        isInstanceOf(value, UInt64) ||
        isInstanceOf(value, Float64) ||
        isInstanceOf(value, Checksum256) ||
        isInstanceOf(value, Checksum160)
    ) {
        return value
    }
 
    if (typeof value === 'number') {
        return UInt64.from(value)
    }
 
    return Name.from(value)
}
 
/** Whether a scope is absent, meaning a query should fall back to its default. A `0` scope is present. */
export function isAbsentScope(value?: TableScopeType | null): value is undefined | null | '' {
    return value === undefined || value === null || value === ''
}
 
/** Resolve a {@link TableScopeType} to the value sent as the `scope` of a table query. */
export function wrapScopeValue(value: TableScopeType): Name | UInt64 | string {
    if (value === undefined || value === null) {
        throw new Error('Scope is required')
    }
 
    if (isInstanceOf(value, Name)) {
        return value
    }
 
    // Strings reach the chain untouched, which reads an all-digit scope as a number and the rest as a name
    if (typeof value === 'string') {
        return value
    }
 
    if (typeof value === 'number' && !Number.isSafeInteger(value)) {
        throw new Error(
            `Scope ${value} is not an integer a number can hold, use UInt64.from() to pass it instead`
        )
    }
 
    return UInt64.from(value)
}
 
export function abiToBlob(abi: ABI): Blob {
    const serializedABI = Serializer.encode({object: abi, type: ABI})
    return new Blob(serializedABI.array)
}
 
export function blobStringToAbi(blobString: string): ABI {
    const blob = Blob.from(blobString)
    return ABI.from(blob)
}
 
export function formatExceptionMessage(except: API.v1.SendTransactionResponseException): string {
    const top = except.stack?.[0]
    if (top?.format) {
        const data = top.data ?? {}
        const substituted = top.format.replace(/\$\{(\w+)\}/g, (_, key) =>
            key in data ? String(data[key]) : `\${${key}}`
        )
        if (substituted) return substituted
    }
    if (typeof top?.data?.s === 'string') {
        return top.data.s
    }
    return except.message
}