// // Formatting helpers shared by the tree items. // const UNITS = ["B", "KB", "MB", "GB", "TB", "PB"]; function bytes(value) { if (typeof value !== "number" || !isFinite(value) || value < 0) { return ""; } let index = 0; let size = value; while (size >= 1000 && index < UNITS.length - 1) { size = size / 1000; index += 1; } let precision = size >= 100 || index === 0 ? 0 : 1; return `${size.toFixed(precision)} ${UNITS[index]}`; } // Relative age, in the same spirit as Docker's "2 hours ago". function age(value) { if (!value) { return ""; } let date = value instanceof Date ? value : new Date(value); if (isNaN(date.getTime()) || date.getTime() === 0) { return ""; } let seconds = Math.max(0, Math.floor((Date.now() - date.getTime()) / 1000)); if (seconds < 60) { return "just now"; } let steps = [ ["minute", 60], ["hour", 60], ["day", 24], ["week", 7], ["month", 4.35], ["year", 12] ]; let amount = seconds; let label = "second"; for (let [name, divisor] of steps) { if (amount < divisor) { break; } amount = amount / divisor; label = name; } let rounded = Math.floor(amount); return `${rounded} ${label}${rounded === 1 ? "" : "s"} ago`; } // Splits an image reference into its registry, repository and tag. function reference(value) { let text = String(value || ""); let digest = null; let tag = null; let atIndex = text.lastIndexOf("@"); if (atIndex > 0) { digest = text.slice(atIndex + 1); text = text.slice(0, atIndex); } let colonIndex = text.lastIndexOf(":"); let slashIndex = text.lastIndexOf("/"); if (colonIndex > slashIndex) { tag = text.slice(colonIndex + 1); text = text.slice(0, colonIndex); } let registry = null; let repository = text; let firstSlash = text.indexOf("/"); if (firstSlash > 0) { let candidate = text.slice(0, firstSlash); if (candidate.includes(".") || candidate.includes(":") || candidate === "localhost") { registry = candidate; repository = text.slice(firstSlash + 1); } } return { registry: registry, repository: repository, tag: tag || "latest", digest: digest, // docker.io/library/nginx reads better as nginx. short: repository.replace(/^library\//, "") }; } module.exports = { bytes, age, reference };