Template-based commit message generation with emoji support, word wrapping, and conventional commit format compliance.
/**
* Format commit message from state using configuration template
* @param state - Application state with answers and configuration
* @returns Formatted commit message string with proper line breaks and sections
*/
function formatCommitMessage(state: State): string;Generates a complete commit message following conventional commit format with:
The commit message format is controlled by the format template string in configuration:
// Default template
const format = '{type}{scope}: {emoji}{subject}';
// Template placeholders:
// {type} - Commit type (feat, fix, etc.)
// {scope} - Commit scope in parentheses or empty
// {emoji} - Commit type emoji with trailing space or empty
// {subject} - Commit subject/title{type}{scope}: {emoji}{subject}
{body}
BREAKING CHANGE: {breakingChangePrefix}{breaking}
{closedIssuePrefix}{closedIssueMessage}{issues}Section Rules:
All body text sections are wrapped at 72 characters:
// Word wrap configuration
const wrapOptions = {
indent: '', // No indentation
trim: true, // Trim whitespace
width: 72 // Maximum line width
};Emojis are conditionally added based on configuration:
// Emoji handling
const emoji = config.disableEmoji ? '' : config.types[answers.type].emoji + ' ';
const breakingEmoji = config.disableEmoji ? '' : config.breakingChangePrefix;
const closedIssueEmoji = config.disableEmoji ? '' : config.closedIssuePrefix;Scope is automatically formatted with parentheses when present:
// Scope formatting
const scope = answers.scope ? '(' + answers.scope.trim() + ')' : '';For Lerna monorepos, affected packages are appended to the body:
/**
* Create affects line for Lerna packages
* @param answers - User answers object containing packages array
* @returns Formatted affects line or empty string
*/
function makeAffectsLine(answers: Answers): string;
// Uses answers.packages (from Lerna question) not answers.lerna (CLI argument)
// Example output: "\naffects: package-a, package-b"Note: The Lerna question sets answers.packages while the CLI argument is --lerna. The makeAffectsLine function specifically looks for answers.packages.
const createState = require('git-cz/lib/createState');
const formatCommitMessage = require('git-cz/lib/formatCommitMessage');
// Create state and set answers
const state = createState();
state.answers = {
type: 'feat',
scope: 'auth',
subject: 'add OAuth integration',
body: 'Implemented OAuth 2.0 authentication flow with Google and GitHub providers. Added token refresh logic and proper error handling.',
breaking: '',
issues: '#123',
lerna: ''
};
const message = formatCommitMessage(state);
console.log(message);Output:
feat(auth): πΈ add OAuth integration
Implemented OAuth 2.0 authentication flow with Google and GitHub providers.
Added token refresh logic and proper error handling.
β
Closes: #123const state = createState();
state.answers = {
type: 'feat',
scope: 'api',
subject: 'redesign user endpoints',
body: 'Complete redesign of user management API endpoints with improved validation and response formats.',
breaking: 'User API endpoints now require authentication tokens. Response format changed from nested objects to flat structure.',
issues: '#456 #789',
lerna: ''
};
const message = formatCommitMessage(state);
console.log(message);Output:
feat(api): πΈ redesign user endpoints
Complete redesign of user management API endpoints with improved
validation and response formats.
BREAKING CHANGE: 𧨠User API endpoints now require authentication tokens.
Response format changed from nested objects to flat structure.
β
Closes: #456 #789const state = createState();
state.answers = {
type: 'fix',
scope: '',
subject: 'resolve dependency conflicts',
body: 'Fixed version conflicts between shared dependencies across packages.',
breaking: '',
issues: '',
packages: ['@myorg/core', '@myorg/utils', '@myorg/cli'] // Lerna packages
};
const message = formatCommitMessage(state);
console.log(message);Output:
fix: π resolve dependency conflicts
Fixed version conflicts between shared dependencies across packages.
affects: @myorg/core, @myorg/utils, @myorg/cliconst state = createState({
format: '{type}{scope}: {subject} {emoji}',
disableEmoji: false
});
state.answers = {
type: 'docs',
scope: 'readme',
subject: 'update installation instructions',
body: '',
breaking: '',
issues: '',
lerna: ''
};
const message = formatCommitMessage(state);
console.log(message);Output:
docs(readme): update installation instructions βοΈconst state = createState({
disableEmoji: true
});
state.answers = {
type: 'fix',
scope: 'parser',
subject: 'handle edge case in validation',
body: 'Fixed parser to properly handle empty string inputs and null values.',
breaking: 'Validation now throws TypeError for invalid input types',
issues: '#321',
lerna: ''
};
const message = formatCommitMessage(state);
console.log(message);Output:
fix(parser): handle edge case in validation
Fixed parser to properly handle empty string inputs and null values.
BREAKING CHANGE: Validation now throws TypeError for invalid input types
Closes: #321// Custom format templates
const formats = {
standard: '{type}{scope}: {emoji}{subject}',
noEmoji: '{type}{scope}: {subject}',
emojiLast: '{type}{scope}: {subject} {emoji}',
verbose: '{emoji}{type}{scope}: {subject}'
};// Length configuration
const config = {
maxMessageLength: 64, // Maximum subject length (including emoji)
minMessageLength: 3 // Minimum subject length
};// Emoji settings
const config = {
disableEmoji: false, // Enable/disable all emojis
breakingChangePrefix: '𧨠', // Breaking change emoji
closedIssuePrefix: 'β
', // Closed issue emoji
closedIssueMessage: 'Closes: ' // Issue closure message
};