Files
skills/docs/communication/emails/email-processing/src/parser/parser.md
2026-05-29 08:20:56 +01:00

2.9 KiB

parser

(no submodules)

Purpose

Wraps postal-mime with a strict input/option boundary, OTel instrumentation, structured error codes, and the @suaveplan/email-processing/hooks pipeline. parseEmail is the package's primary entry point: it takes a raw RFC 822 message in any of the three supported input shapes (string, ArrayBuffer, Uint8Array) and returns a fully-parsed ParsedEmail whose attachments are real MIME parts (no stubs).

Features

  • Three input modes — string, ArrayBuffer, Uint8Array — covering both browser and Node consumers.
  • Zod-validated options at the boundary, raising EMAIL_PROCESSING.INVALID_OPTIONS with the failing issues on context so callers can surface diagnostics.
  • Distinct error codes for INVALID_INPUT (null/undefined/wrong type) and PARSE_FAILURE (postal-mime threw); parse.failure_total is incremented for the latter.
  • Hook pipeline integration — every parse returns the result of emailHooks.applyHooksAsync("email:processing", …).
  • parseEmailAddress and decodeEmailWords re-export the postal-mime low-level helpers under the package's typed surface, with the same INVALID_INPUT guard.

Usage: Basic

import { parseEmail } from "@suaveplan/email-processing/parser";

const parsed = await parseEmail(rawMimeString);
console.log(parsed.subject, parsed.attachments.length);

Usage: Advanced

import { parseEmail } from "@suaveplan/email-processing/parser";
import { onEmailProcessing } from "@suaveplan/email-processing/hooks";

const off = onEmailProcessing((data) => ({
    ...data,
    parsed: {
        ...data.parsed,
        html: data.parsed.html?.replace(/<script[\s\S]*?<\/script>/gi, ""),
    },
}));

try {
    const parsed = await parseEmail(buffer, {
        attachmentEncoding: "base64",
        maxNestingDepth: 64,
    });
    await persist(parsed);
} finally {
    off();
}

API Reference

  • parseEmail(raw, options?) — async; returns ParsedEmail. Throws EmailProcessingError with codes INVALID_INPUT, INVALID_OPTIONS, or PARSE_FAILURE.
  • parseEmailAddress(addressString) — sync; returns EmailAddress[]. Throws EmailProcessingError(INVALID_INPUT) for non-string input.
  • decodeEmailWords(text) — sync; returns decoded RFC 2047 string. Throws EmailProcessingError(INVALID_INPUT) for non-string input.

Implementation Notes

parseEmail records email_processing.parse.total with the attachment count as an attribute so dashboards can surface average attachments-per-message. Parse failures increment a separate parse.failure_total counter (no attachment count is recorded because the parser never reached the attachment array). The Zod options schema is .strict() so unknown option keys are rejected — this catches typos at the boundary instead of letting them silently no-op.