UNPKG

@kadena/kadena-cli

Version:

Kadena CLI tool to interact with the Kadena blockchain (manage keys, transactions, etc.)

201 lines 7.31 kB
import { load } from 'js-yaml'; import path from 'path'; import sanitize from 'sanitize-filename'; import { MAX_CHAIN_IDS, MAX_CHARACTERS_LENGTH } from '../constants/config.js'; import { services } from '../services/index.js'; /** * Assigns a value to an object's property if the value is neither undefined nor an empty string. * This function provides a type-safe way to conditionally update properties on an object. * * @template T - The type of the object to which the value might be assigned. * @template K - The type of the property key on the object. * @param {T} obj - The target object to which the value might be assigned. * @param {K} key - The property key on the object where the value might be assigned. * @param {T[K] | undefined} value - The value to be potentially assigned. If undefined or empty string, no assignment occurs. */ export function safeAssign(obj, key, value) { if (value !== undefined && value !== '') { obj[key] = value; } } /** * Merges properties from the source object into the target object, * overwriting properties on the target only if they are defined in the source. * * @template T - The type of the target object and the source object. * @param {T} target - The target object that will receive properties from the source. * @param {Partial<T>} source - The source object from which properties will be taken. * @returns {T} - The merged object. */ export function mergeConfigs(target, source) { for (const key in source) { if (key in target) { safeAssign(target, key, source[key]); } } return target; } /** * Sanitizes a string to create a safe filename by replacing illegal, control, * reserved and trailing characters with hyphens. It ensures that the file does * not end with a hyphen. * * @param {string} str - The input string that needs to be sanitized. * @returns {string} - The sanitized string, ensuring it does not end with a hyphen. * * @example * const originalString = "This is a <sample> string:file\\name?"; * const sanitizedString = sanitizeFilename(originalString); * console.log(sanitizedString); // Outputs: This-is-a--sample--string-file-name */ export function sanitizeFilename(str) { return sanitize(str); } /** * Checks if the input string contains only alphabetic characters. * * @function * @export * @param {string} str - The input string to be checked. * @returns {boolean} Returns true if the string only contains alphabetic characters (either lower case or upper case), and false if the string contains any non-alphabetic characters. * * @example * * isAlphabetic("HelloWorld"); // returns true * isAlphabetic("123ABC"); // returns false * isAlphabetic("Hello World!"); // returns false */ export function isAlphabetic(str) { const regex = /^[A-Za-z]+$/; return regex.test(str); } /** * Checks if a string contains only characters valid in filenames * * @param {string} str - The input string that needs to be checked. * @returns {boolean} - Returns `true` if the string is valid * * @example * const isValid = isValidFilename("abc-123"); // Outputs: true */ export function isValidFilename(str) { str = str.trim(); if (str.length === 0) return false; // Based on https://superuser.com/a/358861 const regex = /[\\\/:*?"<>|]/; return !regex.test(str); } /** * Checks if a string contains only numeric characters. * * @param {string} str - The input string that needs to be checked. * @returns {boolean} - Returns `true` if the string is numeric, otherwise returns `false`. * * @example * const isNum = isNumeric("12345"); // Outputs: true */ export function isNumeric(str) { const regex = /^[0-9]+$/; return regex.test(str); } // export const skipSymbol = Symbol('skip'); // export const createSymbol = Symbol('createSymbol'); export const notEmpty = (value) => value !== null && value !== undefined; export const truncateText = (str, maxLength = MAX_CHARACTERS_LENGTH) => str.length > maxLength ? `${str.substring(0, maxLength - 3)}...` : str; export const maskStringPreservingStartAndEnd = (str, maxLength = 15, maskChar = '.', maskCharLength = 4) => { if (str.length <= maxLength) { return str; } else { const startChars = str.substring(0, (maxLength - maskCharLength) / 2); const endChars = str.substring(str.length - (maxLength - maskCharLength) / 2); return `${startChars}${maskChar.repeat(maskCharLength)}${endChars}`; } }; export const isNotEmptyString = (value) => value !== null && value !== undefined && value !== ''; export const isNotEmptyObject = (obj) => obj !== undefined && obj !== null && Object.keys(obj).length > 0; /** * Prints zod error issues in format * ```code * {key}: [issues by key]\n * ...repeat * ``` */ export const formatZodError = (error) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const format = error.format(); const formatted = Object.keys(format) .map((key) => { var _a; if (key === '_errors') { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions return Array.isArray(format[key]) && format[key].includes('Required') ? 'Can not be empty' : null; } return `${key}: ${(_a = format[key]) === null || _a === void 0 ? void 0 : _a._errors.join(', ')}`; }) .filter(notEmpty); return formatted.join('\n'); }; export const safeJsonParse = (value) => { try { return JSON.parse(value); } catch (e) { return null; } }; export const safeYamlParse = (value) => { try { return load(value); } catch (e) { return null; } }; export function detectFileParseType(filepath) { const ext = path.extname(filepath); if (ext === '.yaml' || ext === '.yml') { return safeYamlParse; } if (ext === '.json') { return safeJsonParse; } return null; } export async function loadUnknownFile(filepath) { const parser = detectFileParseType(filepath); if (parser === null) return null; const file = await services.filesystem.readFile(filepath); if (file === null) return null; return parser(file); } export const generateAllChainIds = () => Array.from({ length: MAX_CHAIN_IDS }, // eslint-disable-next-line @typescript-eslint/naming-convention (_, index) => index.toString()); /** * Extracts the public key from a given account string. * * @param {string} account - The account string in the format `[kctwu]:[a-zA-Z0-9]{64}`. * * @returns {string} - The extracted public key from the account. * * @throws {Error} - Throws an error if the account format is invalid. * * @example * const account = 'k:abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01'; * const pubKey = getPubKeyFromAccount(account); * console.log(pubKey); // Outputs: abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01 */ export function getPubKeyFromAccount(account) { if (!account.toLowerCase().match(/^[kctwu]:[a-zA-Z0-9]{64}$/)) { throw new Error('Invalid account'); } const pubKey = account.toLowerCase().slice(2); return pubKey; } //# sourceMappingURL=globalHelpers.js.map