@bobfrankston/iflow-direct 0.1.8 → 0.1.10
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/gmail.d.ts +4 -0
- package/gmail.js +6 -0
- package/imap-compat.js +36 -29
- package/imap-native.d.ts +5 -3
- package/imap-native.js +14 -10
- package/package.json +1 -1
- package/types.d.ts +2 -0
package/gmail.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export interface GmailOAuthConfig {
|
|
|
10
10
|
verbose?: boolean;
|
|
11
11
|
rejectUnauthorized?: boolean;
|
|
12
12
|
inactivityTimeout?: number;
|
|
13
|
+
fetchChunkSize?: number;
|
|
14
|
+
fetchChunkSizeMax?: number;
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* Check if email address is Gmail
|
|
@@ -37,5 +39,7 @@ export declare function createAutoImapConfig(config: {
|
|
|
37
39
|
verbose?: boolean;
|
|
38
40
|
rejectUnauthorized?: boolean;
|
|
39
41
|
inactivityTimeout?: number;
|
|
42
|
+
fetchChunkSize?: number;
|
|
43
|
+
fetchChunkSizeMax?: number;
|
|
40
44
|
}): ImapClientConfig;
|
|
41
45
|
//# sourceMappingURL=gmail.d.ts.map
|
package/gmail.js
CHANGED
|
@@ -34,6 +34,8 @@ export function createGmailConfig(config) {
|
|
|
34
34
|
verbose: config.verbose,
|
|
35
35
|
rejectUnauthorized: config.rejectUnauthorized,
|
|
36
36
|
inactivityTimeout: config.inactivityTimeout,
|
|
37
|
+
fetchChunkSize: config.fetchChunkSize,
|
|
38
|
+
fetchChunkSizeMax: config.fetchChunkSizeMax,
|
|
37
39
|
};
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
@@ -52,6 +54,8 @@ export function createAutoImapConfig(config) {
|
|
|
52
54
|
verbose: config.verbose,
|
|
53
55
|
rejectUnauthorized: config.rejectUnauthorized,
|
|
54
56
|
inactivityTimeout: config.inactivityTimeout,
|
|
57
|
+
fetchChunkSize: config.fetchChunkSize,
|
|
58
|
+
fetchChunkSizeMax: config.fetchChunkSizeMax,
|
|
55
59
|
});
|
|
56
60
|
}
|
|
57
61
|
else {
|
|
@@ -63,6 +67,8 @@ export function createAutoImapConfig(config) {
|
|
|
63
67
|
verbose: config.verbose,
|
|
64
68
|
rejectUnauthorized: config.rejectUnauthorized,
|
|
65
69
|
inactivityTimeout: config.inactivityTimeout,
|
|
70
|
+
fetchChunkSize: config.fetchChunkSize,
|
|
71
|
+
fetchChunkSizeMax: config.fetchChunkSizeMax,
|
|
66
72
|
};
|
|
67
73
|
}
|
|
68
74
|
}
|
package/imap-compat.js
CHANGED
|
@@ -73,44 +73,51 @@ export class CompatImapClient {
|
|
|
73
73
|
}
|
|
74
74
|
/** Detect special folders from folder list */
|
|
75
75
|
getSpecialFolders(folders) {
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
76
|
+
// Two-pass detection so RFC 6154 \Drafts / \Sent / \Trash / \Junk /
|
|
77
|
+
// \Archive flags always win over name-based guesses. Previous single-pass
|
|
78
|
+
// `else if (flag || name)` could tag a stray folder named "DRAFT" as the
|
|
79
|
+
// drafts folder on Gmail, beating out [Imap]/Drafts which has the real
|
|
80
|
+
// \Drafts flag — Gmail then rejects APPEND to "DRAFT" as NONEXISTENT.
|
|
81
81
|
const result = {};
|
|
82
82
|
const leafName = (f) => {
|
|
83
83
|
const delim = f.delimiter || ".";
|
|
84
84
|
return (f.path.split(delim).pop() || f.path).toLowerCase();
|
|
85
85
|
};
|
|
86
|
+
const flagsLower = (f) => f.flags.map(fl => fl.toLowerCase());
|
|
87
|
+
// Pass 1: RFC 6154 flags only — authoritative if present
|
|
86
88
|
for (const f of folders) {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
else if (flags.includes("\\drafts") || name === "drafts" || name === "draft") {
|
|
102
|
-
if (!result.drafts)
|
|
103
|
-
result.drafts = f.path;
|
|
104
|
-
}
|
|
105
|
-
else if (flags.includes("\\junk") || flags.includes("\\spam") || name === "spam" || name === "junk" || name === "junk email" || name === "junk e-mail") {
|
|
106
|
-
if (!result.junk)
|
|
107
|
-
result.junk = f.path;
|
|
89
|
+
const flags = flagsLower(f);
|
|
90
|
+
if (!result.inbox && (flags.includes("\\inbox") || leafName(f) === "inbox"))
|
|
91
|
+
result.inbox = f.path;
|
|
92
|
+
if (!result.sent && flags.includes("\\sent"))
|
|
93
|
+
result.sent = f.path;
|
|
94
|
+
if (!result.trash && flags.includes("\\trash"))
|
|
95
|
+
result.trash = f.path;
|
|
96
|
+
if (!result.drafts && flags.includes("\\drafts"))
|
|
97
|
+
result.drafts = f.path;
|
|
98
|
+
if (!result.archive && flags.includes("\\archive"))
|
|
99
|
+
result.archive = f.path;
|
|
100
|
+
if (!result.junk && (flags.includes("\\junk") || flags.includes("\\spam"))) {
|
|
101
|
+
result.junk = f.path;
|
|
108
102
|
if (!result.spam)
|
|
109
103
|
result.spam = f.path;
|
|
110
104
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
}
|
|
106
|
+
// Pass 2: exact leaf-name fallback for servers that don't advertise flags
|
|
107
|
+
for (const f of folders) {
|
|
108
|
+
const name = leafName(f);
|
|
109
|
+
if (!result.sent && (name === "sent" || name === "sent items" || name === "sent mail"))
|
|
110
|
+
result.sent = f.path;
|
|
111
|
+
if (!result.trash && (name === "trash" || name === "deleted items" || name === "deleted"))
|
|
112
|
+
result.trash = f.path;
|
|
113
|
+
if (!result.drafts && (name === "drafts" || name === "draft"))
|
|
114
|
+
result.drafts = f.path;
|
|
115
|
+
if (!result.archive && (name === "archive" || name === "archives"))
|
|
116
|
+
result.archive = f.path;
|
|
117
|
+
if (!result.junk && (name === "spam" || name === "junk" || name === "junk email" || name === "junk e-mail")) {
|
|
118
|
+
result.junk = f.path;
|
|
119
|
+
if (!result.spam)
|
|
120
|
+
result.spam = f.path;
|
|
114
121
|
}
|
|
115
122
|
}
|
|
116
123
|
return result;
|
package/imap-native.d.ts
CHANGED
|
@@ -121,9 +121,11 @@ export declare class NativeImapClient {
|
|
|
121
121
|
* 60s accommodates Gmail which is slow on SEARCH for large folders.
|
|
122
122
|
* Overridable via ImapClientConfig.inactivityTimeout — slow Dovecot servers need 180s+. */
|
|
123
123
|
private inactivityTimeout;
|
|
124
|
-
/** Fetch chunk sizes — start small for quick first paint, ramp up for throughput
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
/** Fetch chunk sizes — start small for quick first paint, ramp up for throughput.
|
|
125
|
+
* Default 25 initial → 500 max. Overridable via ImapClientConfig.fetchChunkSize /
|
|
126
|
+
* fetchChunkSizeMax. Slow servers benefit from smaller chunks (fewer timeouts). */
|
|
127
|
+
private fetchChunkSize;
|
|
128
|
+
private fetchChunkSizeMax;
|
|
127
129
|
/** Active command timer — reset by handleData on every data arrival */
|
|
128
130
|
private commandTimer;
|
|
129
131
|
private sendCommand;
|
package/imap-native.js
CHANGED
|
@@ -29,6 +29,8 @@ export class NativeImapClient {
|
|
|
29
29
|
this.transport = transportFactory();
|
|
30
30
|
this.verbose = config.verbose || false;
|
|
31
31
|
this.inactivityTimeout = config.inactivityTimeout ?? 60000;
|
|
32
|
+
this.fetchChunkSize = config.fetchChunkSize ?? 25;
|
|
33
|
+
this.fetchChunkSizeMax = config.fetchChunkSizeMax ?? 500;
|
|
32
34
|
}
|
|
33
35
|
get connected() { return this._connected; }
|
|
34
36
|
// ── Connection ──
|
|
@@ -296,14 +298,14 @@ export class NativeImapClient {
|
|
|
296
298
|
return [];
|
|
297
299
|
uids.reverse(); // Newest first
|
|
298
300
|
console.log(` [fetch] ${uids.length} UIDs since ${sinceUid} (newest first)`);
|
|
299
|
-
if (uids.length <=
|
|
301
|
+
if (uids.length <= this.fetchChunkSize) {
|
|
300
302
|
const msgs = await this.fetchMessages(uids.join(","), options);
|
|
301
303
|
if (onChunk)
|
|
302
304
|
onChunk(msgs);
|
|
303
305
|
return msgs;
|
|
304
306
|
}
|
|
305
307
|
const allMessages = [];
|
|
306
|
-
let chunkSize =
|
|
308
|
+
let chunkSize = this.fetchChunkSize;
|
|
307
309
|
for (let i = 0; i < uids.length; i += chunkSize) {
|
|
308
310
|
const chunk = uids.slice(i, i + chunkSize);
|
|
309
311
|
const msgs = await this.fetchMessages(chunk.join(","), options);
|
|
@@ -311,8 +313,8 @@ export class NativeImapClient {
|
|
|
311
313
|
console.log(` [fetch] ${allMessages.length}/${uids.length} (chunk of ${chunk.length})`);
|
|
312
314
|
if (onChunk)
|
|
313
315
|
onChunk(msgs);
|
|
314
|
-
if (chunkSize <
|
|
315
|
-
chunkSize = Math.min(chunkSize * 4,
|
|
316
|
+
if (chunkSize < this.fetchChunkSizeMax)
|
|
317
|
+
chunkSize = Math.min(chunkSize * 4, this.fetchChunkSizeMax);
|
|
316
318
|
}
|
|
317
319
|
return allMessages;
|
|
318
320
|
}
|
|
@@ -329,7 +331,7 @@ export class NativeImapClient {
|
|
|
329
331
|
uids.reverse();
|
|
330
332
|
console.log(` [fetch] ${uids.length} UIDs to fetch (newest first)`);
|
|
331
333
|
const allMessages = [];
|
|
332
|
-
let chunkSize =
|
|
334
|
+
let chunkSize = this.fetchChunkSize;
|
|
333
335
|
for (let i = 0; i < uids.length; i += chunkSize) {
|
|
334
336
|
const chunk = uids.slice(i, i + chunkSize);
|
|
335
337
|
const msgs = await this.fetchMessages(chunk.join(","), options);
|
|
@@ -337,8 +339,8 @@ export class NativeImapClient {
|
|
|
337
339
|
console.log(` [fetch] ${allMessages.length}/${uids.length} (chunk of ${chunk.length})`);
|
|
338
340
|
if (onChunk)
|
|
339
341
|
onChunk(msgs);
|
|
340
|
-
if (chunkSize <
|
|
341
|
-
chunkSize = Math.min(chunkSize * 4,
|
|
342
|
+
if (chunkSize < this.fetchChunkSizeMax)
|
|
343
|
+
chunkSize = Math.min(chunkSize * 4, this.fetchChunkSizeMax);
|
|
342
344
|
}
|
|
343
345
|
return allMessages;
|
|
344
346
|
}
|
|
@@ -461,9 +463,11 @@ export class NativeImapClient {
|
|
|
461
463
|
* 60s accommodates Gmail which is slow on SEARCH for large folders.
|
|
462
464
|
* Overridable via ImapClientConfig.inactivityTimeout — slow Dovecot servers need 180s+. */
|
|
463
465
|
inactivityTimeout;
|
|
464
|
-
/** Fetch chunk sizes — start small for quick first paint, ramp up for throughput
|
|
465
|
-
|
|
466
|
-
|
|
466
|
+
/** Fetch chunk sizes — start small for quick first paint, ramp up for throughput.
|
|
467
|
+
* Default 25 initial → 500 max. Overridable via ImapClientConfig.fetchChunkSize /
|
|
468
|
+
* fetchChunkSizeMax. Slow servers benefit from smaller chunks (fewer timeouts). */
|
|
469
|
+
fetchChunkSize;
|
|
470
|
+
fetchChunkSizeMax;
|
|
467
471
|
/** Active command timer — reset by handleData on every data arrival */
|
|
468
472
|
commandTimer = null;
|
|
469
473
|
sendCommand(tag, command) {
|
package/package.json
CHANGED