@lenne.tech/cli
Version:
lenne.Tech CLI: lt
186 lines (185 loc) • 5.55 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = void 0;
/**
* Logger with support for verbose and debug output
*/
class Logger {
constructor(toolbox) {
this.metrics = new Map();
this.toolbox = toolbox;
// Check CLI flags first, then environment variable, then config
const cliVerbose = toolbox.parameters.options.verbose || toolbox.parameters.options.v;
const cliDebug = toolbox.parameters.options.debug || toolbox.parameters.options.d;
const envDebug = process.env.LT_DEBUG === '1' || process.env.LT_DEBUG === 'true';
this.verboseEnabled = cliVerbose || envDebug || false;
this.debugEnabled = cliDebug || envDebug || false;
this.metricsEnabled = process.env.LT_METRICS === '1' || process.env.LT_METRICS === 'true';
}
get print() {
return this.toolbox.print;
}
/**
* Check if verbose mode is enabled
*/
get isVerbose() {
return this.verboseEnabled || this.debugEnabled;
}
/**
* Check if debug mode is enabled
*/
get isDebug() {
return this.debugEnabled;
}
/**
* Log info message (always shown)
*/
info(message) {
this.print.info(message);
}
/**
* Log success message (always shown)
*/
success(message) {
this.print.success(message);
}
/**
* Log warning message (always shown)
*/
warn(message) {
this.print.warning(message);
}
/**
* Log error message (always shown)
*/
error(message) {
this.print.error(message);
}
/**
* Log verbose message (only shown with --verbose or --debug)
*/
verbose(message) {
if (this.isVerbose) {
this.print.info(this.print.colors.dim(`[verbose] ${message}`));
}
}
/**
* Log debug message (only shown with --debug)
*/
debug(message) {
if (this.isDebug) {
this.print.info(this.print.colors.cyan(`[debug] ${message}`));
}
}
/**
* Log a step with timing information (verbose mode)
*/
step(stepName, details) {
if (this.isVerbose) {
const timestamp = new Date().toISOString().substring(11, 23);
const msg = details ? `${stepName}: ${details}` : stepName;
this.print.info(this.print.colors.dim(`[${timestamp}] ${msg}`));
}
}
/**
* Log object as formatted JSON (debug mode)
*/
debugObject(label, obj) {
if (this.isDebug) {
this.print.info(this.print.colors.cyan(`[debug] ${label}:`));
this.print.info(JSON.stringify(obj, null, 2));
}
}
/**
* Log command execution (debug mode)
*/
debugCommand(command) {
if (this.isDebug) {
this.print.info(this.print.colors.yellow(`[cmd] ${command}`));
}
}
/**
* Create a spinner that respects verbose mode
*/
spin(text) {
const spinner = this.print.spin(text);
if (this.isVerbose) {
this.verbose(`Starting: ${text}`);
}
return spinner;
}
/**
* Log timing information
*/
timing(operation, durationMs) {
if (this.isVerbose) {
const duration = durationMs < 1000 ? `${durationMs}ms` : `${(durationMs / 1000).toFixed(2)}s`;
this.print.info(this.print.colors.dim(`[timing] ${operation}: ${duration}`));
}
}
/**
* Record a metric for an operation (for performance tracking)
*/
recordMetric(operation, durationMs) {
if (!this.metricsEnabled)
return;
const existing = this.metrics.get(operation);
if (existing) {
existing.count++;
existing.totalMs += durationMs;
}
else {
this.metrics.set(operation, { count: 1, totalMs: durationMs });
}
}
/**
* Create a timer that automatically records metrics
*/
startTimer(operation) {
const start = Date.now();
return () => {
const duration = Date.now() - start;
this.recordMetric(operation, duration);
if (this.isVerbose) {
this.timing(operation, duration);
}
return duration;
};
}
/**
* Get all collected metrics
*/
getMetrics() {
const result = new Map();
this.metrics.forEach((value, key) => {
result.set(key, {
avgMs: Math.round(value.totalMs / value.count),
count: value.count,
totalMs: value.totalMs,
});
});
return result;
}
/**
* Print metrics summary (if enabled)
*/
printMetricsSummary() {
if (!this.metricsEnabled || this.metrics.size === 0)
return;
this.print.info('');
this.print.info(this.print.colors.dim('─'.repeat(50)));
this.print.info(this.print.colors.bold('Performance Metrics:'));
const sortedMetrics = [...this.metrics.entries()].sort((a, b) => b[1].totalMs - a[1].totalMs);
for (const [operation, data] of sortedMetrics) {
const avgMs = Math.round(data.totalMs / data.count);
this.print.info(this.print.colors.dim(` ${operation}: ${data.count}x, avg ${avgMs}ms, total ${data.totalMs}ms`));
}
}
}
exports.Logger = Logger;
/**
* Extend toolbox
*/
exports.default = (toolbox) => {
toolbox.logger = new Logger(toolbox);
};