import { CommitType, CommitFooter, ConventionalCommit } from '../models'; /** * In-progress version of a `ConventionalCommit` accumulated field-by-field * during an interactive authoring session. Every field is optional so the * formatter can render intermediate states (e.g. the header as it exists * after only `type` has been picked). * * @see ConventionalCommit */ interface CommitDraft { /** Commit type (feat, fix, docs, etc.) */ readonly type?: CommitType; /** Scopes in parentheses (empty or omitted = no scope) */ readonly scope?: readonly string[]; /** Subject line */ readonly subject?: string; /** Full commit body */ readonly body?: string; /** Footer trailers: caller may leave out `BREAKING CHANGE:`; the formatter will synthesize it when needed */ readonly footers?: readonly CommitFooter[]; /** Whether this is a breaking change: controls the `!` subject marker */ readonly breaking?: boolean; /** Breaking change description: surfaces as a `BREAKING CHANGE:` footer when none is already present */ readonly breakingDescription?: string; } /** * Promotes any `ConventionalCommit` to a `CommitDraft`. Useful for editing * a parsed commit inside an authoring session. * * @param commit - Parsed conventional commit * @returns A draft carrying the same fields as the commit * * @example Promoting a parsed commit to an editable draft * ```typescript * toDraft(parseConventionalCommit('feat: add login')) * // => { type: 'feat', scope: [], subject: 'add login', footers: [], breaking: false } * ``` */ declare function toDraft(commit: ConventionalCommit): CommitDraft; /** * Computes the character length of the final header including the * `type(scope)!: ` prefix and the supplied subject. Powers the live * 72-character countdown shown during the subject prompt. * * The subject is passed separately (not read from `draft.subject`) because * the caller typically has not yet committed the in-flight input to the * draft. * * @param draft - Draft supplying type, scope, and breaking marker * @param subject - Subject text being typed * @returns Character length the final header will occupy * * @example Counting a header mid-type * ```typescript * countHeaderLength({ type: 'feat', scope: ['core'] }, 'add login') * // => 'feat(core): add login'.length === 21 * ``` */ declare function countHeaderLength(draft: CommitDraft, subject: string): number; /** * Builds the header line (`type(scope)!: subject`) from a draft. * * Missing fields render as empty; this is intentional so the header can be * displayed incrementally during authoring (e.g. before the subject has been * typed). Scopes are comma-joined to match the parser's multi-scope format. * * @param draft - Draft to render (may be partial) * @returns Header line; never contains a newline * * @example Rendering a complete header * ```typescript * formatHeader({ type: 'feat', scope: ['core'], subject: 'add login' }) * // => 'feat(core): add login' * ``` * * @example Rendering a multi-scope breaking-change header * ```typescript * formatHeader({ type: 'feat', scope: ['versioning', 'questions'], subject: 'add x', breaking: true }) * // => 'feat(versioning,questions)!: add x' * ``` * * @example Rendering a partially-built draft mid-session * ```typescript * formatHeader({ type: 'fix' }) * // => 'fix: ' * ``` */ declare function formatHeader(draft: CommitDraft): string; /** * Renders a draft as the final commit message string: the exact text that * would be written to `.git/COMMIT_EDITMSG`. Layout: header, blank line, * body, blank line, footers. * * If `draft.breaking` and `draft.breakingDescription` are set and no * `BREAKING CHANGE:`-family footer is already present, one is synthesized * at the top of the footer block so the preview mirrors what a compliant * parser will read back. * * @param draft - Commit draft to render * @returns Full commit message string with `\n` separators * * @example Header only * ```typescript * formatCommitMessage({ type: 'feat', subject: 'add login' }) * // => 'feat: add login' * ``` * * @example Multi-scope breaking change with closing footer * ```typescript * formatCommitMessage({ * type: 'feat', * scope: ['versioning', 'questions'], * subject: 'add x', * breaking: true, * breakingDescription: 'removed Y', * footers: [{ key: 'Closes', value: '#1', separator: ':' }], * }) * // => 'feat(versioning,questions)!: add x\n\nBREAKING CHANGE: removed Y\nCloses: #1' * ``` */ declare function formatCommitMessage(draft: CommitDraft): string; export { countHeaderLength, formatCommitMessage, formatHeader, toDraft }; export type { CommitDraft };