Files
suaveplan/packages/communication/emails/email-processing/src/mime-utils/mime-utils.md
2026-05-27 23:29:53 +01:00

2.9 KiB

mime-utils

(no submodules)

Purpose

Wraps the libmime library with a strict, typed boundary so the rest of the package can call RFC 2047 / 2231 / 5322 encoding and decoding helpers without using // @ts-expect-error or leaking any through the consumer surface. Every helper validates its primary string argument and raises an EmailProcessingError with code EMAIL_PROCESSING.INVALID_INPUT rather than silently calling libmime with garbage.

Features

  • Eleven wrappers: encodeWord / encodeWords / decodeWords, decodeHeader / decodeHeaders, parseHeaderValue / buildHeaderValue / buildHeaderParam, foldLines, encodeFlowed / decodeFlowed.
  • Local ambient declaration (libmime.d.ts) so the package compiles without @types/libmime while keeping the inner types narrow.
  • Strict input validation at every entry point — non-string args raise INVALID_INPUT, which is testable and observable.
  • Pass-through of optional parameters such as maxLength, lineLength, afterSpace, delSp so callers retain full libmime flexibility.

Usage: Basic

import { encodeWord, decodeWords } from "@suaveplan/email-processing/mime-utils";

const encoded = encodeWord("résumé", "Q");
const original = decodeWords(encoded);

Usage: Advanced

import {
    parseHeaderValue,
    buildHeaderValue,
    buildHeaderParam,
    foldLines,
} from "@suaveplan/email-processing/mime-utils";

const parsed = parseHeaderValue('text/plain; charset="utf-8"; name="r.txt"');
const segments = buildHeaderParam("filename*", "réport-2024.pdf", 60);
parsed.params.filename = segments.map((s) => s.value).join("");

const header = foldLines(
    `Content-Type: ${buildHeaderValue(parsed)}`,
    76,
    true
);

API Reference

  • encodeWord(str, encoding?, maxLength?)
  • encodeWords(str, encoding?, maxLength?)
  • decodeWords(str)
  • decodeHeader(headerLine) → { key, value }
  • decodeHeaders(headers) → Record<string, string[]>
  • parseHeaderValue(valueString) → StructuredHeaderValue
  • buildHeaderValue(structured) → string
  • buildHeaderParam(key, value, maxLength?) → HeaderParam[]
  • foldLines(str, lineLength?, afterSpace?)
  • encodeFlowed(str, lineLength?)
  • decodeFlowed(str, delSp?)

All throw EmailProcessingError with code EMAIL_PROCESSING.INVALID_INPUT when their primary argument is missing or of the wrong type.

Implementation Notes

libmime ships without TypeScript declarations, so this module owns a local libmime.d.ts declaring only the subset of functions in use. That keeps the package compatible with strict verbatimModuleSyntax and noUncheckedIndexedAccess settings without any casts. The buildHeaderValue guard checks for null/undefined/non-object rather than typeof === "string" because the input is structured — mismatching that guard would let through invalid shapes.