or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

ast-helpers.mdconfiguration.mdformatters.mdindex.mdlinter.mdrule-development.mdrules.md
tile.json

formatters.mddocs/

Output Formatters

Multiple output formats for linting results supporting console output, JSON, SARIF format, and editor integration.

Capabilities

Formatter Classes

Each formatter is implemented as an independent class without a shared base class. All formatters accept options in their constructor and provide a format method.

/**
 * Pretty formatter for human-readable console output
 * Default formatter with color-coded severity levels and file paths
 */
class PrettyFormatter {
  constructor(options?: FormatterOptions): PrettyFormatter;
  
  /**
   * Format lint results as pretty console output
   * @param results - Array of lint results
   * @param todoInfo - Optional TODO statistics
   * @returns Formatted string for console output
   */
  format(results: LintResult[], todoInfo?: TodoInfo): string;
}

/**
 * JSON formatter for structured output
 * Outputs results as JSON array for programmatic consumption
 */
class JsonFormatter {
  constructor(options?: FormatterOptions): JsonFormatter;
  
  /**
   * Format lint results as JSON
   * @param results - Array of lint results
   * @param todoInfo - Optional TODO statistics
   * @returns JSON string representation of results
   */
  format(results: LintResult[], todoInfo?: TodoInfo): string;
  
  /** Default file extension for JSON output */
  defaultFileExtension: 'json';
}

/**
 * SARIF formatter for Static Analysis Results Interchange Format
 * Outputs results compatible with GitHub Security tab and other SARIF consumers
 */
class SarifFormatter {
  constructor(options?: FormatterOptions): SarifFormatter;
  
  /**
   * Format lint results as SARIF format
   * @param results - Array of lint results
   * @param todoInfo - Optional TODO statistics
   * @returns SARIF-compliant JSON string
   */
  format(results: LintResult[], todoInfo?: TodoInfo): string;
  
  /** Default file extension for SARIF output */
  defaultFileExtension: 'sarif';
}

/**
 * Kakoune formatter for Kakoune editor integration
 * Uses external eslint-formatter-kakoune package
 */
class KakouneFormatter {
  constructor(options?: FormatterOptions): KakouneFormatter;
  
  /**
   * Format lint results for Kakoune editor
   * @param results - Array of lint results
   * @param todoInfo - Optional TODO statistics
   * @returns Kakoune-compatible format string
   */
  format(results: LintResult[], todoInfo?: TodoInfo): string;
}

Formatter Options

Configuration options passed to formatter constructors.

interface FormatterOptions {
  /** Print absolute file paths instead of relative paths */
  printFullPath?: boolean;
  
  /** Include TODO items in formatter output */
  includeTodo?: boolean;
  
  /** File path for output (used by some formatters) */
  outputFile?: string;
  
  /** Suppress warnings, show only errors */
  quiet?: boolean;
  
  /** Whether the system is updating TODOs */
  updateTodo?: boolean;
  
  /** Include verbose details in output */
  verbose?: boolean;
  
  /** Whether results contain data */
  hasResultData?: boolean;
  
  /** Configuration object */
  config?: any;
  
  /** Working directory path */
  workingDirectory?: string;
  
  /** Console object for output */
  console?: Console;
  
  /** Whether running in interactive mode */
  isInteractive?: boolean;
}

Formatter Loading

System for dynamically loading formatters by name.

/**
 * Load a formatter by name or path
 * @param options - Options containing format name and formatter options
 * @returns Formatter instance
 */
function loadFormatter(options: LoadFormatterOptions): Formatter;

interface LoadFormatterOptions {
  /** Formatter name or path */
  format: string;
  
  /** Options to pass to formatter constructor */
  printFullPath?: boolean;
  includeTodo?: boolean;
  outputFile?: string;
  quiet?: boolean;
  updateTodo?: boolean;
  verbose?: boolean;
  hasResultData?: boolean;
  config?: any;
  workingDirectory?: string;
  console?: Console;
  isInteractive?: boolean;
}

// Built-in formatter names
type BuiltInFormatterName = 
  | "pretty"      // Default console formatter
  | "json"        // JSON array output
  | "sarif"       // SARIF format for security tools
  | "kakoune"     // Kakoune editor integration
  | "multi";      // Multi-formatter (special case)

Multi-Formatter

Special formatter that can combine multiple output formats based on configuration.

/**
 * Multi-formatter for combining multiple output formats
 * Configured via project configuration rather than constructor options
 */
class MultiFormatter {
  constructor(options?: FormatterOptions): MultiFormatter;
  
  /**
   * Process results using configured formatters
   * Uses project configuration to determine which formatters to apply
   */
  format(results: LintResult[], todoInfo?: TodoInfo): void;
}

Usage Examples:

import { loadFormatter } from "ember-template-lint/lib/formatters/load-formatter.js";

// Load built-in formatters
const prettyFormatter = loadFormatter({ format: "pretty" });
const jsonFormatter = loadFormatter({ 
  format: "json",
  outputFile: "results.json"
});

// Format results
const results = await linter.verify({ source, filePath });
const prettyOutput = prettyFormatter.format(results);
const jsonOutput = jsonFormatter.format(results);

console.log(prettyOutput);

// Custom formatter options
const verboseFormatter = loadFormatter({
  format: "pretty",
  verbose: true,
  printFullPath: true,
  quiet: false
});

// Multi-formatter usage (configured via .template-lintrc.js)
const multiFormatter = loadFormatter({ format: "multi" });
// Uses project configuration to determine output formats

Configuration-Based Formatting

Formatters can be configured in your .template-lintrc.js:

// .template-lintrc.js
module.exports = {
  rules: {
    // ... rules
  },
  format: {
    // Single formatter
    name: "json",
    outputFile: "lint-results.json"
  }
  
  // OR multiple formatters
  format: {
    formatters: [
      { name: "pretty" },
      { name: "json", outputFile: "results.json" },
      { name: "sarif", outputFile: "results.sarif" }
    ]
  }
};

Custom Formatters

You can create custom formatters by implementing the formatter interface:

// Custom formatter example
class CustomFormatter {
  constructor(options = {}) {
    this.options = options;
  }
  
  format(results, todoInfo) {
    // Transform results into desired format
    return results.map(result => 
      `${result.filePath}:${result.line}:${result.column} - ${result.message}`
    ).join('\n');
  }
}

// Load custom formatter
const customFormatter = loadFormatter({ 
  format: "./path/to/custom-formatter.js" 
});

TODO Information

Optional TODO statistics provided to formatters when TODO functionality is enabled.

interface TodoInfo {
  /** Number of new TODOs added */
  add: number;
  
  /** Number of TODOs removed */
  remove: number;
  
  /** Number of stable TODOs (unchanged) */
  stable: number;
  
  /** Number of expired TODOs */
  expired: number;
}

Error Handling

Formatters should handle missing or malformed data gracefully:

// Formatter error handling example
class RobustFormatter {
  format(results = [], todoInfo = null) {
    if (!Array.isArray(results)) {
      return "Error: Invalid results format";
    }
    
    return results
      .filter(result => result && typeof result === 'object')
      .map(result => this.formatResult(result))
      .join('\n');
  }
  
  formatResult(result) {
    const filePath = result.filePath || '<unknown>';
    const line = result.line || 0;
    const column = result.column || 0;
    const message = result.message || 'Unknown error';
    const rule = result.rule || 'unknown-rule';
    
    return `${filePath}:${line}:${column} [${rule}] ${message}`;
  }
}