api-stats-logger
Version:
SDK completo de logging e monitoramento de APIs com nova estrutura de logs organizada, auto-instrumentação, dashboard em tempo real e CLI para configuração automática. Suporta logs estruturados por contexto (HTTP, business, security, system) com campos op
327 lines (292 loc) • 8.44 kB
JavaScript
const chalk = require('chalk');
const ora = require('ora');
const boxen = require('boxen');
const Table = require('cli-table3');
const figures = require('figures');
const inquirer = require('inquirer').default || require('inquirer').createPromptModule();
class UIComponents {
constructor() {
this.colors = {
primary: '#0066CC',
success: '#00CC66',
warning: '#FFAA00',
error: '#FF3333',
info: '#6699FF',
muted: '#999999',
accent: '#FF6600'
};
this.icons = {
success: chalk.green(figures.tick),
error: chalk.red(figures.cross),
warning: chalk.yellow(figures.warning),
info: chalk.blue(figures.info),
arrow: chalk.cyan(figures.arrowRight),
bullet: chalk.gray(figures.bullet),
pointer: chalk.cyan(figures.pointer),
menu: chalk.blue(figures.radioOn),
loading: chalk.blue(figures.ellipsis),
lock: chalk.yellow(figures.circleCross),
key: chalk.green(figures.star),
project: chalk.blue(figures.squareSmallFilled),
api: chalk.magenta(figures.radioOff),
logout: chalk.red(figures.cross),
help: chalk.cyan(figures.questionMarkPrefix),
settings: chalk.gray(figures.hamburger),
delete: chalk.red(figures.cross),
link: chalk.blue(figures.arrowRight),
user: chalk.green(figures.circleFilled),
google: chalk.red('G'),
cli: chalk.cyan(figures.square)
};
}
// Spinner/Loading moderno
createSpinner(text, options = {}) {
return ora({
text: chalk.cyan(text),
color: 'cyan',
spinner: 'dots',
...options
});
}
// Título principal
title(text, subtitle = null) {
const titleBox = boxen(
chalk.bold.hex(this.colors.primary)(text) +
(subtitle ? '\n' + chalk.gray(subtitle) : ''),
{
padding: 1,
margin: 1,
borderStyle: 'round',
borderColor: 'cyan',
backgroundColor: 'black'
}
);
console.log(titleBox);
}
// Seção
section(title, subtitle = null) {
console.log('\n' + chalk.bold.hex(this.colors.primary)(title));
if (subtitle) {
console.log(chalk.gray(subtitle));
}
console.log(chalk.gray('─'.repeat(60)));
}
// Mensagem de sucesso
success(message) {
console.log(`${this.icons.success} ${chalk.green(message)}`);
}
// Mensagem de erro
error(message) {
console.log(`${this.icons.error} ${chalk.red(message)}`);
}
// Mensagem de warning
warning(message) {
console.log(`${this.icons.warning} ${chalk.yellow(message)}`);
}
// Mensagem de info
info(message) {
console.log(`${this.icons.info} ${chalk.blue(message)}`);
}
// Lista com bullet points
list(items, options = {}) {
const icon = options.icon || this.icons.bullet;
const color = options.color || 'white';
items.forEach(item => {
console.log(`${icon} ${chalk[color](item)}`);
});
}
// Tabela moderna
table(headers, rows, options = {}) {
const table = new Table({
head: headers.map(h => chalk.bold.cyan(h)),
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': '│'
},
style: {
head: [],
border: ['gray']
},
...options
});
rows.forEach(row => {
table.push(row);
});
console.log(table.toString());
}
// Menu de seleção moderna
async select(message, choices, options = {}) {
return await inquirer.prompt([
{
type: 'list',
name: 'selected',
message: chalk.bold.cyan(message),
choices: choices.map(choice => ({
name: typeof choice === 'string' ? choice : choice.name,
value: typeof choice === 'string' ? choice : choice.value,
short: typeof choice === 'string' ? choice : choice.short
})),
pageSize: options.pageSize || 10,
prefix: this.icons.menu,
...options
}
]);
}
// Input com validação
async input(message, options = {}) {
return await inquirer.prompt([
{
type: 'input',
name: 'value',
message: chalk.bold.cyan(message),
prefix: this.icons.arrow,
validate: options.validate || (() => true),
default: options.default,
...options
}
]);
}
// Confirmação
async confirm(message, defaultValue = false) {
return await inquirer.prompt([
{
type: 'confirm',
name: 'confirmed',
message: chalk.bold.yellow(message),
default: defaultValue,
prefix: this.icons.warning
}
]);
}
// Multiselect
async multiSelect(message, choices, options = {}) {
return await inquirer.prompt([
{
type: 'checkbox',
name: 'selected',
message: chalk.bold.cyan(message),
choices: choices.map(choice => ({
name: typeof choice === 'string' ? choice : choice.name,
value: typeof choice === 'string' ? choice : choice.value,
checked: typeof choice === 'string' ? false : choice.checked
})),
prefix: this.icons.menu,
...options
}
]);
}
// Password input
async password(message, options = {}) {
return await inquirer.prompt([
{
type: 'password',
name: 'value',
message: chalk.bold.cyan(message),
prefix: this.icons.lock,
mask: '*',
...options
}
]);
}
// Divisor visual
divider(char = '─', length = 60) {
console.log(chalk.gray(char.repeat(length)));
}
// Box com informações
infoBox(title, content, options = {}) {
const boxContent = `${chalk.bold.cyan(title)}\n\n${content}`;
console.log(boxen(boxContent, {
padding: 1,
margin: { top: 1, bottom: 1 },
borderStyle: 'round',
borderColor: options.color || 'cyan',
backgroundColor: options.backgroundColor || 'black',
...options
}));
}
// Lista de comandos (help)
commandList(commands) {
console.log('\n' + chalk.bold.cyan('Comandos Disponíveis:'));
console.log(chalk.gray('─'.repeat(60)));
const table = new Table({
head: ['Comando', 'Descrição'],
colWidths: [25, 50],
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': ' '
},
style: { head: [], border: [] }
});
commands.forEach(cmd => {
table.push([
chalk.green(cmd.command),
chalk.gray(cmd.description)
]);
});
console.log(table.toString());
}
// Status do usuário
userStatus(user) {
const status = boxen(
`${this.icons.user} ${chalk.bold.green(user.name)}\n` +
`${this.icons.arrow} ${chalk.gray(user.email)}\n` +
(user.projects ? `${this.icons.project} ${chalk.blue(user.projects + ' projetos')}` : ''),
{
padding: 1,
margin: 1,
borderStyle: 'round',
borderColor: 'green',
title: 'Status do Usuário',
titleAlignment: 'center'
}
);
console.log(status);
}
// Loading com progresso
async withProgress(message, asyncFn) {
const spinner = this.createSpinner(message);
spinner.start();
try {
const result = await asyncFn();
spinner.succeed(chalk.green(`${message} - Concluído`));
return result;
} catch (error) {
spinner.fail(chalk.red(`${message} - Erro: ${error.message}`));
throw error;
}
}
// Limpar tela
clear() {
console.clear();
}
// Espaçamento
space(lines = 1) {
console.log('\n'.repeat(lines));
}
// Linha horizontal
line(char = '─', color = 'gray') {
console.log(chalk[color](char.repeat(process.stdout.columns || 80)));
}
// Header da aplicação
header() {
this.clear();
this.title('API Stats Logger', 'Ferramenta de linha de comando para gerenciamento de projetos');
}
}
module.exports = UIComponents;