@bobfrankston/mailx-types 0.1.36 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +2 -0
- package/index.js +3 -0
- package/mime-inline-images.d.ts +38 -0
- package/mime-inline-images.js +45 -0
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export { expandRecipients, splitRecipients, isAddressToken, extractAddress, } fr
|
|
|
10
10
|
export type { GroupMap, RecipientToken, ExpansionResult } from "./groups.js";
|
|
11
11
|
export { REMINDER_STATE_FILE, normalizeReminderState, mergeReminderStates, reminderStatesEqual, } from "./reminder-state.js";
|
|
12
12
|
export type { ReminderState } from "./reminder-state.js";
|
|
13
|
+
export { extractInlineImages } from "./mime-inline-images.js";
|
|
14
|
+
export type { InlineImagePart } from "./mime-inline-images.js";
|
|
13
15
|
/** Supported authentication methods */
|
|
14
16
|
export type AuthMethod = "password" | "oauth2";
|
|
15
17
|
/** Mail account configuration */
|
package/index.js
CHANGED
|
@@ -17,6 +17,9 @@ export { expandRecipients, splitRecipients, isAddressToken, extractAddress, } fr
|
|
|
17
17
|
// Reminder dismissed/snoozed cross-device state — one merge implementation
|
|
18
18
|
// for the desktop service (mailx-settings) and Android/web (mailx-store-web).
|
|
19
19
|
export { REMINDER_STATE_FILE, normalizeReminderState, mergeReminderStates, reminderStatesEqual, } from "./reminder-state.js";
|
|
20
|
+
// Outgoing-mail inline images: data: URI → cid: extraction shared by both
|
|
21
|
+
// MIME assemblers (desktop send + Android/web send).
|
|
22
|
+
export { extractInlineImages } from "./mime-inline-images.js";
|
|
20
23
|
// ── Message flag state ──
|
|
21
24
|
//
|
|
22
25
|
// External API surface for the IMAP system flags. The literal strings
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline-image extraction for outgoing mail.
|
|
3
|
+
*
|
|
4
|
+
* The compose editors embed pasted/inlined images as `data:` URIs — that's
|
|
5
|
+
* what renders inside a WebView editor with no server round-trip. But a
|
|
6
|
+
* `data:` URI inside the text/html MIME part is NOT interoperable mail:
|
|
7
|
+
* Outlook desktop (Word renderer) doesn't render data: images at all, and
|
|
8
|
+
* Gmail's web sanitizer strips them, so recipients on the two biggest
|
|
9
|
+
* platforms see broken/missing images while Thunderbird/Apple Mail users see
|
|
10
|
+
* the message fine. The interoperable form is RFC 2392 `cid:` references to
|
|
11
|
+
* base64 image parts inside a multipart/related wrapper — what every mail
|
|
12
|
+
* client has emitted since the 90s.
|
|
13
|
+
*
|
|
14
|
+
* This helper rewrites `<img src="data:...;base64,...">` to `cid:` refs and
|
|
15
|
+
* hands back the extracted parts; the platform send() paths (desktop
|
|
16
|
+
* mailx-service and Android/web web-service) wrap them into
|
|
17
|
+
* multipart/related. Shared here (mailx-types, zero deps) so both MIME
|
|
18
|
+
* assemblers can't drift apart.
|
|
19
|
+
*
|
|
20
|
+
* Non-base64 data: URIs (utf8 SVG etc.) are left in place — rare, small,
|
|
21
|
+
* and rewriting them would mean re-encoding; the size/interop problem this
|
|
22
|
+
* solves comes from pasted photos, which are always base64.
|
|
23
|
+
*/
|
|
24
|
+
export interface InlineImagePart {
|
|
25
|
+
/** Content-ID value WITHOUT angle brackets (use `<${contentId}>` in the header). */
|
|
26
|
+
contentId: string;
|
|
27
|
+
mime: string;
|
|
28
|
+
base64: string;
|
|
29
|
+
}
|
|
30
|
+
/** Pull base64 `data:` images out of the HTML, replacing each src with a
|
|
31
|
+
* `cid:` reference. Identical data: URIs (the same image pasted twice)
|
|
32
|
+
* collapse to one part. `idDomain` scopes the Content-IDs (RFC 2392 wants
|
|
33
|
+
* msg-id-like uniqueness). */
|
|
34
|
+
export declare function extractInlineImages(html: string, idDomain: string): {
|
|
35
|
+
html: string;
|
|
36
|
+
images: InlineImagePart[];
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=mime-inline-images.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline-image extraction for outgoing mail.
|
|
3
|
+
*
|
|
4
|
+
* The compose editors embed pasted/inlined images as `data:` URIs — that's
|
|
5
|
+
* what renders inside a WebView editor with no server round-trip. But a
|
|
6
|
+
* `data:` URI inside the text/html MIME part is NOT interoperable mail:
|
|
7
|
+
* Outlook desktop (Word renderer) doesn't render data: images at all, and
|
|
8
|
+
* Gmail's web sanitizer strips them, so recipients on the two biggest
|
|
9
|
+
* platforms see broken/missing images while Thunderbird/Apple Mail users see
|
|
10
|
+
* the message fine. The interoperable form is RFC 2392 `cid:` references to
|
|
11
|
+
* base64 image parts inside a multipart/related wrapper — what every mail
|
|
12
|
+
* client has emitted since the 90s.
|
|
13
|
+
*
|
|
14
|
+
* This helper rewrites `<img src="data:...;base64,...">` to `cid:` refs and
|
|
15
|
+
* hands back the extracted parts; the platform send() paths (desktop
|
|
16
|
+
* mailx-service and Android/web web-service) wrap them into
|
|
17
|
+
* multipart/related. Shared here (mailx-types, zero deps) so both MIME
|
|
18
|
+
* assemblers can't drift apart.
|
|
19
|
+
*
|
|
20
|
+
* Non-base64 data: URIs (utf8 SVG etc.) are left in place — rare, small,
|
|
21
|
+
* and rewriting them would mean re-encoding; the size/interop problem this
|
|
22
|
+
* solves comes from pasted photos, which are always base64.
|
|
23
|
+
*/
|
|
24
|
+
/** Pull base64 `data:` images out of the HTML, replacing each src with a
|
|
25
|
+
* `cid:` reference. Identical data: URIs (the same image pasted twice)
|
|
26
|
+
* collapse to one part. `idDomain` scopes the Content-IDs (RFC 2392 wants
|
|
27
|
+
* msg-id-like uniqueness). */
|
|
28
|
+
export function extractInlineImages(html, idDomain) {
|
|
29
|
+
const images = [];
|
|
30
|
+
const byDataUri = new Map(); // data-uri → contentId
|
|
31
|
+
const stamp = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
32
|
+
const out = html.replace(/(<img\b[^>]*?\ssrc=)(["'])(data:(image\/[\w.+-]+);base64,([A-Za-z0-9+/=\s]+))\2/gi, (_m, prefix, quote, dataUri, mime, b64) => {
|
|
33
|
+
let cid = byDataUri.get(dataUri);
|
|
34
|
+
if (!cid) {
|
|
35
|
+
cid = `img${images.length + 1}.${stamp}@${idDomain}`;
|
|
36
|
+
byDataUri.set(dataUri, cid);
|
|
37
|
+
// Strip whitespace the editor may have wrapped into the URI;
|
|
38
|
+
// the send path re-wraps at 76 cols per RFC 2045.
|
|
39
|
+
images.push({ contentId: cid, mime, base64: b64.replace(/\s+/g, "") });
|
|
40
|
+
}
|
|
41
|
+
return `${prefix}${quote}cid:${cid}${quote}`;
|
|
42
|
+
});
|
|
43
|
+
return { html: out, images };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=mime-inline-images.js.map
|