CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-consola

Elegant Console Wrapper providing sophisticated logging with multiple levels, fancy colored output, pluggable reporters, interactive prompts, and comprehensive console redirection capabilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

console-integration.mddocs/

Console Integration

Console and standard stream wrapping/mocking functionality for testing and output redirection, including pause/resume capabilities, console method wrapping, and comprehensive stream redirection.

Capabilities

Console Wrapping

Override native console methods to redirect output through Consola reporters and formatting.

interface ConsolaInstance {
  /**
   * Override console methods with Consola logging methods
   * Preserves original methods with __ prefix backup
   */
  wrapConsole(): void;
  
  /**
   * Restore original console methods from backups
   * Removes Consola overrides and restores native behavior
   */
  restoreConsole(): void;
}

Usage Examples:

import { consola } from "consola";

// Override console methods
consola.wrapConsole();

// Now console methods use Consola formatting
console.log("This goes through Consola");     // → consola.log()
console.error("Error message");               // → consola.error()
console.warn("Warning");                      // → consola.warn()

// Original methods available with __ prefix
console.__log("Direct to original console");

// Restore original console
consola.restoreConsole();
console.log("Back to native console");

Stream Wrapping

Redirect standard output and error streams through Consola processing.

interface ConsolaInstance {
  /**
   * Override stdout and stderr streams
   * Redirects stream.write() calls through Consola
   */
  wrapStd(): void;
  
  /**
   * Restore original stream write methods
   * Removes Consola stream redirection
   */
  restoreStd(): void;
}

Usage Examples:

import { consola } from "consola";

// Wrap standard streams
consola.wrapStd();

// Direct stream writes now go through Consola
process.stdout.write("Standard output");      // → consola.log()
process.stderr.write("Error output");        // → consola.log()

// Original methods available with __ prefix
process.stdout.__write("Direct to stdout");

// Restore original streams
consola.restoreStd();

Complete Integration

Wrap both console methods and standard streams for comprehensive output control.

interface ConsolaInstance {
  /**
   * Enable both console and stream wrapping
   * Equivalent to wrapConsole() + wrapStd()
   */
  wrapAll(): void;
  
  /**
   * Restore both console and stream functionality
   * Equivalent to restoreConsole() + restoreStd()
   */
  restoreAll(): void;
}

Usage Examples:

import { consola } from "consola";

// Complete output redirection
consola.wrapAll();

// All output now flows through Consola
console.log("Console message");
process.stdout.write("Stream output");
console.error("Error");

// Comprehensive restore
consola.restoreAll();

// Or selective wrapping for testing
const testLogger = consola.withTag("test");
testLogger.wrapConsole(); // Only console, not streams

Log Pausing and Resuming

Pause and resume log output with automatic queuing for deferred processing.

interface ConsolaInstance {
  /**
   * Pause all log output and queue incoming messages
   * Prevents immediate output while preserving messages
   */
  pauseLogs(): void;
  
  /**
   * Resume log output and process queued messages
   * Flushes accumulated logs in original order
   */
  resumeLogs(): void;
}

Usage Examples:

import { consola } from "consola";

// Pause logging
consola.pauseLogs();

// These messages are queued, not displayed
consola.info("Message 1");
consola.warn("Message 2");
consola.error("Message 3");

// Resume and flush queued messages
consola.resumeLogs();
// Output: All three messages display in order

// Useful for setup/teardown scenarios
async function setupWithLogging() {
  consola.pauseLogs();
  
  // Noisy setup operations
  await initializeDatabase();
  await loadConfiguration();
  await startServices();
  
  consola.resumeLogs();
  consola.success("Setup completed");
}

Mock Functions

Replace logging methods with custom mock functions for testing and log capture.

interface ConsolaInstance {
  /**
   * Replace log methods with mock functions
   * @param mockFn - Factory function creating mock implementations
   */
  mockTypes(mockFn?: ConsolaOptions["mockFn"]): void;
}

interface ConsolaOptions {
  /**
   * Mock function factory for testing
   * @param type - Log type being mocked
   * @param defaults - Default log properties for the type
   * @returns Mock function to replace the log method
   */
  mockFn?: (type: LogType, defaults: InputLogObject) => (...args: any) => void;
}

Usage Examples:

import { createConsola } from "consola";

// Capture logs for testing
const capturedLogs: any[] = [];

const testLogger = createConsola({
  mockFn: (type, defaults) => {
    return (...args) => {
      capturedLogs.push({ type, args, timestamp: Date.now() });
    };
  }
});

// All logging is captured, not output
testLogger.info("Test message", { data: 123 });
testLogger.error("Test error");

console.log(capturedLogs);
// [
//   { type: "info", args: ["Test message", { data: 123 }], timestamp: ... },
//   { type: "error", args: ["Test error"], timestamp: ... }
// ]

// Jest-style mocking
const jestLogger = createConsola({
  mockFn: (type, defaults) => jest.fn()
});

// Spy on specific log types
const debugSpy = jest.spyOn(jestLogger, 'debug');
jestLogger.debug("Debug message");
expect(debugSpy).toHaveBeenCalledWith("Debug message");

Advanced Mock Scenarios

Sophisticated mocking patterns for complex testing scenarios.

Usage Examples:

// Conditional mocking based on log type
const conditionalLogger = createConsola({
  mockFn: (type, defaults) => {
    if (type === "error") {
      // Capture errors but still output them
      return (...args) => {
        global.errorLogs = global.errorLogs || [];
        global.errorLogs.push(args);
        console.error(...args); // Still output to console
      };
    }
    
    if (type === "debug") {
      // Completely silence debug logs
      return () => {};
    }
    
    // Use default behavior for other types
    return undefined;
  }
});

// Instance-level mocking
const regularLogger = createConsola();
const mockLogger = regularLogger.create({ 
  mockFn: (type) => jest.fn() 
});

// Log aggregation and analysis
class LogAnalyzer {
  logs: Array<{ type: LogType; args: any[]; timestamp: number }> = [];
  
  createMockFn() {
    return (type: LogType, defaults: InputLogObject) => {
      return (...args: any[]) => {
        this.logs.push({ type, args, timestamp: Date.now() });
      };
    };
  }
  
  getErrorCount() {
    return this.logs.filter(log => log.type === "error").length;
  }
  
  getLogsInTimeRange(start: number, end: number) {
    return this.logs.filter(log => 
      log.timestamp >= start && log.timestamp <= end
    );
  }
}

const analyzer = new LogAnalyzer();
const analyticsLogger = createConsola({
  mockFn: analyzer.createMockFn()
});

Testing Integration

Complete testing setup patterns for different testing frameworks.

Usage Examples:

// Jest setup
describe("Application Logging", () => {
  let mockLogger: ConsolaInstance;
  let logSpy: jest.SpyInstance;
  
  beforeEach(() => {
    mockLogger = createConsola({
      mockFn: (type) => jest.fn()
    });
    logSpy = jest.spyOn(mockLogger, 'info');
  });
  
  afterEach(() => {
    jest.clearAllMocks();
  });
  
  test("should log user actions", () => {
    const service = new UserService(mockLogger);
    service.createUser({ name: "John" });
    
    expect(logSpy).toHaveBeenCalledWith(
      "User created", 
      { name: "John" }
    );
  });
});

// Vitest setup  
import { vi, describe, test, beforeEach } from "vitest";

describe("Logger Integration", () => {
  beforeEach(() => {
    const mockLogger = createConsola({
      mockFn: () => vi.fn()
    });
    
    // Replace global logger
    vi.mock("./logger", () => ({ logger: mockLogger }));
  });
});

// Manual mock validation
class TestLogCapture {
  private logs: Map<LogType, any[][]> = new Map();
  
  createLogger() {
    return createConsola({
      mockFn: (type) => {
        return (...args) => {
          if (!this.logs.has(type)) {
            this.logs.set(type, []);
          }
          this.logs.get(type)!.push(args);
        };
      }
    });
  }
  
  getLogsForType(type: LogType): any[][] {
    return this.logs.get(type) || [];
  }
  
  hasLoggedError(message: string): boolean {
    const errorLogs = this.getLogsForType("error");
    return errorLogs.some(args => 
      args.some(arg => typeof arg === "string" && arg.includes(message))
    );
  }
  
  clear() {
    this.logs.clear();
  }
}

Legacy Method Aliases

Backward compatibility support for older method names.

interface ConsolaInstance {
  // Legacy aliases (deprecated but supported)
  mock(mockFn?: ConsolaOptions["mockFn"]): void;  // → mockTypes
  pause(): void;                                  // → pauseLogs
  resume(): void;                                 // → resumeLogs
}

Types

type LogType = "silent" | "fatal" | "error" | "warn" | "log" | "info" | "success" | "fail" | "ready" | "start" | "box" | "debug" | "trace" | "verbose";

interface InputLogObject {
  level?: LogLevel;
  tag?: string;
  type?: LogType;
  message?: string;
  additional?: string | string[];
  args?: any[];
  date?: Date;
}

docs

console-integration.md

core-logging.md

index.md

instance-management.md

prompts.md

reporters.md

utilities.md

tile.json