or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

@commitlint/lint

@commitlint/lint is a TypeScript library that provides core linting functionality for commitlint, a tool that validates commit messages against conventional commit format rules. It analyzes commit messages by parsing their structure and checking compliance with configurable rules, supporting both built-in and custom validation rules through a flexible plugin system.

Package Information

  • Package Name: @commitlint/lint
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @commitlint/lint

Core Imports

import lint from "@commitlint/lint";

For CommonJS:

const lint = require("@commitlint/lint").default;

Type imports from @commitlint/types:

import type { 
  LintOptions, 
  LintOutcome, 
  QualifiedRules, 
  RuleConfigSeverity 
} from "@commitlint/types";

Basic Usage

import lint from "@commitlint/lint";

// Basic linting with no rules (always passes)
const result = await lint("feat: add new feature");
console.log(result.valid); // true

// Linting with specific rules
const result = await lint(
  "feat: add new feature",
  {
    "type-enum": [2, "always", ["feat", "fix", "docs"]], // Error level
    "subject-empty": [2, "never"], // Subject must not be empty
  }
);

if (!result.valid) {
  console.log("Errors:", result.errors);
  console.log("Warnings:", result.warnings);
}

Architecture

@commitlint/lint is built around several key components:

  • Main Lint Function: Core validation logic that processes commit messages
  • Rule System: Supports both built-in rules from @commitlint/rules and custom rules via plugins
  • Parser Integration: Uses @commitlint/parse to break down commit message structure
  • Ignore Patterns: Built-in and custom ignore patterns to skip certain commit messages
  • Type System: Full TypeScript integration with comprehensive type definitions from @commitlint/types

Capabilities

Message Linting

Core linting functionality that validates commit messages against a configurable set of rules.

/**
 * Lint a commit message against commitlint rules
 * @param message - The commit message string to validate
 * @param rawRulesConfig - Optional rules configuration object
 * @param rawOpts - Optional linting options
 * @returns Promise resolving to validation results
 */
export default function lint(
  message: string,
  rawRulesConfig?: QualifiedRules,
  rawOpts?: LintOptions
): Promise<LintOutcome>;

interface LintOptions {
  /** If it should ignore the default commit messages (defaults to true) */
  defaultIgnores?: boolean;
  /** Additional commits to ignore, defined by ignore matchers */
  ignores?: Matcher[];
  /** The parser configuration to use when linting the commit */
  parserOpts?: Options;
  /** Plugin system for custom rules */
  plugins?: PluginRecords;
  /** Help URL for documentation */
  helpUrl?: string;
}

interface LintOutcome {
  /** The processed commit message as string */
  input: string;
  /** If the linted commit is considered valid */
  valid: boolean;
  /** All errors, per rule, for the commit */
  errors: LintRuleOutcome[];
  /** All warnings, per rule, for the commit */
  warnings: LintRuleOutcome[];
}

interface LintRuleOutcome {
  /** If the commit is considered valid for the rule */
  valid: boolean;
  /** The severity of the rule (1 = warning, 2 = error) */
  level: RuleConfigSeverity;
  /** The name of the rule */
  name: string;
  /** The message returned from the rule, if invalid */
  message: string;
}

Usage Examples:

import lint from "@commitlint/lint";

// Simple validation
const result = await lint("fix: resolve memory leak");

// With custom rules
const result = await lint(
  "feat(auth): add JWT support",
  {
    "type-enum": [2, "always", ["feat", "fix", "docs", "style"]],
    "scope-empty": [1, "never"], // Warning level
    "subject-min-length": [2, "always", 10],
  }
);

// With parser options
const result = await lint(
  "JIRA-123: implement feature",
  {
    "references-empty": [2, "never"],
  },
  {
    parserOpts: {
      issuePrefixes: ["JIRA-"],
    },
  }
);

// With custom ignore patterns
const result = await lint(
  "WIP: work in progress",
  {
    "type-empty": [2, "never"],
  },
  {
    ignores: [(commit) => commit.startsWith("WIP:")],
  }
);

Rule Configuration System

Rules are configured using arrays with severity level, condition, and optional value:

// QualifiedRules is imported from @commitlint/types
type QualifiedRules = Partial<RulesConfig<RuleConfigQuality.Qualified>>;

type RuleConfigTuple<T = unknown> =
  | Readonly<[RuleConfigSeverity.Disabled]> // [0]
  | Readonly<[RuleConfigSeverity, RuleConfigCondition]> // [1, "always"]
  | Readonly<[RuleConfigSeverity, RuleConfigCondition, T]>; // [2, "always", ["feat", "fix"]]

enum RuleConfigSeverity {
  Disabled = 0,
  Warning = 1,
  Error = 2,
}

type RuleConfigCondition = "always" | "never";

enum RuleConfigQuality {
  User,
  Qualified,
}

// RulesConfig interface defines all available built-in rules
interface RulesConfig<V = RuleConfigQuality.User> {
  "body-case": RuleConfig<V>;
  "body-empty": RuleConfig<V>;
  "body-full-stop": RuleConfig<V, string>;
  "body-leading-blank": RuleConfig<V>;
  "body-max-length": RuleConfig<V, number>;
  "body-max-line-length": RuleConfig<V, number>;
  "body-min-length": RuleConfig<V, number>;
  "footer-empty": RuleConfig<V>;
  "footer-leading-blank": RuleConfig<V>;
  "footer-max-length": RuleConfig<V, number>;
  "footer-max-line-length": RuleConfig<V, number>;
  "footer-min-length": RuleConfig<V, number>;
  "header-case": RuleConfig<V>;
  "header-full-stop": RuleConfig<V, string>;
  "header-max-length": RuleConfig<V, number>;
  "header-min-length": RuleConfig<V, number>;
  "header-trim": RuleConfig<V>;
  "references-empty": RuleConfig<V>;
  "scope-case": RuleConfig<V>;
  "scope-empty": RuleConfig<V>;
  "scope-enum": RuleConfig<V, string[]>;
  "scope-max-length": RuleConfig<V, number>;
  "scope-min-length": RuleConfig<V, number>;
  "signed-off-by": RuleConfig<V, string>;
  "subject-case": RuleConfig<V>;
  "subject-empty": RuleConfig<V>;
  "subject-full-stop": RuleConfig<V, string>;
  "subject-max-length": RuleConfig<V, number>;
  "subject-min-length": RuleConfig<V, number>;
  "trailer-exists": RuleConfig<V, string>;
  "type-case": RuleConfig<V>;
  "type-empty": RuleConfig<V>;
  "type-enum": RuleConfig<V, string[]>;
  "type-max-length": RuleConfig<V, number>;
  "type-min-length": RuleConfig<V, number>;
  // Plugins may add their custom rules
  [key: string]: RuleConfig<V, unknown> | RuleConfig<V, void>;
}

type RuleConfig<V = RuleConfigQuality.Qualified, T = void> = 
  V extends RuleConfigQuality.Qualified ? RuleConfigTuple<T> : RuleConfigTuple<T>;

Rule Configuration Examples:

const rules: QualifiedRules = {
  // Disable rule
  "type-empty": [0],
  
  // Warning when condition is not met
  "subject-min-length": [1, "always", 10],
  
  // Error when condition is not met
  "type-enum": [2, "always", ["feat", "fix", "docs", "style", "refactor", "test", "chore"]],
  
  // Error when condition IS met (never allow empty subjects)
  "subject-empty": [2, "never"],
};

Plugin System

Custom rules can be added through the plugin system:

type PluginRecords = Record<string, Plugin>;

interface Plugin {
  rules: {
    [ruleName: string]: Rule<unknown>;
  };
}

type Rule<Value = unknown> = (
  parsed: Commit,
  when?: RuleConfigCondition,
  value?: Value
) => RuleOutcome | Promise<RuleOutcome>;

type RuleOutcome = Readonly<[boolean, string?]>;

Plugin Usage Example:

import lint from "@commitlint/lint";

const result = await lint(
  "custom: my commit",
  {
    "custom-rule": [2, "always", "required-value"],
  },
  {
    plugins: {
      "my-plugin": {
        rules: {
          "custom-rule": (parsed, when, value) => {
            const isValid = parsed.header?.includes(value) ?? false;
            return [isValid, isValid ? "" : `Header must contain "${value}"`];
          },
        },
      },
    },
  }
);

Parser Options

Configure how commit messages are parsed (using Options from conventional-commits-parser):

interface Options {
  /** Custom header pattern regex */
  headerPattern?: RegExp;
  /** Issue reference prefixes (e.g., ["JIRA-", "TICKET-"]) */
  issuePrefixes?: string[];
  /** Comment character to ignore in commit messages */
  commentChar?: string;
  /** Custom merge pattern regex */
  mergePattern?: RegExp;
  /** Custom revert pattern regex */
  revertPattern?: RegExp;
  /** Merge correlation pattern */
  mergeCorrespondence?: string[];
  /** Revert correspondence pattern */
  revertCorrespondence?: string[];
  /** Field patterns for parsing */
  fieldPattern?: RegExp;
  /** Header correspondence */
  headerCorrespondence?: string[];
  /** Note keywords for parsing commit notes */
  noteKeywords?: string[];
  /** Reference actions for parsing references */
  referenceActions?: string[];
}

Error Handling

The lint function throws errors for invalid configurations:

  • RangeError: When rules are configured but not implemented
  • Error: When rule configurations are invalid (wrong format, invalid severity levels, etc.)

Error Examples:

// Throws RangeError for unknown rule
await lint("test", { "unknown-rule": [2, "always"] });
// RangeError: Found rules without implementation: unknown-rule

// Throws Error for invalid config format
await lint("test", { "type-enum": "invalid" } as any);
// Error: config for rule type-enum must be array

// Throws Error for invalid severity level
await lint("test", { "type-enum": [5, "always"] } as any);
// Error: level for rule type-enum must be between 0 and 2

Ignore Patterns

Control which commit messages are ignored during linting:

type Matcher = (commit: string) => boolean;

interface IsIgnoredOptions {
  /** Custom ignore pattern functions */
  ignores?: Matcher[];
  /** Whether to use built-in default ignore patterns */
  defaults?: boolean;
}

Default ignore patterns include:

  • Merge commits: Merge branch ...
  • Revert commits: Revert "..."
  • Fixup commits: fixup! ...
  • Squash commits: squash! ...

Custom Ignore Example:

const result = await lint(
  "WIP: work in progress",
  { "type-empty": [2, "never"] },
  {
    defaultIgnores: true, // Keep default ignores
    ignores: [
      (commit) => commit.startsWith("WIP:"),
      (commit) => commit.includes("[skip-lint]"),
    ],
  }
);
// This commit will be ignored and return { valid: true }

Types

interface Commit {
  raw: string;
  header: string | null;
  type: string | null;
  scope: string | null;
  subject: string | null;
  body: string | null;
  footer: string | null;
  notes: CommitNote[];
  references: CommitReference[];
  mentions: string[];
  merge: string | null;
  revert: Revert | null;
}

interface CommitNote {
  title: string;
  text: string;
}

interface CommitReference {
  action: string;
  owner: string | null;
  repository: string | null;
  issue: string;
  raw: string;
  prefix: string;
}

interface Revert {
  header: string | null;
  hash: string | null;
}