UNPKG

5.82 kBPlain TextView Raw
1/*
2The MIT License
3
4Copyright (c) 2016 Nick Dodson. nickdodson.com
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22THE SOFTWARE
23 */
24
25/**
26 * Returns a `Boolean` on whether or not the a `String` starts with '0x'
27 * @param str the string input value
28 * @return a boolean if it is or is not hex prefixed
29 * @throws if the str input is not a string
30 */
31export function isHexPrefixed(str: string): boolean {
32 if (typeof str !== 'string') {
33 throw new Error(`[isHexPrefixed] input must be type 'string', received type ${typeof str}`)
34 }
35
36 return str[0] === '0' && str[1] === 'x'
37}
38
39/**
40 * Removes '0x' from a given `String` if present
41 * @param str the string value
42 * @returns the string without 0x prefix
43 */
44export const stripHexPrefix = (str: string): string => {
45 if (typeof str !== 'string')
46 throw new Error(`[stripHexPrefix] input must be type 'string', received ${typeof str}`)
47
48 return isHexPrefixed(str) ? str.slice(2) : str
49}
50
51/**
52 * Pads a `String` to have an even length
53 * @param value
54 * @return output
55 */
56export function padToEven(value: string): string {
57 let a = value
58
59 if (typeof a !== 'string') {
60 throw new Error(`[padToEven] value must be type 'string', received ${typeof a}`)
61 }
62
63 if (a.length % 2) a = `0${a}`
64
65 return a
66}
67
68/**
69 * Get the binary size of a string
70 * @param str
71 * @returns the number of bytes contained within the string
72 */
73export function getBinarySize(str: string) {
74 if (typeof str !== 'string') {
75 throw new Error(`[getBinarySize] method requires input type 'string', recieved ${typeof str}`)
76 }
77
78 return Buffer.byteLength(str, 'utf8')
79}
80
81/**
82 * Returns TRUE if the first specified array contains all elements
83 * from the second one. FALSE otherwise.
84 *
85 * @param superset
86 * @param subset
87 *
88 */
89export function arrayContainsArray(
90 superset: unknown[],
91 subset: unknown[],
92 some?: boolean
93): boolean {
94 if (Array.isArray(superset) !== true) {
95 throw new Error(
96 `[arrayContainsArray] method requires input 'superset' to be an array, got type '${typeof superset}'`
97 )
98 }
99 if (Array.isArray(subset) !== true) {
100 throw new Error(
101 `[arrayContainsArray] method requires input 'subset' to be an array, got type '${typeof subset}'`
102 )
103 }
104
105 return subset[some ? 'some' : 'every']((value) => superset.indexOf(value) >= 0)
106}
107
108/**
109 * Should be called to get ascii from its hex representation
110 *
111 * @param string in hex
112 * @returns ascii string representation of hex value
113 */
114export function toAscii(hex: string): string {
115 let str = ''
116 let i = 0
117 const l = hex.length
118
119 if (hex.substring(0, 2) === '0x') i = 2
120
121 for (; i < l; i += 2) {
122 const code = parseInt(hex.substr(i, 2), 16)
123 str += String.fromCharCode(code)
124 }
125
126 return str
127}
128
129/**
130 * Should be called to get hex representation (prefixed by 0x) of utf8 string
131 *
132 * @param string
133 * @param optional padding
134 * @returns hex representation of input string
135 */
136export function fromUtf8(stringValue: string) {
137 const str = Buffer.from(stringValue, 'utf8')
138
139 return `0x${padToEven(str.toString('hex')).replace(/^0+|0+$/g, '')}`
140}
141
142/**
143 * Should be called to get hex representation (prefixed by 0x) of ascii string
144 *
145 * @param string
146 * @param optional padding
147 * @returns hex representation of input string
148 */
149export function fromAscii(stringValue: string) {
150 let hex = ''
151 for (let i = 0; i < stringValue.length; i++) {
152 const code = stringValue.charCodeAt(i)
153 const n = code.toString(16)
154 hex += n.length < 2 ? `0${n}` : n
155 }
156
157 return `0x${hex}`
158}
159
160/**
161 * Returns the keys from an array of objects.
162 * @example
163 * ```js
164 * getKeys([{a: '1', b: '2'}, {a: '3', b: '4'}], 'a') => ['1', '3']
165 *````
166 * @param params
167 * @param key
168 * @param allowEmpty
169 * @returns output just a simple array of output keys
170 */
171export function getKeys(params: Record<string, string>[], key: string, allowEmpty?: boolean) {
172 if (!Array.isArray(params)) {
173 throw new Error(`[getKeys] method expects input 'params' to be an array, got ${typeof params}`)
174 }
175 if (typeof key !== 'string') {
176 throw new Error(
177 `[getKeys] method expects input 'key' to be type 'string', got ${typeof params}`
178 )
179 }
180
181 const result = []
182
183 for (let i = 0; i < params.length; i++) {
184 let value = params[i][key]
185 if (allowEmpty && !value) {
186 value = ''
187 } else if (typeof value !== 'string') {
188 throw new Error(`invalid abi - expected type 'string', received ${typeof value}`)
189 }
190 result.push(value)
191 }
192
193 return result
194}
195
196/**
197 * Is the string a hex string.
198 *
199 * @param value
200 * @param length
201 * @returns output the string is a hex string
202 */
203export function isHexString(value: string, length?: number): boolean {
204 if (typeof value !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) return false
205
206 if (length && value.length !== 2 + 2 * length) return false
207
208 return true
209}