plazbot-cli
Version:
CLI para Plazbot SDK
110 lines (96 loc) • 3.33 kB
text/typescript
import chalk from 'chalk';
import ora, { Ora } from 'ora';
import Table from 'cli-table3';
// Colores del tema Plazbot
export const theme = {
primary: chalk.hex('#4CAF50'),
secondary: chalk.hex('#2196F3'),
accent: chalk.hex('#FFA726'),
success: chalk.hex('#66BB6A'),
error: chalk.hex('#EF5350'),
warning: chalk.hex('#FFA726'),
muted: chalk.gray,
bold: chalk.bold,
dim: chalk.dim,
};
// Spinner
export function createSpinner(text: string): Ora {
return ora({
text: theme.muted(text),
spinner: 'dots',
color: 'green',
});
}
// Tabla formateada
export function createTable(headers: string[], rows: string[][]): string {
const table = new Table({
head: headers.map(h => theme.bold.hex('#4CAF50')(h)),
style: {
head: [],
border: ['gray'],
},
chars: {
'top': '─', 'top-mid': '┬', 'top-left': '┌', 'top-right': '┐',
'bottom': '─', 'bottom-mid': '┴', 'bottom-left': '└', 'bottom-right': '┘',
'left': '│', 'left-mid': '├', 'mid': '─', 'mid-mid': '┼',
'right': '│', 'right-mid': '┤', 'middle': '│'
}
});
rows.forEach(row => table.push(row));
return table.toString();
}
// Box simple
export function box(content: string, title?: string): string {
const lines = content.split('\n');
const maxLen = Math.max(...lines.map(l => stripAnsi(l).length), title ? stripAnsi(title).length + 4 : 0);
const width = maxLen + 4;
let result = '';
if (title) {
result += theme.muted(' ┌─ ') + theme.primary(title) + theme.muted(' ' + '─'.repeat(Math.max(0, width - stripAnsi(title).length - 5))) + theme.muted('┐') + '\n';
} else {
result += theme.muted(' ┌' + '─'.repeat(width) + '┐') + '\n';
}
for (const line of lines) {
const pad = ' '.repeat(Math.max(0, maxLen - stripAnsi(line).length));
result += theme.muted(' │') + ' ' + line + pad + ' ' + theme.muted('│') + '\n';
}
result += theme.muted(' └' + '─'.repeat(width) + '┘');
return result;
}
// Strip ANSI codes para calcular longitud real
function stripAnsi(str: string): string {
return str.replace(/\x1b\[[0-9;]*m/g, '');
}
// Formato de fecha legible
export function formatDate(date: string | Date): string {
const d = new Date(date);
return d.toLocaleDateString('es-ES', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
// Status badge
export function statusBadge(enabled: boolean): string {
return enabled
? theme.success('● activo')
: theme.error('○ inactivo');
}
// Key-value pair formateado
export function kvPair(key: string, value: string): string {
return ` ${theme.muted(key + ':')} ${value}`;
}
// Sección con título
export function section(title: string): string {
return '\n' + theme.bold.hex('#4CAF50')(` ${title}`) + '\n' + theme.muted(' ' + '─'.repeat(40));
}
// Progress bar simple
export function progressBar(current: number, total: number, width: number = 30): string {
const percent = Math.round((current / total) * 100);
const filled = Math.round((current / total) * width);
const empty = width - filled;
const bar = theme.success('█'.repeat(filled)) + theme.muted('░'.repeat(empty));
return `${bar} ${theme.bold(percent + '%')} (${current}/${total})`;
}