Shared TypeScript type definitions for the commitlint ecosystem.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The commit parsing system provides types for integrating with conventional-commits-parser to parse and analyze commit message structure. This enables extracting structured data from commit messages for validation and processing.
type Parser = (message: string, options: Options) => Omit<Commit, "raw">;Parser function that converts a raw commit message string into a structured commit object:
The parsing types integrate directly with the conventional-commits-parser library:
import type { Commit, Options } from "conventional-commits-parser";import { Parser } from "@commitlint/types";
import { sync as parser } from "conventional-commits-parser";
// Using the parser type
const parseCommit: Parser = (message, options) => {
const parsed = parser(message, options);
// Remove raw property to match return type
const { raw, ...commit } = parsed;
return commit;
};
// Parse a commit message
const commitMessage = "feat(auth): add OAuth2 integration\n\nThis enables users to login with Google and GitHub.";
const parsedCommit = parseCommit(commitMessage, {
headerPattern: /^(\w*)(?:\(([\w$.\-* ]*)\))?: (.*)$/,
headerCorrespondence: ["type", "scope", "subject"]
});
console.log(parsedCommit);
// {
// type: "feat",
// scope: "auth",
// subject: "add OAuth2 integration",
// header: "feat(auth): add OAuth2 integration",
// body: "This enables users to login with Google and GitHub.",
// footer: null,
// notes: [],
// references: [],
// mentions: [],
// revert: null
// }import { Parser } from "@commitlint/types";
import type { Options } from "conventional-commits-parser";
// Custom parser options for different commit formats
const angularOptions: Options = {
headerPattern: /^(\w*)(?:\(([\w$.\-* ]*)\))?: (.*)$/,
headerCorrespondence: ["type", "scope", "subject"],
noteKeywords: ["BREAKING CHANGE"],
revertPattern: /^(?:Revert|revert:)\s"?([\s\S]+?)"?\s*This reverts commit (\w*)\./i,
revertCorrespondence: ["header", "hash"]
};
const conventionalCommitsOptions: Options = {
headerPattern: /^(\w*)(?:\((.*)\))?!?: (.*)$/,
headerCorrespondence: ["type", "scope", "subject"],
noteKeywords: ["BREAKING CHANGE", "BREAKING-CHANGE"],
issuePrefixes: ["#", "gh-"],
referenceActions: [
"close", "closes", "closed",
"fix", "fixes", "fixed",
"resolve", "resolves", "resolved"
]
};
// Parser factory
function createParser(options: Options): Parser {
return (message, parserOptions) => {
const mergedOptions = { ...options, ...parserOptions };
const parsed = parser(message, mergedOptions);
const { raw, ...commit } = parsed;
return commit;
};
}
const angularParser = createParser(angularOptions);
const conventionalParser = createParser(conventionalCommitsOptions);import { Parser, LintOptions } from "@commitlint/types";
import type { Options } from "conventional-commits-parser";
// Using parser in lint context
function createLintOptions(
customParser?: Parser,
parserOpts?: Options
): LintOptions {
return {
parserOpts: parserOpts || {
headerPattern: /^(\w*)(?:\(([\w$.\-* ]*)\))?: (.*)$/,
headerCorrespondence: ["type", "scope", "subject"],
noteKeywords: ["BREAKING CHANGE"]
},
defaultIgnores: true,
ignores: [
(commit) => commit.startsWith("Merge"),
(commit) => commit.startsWith("Revert")
]
};
}
// Example usage with custom parsing options
const lintOptions = createLintOptions(undefined, {
headerPattern: /^(\w+)(\(.+\))?: (.+)$/,
headerCorrespondence: ["type", "scope", "subject"],
fieldPattern: /^-(.*?)-$/,
noteKeywords: ["BREAKING CHANGE", "DEPRECATED"],
referenceActions: ["closes", "fixes", "resolves"]
});import { Parser } from "@commitlint/types";
import type { Commit } from "conventional-commits-parser";
// Analyzer using parsed commit structure
function analyzeCommit(parser: Parser, message: string, options: Options) {
const commit = parser(message, options);
return {
hasType: Boolean(commit.type),
hasScope: Boolean(commit.scope),
hasSubject: Boolean(commit.subject),
hasBody: Boolean(commit.body),
hasFooter: Boolean(commit.footer),
hasBreakingChanges: commit.notes?.some(note =>
note.title === "BREAKING CHANGE"
) || false,
references: commit.references?.length || 0,
mentions: commit.mentions?.length || 0,
isRevert: Boolean(commit.revert),
// Validation helpers
isValid: Boolean(commit.type && commit.subject),
isEmpty: !commit.type && !commit.subject && !commit.body,
// Structure summary
structure: {
header: commit.header,
components: {
type: commit.type,
scope: commit.scope,
subject: commit.subject
},
body: commit.body,
footer: commit.footer
}
};
}
// Usage
const analysis = analyzeCommit(
parseCommit,
"feat(api)!: add user authentication\n\nBREAKING CHANGE: API now requires auth tokens\n\nCloses #123",
angularOptions
);
console.log(analysis);
// {
// hasType: true,
// hasScope: true,
// hasSubject: true,
// hasBody: false,
// hasFooter: false,
// hasBreakingChanges: true,
// references: 1,
// mentions: 0,
// isRevert: false,
// isValid: true,
// isEmpty: false,
// structure: { ... }
// }import { Parser } from "@commitlint/types";
import type { Options } from "conventional-commits-parser";
// Parser that detects and handles multiple commit formats
class MultiFormatParser {
private parsers: Map<string, { parser: Parser; options: Options }> = new Map();
addFormat(name: string, parser: Parser, options: Options) {
this.parsers.set(name, { parser, options });
}
parse(message: string): { format: string; commit: ReturnType<Parser> } | null {
for (const [format, { parser, options }] of this.parsers) {
try {
const commit = parser(message, options);
// Check if parse was successful (has required components)
if (commit.type && commit.subject) {
return { format, commit };
}
} catch (error) {
// Continue to next parser
continue;
}
}
return null; // No parser succeeded
}
}
// Setup multi-format parser
const multiParser = new MultiFormatParser();
multiParser.addFormat("angular", parseCommit, angularOptions);
multiParser.addFormat("conventional", parseCommit, conventionalCommitsOptions);
multiParser.addFormat("custom", parseCommit, {
headerPattern: /^(\w+): (.+)$/,
headerCorrespondence: ["type", "subject"]
});
// Usage
const result = multiParser.parse("feat: add new feature");
if (result) {
console.log(`Detected format: ${result.format}`);
console.log("Parsed commit:", result.commit);
}import { Parser } from "@commitlint/types";
import type { Options, Commit } from "conventional-commits-parser";
// Validation wrapper for parser
function createValidatingParser(
baseParser: Parser,
validator: (commit: Omit<Commit, "raw">) => string[]
): Parser {
return (message, options) => {
const commit = baseParser(message, options);
const errors = validator(commit);
if (errors.length > 0) {
throw new Error(`Parse validation failed: ${errors.join(", ")}`);
}
return commit;
};
}
// Validation rules
function validateParsedCommit(commit: Omit<Commit, "raw">): string[] {
const errors: string[] = [];
if (!commit.type) {
errors.push("Missing commit type");
}
if (!commit.subject) {
errors.push("Missing commit subject");
}
if (commit.subject && commit.subject.length > 50) {
errors.push("Subject too long (max 50 characters)");
}
if (commit.type && !["feat", "fix", "docs", "style", "refactor", "test", "chore"].includes(commit.type)) {
errors.push(`Invalid commit type: ${commit.type}`);
}
return errors;
}
// Create validating parser
const validatingParser = createValidatingParser(parseCommit, validateParsedCommit);
// Usage
try {
const commit = validatingParser("invalid: this is a very long subject that exceeds the maximum allowed length", angularOptions);
console.log("Valid commit:", commit);
} catch (error) {
console.error("Parse error:", error.message);
}