better-email-mcp 0.1.0
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/README.md +123 -0
- package/dist/backends/imap.d.ts +46 -0
- package/dist/backends/imap.d.ts.map +1 -0
- package/dist/backends/imap.js +300 -0
- package/dist/backends/imap.js.map +1 -0
- package/dist/backends/jmap.d.ts +33 -0
- package/dist/backends/jmap.d.ts.map +1 -0
- package/dist/backends/jmap.js +374 -0
- package/dist/backends/jmap.js.map +1 -0
- package/dist/imap/client.d.ts +36 -0
- package/dist/imap/client.d.ts.map +1 -0
- package/dist/imap/client.js +212 -0
- package/dist/imap/client.js.map +1 -0
- package/dist/imap/parser.d.ts +73 -0
- package/dist/imap/parser.d.ts.map +1 -0
- package/dist/imap/parser.js +349 -0
- package/dist/imap/parser.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/smtp/client.d.ts +39 -0
- package/dist/smtp/client.d.ts.map +1 -0
- package/dist/smtp/client.js +241 -0
- package/dist/smtp/client.js.map +1 -0
- package/dist/tools/register.d.ts +4 -0
- package/dist/tools/register.d.ts.map +1 -0
- package/dist/tools/register.js +147 -0
- package/dist/tools/register.js.map +1 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JmapBackend = exports.JmapError = void 0;
|
|
4
|
+
class JmapError extends Error {
|
|
5
|
+
type;
|
|
6
|
+
description;
|
|
7
|
+
constructor(type, description) {
|
|
8
|
+
super(`JMAP error [${type}]: ${description}`);
|
|
9
|
+
this.type = type;
|
|
10
|
+
this.description = description;
|
|
11
|
+
this.name = "JmapError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.JmapError = JmapError;
|
|
15
|
+
const DEFAULT_SESSION_URL = "https://api.fastmail.com/.well-known/jmap";
|
|
16
|
+
const USING = [
|
|
17
|
+
"urn:ietf:params:jmap:core",
|
|
18
|
+
"urn:ietf:params:jmap:mail",
|
|
19
|
+
"urn:ietf:params:jmap:submission",
|
|
20
|
+
];
|
|
21
|
+
const LIST_PROPERTIES = [
|
|
22
|
+
"id",
|
|
23
|
+
"subject",
|
|
24
|
+
"from",
|
|
25
|
+
"to",
|
|
26
|
+
"cc",
|
|
27
|
+
"receivedAt",
|
|
28
|
+
"preview",
|
|
29
|
+
"keywords",
|
|
30
|
+
"mailboxIds",
|
|
31
|
+
"hasAttachment",
|
|
32
|
+
];
|
|
33
|
+
const FULL_PROPERTIES = [
|
|
34
|
+
...LIST_PROPERTIES,
|
|
35
|
+
"textBody",
|
|
36
|
+
"htmlBody",
|
|
37
|
+
"bodyValues",
|
|
38
|
+
];
|
|
39
|
+
class JmapBackend {
|
|
40
|
+
config;
|
|
41
|
+
session = null;
|
|
42
|
+
identity = null;
|
|
43
|
+
mailboxCache = new Map(); // id → path
|
|
44
|
+
mailboxNameToId = new Map(); // path → id
|
|
45
|
+
constructor(config) {
|
|
46
|
+
this.config = config;
|
|
47
|
+
}
|
|
48
|
+
async connect() {
|
|
49
|
+
// 1. Discover session
|
|
50
|
+
const sessionUrl = this.config.sessionUrl ?? DEFAULT_SESSION_URL;
|
|
51
|
+
const sessionRes = await fetch(sessionUrl, {
|
|
52
|
+
headers: { Authorization: `Bearer ${this.config.token}` },
|
|
53
|
+
});
|
|
54
|
+
if (!sessionRes.ok) {
|
|
55
|
+
throw new Error(`JMAP session discovery failed: ${sessionRes.status} ${sessionRes.statusText}`);
|
|
56
|
+
}
|
|
57
|
+
const sessionData = await sessionRes.json();
|
|
58
|
+
this.session = {
|
|
59
|
+
apiUrl: sessionData.apiUrl,
|
|
60
|
+
accountId: sessionData.primaryAccounts["urn:ietf:params:jmap:mail"],
|
|
61
|
+
};
|
|
62
|
+
// 2. Fetch mailboxes and identity in one request
|
|
63
|
+
const responses = await this.jmapRequest([
|
|
64
|
+
[
|
|
65
|
+
"Mailbox/get",
|
|
66
|
+
{
|
|
67
|
+
accountId: this.session.accountId,
|
|
68
|
+
properties: ["id", "name", "parentId", "role"],
|
|
69
|
+
},
|
|
70
|
+
"0",
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
"Identity/get",
|
|
74
|
+
{
|
|
75
|
+
accountId: this.session.accountId,
|
|
76
|
+
},
|
|
77
|
+
"1",
|
|
78
|
+
],
|
|
79
|
+
]);
|
|
80
|
+
// Process mailboxes
|
|
81
|
+
const mailboxResponse = this.findResponse(responses, "Mailbox/get");
|
|
82
|
+
const mailboxes = mailboxResponse.list;
|
|
83
|
+
const mailboxesById = new Map();
|
|
84
|
+
for (const mb of mailboxes) {
|
|
85
|
+
mailboxesById.set(mb.id, mb);
|
|
86
|
+
}
|
|
87
|
+
this.mailboxCache.clear();
|
|
88
|
+
this.mailboxNameToId.clear();
|
|
89
|
+
for (const mb of mailboxes) {
|
|
90
|
+
const path = this.buildMailboxPath(mb, mailboxesById);
|
|
91
|
+
this.mailboxCache.set(mb.id, path);
|
|
92
|
+
this.mailboxNameToId.set(path, mb.id);
|
|
93
|
+
}
|
|
94
|
+
// Process identity
|
|
95
|
+
const identityResponse = this.findResponse(responses, "Identity/get");
|
|
96
|
+
const identities = identityResponse.list;
|
|
97
|
+
if (identities.length > 0) {
|
|
98
|
+
this.identity = {
|
|
99
|
+
id: identities[0].id,
|
|
100
|
+
email: identities[0].email,
|
|
101
|
+
name: identities[0].name ?? "",
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async disconnect() {
|
|
106
|
+
this.session = null;
|
|
107
|
+
this.identity = null;
|
|
108
|
+
this.mailboxCache.clear();
|
|
109
|
+
this.mailboxNameToId.clear();
|
|
110
|
+
}
|
|
111
|
+
async listFolders() {
|
|
112
|
+
return Array.from(this.mailboxNameToId.keys()).sort();
|
|
113
|
+
}
|
|
114
|
+
async listMessages(options) {
|
|
115
|
+
this.ensureConnected();
|
|
116
|
+
const filter = {};
|
|
117
|
+
if (options?.folder) {
|
|
118
|
+
const mailboxId = this.mailboxNameToId.get(options.folder);
|
|
119
|
+
if (!mailboxId) {
|
|
120
|
+
throw new Error(`Unknown folder: ${options.folder}`);
|
|
121
|
+
}
|
|
122
|
+
filter.inMailbox = mailboxId;
|
|
123
|
+
}
|
|
124
|
+
const responses = await this.jmapRequest([
|
|
125
|
+
[
|
|
126
|
+
"Email/query",
|
|
127
|
+
{
|
|
128
|
+
accountId: this.session.accountId,
|
|
129
|
+
filter,
|
|
130
|
+
sort: [{ property: "receivedAt", isAscending: false }],
|
|
131
|
+
position: options?.offset ?? 0,
|
|
132
|
+
limit: options?.limit ?? 25,
|
|
133
|
+
collapseThreads: true,
|
|
134
|
+
},
|
|
135
|
+
"0",
|
|
136
|
+
],
|
|
137
|
+
[
|
|
138
|
+
"Email/get",
|
|
139
|
+
{
|
|
140
|
+
accountId: this.session.accountId,
|
|
141
|
+
"#ids": {
|
|
142
|
+
name: "Email/query",
|
|
143
|
+
path: "/ids",
|
|
144
|
+
resultOf: "0",
|
|
145
|
+
},
|
|
146
|
+
properties: LIST_PROPERTIES,
|
|
147
|
+
},
|
|
148
|
+
"1",
|
|
149
|
+
],
|
|
150
|
+
]);
|
|
151
|
+
const emailResponse = this.findResponse(responses, "Email/get");
|
|
152
|
+
return emailResponse.list.map((raw) => this.mapJmapEmail(raw));
|
|
153
|
+
}
|
|
154
|
+
async getMessage(id) {
|
|
155
|
+
this.ensureConnected();
|
|
156
|
+
const responses = await this.jmapRequest([
|
|
157
|
+
[
|
|
158
|
+
"Email/get",
|
|
159
|
+
{
|
|
160
|
+
accountId: this.session.accountId,
|
|
161
|
+
ids: [id],
|
|
162
|
+
properties: FULL_PROPERTIES,
|
|
163
|
+
fetchAllBodyValues: true,
|
|
164
|
+
},
|
|
165
|
+
"0",
|
|
166
|
+
],
|
|
167
|
+
]);
|
|
168
|
+
const emailResponse = this.findResponse(responses, "Email/get");
|
|
169
|
+
if (emailResponse.notFound?.includes(id)) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
if (emailResponse.list.length === 0) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
const raw = emailResponse.list[0];
|
|
176
|
+
const message = this.mapJmapEmail(raw);
|
|
177
|
+
// Assemble body from textBody parts
|
|
178
|
+
const textParts = raw.textBody ?? [];
|
|
179
|
+
const bodyText = textParts
|
|
180
|
+
.map((part) => raw.bodyValues?.[part.partId]?.value ?? "")
|
|
181
|
+
.join("\n");
|
|
182
|
+
if (bodyText) {
|
|
183
|
+
message.body = bodyText;
|
|
184
|
+
}
|
|
185
|
+
return message;
|
|
186
|
+
}
|
|
187
|
+
async searchMessages(options) {
|
|
188
|
+
this.ensureConnected();
|
|
189
|
+
const filter = { text: options.query };
|
|
190
|
+
if (options.folder) {
|
|
191
|
+
const mailboxId = this.mailboxNameToId.get(options.folder);
|
|
192
|
+
if (!mailboxId) {
|
|
193
|
+
throw new Error(`Unknown folder: ${options.folder}`);
|
|
194
|
+
}
|
|
195
|
+
filter.inMailbox = mailboxId;
|
|
196
|
+
}
|
|
197
|
+
const responses = await this.jmapRequest([
|
|
198
|
+
[
|
|
199
|
+
"Email/query",
|
|
200
|
+
{
|
|
201
|
+
accountId: this.session.accountId,
|
|
202
|
+
filter,
|
|
203
|
+
sort: [{ property: "receivedAt", isAscending: false }],
|
|
204
|
+
limit: options.limit ?? 25,
|
|
205
|
+
},
|
|
206
|
+
"0",
|
|
207
|
+
],
|
|
208
|
+
[
|
|
209
|
+
"Email/get",
|
|
210
|
+
{
|
|
211
|
+
accountId: this.session.accountId,
|
|
212
|
+
"#ids": {
|
|
213
|
+
name: "Email/query",
|
|
214
|
+
path: "/ids",
|
|
215
|
+
resultOf: "0",
|
|
216
|
+
},
|
|
217
|
+
properties: LIST_PROPERTIES,
|
|
218
|
+
},
|
|
219
|
+
"1",
|
|
220
|
+
],
|
|
221
|
+
]);
|
|
222
|
+
const emailResponse = this.findResponse(responses, "Email/get");
|
|
223
|
+
return emailResponse.list.map((raw) => this.mapJmapEmail(raw));
|
|
224
|
+
}
|
|
225
|
+
async sendMessage(options) {
|
|
226
|
+
this.ensureConnected();
|
|
227
|
+
if (!this.identity) {
|
|
228
|
+
throw new Error("No identity available for sending");
|
|
229
|
+
}
|
|
230
|
+
// Find drafts mailbox
|
|
231
|
+
let draftsId;
|
|
232
|
+
for (const [id, path] of this.mailboxCache) {
|
|
233
|
+
if (path.toLowerCase() === "drafts") {
|
|
234
|
+
draftsId = id;
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (!draftsId) {
|
|
239
|
+
throw new Error("Drafts mailbox not found");
|
|
240
|
+
}
|
|
241
|
+
const emailCreate = {
|
|
242
|
+
mailboxIds: { [draftsId]: true },
|
|
243
|
+
from: [{ name: this.identity.name, email: this.identity.email }],
|
|
244
|
+
to: options.to.map((email) => ({ email })),
|
|
245
|
+
...(options.cc?.length
|
|
246
|
+
? { cc: options.cc.map((email) => ({ email })) }
|
|
247
|
+
: {}),
|
|
248
|
+
...(options.bcc?.length
|
|
249
|
+
? { bcc: options.bcc.map((email) => ({ email })) }
|
|
250
|
+
: {}),
|
|
251
|
+
subject: options.subject,
|
|
252
|
+
textBody: [{ partId: "textBody", type: "text/plain" }],
|
|
253
|
+
bodyValues: {
|
|
254
|
+
textBody: { value: options.textBody },
|
|
255
|
+
...(options.htmlBody
|
|
256
|
+
? { htmlBody: { value: options.htmlBody } }
|
|
257
|
+
: {}),
|
|
258
|
+
},
|
|
259
|
+
...(options.htmlBody
|
|
260
|
+
? { htmlBody: [{ partId: "htmlBody", type: "text/html" }] }
|
|
261
|
+
: {}),
|
|
262
|
+
keywords: { $draft: true },
|
|
263
|
+
};
|
|
264
|
+
if (options.inReplyTo) {
|
|
265
|
+
emailCreate.inReplyTo = [options.inReplyTo];
|
|
266
|
+
}
|
|
267
|
+
const responses = await this.jmapRequest([
|
|
268
|
+
[
|
|
269
|
+
"Email/set",
|
|
270
|
+
{
|
|
271
|
+
accountId: this.session.accountId,
|
|
272
|
+
create: { draft: emailCreate },
|
|
273
|
+
},
|
|
274
|
+
"0",
|
|
275
|
+
],
|
|
276
|
+
[
|
|
277
|
+
"EmailSubmission/set",
|
|
278
|
+
{
|
|
279
|
+
accountId: this.session.accountId,
|
|
280
|
+
create: {
|
|
281
|
+
submission: {
|
|
282
|
+
emailId: "#draft",
|
|
283
|
+
identityId: this.identity.id,
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
"1",
|
|
288
|
+
],
|
|
289
|
+
]);
|
|
290
|
+
const emailSetResponse = this.findResponse(responses, "Email/set");
|
|
291
|
+
const createdId = emailSetResponse.created?.draft?.id;
|
|
292
|
+
if (!createdId) {
|
|
293
|
+
const err = emailSetResponse.notCreated?.draft;
|
|
294
|
+
throw new JmapError(err?.type ?? "unknown", err?.description ?? "Failed to create email");
|
|
295
|
+
}
|
|
296
|
+
return { id: createdId };
|
|
297
|
+
}
|
|
298
|
+
// --- Private helpers ---
|
|
299
|
+
ensureConnected() {
|
|
300
|
+
if (!this.session) {
|
|
301
|
+
throw new Error("Not connected. Call connect() first.");
|
|
302
|
+
}
|
|
303
|
+
return this.session;
|
|
304
|
+
}
|
|
305
|
+
async jmapRequest(methodCalls) {
|
|
306
|
+
const session = this.ensureConnected();
|
|
307
|
+
const res = await fetch(session.apiUrl, {
|
|
308
|
+
method: "POST",
|
|
309
|
+
headers: {
|
|
310
|
+
"Content-Type": "application/json",
|
|
311
|
+
Authorization: `Bearer ${this.config.token}`,
|
|
312
|
+
},
|
|
313
|
+
body: JSON.stringify({
|
|
314
|
+
using: USING,
|
|
315
|
+
methodCalls,
|
|
316
|
+
}),
|
|
317
|
+
});
|
|
318
|
+
if (!res.ok) {
|
|
319
|
+
throw new Error(`JMAP request failed: ${res.status} ${res.statusText}`);
|
|
320
|
+
}
|
|
321
|
+
const data = await res.json();
|
|
322
|
+
const methodResponses = data.methodResponses;
|
|
323
|
+
// Check for method-level errors
|
|
324
|
+
for (const response of methodResponses) {
|
|
325
|
+
if (response[0] === "error") {
|
|
326
|
+
throw new JmapError(response[1].type ?? "unknown", response[1].description ?? "Unknown JMAP error");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return methodResponses;
|
|
330
|
+
}
|
|
331
|
+
findResponse(responses, methodName) {
|
|
332
|
+
for (const response of responses) {
|
|
333
|
+
if (response[0] === methodName) {
|
|
334
|
+
return response[1];
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
throw new Error(`Expected ${methodName} response not found`);
|
|
338
|
+
}
|
|
339
|
+
buildMailboxPath(mailbox, mailboxesById) {
|
|
340
|
+
const parts = [mailbox.name];
|
|
341
|
+
let current = mailbox;
|
|
342
|
+
while (current.parentId) {
|
|
343
|
+
const parent = mailboxesById.get(current.parentId);
|
|
344
|
+
if (!parent)
|
|
345
|
+
break;
|
|
346
|
+
parts.unshift(parent.name);
|
|
347
|
+
current = parent;
|
|
348
|
+
}
|
|
349
|
+
return parts.join("/");
|
|
350
|
+
}
|
|
351
|
+
mapJmapEmail(raw) {
|
|
352
|
+
const mailboxId = Object.keys(raw.mailboxIds ?? {})[0];
|
|
353
|
+
const folder = mailboxId
|
|
354
|
+
? this.mailboxCache.get(mailboxId) ?? mailboxId
|
|
355
|
+
: "";
|
|
356
|
+
const message = {
|
|
357
|
+
id: raw.id,
|
|
358
|
+
subject: raw.subject ?? "",
|
|
359
|
+
from: raw.from?.[0]?.email ?? raw.from?.[0]?.name ?? "",
|
|
360
|
+
to: (raw.to ?? []).map((a) => a.email),
|
|
361
|
+
date: raw.receivedAt ?? "",
|
|
362
|
+
snippet: raw.preview ?? "",
|
|
363
|
+
isRead: raw.keywords?.$seen === true,
|
|
364
|
+
folder,
|
|
365
|
+
};
|
|
366
|
+
const cc = (raw.cc ?? []).map((a) => a.email);
|
|
367
|
+
if (cc.length > 0) {
|
|
368
|
+
message.cc = cc;
|
|
369
|
+
}
|
|
370
|
+
return message;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
exports.JmapBackend = JmapBackend;
|
|
374
|
+
//# sourceMappingURL=jmap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jmap.js","sourceRoot":"","sources":["../../src/backends/jmap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal IMAP client using Node's built-in net/tls modules.
|
|
3
|
+
* Supports only the commands needed by the IMAP backend:
|
|
4
|
+
* LOGIN, LIST, SELECT, UID SEARCH, UID FETCH, LOGOUT.
|
|
5
|
+
*/
|
|
6
|
+
import { ImapResponse } from "./parser.js";
|
|
7
|
+
export interface ImapClientConfig {
|
|
8
|
+
host: string;
|
|
9
|
+
port: number;
|
|
10
|
+
tls: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class ImapError extends Error {
|
|
13
|
+
readonly code: string;
|
|
14
|
+
constructor(code: string, message: string);
|
|
15
|
+
}
|
|
16
|
+
export declare class ImapClient {
|
|
17
|
+
private socket;
|
|
18
|
+
private tagCounter;
|
|
19
|
+
private buffer;
|
|
20
|
+
private literalRemaining;
|
|
21
|
+
private literalBuffer;
|
|
22
|
+
private currentLines;
|
|
23
|
+
private pending;
|
|
24
|
+
private greetingResolve;
|
|
25
|
+
connect(config: ImapClientConfig): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Send an IMAP command and collect all responses until the tagged completion.
|
|
28
|
+
* Returns array of untagged responses. Throws on NO/BAD.
|
|
29
|
+
*/
|
|
30
|
+
command(cmd: string): Promise<ImapResponse[]>;
|
|
31
|
+
disconnect(): Promise<void>;
|
|
32
|
+
private onData;
|
|
33
|
+
private processBuffer;
|
|
34
|
+
private handleLine;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/imap/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAqB,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;CACd;AAED,qBAAa,SAAU,SAAQ,KAAK;aAEhB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM;CAKlB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA2C;IACzD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,YAAY,CAAgB;IAGpC,OAAO,CAAC,OAAO,CAKC;IAGhB,OAAO,CAAC,eAAe,CAA+C;IAEhE,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8CtD;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAa7C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBjC,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,aAAa;IAsDrB,OAAO,CAAC,UAAU;CA+BnB"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal IMAP client using Node's built-in net/tls modules.
|
|
4
|
+
* Supports only the commands needed by the IMAP backend:
|
|
5
|
+
* LOGIN, LIST, SELECT, UID SEARCH, UID FETCH, LOGOUT.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.ImapClient = exports.ImapError = void 0;
|
|
42
|
+
const net = __importStar(require("net"));
|
|
43
|
+
const tls = __importStar(require("tls"));
|
|
44
|
+
const parser_js_1 = require("./parser.js");
|
|
45
|
+
class ImapError extends Error {
|
|
46
|
+
code;
|
|
47
|
+
constructor(code, message) {
|
|
48
|
+
super(`IMAP error [${code}]: ${message}`);
|
|
49
|
+
this.code = code;
|
|
50
|
+
this.name = "ImapError";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.ImapError = ImapError;
|
|
54
|
+
class ImapClient {
|
|
55
|
+
socket = null;
|
|
56
|
+
tagCounter = 0;
|
|
57
|
+
buffer = "";
|
|
58
|
+
literalRemaining = 0;
|
|
59
|
+
literalBuffer = "";
|
|
60
|
+
currentLines = [];
|
|
61
|
+
// Pending command awaiting tagged response
|
|
62
|
+
pending = null;
|
|
63
|
+
// Queue for incoming lines when no command is pending
|
|
64
|
+
greetingResolve = null;
|
|
65
|
+
async connect(config) {
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
const onGreeting = (resp) => {
|
|
68
|
+
if (resp.type === "OK" || resp.type === "PREAUTH") {
|
|
69
|
+
resolve();
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
reject(new ImapError("greeting", `Server rejected connection: ${resp.text}`));
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
this.greetingResolve = onGreeting;
|
|
76
|
+
const onConnect = () => {
|
|
77
|
+
// Socket connected, waiting for greeting
|
|
78
|
+
};
|
|
79
|
+
const onError = (err) => {
|
|
80
|
+
this.greetingResolve = null;
|
|
81
|
+
reject(new ImapError("connect", err.message));
|
|
82
|
+
};
|
|
83
|
+
if (config.tls) {
|
|
84
|
+
this.socket = tls.connect({ host: config.host, port: config.port }, onConnect);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.socket = net.connect({ host: config.host, port: config.port }, onConnect);
|
|
88
|
+
}
|
|
89
|
+
this.socket.setEncoding("utf-8");
|
|
90
|
+
this.socket.on("data", (data) => this.onData(data));
|
|
91
|
+
this.socket.on("error", onError);
|
|
92
|
+
this.socket.on("close", () => {
|
|
93
|
+
if (this.pending) {
|
|
94
|
+
this.pending.reject(new ImapError("closed", "Connection closed unexpectedly"));
|
|
95
|
+
this.pending = null;
|
|
96
|
+
}
|
|
97
|
+
this.socket = null;
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Send an IMAP command and collect all responses until the tagged completion.
|
|
103
|
+
* Returns array of untagged responses. Throws on NO/BAD.
|
|
104
|
+
*/
|
|
105
|
+
async command(cmd) {
|
|
106
|
+
if (!this.socket) {
|
|
107
|
+
throw new ImapError("disconnected", "Not connected");
|
|
108
|
+
}
|
|
109
|
+
const tag = `A${++this.tagCounter}`;
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
this.pending = { tag, responses: [], resolve, reject };
|
|
112
|
+
this.socket.write(`${tag} ${cmd}\r\n`);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
async disconnect() {
|
|
116
|
+
if (!this.socket)
|
|
117
|
+
return;
|
|
118
|
+
try {
|
|
119
|
+
await this.command("LOGOUT");
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Ignore errors during logout
|
|
123
|
+
}
|
|
124
|
+
if (this.socket) {
|
|
125
|
+
this.socket.destroy();
|
|
126
|
+
this.socket = null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// --- Private ---
|
|
130
|
+
onData(data) {
|
|
131
|
+
this.buffer += data;
|
|
132
|
+
this.processBuffer();
|
|
133
|
+
}
|
|
134
|
+
processBuffer() {
|
|
135
|
+
while (this.buffer.length > 0) {
|
|
136
|
+
// If we're reading a literal, consume bytes
|
|
137
|
+
if (this.literalRemaining > 0) {
|
|
138
|
+
if (this.buffer.length < this.literalRemaining) {
|
|
139
|
+
// Not enough data yet
|
|
140
|
+
this.literalBuffer += this.buffer;
|
|
141
|
+
this.literalRemaining -= this.buffer.length;
|
|
142
|
+
this.buffer = "";
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.literalBuffer += this.buffer.substring(0, this.literalRemaining);
|
|
146
|
+
this.buffer = this.buffer.substring(this.literalRemaining);
|
|
147
|
+
this.literalRemaining = 0;
|
|
148
|
+
// Append literal content to the current line being built
|
|
149
|
+
this.currentLines[this.currentLines.length - 1] += this.literalBuffer;
|
|
150
|
+
this.literalBuffer = "";
|
|
151
|
+
// Continue processing — the line continues after the literal
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
// Look for end of line
|
|
155
|
+
const crlfIdx = this.buffer.indexOf("\r\n");
|
|
156
|
+
if (crlfIdx === -1)
|
|
157
|
+
return; // Need more data
|
|
158
|
+
const line = this.buffer.substring(0, crlfIdx);
|
|
159
|
+
this.buffer = this.buffer.substring(crlfIdx + 2);
|
|
160
|
+
// Check if line ends with a literal marker {N}
|
|
161
|
+
const literalMatch = line.match(/\{(\d+)\}$/);
|
|
162
|
+
if (literalMatch) {
|
|
163
|
+
this.literalRemaining = parseInt(literalMatch[1], 10);
|
|
164
|
+
this.literalBuffer = "";
|
|
165
|
+
// Store partial line (without the {N}) for continuation
|
|
166
|
+
this.currentLines.push(line.substring(0, line.length - literalMatch[0].length));
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
// Complete line — join with any previous literal parts
|
|
170
|
+
let fullLine;
|
|
171
|
+
if (this.currentLines.length > 0) {
|
|
172
|
+
this.currentLines.push(line);
|
|
173
|
+
fullLine = this.currentLines.join("");
|
|
174
|
+
this.currentLines = [];
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
fullLine = line;
|
|
178
|
+
}
|
|
179
|
+
this.handleLine(fullLine);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
handleLine(line) {
|
|
183
|
+
const resp = (0, parser_js_1.parseResponseLine)(line);
|
|
184
|
+
// Server greeting (before any command)
|
|
185
|
+
if (this.greetingResolve && resp.tag === "*") {
|
|
186
|
+
const resolve = this.greetingResolve;
|
|
187
|
+
this.greetingResolve = null;
|
|
188
|
+
resolve(resp);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (!this.pending)
|
|
192
|
+
return;
|
|
193
|
+
// Untagged response — collect it
|
|
194
|
+
if (resp.tag === "*" || resp.tag === "+") {
|
|
195
|
+
this.pending.responses.push(resp);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// Tagged response — check if it matches our pending command
|
|
199
|
+
if (resp.tag === this.pending.tag) {
|
|
200
|
+
const { responses, resolve, reject } = this.pending;
|
|
201
|
+
this.pending = null;
|
|
202
|
+
if (resp.type === "OK") {
|
|
203
|
+
resolve(responses);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
reject(new ImapError(resp.type ?? "unknown", resp.text || "Command failed"));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
exports.ImapClient = ImapClient;
|
|
212
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/imap/client.ts"],"names":[],"mappings":"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"}
|