@bobfrankston/mailx-types 0.1.45 → 0.1.47
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/mailx-api.d.ts +17 -1
- package/mime-build.js +35 -30
- package/package.json +1 -1
package/mailx-api.d.ts
CHANGED
|
@@ -78,10 +78,26 @@ export interface MailxApi {
|
|
|
78
78
|
moveFolderToTrash(accountId: string, folderId: number): Promise<void>;
|
|
79
79
|
emptyFolder(accountId: string, folderId: number): Promise<void>;
|
|
80
80
|
sendMessage(msg: any): Promise<void>;
|
|
81
|
-
|
|
81
|
+
/** Positional here because both service classes implement it that way;
|
|
82
|
+
* the bridge is what turns the client's single params object into these
|
|
83
|
+
* arguments. Keep the tail in sync with jsonrpc's `case "saveDraft"` —
|
|
84
|
+
* this list had already fallen behind by one (`from`), and `attachments`
|
|
85
|
+
* made it two (2026-08-11). A param missing here is a param silently
|
|
86
|
+
* dropped on the way to the daemon. */
|
|
87
|
+
saveDraft(accountId: string, subject: string, bodyHtml: string, bodyText: string, to?: string, cc?: string, previousDraftUid?: number, draftId?: string, bcc?: string, from?: string, attachments?: {
|
|
88
|
+
filename: string;
|
|
89
|
+
mimeType: string;
|
|
90
|
+
dataBase64: string;
|
|
91
|
+
}[]): Promise<{
|
|
82
92
|
draftUid: number | null;
|
|
83
93
|
draftId: string;
|
|
84
94
|
}>;
|
|
95
|
+
/** Open a compose-window attachment in the OS default app. Optional:
|
|
96
|
+
* desktop-only (Android has no staging dir to launch from). */
|
|
97
|
+
openPendingAttachment?(filename: string, mimeType: string, dataBase64: string): Promise<{
|
|
98
|
+
ok: boolean;
|
|
99
|
+
path: string;
|
|
100
|
+
}>;
|
|
85
101
|
deleteDraft(accountId: string, draftUid: number, draftId?: string): Promise<void>;
|
|
86
102
|
getOutboxStatus(): any | Promise<any>;
|
|
87
103
|
listQueuedOutgoing(): any[] | Promise<any[]>;
|
package/mime-build.js
CHANGED
|
@@ -64,14 +64,18 @@ export function buildMimeMessage(opts) {
|
|
|
64
64
|
`MIME-Version: 1.0`,
|
|
65
65
|
];
|
|
66
66
|
const commonHeaders = headers.filter((h) => h !== null);
|
|
67
|
-
// ── draft: a single text/html part
|
|
67
|
+
// ── draft: a single text/html part, plus attachments if there are any ──
|
|
68
|
+
// "Simple" means no alternative and no inline-image extraction — it does
|
|
69
|
+
// NOT mean "drop the user's files". This branch used to `return` before
|
|
70
|
+
// ever reading opts.attachments, so a draft saved with a 65KB image was
|
|
71
|
+
// written body-only and the file was gone on reopen (Bob 2026-08-11).
|
|
68
72
|
if (opts.simpleHtml) {
|
|
69
73
|
const body = opts.bodyHtml || opts.bodyText || "";
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
const htmlPart = {
|
|
75
|
+
headers: [`Content-Type: text/html; charset=UTF-8`, `Content-Transfer-Encoding: quoted-printable`],
|
|
76
|
+
body: encodeQuotedPrintable(body),
|
|
77
|
+
};
|
|
78
|
+
const raw = wrapWithAttachments(commonHeaders, htmlPart, opts.attachments || [], newBoundary);
|
|
75
79
|
return { raw, messageId, inlineImageCount: 0 };
|
|
76
80
|
}
|
|
77
81
|
// Pasted images live in the editor HTML as data: URIs — fine in a WebView,
|
|
@@ -130,31 +134,32 @@ export function buildMimeMessage(opts) {
|
|
|
130
134
|
body: textEncoded,
|
|
131
135
|
};
|
|
132
136
|
};
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const filename = (att.filename || "attachment").replace(/[\r\n"]/g, "_");
|
|
144
|
-
const mime = att.mimeType || "application/octet-stream";
|
|
145
|
-
parts.push(`--${mixedBoundary}\r\n` +
|
|
146
|
-
`Content-Type: ${mime}; name="${filename}"\r\n` +
|
|
147
|
-
`Content-Disposition: attachment; filename="${filename}"\r\n` +
|
|
148
|
-
`Content-Transfer-Encoding: base64\r\n\r\n` +
|
|
149
|
-
`${wrap76(att.dataBase64 || "")}\r\n`);
|
|
150
|
-
}
|
|
151
|
-
raw = [...commonHeaders, `Content-Type: multipart/mixed; boundary="${mixedBoundary}"`].join("\r\n")
|
|
152
|
-
+ `\r\n\r\n` + parts.join("") + `--${mixedBoundary}--\r\n`;
|
|
137
|
+
const raw = wrapWithAttachments(commonHeaders, makeInner(), opts.attachments || [], newBoundary);
|
|
138
|
+
return { raw, messageId, inlineImageCount: inlineImages.length };
|
|
139
|
+
}
|
|
140
|
+
/** Emit `inner` as the whole body, or — when there are attachments — as the
|
|
141
|
+
* first part of a multipart/mixed followed by one base64 part per file.
|
|
142
|
+
* Shared by the draft and send paths so a file can never be dropped by one
|
|
143
|
+
* of them alone. */
|
|
144
|
+
function wrapWithAttachments(commonHeaders, inner, attachments, newBoundary) {
|
|
145
|
+
if (attachments.length === 0) {
|
|
146
|
+
return [...commonHeaders, ...inner.headers].join("\r\n") + `\r\n\r\n` + inner.body;
|
|
153
147
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
148
|
+
const mixedBoundary = newBoundary();
|
|
149
|
+
const parts = [
|
|
150
|
+
`--${mixedBoundary}\r\n` + inner.headers.join("\r\n") + `\r\n\r\n` + inner.body,
|
|
151
|
+
];
|
|
152
|
+
for (const att of attachments) {
|
|
153
|
+
// A quote or newline in a filename would break out of the header.
|
|
154
|
+
const filename = (att.filename || "attachment").replace(/[\r\n"]/g, "_");
|
|
155
|
+
const mime = att.mimeType || "application/octet-stream";
|
|
156
|
+
parts.push(`--${mixedBoundary}\r\n` +
|
|
157
|
+
`Content-Type: ${mime}; name="${filename}"\r\n` +
|
|
158
|
+
`Content-Disposition: attachment; filename="${filename}"\r\n` +
|
|
159
|
+
`Content-Transfer-Encoding: base64\r\n\r\n` +
|
|
160
|
+
`${wrap76(att.dataBase64 || "")}\r\n`);
|
|
157
161
|
}
|
|
158
|
-
return
|
|
162
|
+
return [...commonHeaders, `Content-Type: multipart/mixed; boundary="${mixedBoundary}"`].join("\r\n")
|
|
163
|
+
+ `\r\n\r\n` + parts.join("") + `--${mixedBoundary}--\r\n`;
|
|
159
164
|
}
|
|
160
165
|
//# sourceMappingURL=mime-build.js.map
|