UNPKG

libyear

Version:

A simple measure of software dependency freshness

61 lines (60 loc) 2.25 kB
import { stripVTControlCharacters, styleText } from "node:util"; import terminalLink from "terminal-link"; const compact = process.stdout.columns < 110; const cellSeparator = compact ? " " : " │ "; const rowStart = compact ? "" : "│ "; const rowEnd = compact ? "" : " │"; const styleCell = (cell, length) => { const { format, href, value } = typeof cell === "object" ? cell : { value: cell }; let text = String(value); if (href) { text = terminalLink(text, href, { fallback: false }); } const maxLength = length + (text.length - stripVTControlCharacters(text).length); switch (typeof value) { case "number": text = text.padStart(maxLength, " "); break; default: text = text.padEnd(maxLength, " "); } if (format) { text = styleText(format, text); } return text; }; const styleRow = (cells) => `${rowStart}${cells.join(cellSeparator)}${rowEnd}`; const styleBodyRow = (data, schema) => styleRow(Object.entries(data).map(([key, cell]) => styleCell(cell, schema[key] ?? 0))); const styleHeaderRow = (schema) => styleRow(Object.entries(schema).map(([key, value]) => key.padEnd(value, " "))); const styleDivider = (type, schema) => { const spacer = "─"; const [start, middle, end] = compact ? ["", "─", ""] : { top: ["┌", "┬", "┐"], middle: ["├", "┼", "┤"], bottom: ["└", "┴", "┘"], }[type]; return `${start}${Object.values(schema) .map((length) => spacer.repeat(length + (cellSeparator.length - 1))) .join(middle)}${end}`; }; export const styleTable = (data) => { const schema = {}; data.forEach((row) => { Object.entries(row).forEach(([key, cell]) => { schema[key] = Math.max(schema[key] ?? 0, key.length, String(cell?.value ?? cell).length); }); }); return [ styleDivider("top", schema), styleHeaderRow(schema), styleDivider("middle", schema), ...data .map((row) => styleBodyRow(row, schema)) .toSpliced(data.length - 1, 0, styleDivider("middle", schema)), styleDivider("bottom", schema), ].join("\n"); };