88 lines
2.9 KiB
Markdown
88 lines
2.9 KiB
Markdown
# mime-utils
|
|
|
|
<!-- begin:auto-docs -->
|
|
_(no submodules)_
|
|
<!-- end:auto-docs -->
|
|
|
|
## 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
|
|
|
|
```ts
|
|
import { encodeWord, decodeWords } from "@suaveplan/email-processing/mime-utils";
|
|
|
|
const encoded = encodeWord("résumé", "Q");
|
|
const original = decodeWords(encoded);
|
|
```
|
|
|
|
## Usage: Advanced
|
|
|
|
```ts
|
|
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.
|