# cid-resolver _(no submodules)_ ## Purpose Resolves Content-ID references inside HTML email bodies. Email clients that send inline images embed them as MIME parts with a `Content-ID` header and reference them in HTML with ``. After parsing, the rendered HTML needs those references replaced by something a downstream consumer (an inbox UI, a digest builder, an audit trail) can serve — either a data URI, a static URL, or an explicit URL mapping. ## Features - Three resolution strategies, evaluated in order: explicit `urlMap` (`Object.hasOwn`-checked so prototype keys cannot leak), `urlPrefix` + filename / contentHash, then data URI fallback. - Configurable `maxDataUriSize` (default 5 MiB) — attachments larger than the cap fall through to the unresolved list rather than exploding the HTML string. - Deduplicates CID references via `extractCidReferences`. - `isReferencedInline` short-circuits the lookup so callers can classify attachments as "inline" vs "true attachment" before serialising. - Strict input validation — non-string `html` inputs raise `EMAIL_PROCESSING.INVALID_INPUT`. ## Usage: Basic ```ts import { resolveCidReferences } from "@suaveplan/email-processing/cid-resolver"; const out = resolveCidReferences(parsed.html ?? "", processedAttachments); console.log(out.resolvedCount, out.unresolvedCids); ``` ## Usage: Advanced ```ts import { resolveCidReferences, isReferencedInline, } from "@suaveplan/email-processing/cid-resolver"; const result = resolveCidReferences(parsed.html ?? "", processed, { urlMap: { "logo@brand": "https://cdn.brand/logo.png" }, urlPrefix: "/inbox/inline/", maxDataUriSize: 2 * 1024 * 1024, }); const inlineAttachments = processed.filter((a) => isReferencedInline(parsed.html ?? "", a) ); const trueAttachments = processed.filter( (a) => !isReferencedInline(parsed.html ?? "", a) ); ``` ## API Reference - `CidResolverOptions` — `{ maxDataUriSize?, urlPrefix?, urlMap? }`. - `CidResolutionResult` — `{ html, totalReferences, resolvedCount, unresolvedCids }`. - `resolveCidReferences(html, attachments, options?)` — primary entry. - `extractCidReferences(html)` — deduped list of CIDs found. - `isReferencedInline(html, attachment)` — boolean. Errors: `INVALID_INPUT` for non-string `html`. ## Implementation Notes `Object.hasOwn(urlMap, cleanRef)` is used in preference to a direct truthy check so a deliberate `urlMap: { id: "" }` mapping is still recognised as "set", and so a polluted prototype cannot inject phantom keys. `String.prototype.matchAll` is used over `regex.exec` loops to keep the resolver simple and avoid stateful `lastIndex` bugs. The data URI fallback uses `btoa(String.fromCharCode(...))` so it works in the browser and Node without buffer polyfills.