@hyperfrontend/versioning/changelogChangelog Module
The changelog module provides comprehensive parsing, manipulation, and serialization of CHANGELOG.md files.
Architecture Overview
Module Dependencies
Data Model
Parse Pipeline
Section Types
The module recognizes these standard changelog section types:
| Type | Common Headings |
|---|---|
breaking |
Breaking Changes, BREAKING |
features |
Features, Added, New |
fixes |
Bug Fixes, Fixed |
performance |
Performance, Perf |
documentation |
Documentation, Docs |
deprecations |
Deprecated |
refactoring |
Refactored, Refactor |
tests |
Tests, Testing |
build |
Build, Dependencies |
ci |
CI, Continuous Integration |
chores |
Chores, Misc |
other |
Other (fallback) |
Usage Examples
Parsing a Changelog
import { parseChangelog } from '@hyperfrontend/versioning'
const markdown = `
# Changelog
## [1.0.0] - 2024-01-15
### Features
- Initial release
`
const changelog = parseChangelog(markdown)
Creating a Changelog Programmatically
import { createChangelog, createChangelogEntry, createChangelogSection, createChangelogItem } from '@hyperfrontend/versioning'
const changelog = createChangelog({
header: { title: '# Changelog', description: [], links: [] },
entries: [
createChangelogEntry('1.0.0', {
date: '2024-01-15',
sections: [createChangelogSection('features', 'Features', [createChangelogItem('Initial release')])],
}),
],
metadata: { format: 'keep-a-changelog', isConventional: false, warnings: [] },
})
Serializing to Markdown
import { serializeChangelog } from '@hyperfrontend/versioning'
const markdown = serializeChangelog(changelog, {
includeScope: true,
useAsterisks: false,
})
Comparing Changelogs
import { isChangelogEqual, diffChangelogs } from '@hyperfrontend/versioning'
const areEqual = isChangelogEqual(changelog1, changelog2)
const diff = diffChangelogs(changelog1, changelog2)
Filtering Entries
import { filterByVersionRange, filterBreakingChanges } from '@hyperfrontend/versioning'
const recent = filterByVersionRange(changelog, '1.0.0', '2.0.0')
const breaking = filterBreakingChanges(changelog)
Merging Changelogs
import { mergeChangelogs } from '@hyperfrontend/versioning'
const result = mergeChangelogs(source, target, {
entryStrategy: 'union',
sectionStrategy: 'union',
itemStrategy: 'union',
})
Transforming Entries
import { transformEntries, sortEntries, compact } from '@hyperfrontend/versioning'
const updated = transformEntries(changelog, (entry) => ({
...entry,
date: entry.date ?? new Date().toISOString().split('T')[0],
}))
const sorted = sortEntries(updated)
const cleaned = compact(sorted)
Merge Strategies
| Strategy | Entry Behavior | Section Behavior | Item Behavior |
|---|---|---|---|
source |
Use source entry | Use source section | Use source item |
target |
Use target entry | Use target section | Use target item |
union |
Include both (unique) | Combine sections | Combine items |
latest |
Use newer entry | Merge by type | Replace by description |
Design Principles
- Immutability: All operations return new objects; inputs are never mutated
- No Regex: Character-by-character parsing to prevent ReDoS vulnerabilities
- Functional: Pure functions without class-based state
- Lossless: Round-trip parsing preserves original formatting where possible
- Type-Safe: Full TypeScript support with strict typing
See Also
- semver/ — Version parsing and comparison
- commits/ — Generates changelog entries from commits
- flow/ — Orchestrates changelog generation
- workspace/ — Discovers changelog files
- Main README — Package overview and quick start
- ARCHITECTURE.md — Design principles and data flow
API Reference
ƒ Functions
addEntry(changelog: Changelog, entry: ChangelogEntry, options?: AddEntryOptions): Changelog
Parameters
Returns
ChangelogExample
Adding a new entry to a changelog
const newChangelog = addEntry(changelog, {
version: '1.2.0',
date: '2024-01-15',
unreleased: false,
sections: [...]
})addItemToEntry(changelog: Changelog, version: string, sectionType: string, item: ChangelogItem): Changelog
Parameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog containing the entry to modify |
§version | string | The version identifier of the entry to update |
§sectionType | string | Category identifier for grouping changes (e.g., 'features', 'fixes') |
§item | ChangelogItem | Description of the change with optional scope and metadata |
Returns
ChangelogExample
Adding a feature item to an entry
const item = { description: 'Add dark mode support', scope: 'ui' }
const updated = addItemToEntry(changelog, '1.2.0', 'features', item)
// Item added to the features section of version 1.2.0Parameters
Returns
ChangelogExample
Adding an unreleased entry with sections
const sections = [createChangelogSection('features', 'Added', [item])]
const updated = addUnreleasedEntry(changelog, sections)
// => Changelog with unreleased entry at the topappendChangelog(source: Changelog, target: Changelog, position: "start" | "end"): Changelog
Parameters
Returns
ChangelogExample
Appending entries to a changelog
const combined = appendChangelog(mainChangelog, newChangelog, 'start')
// newChangelog entries appear before mainChangelog entriesParameters
Returns
CompatibilityResultExample
Checking schema compatibility before merge
const result = checkSchemaCompatibility(mainChangelog, branchChangelog)
if (!result.compatible) {
console.log('Schema differences:', result.differences)
}Parameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to clone |
Returns
ChangelogExample
Cloning a changelog
const copy = cloneChangelog(changelog)
// Independent deep copy, safe to mutateParameters
Returns
ChangelogExample
Combining multiple changelogs
const unified = combineChangelogs([pkg1Changelog, pkg2Changelog], {
strategy: 'merge-sections',
})
// All entries from both changelogs merged with conflict resolutionParameters
Returns
ChangelogExample
Compacting a changelog
const compacted = compact(changelog)
// Empty sections and entries removed (unreleased kept)
const strict = compact(changelog, false)
// Even empty unreleased entry is removedParameters
| Name | Type | Description |
|---|---|---|
§options? | Partial<Changelog> | Optional configuration to customize the changelog |
Returns
ChangelogExample
Creating a changelog with custom source
const changelog = createChangelog({ source: 'CHANGELOG.md' })
// => { source: 'CHANGELOG.md', header: { title: '# Changelog', ... }, entries: [] }createChangelogEntry(version: string, options?: Partial<Omit<ChangelogEntry, "version">>): ChangelogEntry
Parameters
Returns
ChangelogEntryExample
Creating a changelog entry with date and sections
const entry = createChangelogEntry('1.0.0', {
date: '2024-01-15',
sections: [createChangelogSection('features', 'Added', items)],
})createChangelogItem(description: string, options?: Partial<Omit<ChangelogItem, "description">>): ChangelogItem
Parameters
Returns
ChangelogItemExample
Creating a changelog item with options
const item = createChangelogItem('Add user authentication', {
scope: 'auth',
breaking: false,
references: [{ number: 42, type: 'issue' }],
})Parameters
Returns
ChangelogLinkExample
Creating a version comparison link
const link = createChangelogLink('1.0.0', 'https://github.com/org/repo/compare/v0.9.0...v1.0.0')
// => { label: '1.0.0', url: 'https://github.com/...' }createChangelogSection(type: ChangelogSectionType, heading: string, items: unknown): ChangelogSection
Parameters
Returns
ChangelogSectionExample
Creating a features section with items
const section = createChangelogSection('features', 'Added', [
createChangelogItem('New dashboard widget'),
])Returns
CommitRefExample
Creating a commit reference
const ref = createCommitRef('abc1234def5678', 'https://github.com/org/repo/commit/abc1234def5678')
// => { hash: 'abc1234def5678', shortHash: 'abc1234', url: 'https://...' }Returns
ChangelogExample
Creating an empty changelog with standard header
const changelog = createEmptyChangelog()
// => Changelog with standard Keep a Changelog header and no entriesParameters
Returns
IssueRefExample
Creating issue and PR references
const issueRef = createIssueRef(42, 'issue', 'https://github.com/org/repo/issues/42')
// => { number: 42, type: 'issue', url: 'https://...' }
const prRef = createIssueRef(123, 'pull-request')
// => { number: 123, type: 'pull-request', url: undefined }Returns
stringExample
Creating blank line spacing
createSpacing(2, '\n')
// => '\n\n'Parameters
| Name | Type | Description |
|---|---|---|
§sections | unknown | Optional array of changelog sections (default: []) |
Returns
ChangelogEntryExample
Creating an unreleased entry
const unreleased = createUnreleasedEntry([
createChangelogSection('features', 'Added', [item]),
])
// => { version: 'Unreleased', date: null, unreleased: true, sections: [...] }Parameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to deduplicate |
Returns
ChangelogExample
Deduplicating items across sections
const deduped = deduplicateItems(changelog)
// Duplicate items (same scope:description) are removedParameters
Returns
ChangelogDiffExample
Comparing two changelogs
const diff = diffChangelogs(mainChangelog, branchChangelog)
console.log(`Added: ${diff.added.length}, Removed: ${diff.removed.length}`)Parameters
Returns
EntryDiffExample
Computing diff between two entries
const diff = diffEntries(entryV1, entryV2)
// => { version: '1.0.0', changes: [{ path: ['date'], type: 'changed', ... }], sectionsChanged: true }Parameters
Returns
ChangelogExample
Excluding items by scope
const publicChanges = excludeByScope(changelog, ['internal', 'test'])
// Items scoped to 'internal' or 'test' are removedParameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to filter |
Returns
ChangelogExample
Filtering for breaking changes
const breaking = filterBreakingChanges(changelog)
// Only entries containing breaking changes or items marked as breakingParameters
Returns
ChangelogExample
Filtering entries by date range
const q1 = filterByDateRange(changelog, '2024-01-01', '2024-03-31')
// Entries released in Q1 2024Parameters
Returns
ChangelogExample
Filtering items by scope
const apiChanges = filterByScope(changelog, ['api', 'core'])
// Only items scoped to 'api' or 'core'Parameters
Returns
ChangelogExample
Filtering by semver range
const majors = filterByVersionRange(changelog, '>=1.0.0 <2.0.0')Parameters
Returns
ChangelogExample
Filtering out unreleased entries
const filtered = filterEntries(changelog, (entry) => !entry.unreleased)Parameters
Returns
ChangelogExample
Filtering from a start version
const recent = filterFromVersion(changelog, '2.0.0')
// Only entries for version 2.0.0 and laterParameters
Returns
ChangelogExample
Filtering items with references
const withRefs = filterItems(changelog, (item) => item.references.length > 0)
// Only items with issue/PR referencesfilterRecentEntries(changelog: Changelog, count: number, includeUnreleased: boolean): Changelog
Parameters
Returns
ChangelogExample
Getting the most recent entries
const latest = filterRecentEntries(changelog, 5)
// Last 5 released versions (plus unreleased if present)Parameters
Returns
ChangelogExample
Filtering for user-facing sections
const userFacing = filterSections(changelog, (section) =>
['features', 'fixes', 'breaking'].includes(section.type)
)Parameters
Returns
ChangelogExample
Filtering to specific section types
const userChanges = filterSectionTypes(changelog, ['features', 'fixes'])
// Only features and fixes sections remainParameters
Returns
ChangelogExample
Filtering to an end version
const legacy = filterToVersion(changelog, '1.9.9')
// Only entries for versions up to 1.9.9filterVersionRange(changelog: Changelog, startVersion: string, endVersion: string): Changelog
Parameters
Returns
ChangelogExample
Filtering entries within a version range
const range = filterVersionRange(changelog, '1.5.0', '2.0.0')
// Entries from 1.5.0 through 2.0.0Parameters
Returns
stringExample
Formatting a markdown link
formatLink('1.0.0', 'https://github.com/org/repo/releases/tag/v1.0.0')
// => '[1.0.0](https://github.com/org/repo/releases/tag/v1.0.0)'Parameters
Returns
ChangelogEntryExample
Getting an entry by version
const entry = getEntryByVersion(changelog, '1.0.0')
// => ChangelogEntry for 1.0.0 or undefinedParameters
| Name | Type | Description |
|---|---|---|
§useAsterisks | boolean | Whether to use * instead of - |
Returns
stringExample
Getting list markers
getListMarker(false) // => '- '
getListMarker(true) // => '* 'getSectionHeading(type: ChangelogSectionType, customHeadings?: Partial<Record<ChangelogSectionType, string>>): string
Parameters
Returns
stringExample
Getting section headings
getSectionHeading('features')
// => 'Added'
getSectionHeading('features', { features: 'New Features' })
// => 'New Features'Parameters
| Name | Type | Description |
|---|---|---|
§heading | string | The heading string to parse |
Returns
ChangelogSectionTypeExample
Mapping heading strings to section types
getSectionType('Added')
// => 'features'
getSectionType('Bug Fixes')
// => 'fixes'
getSectionType('Custom Section')
// => 'other'Parameters
| Name | Type | Description |
|---|---|---|
§hash | string | The full commit hash |
Returns
stringExample
Extracting short hash from full hash
getShortHash('abc1234def5678901234567890')
// => 'abc1234'Parameters
Returns
booleanExample
Checking if a changelog contains a version
hasVersion(changelog, '2.0.0')
// => true if an entry for version 2.0.0 existsReturns
booleanExample
Checking if changelogs have the same versions
haveSameVersions(changelog1, changelog2)
// => true if both have entries for the same version stringsReturns
booleanExample
Checking changelog equality
if (isChangelogEqual(mainChangelog, branchChangelog)) {
console.log('Changelogs are identical')
}Returns
booleanExample
Comparing commit references
isCommitRefEqual(commitA, commitB)
// => true if hash, shortHash, and url matchReturns
booleanExample
Comparing changelog entries
isEntryEqual(entryA, entryB)
// => true if version, date, sections, and all nested data matchReturns
booleanExample
Comparing changelog headers
isHeaderEqual(changelog1.header, changelog2.header)
// => true if titles, descriptions, and links matchReturns
booleanExample
Comparing issue references
isIssueRefEqual({ number: 42, type: 'issue' }, { number: 42, type: 'issue' })
// => trueReturns
booleanExample
Comparing changelog items
isItemEqual(itemA, itemB)
// => true if description, scope, breaking, commits, and references matchReturns
booleanExample
Comparing changelog links
isLinkEqual({ label: '1.0.0', url: '...' }, { label: '1.0.0', url: '...' })
// => trueReturns
booleanExample
Comparing changelog metadata
isMetadataEqual(changelog1.metadata, changelog2.metadata)
// => true if format, isConventional, repositoryUrl, and warnings matchReturns
booleanExample
Comparing changelog sections
isSectionEqual(featuresA, featuresB)
// => true if type, heading, and all items matchParameters
Returns
MergeResultExample
Merging two changelogs
const result = mergeChangelogs(mainChangelog, branchChangelog)
console.log(`Merged ${result.stats.merged} entries`)Parameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to normalize |
Returns
ChangelogExample
Normalizing section headings
const normalized = normalizeSectionHeadings(changelog)
// 'New Features' becomes 'Added', 'Bug Fixes' becomes 'Fixed', etc.Parameters
Returns
ChangelogExample
Parsing a changelog markdown string
const markdown = `# Changelog
## [1.0.0] - 2024-01-15
### Added
- Initial release`
const changelog = parseChangelog(markdown, 'CHANGELOG.md')
// => { header: { title: '# Changelog', ... }, entries: [{ version: '1.0.0', ... }] }Parameters
Returns
CommitRef[]Example
Parsing commit references from text
parseCommitRefs('Fixed bug (abc1234)', 'https://github.com/org/repo')
// => [{ hash: 'abc1234', shortHash: 'abc1234', url: 'https://github.com/org/repo/commit/abc1234' }]Parameters
Returns
IssueRef[]Example
Parsing issue references from text
parseIssueRefs('Closes #42 and PR #123', 'https://github.com/org/repo')
// => [{ number: 42, type: 'issue', url: '...' }, { number: 123, type: 'pull-request', url: '...' }]Parameters
| Name | Type | Description |
|---|---|---|
§text | string | The text to parse for scope |
Returns
ScopeFromItemExample
Parsing scope from changelog items
parseScopeFromItem('**api:** Add new endpoint')
// => { scope: 'api', description: 'Add new endpoint' }
parseScopeFromItem('Simple change without scope')
// => { scope: undefined, description: 'Simple change without scope' }Parameters
| Name | Type | Description |
|---|---|---|
§heading | string | The heading string to parse |
Returns
ParsedVersionHeadingExample
Parsing version headings
parseVersionFromHeading('[1.2.3] - 2024-01-15')
// => { version: '1.2.3', date: '2024-01-15', compareUrl: undefined }
parseVersionFromHeading('v2.0.0')
// => { version: '2.0.0', date: null, compareUrl: undefined }releaseUnreleased(changelog: Changelog, version: string, date?: string, compareUrl?: string): Changelog
Parameters
Returns
ChangelogExample
Releasing unreleased changes as a new version
const released = releaseUnreleased(changelog, '2.0.0', '2024-03-01')
// Unreleased entry becomes version 2.0.0 with the specified dateParameters
Returns
ChangelogExample
Removing empty entries
const cleaned = removeEmptyEntries(changelog)
// Entries with no content are removed (unreleased kept by default)
const strict = removeEmptyEntries(changelog, false)
// Even empty unreleased entry is removedParameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to remove empty sections from |
Returns
ChangelogExample
Removing empty sections from all entries
const cleaned = removeEmptySections(changelog)
// Sections with no items are removed from all entriesremoveEntries(changelog: Changelog, versions: unknown, options?: RemoveEntryOptions): Changelog
Parameters
Returns
ChangelogExample
Removing multiple entries
const cleaned = removeEntries(changelog, ['0.1.0', '0.2.0'])
// Pre-release versions removed from changelogremoveEntry(changelog: Changelog, version: string, options?: RemoveEntryOptions): Changelog
Parameters
Returns
ChangelogExample
Removing an entry by version
const newChangelog = removeEntry(changelog, '1.0.0')removeItem(changelog: Changelog, version: string, sectionType: string, itemDescription: string, options?: RemoveSectionOptions): Changelog
Parameters
Returns
ChangelogExample
Removing a specific item from a section
const updated = removeItem(changelog, '1.0.0', 'features', 'Add dark mode')
// The 'Add dark mode' item is removed from features in 1.0.0removeSection(changelog: Changelog, version: string, sectionType: string, options?: RemoveSectionOptions): Changelog
Parameters
Returns
ChangelogExample
Removing a deprecated section
const updated = removeSection(changelog, '1.0.0', 'deprecated')
// Version 1.0.0 no longer has a deprecated sectionParameters
Returns
ChangelogExample
Removing the unreleased entry
const released = removeUnreleased(changelog)
// Changelog without the unreleased entry
// Silently ignore if not found
const safe = removeUnreleased(changelog, { throwIfNotFound: false })Parameters
| Name | Type | Description |
|---|---|---|
§options? | SerializeOptions | User-provided options |
Returns
Required<SerializeOptions>Example
Resolving serialize options with defaults
const opts = resolveOptions({ includeCommits: true })
// => { includeCommits: true, includeScope: true, lineEnding: '\n', ... }Parameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to reverse |
Returns
ChangelogExample
Reversing entry order
const reversed = reverseEntries(changelog)
// Oldest entries now appear firstParameters
Returns
stringExamples
Basic serialization
const markdown = serializeChangelog(changelog)Serializing with custom options
const markdown = serializeChangelog(changelog, {
includeCommits: false,
useAsterisks: true,
})Parameters
Returns
stringExamples
Basic JSON serialization
const json = serializeChangelogToJson(changelog)Pretty-printing with custom indentation
const json = serializeChangelogToJson(changelog, {
pretty: true,
indent: 4,
})Parameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to sort |
Returns
ChangelogExample
Sorting changelog entries by version
const sorted = sortEntries(changelog)
// Entries ordered: Unreleased, 2.0.0, 1.1.0, 1.0.0, ...Parameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to sort |
Returns
ChangelogExample
Sorting entries by date
const sorted = sortEntriesByDate(changelog)
// Entries ordered by release date, most recent firstParameters
Returns
ChangelogExample
Sorting sections within entries
const sorted = sortSections(changelog)
// Sections in each entry follow: breaking, features, fixes, ...
const custom = sortSections(changelog, ['fixes', 'features', 'breaking'])
// Custom ordering: fixes first, then features, then breakingParameters
| Name | Type | Description |
|---|---|---|
§changelog | Changelog | The changelog to strip |
Returns
ChangelogExample
Stripping metadata from a changelog
const stripped = stripMetadata(changelog)
// Source and warnings removed, only format and isConventional retainedParameters
| Name | Type | Description |
|---|---|---|
§diff | ChangelogDiff | The diff to summarize |
Returns
stringExample
Creating human-readable diff summary
const diff = diffChangelogs(oldChangelog, newChangelog)
summarizeDiff(diff)
// => 'Added 2 version(s): 1.2.0, 1.1.0; Modified 1 version(s): 1.0.0'toJsonObject(changelog: Changelog, options?: JsonSerializeOptions): Record<string, unknown>
Parameters
Returns
Record<string, unknown>Example
Converting changelog to plain object
const obj = toJsonObject(changelog, { includeSource: true })
// => { source: 'CHANGELOG.md', header: { title: '...', ... }, entries: [...] }
// Send as API response
res.json(obj)Parameters
| Name | Type | Description |
|---|---|---|
§input | string | The markdown content to tokenize |
Returns
Token[]Example
Tokenizing changelog markdown
const tokens = tokenize('# Changelog\n\n## [1.0.0]\n- Added feature')
// => [{ type: 'heading-1', value: 'Changelog', ... }, { type: 'heading-2', ... }, ...]Parameters
Returns
ChangelogExample
Transforming all entries
const transformed = transformEntries(changelog, (entry) => ({
...entry,
date: entry.date?.toUpperCase()
}))Parameters
Returns
ChangelogExample
Prefixing item descriptions with scope
const prefixed = transformItems(changelog, (item) => ({
...item,
description: `[${item.scope || 'misc'}] ${item.description}`,
}))Parameters
Returns
ChangelogExample
Uppercasing section headings
const renamed = transformSections(changelog, (section) => ({
...section,
heading: section.heading.toUpperCase(),
}))updateEntry(changelog: Changelog, version: string, updates: Partial<ChangelogEntry> | (entry: ChangelogEntry) => ChangelogEntry): Changelog
Parameters
Returns
ChangelogExample
Updating a specific entry
const updated = updateEntry(changelog, '1.0.0', { date: '2024-01-15' })
// Or with transformer function
const modified = updateEntry(changelog, '1.0.0', (entry) => ({
...entry,
compareUrl: `https://github.com/org/repo/compare/v0.9.0...v${entry.version}`,
}))Parameters
Returns
ChangelogExample
Updating the changelog header
const updated = updateHeader(changelog, { title: '# Release Notes' })Parameters
Returns
ChangelogExample
Updating changelog metadata
const updated = updateMetadata(changelog, { repositoryUrl: 'https://github.com/org/repo' })Parameters
| Name | Type | Description |
|---|---|---|
§changelog | unknown | The changelog object to validate |
Returns
ValidationResultExample
Validating a changelog object
const result = validateChangelog(myChangelog)
if (!result.valid) {
console.log('Validation errors:', result.errors)
}◈ Interfaces
Properties
Complete representation of a CHANGELOG.md file. Designed for lossless round-tripping: parse -> modify -> serialize.
Properties
Represents a single version entry in a changelog.
Properties
The header section of a changelog file.
Represents an individual change within a changelog section.
Properties
Represents a link defined in the changelog header or elsewhere.
Additional information extracted during parsing.
Properties
Represents a category of changes (Features, Bug Fixes, etc.)
Represents a reference to a git commit in a changelog item.
Properties
Represents a reference to an issue or pull request.
Properties
Properties
Properties
Properties
Properties
Properties
readonly sectionHeadings?:Partial<Record<ChangelogSectionType, string>>— ◆ Types
Detected format/style of the changelog file.
type ChangelogFormat = "keep-a-changelog" | "conventional" | "custom" | "unknown"Categories for grouping changes in a changelog entry.
type ChangelogSectionType = "breaking" | "features" | "fixes" | "performance" | "documentation" | "deprecations" | "refactoring" | "tests" | "build" | "ci" | "chores" | "other"type EntryPredicate = (entry: ChangelogEntry, index: number) => booleantype EntryTransformer = (entry: ChangelogEntry, index: number) => ChangelogEntrytype ItemPredicate = (item: ChangelogItem, section: ChangelogSection, entry: ChangelogEntry) => booleantype ItemTransformer = (item: ChangelogItem, section: ChangelogSection, entry: ChangelogEntry) => ChangelogItemtype MergeStrategy = "source" | "target" | "union" | "latest"type SectionPredicate = (section: ChangelogSection, entry: ChangelogEntry) => booleantype SectionTransformer = (section: ChangelogSection, entry: ChangelogEntry) => ChangelogSectiontype TokenType = "heading-1" | "heading-2" | "heading-3" | "heading-4" | "list-item" | "link-text" | "link-url" | "text" | "newline" | "blank-line" | "bold" | "code" | "eof"