A robust encoder/decoder for structured metadata within Git commit messages. Built with Hexagonal Architecture and Domain-Driven Design (DDD).
- Standard Compliant: Follows the Git "trailer" convention (RFC 822 / Email headers)
- DoS Protection: Built-in 5MB message size limit to prevent attacks
- Structured Domain: Formalized entities and value objects for type safety
- Zod Validation: Schema-driven validation with helpful error messages
- Case Normalization: Trailer keys normalized to lowercase for consistency
- Pure Domain Logic: No I/O, no Git subprocess execution
- Domain Purity: Core logic independent of infrastructure
- Type Safety: Value Objects ensure data validity at instantiation
- Immutability: All entities are immutable
- Separation of Concerns: Encoding/decoding in dedicated service
- Node.js: >= 20.0.0
- @git-stunts/plumbing: >= 2.7.0
npm install @git-stunts/trailer-codecimport TrailerCodec from '@git-stunts/trailer-codec';
const codec = new TrailerCodec();
// Encode from plain object
const message = codec.encode({
title: 'feat: add user authentication',
body: 'Implemented OAuth2 flow with JWT tokens.',
trailers: {
'Signed-off-by': 'James Ross',
'Reviewed-by': 'Alice Smith'
}
});
console.log(message);
// feat: add user authentication
//
// Implemented OAuth2 flow with JWT tokens.
//
// signed-off-by: James Ross
// reviewed-by: Alice Smith
// Decode back to structured data
const decoded = codec.decode(message);
console.log(decoded.title); // "feat: add user authentication"
console.log(decoded.trailers); // [GitTrailer, GitTrailer]import { GitCommitMessage } from '@git-stunts/trailer-codec';
const msg = new GitCommitMessage({
title: 'fix: resolve memory leak',
body: 'Fixed WeakMap reference cycle.',
trailers: [
{ key: 'Issue', value: 'GH-123' },
{ key: 'Signed-off-by', value: 'James Ross' }
]
});
console.log(msg.toString());Trailer codec enforces strict validation:
| Rule | Constraint | Error Type |
|---|---|---|
| Message Size | β€ 5MB | ValidationError |
| Title | Must be non-empty string | ValidationError |
| Trailer Key | Alphanumeric, hyphens, underscores only (/^[A-Za-z0-9_-]+$/) |
ValidationError |
| Key Length | β€ 100 characters (prevents ReDoS) | ValidationError |
| Trailer Value | Must be non-empty string | ValidationError |
Key Normalization: All trailer keys are automatically normalized to lowercase (e.g., Signed-Off-By β signed-off-by).
- No Code Execution: Pure string manipulation, no
eval()or dynamic execution - DoS Protection: Rejects messages > 5MB
- ReDoS Prevention: Max key length limits regex execution time
- No Git Subprocess: Library performs no I/O operations
See SECURITY.md for details.
- Tests execute inside Docker to protect the host repository.
- Run
npm testlocally to build thedocker-composerig (GIT_STUNTS_DOCKER=1is injected inside the container) andtest/support/ensure-docker.jsverifies the guard before any Vitest suites begin. - For in-container debugging, shell into the image and run
npm test(the guard prevents execution outside Docker).
Apache-2.0