export const untrailingSlashIt = (str: string): string => str.replace(/\/$/, ""); export const trailingSlashIt = (str: string): string => untrailingSlashIt(str) + "/"; export const formatBytes = (bytes: number, decimals: number = 2): string => { if (bytes === 0) return "0 Bytes"; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ["Bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; }; export const stringifyObjectLiteral = (obj: unknown, indent = 2): string => { if (obj === null) return "null"; if (obj === undefined) return "undefined"; if (typeof obj === "string") return `"${obj}"`; if (typeof obj === "number" || typeof obj === "boolean") return String(obj); if (Array.isArray(obj)) { const items = obj.map((item) => stringifyObjectLiteral(item, indent)); return `[${items.join(", ")}]`; } if (typeof obj === "object") { const entries = Object.entries(obj).map( ([key, value]) => `${key}: ${stringifyObjectLiteral(value, indent)}` ); if (entries.length === 0) return "{}"; const spacing = " ".repeat(indent); return `{\n${spacing}${entries.join(`,\n${spacing}`)},\n}`; } return String(obj); }; export const removeKeyFromObject = ( obj: Record, key: string ): Record => { const newObj = { ...obj }; delete newObj[key]; return newObj; }; export const formatResult = (data: any, indent = 0): string => { const indentStr = " ".repeat(indent); const nextIndentStr = " ".repeat(indent + 1); if (!Array.isArray(data)) { return JSON.stringify(data); } // Check if array contains any arrays const hasArrays = data.some((item) => Array.isArray(item)); if (hasArrays) { // If array contains arrays, put each element on a new line const items = data.map((item) => { if (Array.isArray(item)) { return nextIndentStr + formatResult(item, indent + 1); } return nextIndentStr + JSON.stringify(item); }); return `[\n${items.join(",\n")}\n${indentStr}]`; } else { // If array contains only primitives, keep them on the same line return `[${data.map((item) => JSON.stringify(item)).join(", ")}]`; } }; export const formatDuration = (ms: number) => { if (ms < 1000) { return `${Math.round(ms)}ms`; } return `${(ms / 1000).toFixed(2)}s`; }; export const round = (input: number, decimals: number): number => { const multiplier = 10 ** decimals; return Math.round(input * multiplier) / multiplier; };