Linter for Ember or Handlebars templates.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Multiple output formats for linting results supporting console output, JSON, SARIF format, and editor integration.
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;
}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;
}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)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 formatsFormatters 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" }
]
}
};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"
});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;
}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}`;
}
}Install with Tessl CLI
npx tessl i tessl/npm-ember-template-lint