The configuration system provides types for loading, processing, and validating commitlint configuration files. This includes support for extending configurations, loading presets, and integrating plugins.
interface UserConfig {
extends?: string | string[];
formatter?: string;
rules?: Partial<RulesConfig>;
parserPreset?: string | ParserPreset | Promise<ParserPreset>;
ignores?: ((commit: string) => boolean)[];
defaultIgnores?: boolean;
plugins?: (string | Plugin)[];
helpUrl?: string;
prompt?: UserPromptConfig;
[key: string]: unknown;
}User-provided configuration that can be loaded from .commitlintrc, package.json, or configuration files:
interface LoadOptions {
cwd?: string;
file?: string;
}Options for loading configuration:
interface QualifiedConfig {
extends: string[];
formatter: string;
rules: QualifiedRules;
parserPreset?: ParserPreset;
ignores?: ((commit: string) => boolean)[];
defaultIgnores?: boolean;
plugins: PluginRecords;
helpUrl: string;
prompt: UserPromptConfig;
}Fully processed and resolved configuration after loading and extending:
type QualifiedRules = Partial<RulesConfig<RuleConfigQuality.Qualified>>;Rules configuration where all rule values are resolved to their final tuple form (no functions or promises).
interface ParserPreset {
name?: string;
path?: string;
parserOpts?: unknown;
}Configuration for conventional-commits-parser integration:
interface Plugin {
rules: {
[ruleName: string]: Rule | AsyncRule | SyncRule;
};
}Plugin structure containing custom rules:
type PluginRecords = Record<string, Plugin>;Registry of loaded plugins mapped by plugin name.
import { UserConfig } from "@commitlint/types";
const config: UserConfig = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [2, "always", ["feat", "fix", "docs", "style", "refactor"]],
"subject-max-length": [1, "always", 50]
},
helpUrl: "https://commitlint.js.org/"
};import { UserConfig, Plugin } from "@commitlint/types";
// Custom plugin
const customPlugin: Plugin = {
rules: {
"custom-rule": (parsed, when, value) => {
// Rule implementation
return [true];
}
}
};
const config: UserConfig = {
extends: ["@commitlint/config-conventional"],
plugins: [
"@commitlint/plugin-custom",
customPlugin
],
rules: {
"custom-rule": [2, "always", { someOption: true }]
},
ignores: [
(commit) => commit.includes("[skip ci]"),
(commit) => commit.startsWith("WIP:")
],
defaultIgnores: false
};import { UserConfig, ParserPreset } from "@commitlint/types";
// String preset
const simpleConfig: UserConfig = {
parserPreset: "conventional-changelog-angular"
};
// Object preset
const objectPreset: ParserPreset = {
name: "custom-preset",
parserOpts: {
headerPattern: /^(\w*)(?:\(([\w$.\-* ]*)\))?: (.*)$/,
headerCorrespondence: ["type", "scope", "subject"],
noteKeywords: ["BREAKING CHANGE", "BREAKING CHANGES"]
}
};
const advancedConfig: UserConfig = {
parserPreset: objectPreset
};
// Promise preset (for async loading)
const promiseConfig: UserConfig = {
parserPreset: import("./custom-preset").then(m => m.preset)
};import { LoadOptions, QualifiedConfig } from "@commitlint/types";
// Load options
const loadOptions: LoadOptions = {
cwd: process.cwd(),
file: ".commitlintrc.json"
};
// Processing qualified config
function processQualifiedConfig(config: QualifiedConfig): void {
console.log(`Using formatter: ${config.formatter}`);
console.log(`Extended from: ${config.extends.join(", ")}`);
console.log(`Help URL: ${config.helpUrl}`);
// Process rules
Object.entries(config.rules).forEach(([ruleName, ruleConfig]) => {
console.log(`Rule ${ruleName}:`, ruleConfig);
});
// Process plugins
Object.keys(config.plugins).forEach(pluginName => {
console.log(`Plugin loaded: ${pluginName}`);
});
}import { UserConfig } from "@commitlint/types";
// Single extend
const singleExtend: UserConfig = {
extends: "@commitlint/config-conventional"
};
// Multiple extends (processed in order)
const multipleExtends: UserConfig = {
extends: [
"@commitlint/config-conventional",
"@commitlint/config-lerna-scopes",
"./custom-rules"
]
};
// Override extended rules
const withOverrides: UserConfig = {
extends: "@commitlint/config-conventional",
rules: {
// Override the conventional config's type-enum rule
"type-enum": [2, "always", ["feat", "fix", "docs", "custom"]],
// Add new rule not in conventional config
"custom-rule": [1, "always"]
}
};import { UserConfig, QualifiedConfig } from "@commitlint/types";
function validateUserConfig(config: UserConfig): string[] {
const errors: string[] = [];
// Validate extends
if (config.extends) {
const extends_ = Array.isArray(config.extends) ? config.extends : [config.extends];
extends_.forEach(extend => {
if (typeof extend !== "string") {
errors.push(`Invalid extends value: ${extend}`);
}
});
}
// Validate formatter
if (config.formatter && typeof config.formatter !== "string") {
errors.push("Formatter must be a string");
}
// Validate ignores
if (config.ignores) {
config.ignores.forEach((ignore, index) => {
if (typeof ignore !== "function") {
errors.push(`Ignore at index ${index} must be a function`);
}
});
}
return errors;
}