"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.assertPrefixedHexString = exports.assertHexString = exports.isPrefixedHexString = exports.isHexString = exports.intToHex = exports.bytesToHex = exports.hexToBytes = exports.makeHexString = void 0; const bytes_1 = require("./bytes"); /** * Creates unprefixed hex string from wide range of data. * * TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208 * * @param input * @param len of the resulting HexString WITHOUT prefix! */ function makeHexString(input, len) { if (typeof input === 'number') { return intToHex(input, len); } if (input instanceof Uint8Array) { return bytesToHex(input, len); } if (typeof input === 'string') { if (isPrefixedHexString(input)) { const hex = input.slice(2); if (len && hex.length !== len) { throw new TypeError(`Length mismatch for valid hex string. Expecting length ${len}: ${hex}`); } return hex; } else { // We use assertHexString() as there might be more reasons why a string is not valid hex string // and usage of isHexString() would not give enough information to the user on what is going // wrong. assertHexString(input, len); return input; } } throw new TypeError('Not HexString compatible type!'); } exports.makeHexString = makeHexString; /** * Converts a hex string to Uint8Array * * @param hex string input without 0x prefix! */ function hexToBytes(hex) { assertHexString(hex); const bytes = (0, bytes_1.makeBytes)(hex.length / 2); for (let i = 0; i < bytes.length; i++) { const hexByte = hex.substr(i * 2, 2); bytes[i] = parseInt(hexByte, 16); } return bytes; } exports.hexToBytes = hexToBytes; /** * Converts array of number or Uint8Array to HexString without prefix. * * @param bytes The input array * @param len The length of the non prefixed HexString */ function bytesToHex(bytes, len) { const hexByte = (n) => n.toString(16).padStart(2, '0'); const hex = Array.from(bytes, hexByte).join(''); // TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208 if (len && hex.length !== len) { throw new TypeError(`Resulting HexString does not have expected length ${len}: ${hex}`); } return hex; } exports.bytesToHex = bytesToHex; /** * Converts integer number to hex string. * * Optionally provides '0x' prefix or padding * * @param int The positive integer to be converted * @param len The length of the non prefixed HexString */ function intToHex(int, len) { if (!Number.isInteger(int)) throw new TypeError('the value provided is not integer'); if (int > Number.MAX_SAFE_INTEGER) throw new TypeError('the value provided exceeds safe integer'); if (int < 0) throw new TypeError('the value provided is a negative integer'); const hex = int.toString(16); // TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208 if (len && hex.length !== len) { throw new TypeError(`Resulting HexString does not have expected length ${len}: ${hex}`); } return hex; } exports.intToHex = intToHex; /** * Type guard for HexStrings. * Requires no 0x prefix! * * TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208 * * @param s string input * @param len expected length of the HexString */ function isHexString(s, len) { return typeof s === 'string' && /^[0-9a-f]+$/i.test(s) && (!len || s.length === len); } exports.isHexString = isHexString; /** * Type guard for PrefixedHexStrings. * Does enforce presence of 0x prefix! * * @param s string input */ function isPrefixedHexString(s) { return typeof s === 'string' && /^0x[0-9a-f]+$/i.test(s); } exports.isPrefixedHexString = isPrefixedHexString; /** * Verifies if the provided input is a HexString. * * TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208 * * @param s string input * @param len expected length of the HexString * @param name optional name for the asserted value * @returns HexString or throws error */ function assertHexString(s, len, name = 'value') { if (!isHexString(s, len)) { if (isPrefixedHexString(s)) { throw new TypeError(`${name} not valid non prefixed hex string (has 0x prefix): ${s}`); } // Don't display length error if no length specified in order not to confuse user const lengthMsg = len ? ` of length ${len}` : ''; throw new TypeError(`${name} not valid hex string${lengthMsg}: ${s}`); } } exports.assertHexString = assertHexString; /** * Verifies if the provided input is a PrefixedHexString. * * @param s string input * @param len expected length of the HexString * @param name optional name for the asserted value * @returns HexString or throws error */ function assertPrefixedHexString(s, name = 'value') { if (!isPrefixedHexString(s)) { throw new TypeError(`${name} not valid prefixed hex string: ${s}`); } } exports.assertPrefixedHexString = assertPrefixedHexString;