UNPKG

claude-switcher

Version:

Cross-platform CLI tool for switching between different Claude AI model configurations. Supports automatic backup, rollback, and multi-platform configuration management for Claude API integrations.

253 lines (252 loc) 10.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.OutputFormatter = void 0; const chalk_1 = __importDefault(require("chalk")); const BOX_CHARS = { simple: { topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘', horizontal: '─', vertical: '│', cross: '┼', topTee: '┬', bottomTee: '┴', leftTee: '├', rightTee: '┤' }, double: { topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝', horizontal: '═', vertical: '║', cross: '╬', topTee: '╦', bottomTee: '╩', leftTee: '╠', rightTee: '╣' }, rounded: { topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯', horizontal: '─', vertical: '│', cross: '┼', topTee: '┬', bottomTee: '┴', leftTee: '├', rightTee: '┤' } }; class OutputFormatter { static createTable(data, columns, options) { if (data.length === 0) { return chalk_1.default.gray('(无数据)'); } const style = options?.style ?? 'simple'; const showHeader = options?.showHeader ?? true; const padding = options?.padding ?? 1; const chars = BOX_CHARS[style]; const columnWidths = columns.map(col => { const headerWidth = col.header.length; const dataWidth = Math.max(...data.map(row => String(row[col.key] || '').length)); return Math.max(headerWidth, dataWidth, col.width || 0); }); if (options?.maxWidth) { const totalWidth = columnWidths.reduce((sum, width) => sum + width, 0) + (columns.length - 1) * 3 + 4; if (totalWidth > options.maxWidth) { const availableWidth = options.maxWidth - (columns.length - 1) * 3 - 4; const avgWidth = Math.floor(availableWidth / columns.length); columnWidths.forEach((_, index) => { columnWidths[index] = Math.min(columnWidths[index], avgWidth); }); } } const lines = []; const topBorder = chars.topLeft + columnWidths.map(width => chars.horizontal.repeat(width + padding * 2)) .join(chars.topTee) + chars.topRight; lines.push(topBorder); if (showHeader) { const headerRow = chars.vertical + columns.map((col, index) => { const content = OutputFormatter.alignText(col.header, columnWidths[index], col.align || 'left'); return ' '.repeat(padding) + chalk_1.default.bold(content) + ' '.repeat(padding); }).join(chars.vertical) + chars.vertical; lines.push(headerRow); const headerSeparator = chars.leftTee + columnWidths.map(width => chars.horizontal.repeat(width + padding * 2)) .join(chars.cross) + chars.rightTee; lines.push(headerSeparator); } data.forEach(row => { const dataRow = chars.vertical + columns.map((col, index) => { let content = String(row[col.key] || ''); if (content.length > columnWidths[index]) { content = content.substring(0, columnWidths[index] - 3) + '...'; } content = OutputFormatter.alignText(content, columnWidths[index], col.align || 'left'); if (col.color) { content = col.color(content); } return ' '.repeat(padding) + content + ' '.repeat(padding); }).join(chars.vertical) + chars.vertical; lines.push(dataRow); }); const bottomBorder = chars.bottomLeft + columnWidths.map(width => chars.horizontal.repeat(width + padding * 2)) .join(chars.bottomTee) + chars.bottomRight; lines.push(bottomBorder); return lines.join('\n'); } static createList(items, options) { if (items.length === 0) { return chalk_1.default.gray('(无项目)'); } const bullet = options?.bullet ?? '•'; const indent = ' '.repeat(options?.indent ?? 2); const color = options?.color ?? ((text) => text); return items.map((item, index) => { const marker = options?.numbered ? `${index + 1}.` : bullet; return `${indent}${color(marker)} ${item}`; }).join('\n'); } static createKeyValue(data, options) { const keyColor = options?.keyColor ?? chalk_1.default.cyan; const valueColor = options?.valueColor ?? ((text) => text); const separator = options?.separator ?? ':'; const indent = ' '.repeat(options?.indent ?? 2); const keyWidth = options?.keyWidth ?? Math.max(...Object.keys(data).map(k => k.length)); return Object.entries(data).map(([key, value]) => { const paddedKey = key.padEnd(keyWidth); const formattedValue = value === null || value === undefined ? chalk_1.default.gray('(未设置)') : String(value); return `${indent}${keyColor(paddedKey)}${separator} ${valueColor(formattedValue)}`; }).join('\n'); } static createStatus(items, options) { const indent = ' '.repeat(options?.indent ?? 2); const showDetails = options?.showDetails ?? false; const statusIcons = { success: { icon: '✅', color: chalk_1.default.green }, error: { icon: '❌', color: chalk_1.default.red }, warning: { icon: '⚠️', color: chalk_1.default.yellow }, info: { icon: 'ℹ️', color: chalk_1.default.blue }, pending: { icon: '⏳', color: chalk_1.default.gray } }; return items.map(item => { const { icon, color } = statusIcons[item.status]; let line = `${indent}${icon} ${color(item.label)}`; if (showDetails && item.details) { line += `\n${indent} ${chalk_1.default.gray(item.details)}`; } return line; }).join('\n'); } static createProgress(label, current, total, options) { const width = options?.width ?? 30; const showPercentage = options?.showPercentage ?? true; const showNumbers = options?.showNumbers ?? false; const color = options?.color ?? chalk_1.default.cyan; const percentage = Math.min(100, Math.max(0, (current / total) * 100)); const filled = Math.floor((percentage / 100) * width); const empty = width - filled; const bar = color('█'.repeat(filled)) + chalk_1.default.gray('░'.repeat(empty)); let result = `${label}: [${bar}]`; if (showPercentage) { result += ` ${Math.round(percentage)}%`; } if (showNumbers) { result += ` (${current}/${total})`; } return result; } static createBox(message, options) { const style = options?.style ?? 'simple'; const color = options?.color ?? ((text) => text); const padding = options?.padding ?? 1; const chars = BOX_CHARS[style]; const lines = Array.isArray(message) ? message : [message]; const maxContentWidth = Math.max(...lines.map(line => line.length)); const titleWidth = options?.title ? options.title.length : 0; const contentWidth = Math.max(maxContentWidth, titleWidth); const boxWidth = options?.width ?? contentWidth + padding * 2; const result = []; if (options?.title) { const titlePadding = Math.max(0, boxWidth - options.title.length - 2); const leftPadding = Math.floor(titlePadding / 2); const rightPadding = titlePadding - leftPadding; result.push(color(chars.topLeft + chars.horizontal.repeat(leftPadding) + ` ${options.title} ` + chars.horizontal.repeat(rightPadding) + chars.topRight)); } else { result.push(color(chars.topLeft + chars.horizontal.repeat(boxWidth) + chars.topRight)); } lines.forEach(line => { const paddedLine = line.padEnd(boxWidth - padding * 2); result.push(color(chars.vertical + ' '.repeat(padding) + paddedLine + ' '.repeat(padding) + chars.vertical)); }); result.push(color(chars.bottomLeft + chars.horizontal.repeat(boxWidth) + chars.bottomRight)); return result.join('\n'); } static alignText(text, width, align) { if (text.length >= width) { return text.substring(0, width); } switch (align) { case 'center': const totalPadding = width - text.length; const leftPadding = Math.floor(totalPadding / 2); const rightPadding = totalPadding - leftPadding; return ' '.repeat(leftPadding) + text + ' '.repeat(rightPadding); case 'right': return text.padStart(width); default: return text.padEnd(width); } } static createSeparator(width = 50, char = '─', color) { const line = char.repeat(width); return color ? color(line) : chalk_1.default.gray(line); } static createHeader(title, options) { const level = options?.level ?? 1; const color = options?.color ?? chalk_1.default.blue.bold; const separator = options?.separator ?? true; const width = options?.width ?? Math.max(50, title.length + 10); let result = color(title); if (separator) { const separatorChar = level === 1 ? '═' : level === 2 ? '─' : '·'; result += '\n' + chalk_1.default.gray(separatorChar.repeat(width)); } return result; } } exports.OutputFormatter = OutputFormatter;