semantic-ds-toolkit
Version:
Performance-first semantic layer for modern data stacks - Stable Column Anchors & intelligent inference
309 lines • 11.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.format = exports.output = exports.OutputFormatter = exports.themes = void 0;
const chalk_1 = __importDefault(require("chalk"));
exports.themes = {
default: {
primary: chalk_1.default.blue,
secondary: chalk_1.default.cyan,
success: chalk_1.default.green,
warning: chalk_1.default.yellow,
error: chalk_1.default.red,
info: chalk_1.default.blue,
muted: chalk_1.default.gray,
highlight: chalk_1.default.white.bold,
accent: chalk_1.default.magenta
},
dark: {
primary: chalk_1.default.blueBright,
secondary: chalk_1.default.cyanBright,
success: chalk_1.default.greenBright,
warning: chalk_1.default.yellowBright,
error: chalk_1.default.redBright,
info: chalk_1.default.blueBright,
muted: chalk_1.default.gray,
highlight: chalk_1.default.whiteBright.bold,
accent: chalk_1.default.magentaBright
},
minimal: {
primary: chalk_1.default.white,
secondary: chalk_1.default.gray,
success: chalk_1.default.green,
warning: chalk_1.default.yellow,
error: chalk_1.default.red,
info: chalk_1.default.white,
muted: chalk_1.default.gray,
highlight: chalk_1.default.white.bold,
accent: chalk_1.default.white
}
};
class OutputFormatter {
theme;
useEmoji;
useColor;
constructor(themeName = 'default', options = {}) {
this.theme = exports.themes[themeName] || exports.themes.default;
this.useEmoji = options.emoji !== false;
this.useColor = options.color !== false;
// Disable colors if NO_COLOR environment variable is set
if (process.env.NO_COLOR) {
this.useColor = false;
}
}
// Status indicators with optional emoji
success(text, emoji = '✅') {
const icon = this.useEmoji ? `${emoji} ` : '';
const styled = this.useColor ? this.theme.success(text) : text;
return `${icon}${styled}`;
}
error(text, emoji = '❌') {
const icon = this.useEmoji ? `${emoji} ` : '';
const styled = this.useColor ? this.theme.error(text) : text;
return `${icon}${styled}`;
}
warning(text, emoji = '⚠️') {
const icon = this.useEmoji ? `${emoji} ` : '';
const styled = this.useColor ? this.theme.warning(text) : text;
return `${icon}${styled}`;
}
info(text, emoji = 'ℹ️') {
const icon = this.useEmoji ? `${emoji} ` : '';
const styled = this.useColor ? this.theme.info(text) : text;
return `${icon}${styled}`;
}
// Semantic formatting
title(text, emoji = '🚀') {
const icon = this.useEmoji ? `${emoji} ` : '';
const styled = this.useColor ? this.theme.primary.bold(text) : text;
return `${icon}${styled}`;
}
subtitle(text) {
return this.useColor ? this.theme.secondary(text) : text;
}
highlight(text) {
return this.useColor ? this.theme.highlight(text) : text;
}
muted(text) {
return this.useColor ? this.theme.muted(text) : text;
}
accent(text) {
return this.useColor ? this.theme.accent(text) : text;
}
// Command/code formatting
command(text) {
const styled = this.useColor ? this.theme.accent(text) : text;
return this.useEmoji ? `$ ${styled}` : styled;
}
code(text) {
return this.useColor ? chalk_1.default.bgGray.black(` ${text} `) : `\`${text}\``;
}
path(text) {
return this.useColor ? this.theme.info(text) : text;
}
// Data formatting
table(headers, rows) {
if (!this.useColor) {
return this.formatPlainTable(headers, rows);
}
const headerRow = headers.map(h => this.theme.highlight(h)).join(' │ ');
const separator = '─'.repeat(headerRow.length);
const dataRows = rows.map(row => row.map((cell, i) => {
if (i === 0)
return this.theme.primary(cell);
if (cell.match(/^\d+(\.\d+)?$/))
return this.theme.accent(cell);
if (cell.match(/^(true|false)$/i))
return this.theme.secondary(cell);
return cell;
}).join(' │ '));
return [
headerRow,
separator,
...dataRows
].join('\n');
}
formatPlainTable(headers, rows) {
const allRows = [headers, ...rows];
const columnWidths = headers.map((_, i) => Math.max(...allRows.map(row => (row[i] || '').length)));
const formatRow = (row) => row.map((cell, i) => (cell || '').padEnd(columnWidths[i])).join(' | ');
return [
formatRow(headers),
columnWidths.map(w => '-'.repeat(w)).join('-+-'),
...rows.map(formatRow)
].join('\n');
}
// Progress indicators
progress(current, total, label) {
const percentage = Math.round((current / total) * 100);
const bar = this.createProgressBar(percentage);
const stats = `${current}/${total} (${percentage}%)`;
const labelText = label ? ` ${label}` : '';
return `${bar} ${this.muted(stats)}${labelText}`;
}
createProgressBar(percentage, width = 20) {
const filled = Math.round((percentage / 100) * width);
const empty = width - filled;
if (this.useEmoji) {
return `[${'█'.repeat(filled)}${' '.repeat(empty)}]`;
}
else {
return `[${'#'.repeat(filled)}${'.'.repeat(empty)}]`;
}
}
// List formatting
bulletList(items, bullet = '•') {
const bulletChar = this.useEmoji ? bullet : '-';
return items.map(item => ` ${this.muted(bulletChar)} ${item}`).join('\n');
}
numberedList(items) {
return items.map((item, i) => ` ${this.muted(`${i + 1}.`)} ${item}`).join('\n');
}
// Semantic data science specific formatting
confidence(score) {
const percentage = Math.round(score * 100);
let color = this.theme.muted;
let emoji = '⚪';
if (score >= 0.9) {
color = this.theme.success;
emoji = '🟢';
}
else if (score >= 0.8) {
color = this.theme.warning;
emoji = '🟡';
}
else if (score >= 0.7) {
color = this.theme.error;
emoji = '🟠';
}
else {
color = this.theme.error;
emoji = '🔴';
}
const styled = this.useColor ? color(`${percentage}%`) : `${percentage}%`;
return this.useEmoji ? `${emoji} ${styled}` : styled;
}
semanticType(type) {
const typeColors = {
identifier: this.theme.primary,
email: this.theme.info,
phone: this.theme.accent,
address: this.theme.secondary,
timestamp: this.theme.warning,
currency: this.theme.success,
percentage: this.theme.warning,
url: this.theme.info,
category: this.theme.accent,
description: this.theme.muted
};
const color = typeColors[type.toLowerCase()] || this.theme.muted;
return this.useColor ? color(type) : type;
}
timeSaved(amount) {
const emoji = this.useEmoji ? '⚡ ' : '';
const styled = this.useColor ? this.theme.success.bold(amount) : amount;
return `${emoji}${styled}`;
}
// Box drawing
box(content, title, style = 'single') {
const lines = content.split('\n');
const maxWidth = Math.max(...lines.map(line => line.length));
const width = Math.max(maxWidth, title?.length || 0) + 4;
const chars = this.getBoxChars(style);
let result = [];
// Top border
if (title) {
const titlePadding = Math.max(0, width - title.length - 4);
const leftPad = Math.floor(titlePadding / 2);
const rightPad = titlePadding - leftPad;
result.push(chars.topLeft + chars.horizontal.repeat(leftPad + 1) + ` ${title} ` + chars.horizontal.repeat(rightPad + 1) + chars.topRight);
}
else {
result.push(chars.topLeft + chars.horizontal.repeat(width - 2) + chars.topRight);
}
// Content
lines.forEach(line => {
const padding = width - line.length - 4;
result.push(chars.vertical + ` ${line}${' '.repeat(padding)} ` + chars.vertical);
});
// Bottom border
result.push(chars.bottomLeft + chars.horizontal.repeat(width - 2) + chars.bottomRight);
return result.join('\n');
}
getBoxChars(style) {
const styles = {
single: {
topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',
horizontal: '─', vertical: '│'
},
double: {
topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',
horizontal: '═', vertical: '║'
},
rounded: {
topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',
horizontal: '─', vertical: '│'
}
};
return styles[style];
}
// Utility methods
dim(text) {
return this.useColor ? chalk_1.default.dim(text) : text;
}
bold(text) {
return this.useColor ? chalk_1.default.bold(text) : text;
}
underline(text) {
return this.useColor ? chalk_1.default.underline(text) : text;
}
strikethrough(text) {
return this.useColor ? chalk_1.default.strikethrough(text) : text;
}
// Output methods
print(text) {
console.log(text);
}
printSuccess(text, emoji) {
console.log(this.success(text, emoji));
}
printError(text, emoji) {
console.error(this.error(text, emoji));
}
printWarning(text, emoji) {
console.log(this.warning(text, emoji));
}
printInfo(text, emoji) {
console.log(this.info(text, emoji));
}
printTitle(text, emoji) {
console.log(this.title(text, emoji));
}
printBox(content, title, style) {
console.log(this.box(content, title, style));
}
}
exports.OutputFormatter = OutputFormatter;
// Export default formatter instance
exports.output = new OutputFormatter();
// Utility functions for quick access
exports.format = {
success: (text, emoji) => exports.output.success(text, emoji),
error: (text, emoji) => exports.output.error(text, emoji),
warning: (text, emoji) => exports.output.warning(text, emoji),
info: (text, emoji) => exports.output.info(text, emoji),
title: (text, emoji) => exports.output.title(text, emoji),
subtitle: (text) => exports.output.subtitle(text),
highlight: (text) => exports.output.highlight(text),
muted: (text) => exports.output.muted(text),
command: (text) => exports.output.command(text),
code: (text) => exports.output.code(text),
path: (text) => exports.output.path(text),
confidence: (score) => exports.output.confidence(score),
semanticType: (type) => exports.output.semanticType(type),
timeSaved: (amount) => exports.output.timeSaved(amount)
};
exports.default = OutputFormatter;
//# sourceMappingURL=output-formatter.js.map