formatters.ts•4.89 kB
/**
* Output formatting utilities
*/
import Table from 'cli-table3';
import chalk from 'chalk';
/**
* Format data as table
*/
export function formatAsTable(data: any[], options: { noHeader?: boolean } = {}): string {
if (data.length === 0) {
return chalk.yellow('No data');
}
// Get columns from first row
const firstRow = data[0];
if (typeof firstRow !== 'object' || firstRow === null) {
return JSON.stringify(data, null, 2);
}
const columns = Object.keys(firstRow);
// Create table
const table = new Table({
head: options.noHeader ? [] : columns.map(col => chalk.cyan(col)),
style: {
head: [],
border: ['grey'],
},
});
// Add rows
data.forEach(row => {
const values = columns.map(col => {
const value = row[col];
if (value === null || value === undefined) {
return chalk.gray('null');
}
if (typeof value === 'object') {
return JSON.stringify(value);
}
return String(value);
});
table.push(values);
});
return table.toString();
}
/**
* Format data as JSON
*/
export function formatAsJSON(data: any[], options: { pretty?: boolean } = {}): string {
if (options.pretty !== false) {
return JSON.stringify(data, null, 2);
}
return JSON.stringify(data);
}
/**
* Format data as CSV
*/
export function formatAsCSV(data: any[], options: { noHeader?: boolean } = {}): string {
if (data.length === 0) {
return '';
}
const firstRow = data[0];
if (typeof firstRow !== 'object' || firstRow === null) {
return data.join('\n');
}
const columns = Object.keys(firstRow);
const lines: string[] = [];
// Add header
if (!options.noHeader) {
lines.push(columns.join(','));
}
// Add rows
data.forEach(row => {
const values = columns.map(col => {
const value = row[col];
if (value === null || value === undefined) {
return '';
}
if (typeof value === 'object') {
return `"${JSON.stringify(value).replace(/"/g, '""')}"`;
}
const str = String(value);
// Escape if contains comma, quote, or newline
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
return `"${str.replace(/"/g, '""')}"`;
}
return str;
});
lines.push(values.join(','));
});
return lines.join('\n');
}
/**
* Format output based on format type
*/
export function formatOutput(
data: any[],
format: 'table' | 'json' | 'csv',
options: { noHeader?: boolean; pretty?: boolean } = {}
): string {
switch (format) {
case 'table':
return formatAsTable(data, options);
case 'json':
return formatAsJSON(data, options);
case 'csv':
return formatAsCSV(data, options);
default:
return formatAsJSON(data, options);
}
}
/**
* Format project list for display
*/
export function formatProjectsList(projects: any[], format: 'table' | 'json' | 'csv' = 'table'): string {
if (format === 'table') {
const table = new Table({
head: [
chalk.cyan('Project Code'),
chalk.cyan('Project Name'),
chalk.cyan('Type'),
chalk.cyan('Status'),
],
style: {
head: [],
border: ['grey'],
},
});
projects.forEach(p => {
table.push([
chalk.white(p.projectCode),
chalk.green(p.projectName),
chalk.blue(p.productType),
p.status === 'normal' ? chalk.green('✓') : chalk.yellow(p.status),
]);
});
return table.toString();
}
return formatOutput(projects, format);
}
/**
* Format query result summary
*/
export function formatQuerySummary(result: {
rowCount: number;
executionTimeMs: number;
query: any;
}): string {
const lines: string[] = [];
lines.push(chalk.gray('─'.repeat(60)));
lines.push(chalk.cyan('Query Summary:'));
lines.push(` Rows: ${chalk.white(result.rowCount)}`);
lines.push(` Execution Time: ${chalk.white(result.executionTimeMs)}ms`);
if (result.query.mql) {
const mql = result.query.mql.length > 50
? result.query.mql.slice(0, 50) + '...'
: result.query.mql;
lines.push(` Query: ${chalk.gray(mql)}`);
}
lines.push(chalk.gray('─'.repeat(60)));
return lines.join('\n');
}
/**
* Print success message
*/
export function printSuccess(message: string): void {
console.log(chalk.green('✓'), message);
}
/**
* Print error message
*/
export function printError(message: string, error?: Error): void {
console.error(chalk.red('✗'), message);
if (error && error.message) {
console.error(chalk.gray(' '), chalk.red(error.message));
}
}
/**
* Print warning message
*/
export function printWarning(message: string): void {
console.log(chalk.yellow('⚠'), message);
}
/**
* Print info message
*/
export function printInfo(message: string): void {
console.log(chalk.blue('ℹ'), message);
}