82 lines
1.9 KiB
TypeScript
82 lines
1.9 KiB
TypeScript
import chalk from 'chalk'
|
||
|
||
export const colors = {
|
||
success: chalk.green,
|
||
error: chalk.red,
|
||
warning: chalk.yellow,
|
||
info: chalk.blue,
|
||
dim: chalk.dim,
|
||
bold: chalk.bold,
|
||
cyan: chalk.cyan,
|
||
magenta: chalk.magenta,
|
||
}
|
||
|
||
export function logSuccess(message: string): void {
|
||
console.log(colors.success('✓'), message)
|
||
}
|
||
|
||
export function logError(message: string): void {
|
||
console.log(colors.error('✗'), message)
|
||
}
|
||
|
||
export function logWarning(message: string): void {
|
||
console.log(colors.warning('⚠'), message)
|
||
}
|
||
|
||
export function logInfo(message: string): void {
|
||
console.log(colors.info('ℹ'), message)
|
||
}
|
||
|
||
export function logDim(message: string): void {
|
||
console.log(colors.dim(message))
|
||
}
|
||
|
||
/**
|
||
* Print a table with aligned columns
|
||
*/
|
||
export function printTable(
|
||
headers: string[],
|
||
rows: string[][],
|
||
options: { padding?: number } = {}
|
||
): void {
|
||
const { padding = 2 } = options
|
||
|
||
// Calculate column widths
|
||
const columnWidths = headers.map((header, i) => {
|
||
const maxDataWidth = Math.max(...rows.map(row => (row[i] || '').length))
|
||
return Math.max(header.length, maxDataWidth)
|
||
})
|
||
|
||
// Print header
|
||
const headerLine = headers
|
||
.map((h, i) => colors.bold(h.padEnd(columnWidths[i] + padding)))
|
||
.join('')
|
||
console.log(headerLine)
|
||
|
||
// Print separator
|
||
const separator = columnWidths
|
||
.map(w => colors.dim('─'.repeat(w + padding)))
|
||
.join('')
|
||
console.log(separator)
|
||
|
||
// Print rows
|
||
for (const row of rows) {
|
||
const line = row
|
||
.map((cell, i) => (cell || '').padEnd(columnWidths[i] + padding))
|
||
.join('')
|
||
console.log(line)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Format a version comparison for display
|
||
*/
|
||
export function formatVersionComparison(local: string, remote: string | null): string {
|
||
if (remote === null) {
|
||
return colors.cyan('(not published)')
|
||
}
|
||
if (local === remote) {
|
||
return colors.dim(remote)
|
||
}
|
||
return `${colors.dim(remote)} → ${colors.success(local)}`
|
||
}
|