react-native-email-imap-smtp 0.3.31 → 0.3.33
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 +1 -1
- package/android/src/main/java/com/margelo/nitro/emailimapsmtp/EmailImapSmtp.kt +128 -59
- package/lib/typescript/server/src/imapHandler.d.ts +5 -0
- package/lib/typescript/server/src/imapHandler.d.ts.map +1 -1
- package/lib/typescript/server/src/index.d.ts.map +1 -1
- package/lib/typescript/server/src/smtpHandler.d.ts.map +1 -1
- package/lib/typescript/src/EmailImapSmtp.nitro.d.ts +2 -0
- package/lib/typescript/src/EmailImapSmtp.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +2 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JSmtpServerInfo.hpp +8 -3
- package/nitrogen/generated/android/c++/JVariant_ImapServerInfo_SmtpServerInfo.hpp +1 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/emailimapsmtp/SmtpServerInfo.kt +9 -4
- package/nitrogen/generated/ios/EmailImapSmtp-Swift-Cxx-Bridge.hpp +15 -15
- package/nitrogen/generated/ios/swift/SmtpServerInfo.swift +19 -1
- package/nitrogen/generated/shared/c++/SmtpServerInfo.hpp +7 -2
- package/package.json +1 -1
- package/server/lib/imapHandler.d.ts +5 -0
- package/server/lib/imapHandler.d.ts.map +1 -1
- package/server/lib/imapHandler.js +68 -22
- package/server/lib/imapHandler.js.map +1 -1
- package/server/lib/index.d.ts.map +1 -1
- package/server/lib/index.js +24 -9
- package/server/lib/index.js.map +1 -1
- package/server/lib/smtpHandler.d.ts.map +1 -1
- package/server/lib/smtpHandler.js +76 -8
- package/server/lib/smtpHandler.js.map +1 -1
- package/server/src/imapHandler.ts +72 -23
- package/server/src/imapflow.d.ts +31 -0
- package/server/src/index.ts +50 -16
- package/server/src/smtpHandler.ts +310 -242
- package/src/EmailImapSmtp.nitro.ts +2 -0
- package/src/types.ts +2 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// imapflow 类型补充声明(module augmentation)
|
|
3
|
+
// ============================================================
|
|
4
|
+
//
|
|
5
|
+
// imapflow v1.5.0 的官方 .d.ts(lib/imap-flow.d.ts)未声明以下运行时属性,
|
|
6
|
+
// 但源码 lib/imap-flow.js 中确实存在(this.isClosed / this.state / this.states):
|
|
7
|
+
// - isClosed: boolean 连接已关闭时为 true
|
|
8
|
+
// - states: { ... } 连接状态常量枚举
|
|
9
|
+
// - state: number 当前连接状态值(对应 states 中的常量)
|
|
10
|
+
//
|
|
11
|
+
// 通过 declare module 合并到 ImapFlow 类上,避免用 any 绕过类型检查。
|
|
12
|
+
// 不要删除本文件:断线检测(ensureConnected / isSessionClosed)依赖这些字段。
|
|
13
|
+
// ============================================================
|
|
14
|
+
|
|
15
|
+
import 'imapflow';
|
|
16
|
+
|
|
17
|
+
declare module 'imapflow' {
|
|
18
|
+
interface ImapFlow {
|
|
19
|
+
/** 连接是否已关闭(服务器断开后为 true) */
|
|
20
|
+
isClosed: boolean;
|
|
21
|
+
/** 当前连接状态值(对应 states 中的常量) */
|
|
22
|
+
state: number;
|
|
23
|
+
/** 连接状态常量枚举:NOT_AUTHENTICATED / AUTHENTICATED / SELECTED / LOGOUT */
|
|
24
|
+
states: {
|
|
25
|
+
NOT_AUTHENTICATED: number;
|
|
26
|
+
AUTHENTICATED: number;
|
|
27
|
+
SELECTED: number;
|
|
28
|
+
LOGOUT: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
package/server/src/index.ts
CHANGED
|
@@ -168,6 +168,28 @@ app.use((req, _res, next) => {
|
|
|
168
168
|
// IMAP Routes
|
|
169
169
|
// ══════════════════════════════════════════════════════════════
|
|
170
170
|
|
|
171
|
+
// ─── 带静默重连的 IMAP 读操作包装 ─────────────────────────
|
|
172
|
+
|
|
173
|
+
/** 连接类错误 → 静默重连(fn 内部 ensureSession 会自动重连)→ 同参数重试一次。
|
|
174
|
+
* 只用于读操作;写操作不自动重试(避免断线重试造成重复执行)。 */
|
|
175
|
+
async function withImapReconnect<T>(
|
|
176
|
+
sessionId: string,
|
|
177
|
+
fn: () => Promise<T>
|
|
178
|
+
): Promise<T> {
|
|
179
|
+
try {
|
|
180
|
+
return await fn();
|
|
181
|
+
} catch (err: any) {
|
|
182
|
+
if (imap.isConnectionError(err) || imap.isSessionClosed(sessionId)) {
|
|
183
|
+
console.log(
|
|
184
|
+
'[imap] connection error, auto-reconnect & retry:',
|
|
185
|
+
err?.message
|
|
186
|
+
);
|
|
187
|
+
return await fn(); // 只重试一次;再失败则向上抛
|
|
188
|
+
}
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
171
193
|
// ─── 连接 ─────────────────────────────────────────────────
|
|
172
194
|
|
|
173
195
|
app.post('/api/imap/connect', async (req, res) => {
|
|
@@ -192,7 +214,9 @@ app.post('/api/imap/disconnect', async (req, res) => {
|
|
|
192
214
|
|
|
193
215
|
app.post('/api/imap/listMailboxes', async (req, res) => {
|
|
194
216
|
try {
|
|
195
|
-
const result = await
|
|
217
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
218
|
+
imap.listMailboxes(req.body.sessionId)
|
|
219
|
+
);
|
|
196
220
|
res.json(result);
|
|
197
221
|
} catch (err: any) {
|
|
198
222
|
res.status(500).json({ error: err.message });
|
|
@@ -201,10 +225,12 @@ app.post('/api/imap/listMailboxes', async (req, res) => {
|
|
|
201
225
|
|
|
202
226
|
app.post('/api/imap/selectMailbox', async (req, res) => {
|
|
203
227
|
try {
|
|
204
|
-
const result = await
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
228
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
229
|
+
imap.selectMailbox(
|
|
230
|
+
req.body.sessionId,
|
|
231
|
+
req.body.mailbox,
|
|
232
|
+
req.body.readOnly ?? false
|
|
233
|
+
)
|
|
208
234
|
);
|
|
209
235
|
res.json(result);
|
|
210
236
|
} catch (err: any) {
|
|
@@ -214,7 +240,9 @@ app.post('/api/imap/selectMailbox', async (req, res) => {
|
|
|
214
240
|
|
|
215
241
|
app.post('/api/imap/refreshMailbox', async (req, res) => {
|
|
216
242
|
try {
|
|
217
|
-
const result = await
|
|
243
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
244
|
+
imap.refreshMailbox(req.body.sessionId)
|
|
245
|
+
);
|
|
218
246
|
res.json(result);
|
|
219
247
|
} catch (err: any) {
|
|
220
248
|
res.status(500).json({ error: err.message });
|
|
@@ -223,7 +251,9 @@ app.post('/api/imap/refreshMailbox', async (req, res) => {
|
|
|
223
251
|
|
|
224
252
|
app.post('/api/imap/fetchFolders', async (req, res) => {
|
|
225
253
|
try {
|
|
226
|
-
const result = await
|
|
254
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
255
|
+
imap.fetchFolders(req.body.sessionId)
|
|
256
|
+
);
|
|
227
257
|
res.json(result);
|
|
228
258
|
} catch (err: any) {
|
|
229
259
|
res.status(500).json({ error: err.message });
|
|
@@ -283,7 +313,9 @@ app.post('/api/imap/unsubscribeFolder', async (req, res) => {
|
|
|
283
313
|
|
|
284
314
|
app.post('/api/imap/fetchEmails', async (req, res) => {
|
|
285
315
|
try {
|
|
286
|
-
const result = await
|
|
316
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
317
|
+
imap.fetchEmails(req.body.sessionId, req.body.options)
|
|
318
|
+
);
|
|
287
319
|
res.json(result);
|
|
288
320
|
} catch (err: any) {
|
|
289
321
|
res.status(500).json({ error: err.message });
|
|
@@ -292,7 +324,9 @@ app.post('/api/imap/fetchEmails', async (req, res) => {
|
|
|
292
324
|
|
|
293
325
|
app.post('/api/imap/fetchEmailByUID', async (req, res) => {
|
|
294
326
|
try {
|
|
295
|
-
const result = await
|
|
327
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
328
|
+
imap.fetchEmailByUID(req.body.sessionId, req.body.uid)
|
|
329
|
+
);
|
|
296
330
|
res.json(result);
|
|
297
331
|
} catch (err: any) {
|
|
298
332
|
res.status(500).json({ error: err.message });
|
|
@@ -301,9 +335,8 @@ app.post('/api/imap/fetchEmailByUID', async (req, res) => {
|
|
|
301
335
|
|
|
302
336
|
app.post('/api/imap/searchEmails', async (req, res) => {
|
|
303
337
|
try {
|
|
304
|
-
const result = await
|
|
305
|
-
req.body.sessionId,
|
|
306
|
-
req.body.criteria
|
|
338
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
339
|
+
imap.searchEmails(req.body.sessionId, req.body.criteria)
|
|
307
340
|
);
|
|
308
341
|
res.json(result);
|
|
309
342
|
} catch (err: any) {
|
|
@@ -400,9 +433,8 @@ app.post('/api/imap/fetchAttachment', async (req, res) => {
|
|
|
400
433
|
|
|
401
434
|
app.post('/api/imap/fetchAllAttachments', async (req, res) => {
|
|
402
435
|
try {
|
|
403
|
-
const result = await
|
|
404
|
-
req.body.sessionId,
|
|
405
|
-
req.body.uid
|
|
436
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
437
|
+
imap.fetchAllAttachments(req.body.sessionId, req.body.uid)
|
|
406
438
|
);
|
|
407
439
|
res.json(result);
|
|
408
440
|
} catch (err: any) {
|
|
@@ -437,7 +469,9 @@ app.post('/api/imap/stopIdle', async (req, res) => {
|
|
|
437
469
|
|
|
438
470
|
app.post('/api/imap/getQuota', async (req, res) => {
|
|
439
471
|
try {
|
|
440
|
-
const result = await
|
|
472
|
+
const result = await withImapReconnect(req.body.sessionId, () =>
|
|
473
|
+
imap.getQuota(req.body.sessionId, req.body.root)
|
|
474
|
+
);
|
|
441
475
|
res.json(result);
|
|
442
476
|
} catch (err: any) {
|
|
443
477
|
res.status(500).json({ error: err.message });
|