TrailerCodecService is the heart of @git-stunts/trailer-codec. This document explains how the service decodes/encodes commit messages, what helper classes it injects, and how to customize each stage without touching the core class (src/domain/services/TrailerCodecService.js).
| Option | Default | Purpose |
|---|---|---|
schemaBundle |
getDefaultTrailerSchemaBundle() |
Supplies GitTrailerSchema, keyPattern, and keyRegex. Pass a custom bundle from createGitTrailerSchemaBundle() to change validation rules. |
trailerFactory |
new GitTrailer(key, value, schema) |
Creates trailer value objects. Swap this out for instrumentation or a different trailer implementation. |
parser |
new TrailerParser({ keyPattern: schemaBundle.keyPattern }) |
Splits body vs trailers, validates the blank-line separator, and exposes lineRegex (compiled from schemaBundle.keyPattern) so you can match each trailer line consistently. Inject a decorated parser to control detection heuristics and refer to docs/PARSER.md for parser internals. |
messageNormalizer |
new MessageNormalizer() |
Normalizes line endings (\r\n → \n) and guards against messages > 5 MB (throws TrailerTooLargeError). Override to adjust the max size or normalization logic. |
titleExtractor |
extractTitle |
Grabs the first line as the title, trims it, and skips consecutive blank lines. Replace to support multi-line titles or custom separators. |
bodyComposer |
composeBody |
Trims leading/trailing blank lines from the body while preserving user whitespace inside. Swap it when you want to preserve blank lines that occur at the edges. |
formatters |
{} |
Accepts { titleFormatter, bodyFormatter } functions applied before serialization. Use them to normalize casing, apply templates, or inject defaults before encode(). |
TrailerParser compiles the schemaBundle.keyPattern into parser.lineRegex during construction, so each trailer line is matched with the same RegExp used for validation; refer to docs/PARSER.md or TrailerParser constructor docs for more detail when you override this behavior.
- Empty message guard — Immediately returns an empty
GitCommitMessagewhen givenundefined/''so downstream code receives an entity instead ofnull. - Message size check —
MessageNormalizer.guardMessageSize()enforces the 5 MB limit and throwsTrailerTooLargeErrorwhen exceeded. - Line normalization —
MessageNormalizer.normalizeLines()converts\r\nto\nand splits into lines. - Title extraction —
extractTitle()takes the first line, trims it, and skips all blank lines between the title and body. - Split body/trailers —
TrailerParser.split()walks backward from the end of the message (using_findTrailerStart) to locate the trailer block and enforce the blank-line guard (TrailerNoSeparatorError). - Compose body —
composeBody()trims blank lines from the edges but keeps inner spacing intact. - Build trailers — Iterates over the trailer lines, matches each against
parser.lineRegex, and callstrailerFactory(key, value, schemaBundle.schema)to convert them intoGitTrailerinstances. - Entity construction — Returns a
GitCommitMessagewith the normalized title/body and the built trailers;formatters(e.g.,titleFormatter,bodyFormatter) run during this step.
encode(messageEntity)accepts either aGitCommitMessageinstance or a plain object. If it is not already an entity, it constructs a newGitCommitMessageusing the sameschemaBundleandformatters, ensuring validation still runs.GitCommitMessage.toString()outputs the final commit string (title, blank line, body, blank line, trailers) and trims trailing whitespace.
- Schema bundle: call
createGitTrailerSchemaBundle()withkeyPattern/keyMaxLengthand pass it asschemaBundleto alter validation. - Parser: supply a custom
TrailerParser(e.g., with aparserOptionsobject) viacreateConfiguredCodec; it can override_findTrailerStartheuristics while still leveraging the rest of the service. - Trailer factory: use
trailerFactoryto wrapGitTrailercreation with logging, metrics, or a different subclass. - Helpers: replace
MessageNormalizer,extractTitle, orcomposeBodywhen you need different normalization or trimming strategies (useful for non-Git commit inputs). - Formatters: pass
formatters(e.g.,{ titleFormatter: (value) => value.toUpperCase() }) to modify the title/body before serialization.
For a ready-to-use abstraction, prefer createConfiguredCodec() (which wires your custom schema, parser, and formatters) or extend TrailerCodecService via dependency injection rather than subclassing.