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

linter.mddocs/

Linting Engine

Core linting functionality for processing Handlebars templates with configurable rules and comprehensive error reporting.

Capabilities

Linter Class

Main linting engine that processes templates and executes configured rules.

/**
 * Main linting engine for Ember and Handlebars templates
 * @param options - Configuration options for the linter instance
 */
class Linter {
  constructor(options?: LinterOptions): Linter;
  
  /**
   * Load configuration from project files (.template-lintrc.js, etc.)
   * Must be called before running verification
   */
  loadConfig(): Promise<void>;
  
  /**
   * Lint a template and return violations
   * @param options - Template content and metadata
   * @returns Array of linting violations
   */
  verify(options: VerifyOptions): Promise<LintResult[]>;
  
  /**
   * Lint a template and apply automatic fixes where possible
   * @param options - Template content and metadata
   * @returns Results with original source, fixed source, and remaining violations
   */
  verifyAndFix(options: VerifyOptions): Promise<FixResult>;
}

Linter Options

Configuration options for initializing a Linter instance.

interface LinterOptions {
  /** Working directory for resolving config files and plugins (default: process.cwd()) */
  workingDir?: string;
  
  /** Console object for logging (default: console) */
  console?: Console;
  
  /** Inline rule specification in format "rule-name:severity" or "rule-name:[severity, config]" */
  rule?: string;
  
  /** Path to custom configuration file */
  configPath?: string;
  
  /** Allow inline configuration comments in templates (default: true) */
  allowInlineConfig?: boolean;
  
  /** Report unused template-lint-disable directives (default: false) */
  reportUnusedDisableDirectives?: boolean;
  
  /** Check HBS template literals in JavaScript/TypeScript files (default: true) */
  checkHbsTemplateLiterals?: boolean;
}

Verify Options

Options for template verification operations.

interface VerifyOptions {
  /** Template source code to lint */
  source: string;
  
  /** File path for the template (used for configuration overrides and error reporting) */
  filePath: string;
  
  /** Working directory (defaults to linter's workingDir) */
  workingDir?: string;
  
  /** Configuration resolver for dynamic configuration */
  configResolver?: ConfigResolver;
}

interface ConfigResolver {
  /** Resolve EditorConfig settings for the file */
  editorConfig?(): Record<string, any>;
}

Lint Results

Structure of linting violation results.

interface LintResult {
  /** Name of the rule that generated this violation */
  rule: string;
  
  /** Human-readable description of the violation */
  message: string;
  
  /** Line number where violation occurs (1-based) */
  line: number;
  
  /** Column number where violation occurs (0-based) */
  column: number;
  
  /** Severity level: -1=todo, 0=ignore, 1=warning, 2=error */
  severity: -1 | 0 | 1 | 2;
  
  /** Source code context where violation occurs */
  source?: string;
  
  /** Automatic fix information if available */
  fix?: FixInfo;
  
  /** End position for multi-character violations */
  endLine?: number;
  endColumn?: number;
  
  /** Whether this is a fatal parsing error */
  fatal?: boolean;
}

interface FixInfo {
  /** Range to replace in the source */
  range: [number, number];
  
  /** Text to replace the range with */
  text: string;
}

Fix Results

Results from verifyAndFix operations.

interface FixResult {
  /** Original template source */
  source: string;
  
  /** Fixed template source (may be same as source if no fixes applied) */
  output: string;
  
  /** Remaining violations that could not be auto-fixed */
  messages: LintResult[];
  
  /** Whether any fixes were applied */
  isFixed: boolean;
}

Usage Examples:

import Linter from "ember-template-lint";

// Basic linting
const linter = new Linter();
await linter.loadConfig();

const results = await linter.verify({
  source: '<div>{{message}}</div>',
  filePath: 'app/templates/component.hbs'
});

// Auto-fixing
const fixResult = await linter.verifyAndFix({
  source: '<div   class="example"  >{{message}}</div>',
  filePath: 'app/templates/component.hbs'
});

console.log('Fixed source:', fixResult.output);
console.log('Remaining issues:', fixResult.messages);

// Custom configuration
const customLinter = new Linter({
  workingDir: '/path/to/project',
  rule: 'no-bare-strings:error',
  allowInlineConfig: false,
  reportUnusedDisableDirectives: true
});

await customLinter.loadConfig();

// Lint JavaScript template literals
const jsResults = await customLinter.verify({
  source: 'const template = hbs`<div>{{message}}</div>`;',
  filePath: 'app/components/example.js'
});

Error Handling

// Fatal errors (parsing failures) are included in results
interface FatalError extends LintResult {
  fatal: true;
  message: string;
  source: string; // Stack trace
  line?: number;
  column?: number;
}

Example with error handling:

try {
  const results = await linter.verify({
    source: '<div {{invalid-syntax}}',
    filePath: 'broken-template.hbs'
  });
  
  const fatalErrors = results.filter(r => r.fatal);
  const lintViolations = results.filter(r => !r.fatal);
  
  if (fatalErrors.length > 0) {
    console.error('Template parsing failed:', fatalErrors[0].message);
  }
  
} catch (error) {
  console.error('Linter configuration error:', error.message);
}