@wirecat/mail-cli 0.0.0-stage → 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.
Files changed (226) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/LICENSE +204 -0
  3. package/README.md +141 -2
  4. package/dist/bin/mail.d.ts +3 -0
  5. package/dist/bin/mail.d.ts.map +1 -0
  6. package/dist/bin/mail.js +36 -0
  7. package/dist/bin/mail.js.map +1 -0
  8. package/dist/bundle/all-profiles-TKMBELRZ.js +286 -0
  9. package/dist/bundle/anthropic-7LMUAEIZ.js +72 -0
  10. package/dist/bundle/app-server-JGMIJDD4.js +229 -0
  11. package/dist/bundle/bun-XRO6XJHQ.js +169 -0
  12. package/dist/bundle/bun-sqlite-Z54LEHVM.js +71 -0
  13. package/dist/bundle/chunk-2LLNPNMB.js +24 -0
  14. package/dist/bundle/chunk-3E3WA2L6.js +1932 -0
  15. package/dist/bundle/chunk-3KEVLSNN.js +138 -0
  16. package/dist/bundle/chunk-3KOA73LS.js +3416 -0
  17. package/dist/bundle/chunk-4E7BN3TC.js +122 -0
  18. package/dist/bundle/chunk-4FEMINO2.js +409 -0
  19. package/dist/bundle/chunk-5BVIWP3S.js +71 -0
  20. package/dist/bundle/chunk-5D4AEUVA.js +24783 -0
  21. package/dist/bundle/chunk-5NYMNSSO.js +264 -0
  22. package/dist/bundle/chunk-5WGEUDE4.js +27 -0
  23. package/dist/bundle/chunk-6MAZWSC3.js +132 -0
  24. package/dist/bundle/chunk-75CWWETH.js +379 -0
  25. package/dist/bundle/chunk-7SXGLT6T.js +444 -0
  26. package/dist/bundle/chunk-BTQX2ZSZ.js +288 -0
  27. package/dist/bundle/chunk-CEW6KIFA.js +1193 -0
  28. package/dist/bundle/chunk-CH6RXYAX.js +82 -0
  29. package/dist/bundle/chunk-D72URWJE.js +532 -0
  30. package/dist/bundle/chunk-DFDN6AUB.js +21 -0
  31. package/dist/bundle/chunk-EOEDICIE.js +6848 -0
  32. package/dist/bundle/chunk-F6D6PJ34.js +100 -0
  33. package/dist/bundle/chunk-FDCGTODC.js +78 -0
  34. package/dist/bundle/chunk-FZ5FXIG6.js +18 -0
  35. package/dist/bundle/chunk-GAH7N7HO.js +8181 -0
  36. package/dist/bundle/chunk-GK4M2SUP.js +195 -0
  37. package/dist/bundle/chunk-GN62YOT5.js +161 -0
  38. package/dist/bundle/chunk-GQQJOH7A.js +7050 -0
  39. package/dist/bundle/chunk-GWDCKUBI.js +781 -0
  40. package/dist/bundle/chunk-HTQTIKWP.js +928 -0
  41. package/dist/bundle/chunk-IK5TH3O7.js +217 -0
  42. package/dist/bundle/chunk-J3QXTBD2.js +2742 -0
  43. package/dist/bundle/chunk-J6MSJLIW.js +45 -0
  44. package/dist/bundle/chunk-JBBZCTTF.js +76 -0
  45. package/dist/bundle/chunk-JVMVLITS.js +260 -0
  46. package/dist/bundle/chunk-K4FVKPDQ.js +525 -0
  47. package/dist/bundle/chunk-KHTO2Q6E.js +886 -0
  48. package/dist/bundle/chunk-KM7Q67Z3.js +63 -0
  49. package/dist/bundle/chunk-LQ37ALDJ.js +2416 -0
  50. package/dist/bundle/chunk-MNOIRJEO.js +2315 -0
  51. package/dist/bundle/chunk-MS53RALV.js +168 -0
  52. package/dist/bundle/chunk-NK7EB63L.js +36225 -0
  53. package/dist/bundle/chunk-NPGVOZVK.js +2 -0
  54. package/dist/bundle/chunk-OTUOZ33L.js +82 -0
  55. package/dist/bundle/chunk-P7P5MNAU.js +46 -0
  56. package/dist/bundle/chunk-QLEUNU6G.js +537 -0
  57. package/dist/bundle/chunk-QQB7WT7R.js +216 -0
  58. package/dist/bundle/chunk-QX7RCLRS.js +23 -0
  59. package/dist/bundle/chunk-T6464KYA.js +35130 -0
  60. package/dist/bundle/chunk-TE5U5OAM.js +73 -0
  61. package/dist/bundle/chunk-TI6VBZKJ.js +166 -0
  62. package/dist/bundle/chunk-TQFCPUIM.js +53 -0
  63. package/dist/bundle/chunk-TVREDYX4.js +3574 -0
  64. package/dist/bundle/chunk-TWPDVUBR.js +106 -0
  65. package/dist/bundle/chunk-TWTATDM7.js +461 -0
  66. package/dist/bundle/chunk-UH4DDRHA.js +2989 -0
  67. package/dist/bundle/chunk-VEIZZRQ5.js +630 -0
  68. package/dist/bundle/chunk-WLFLBWNH.js +54 -0
  69. package/dist/bundle/chunk-WXAXYJJ7.js +486 -0
  70. package/dist/bundle/chunk-XQUUANA2.js +24600 -0
  71. package/dist/bundle/chunk-Y5E2WNWB.js +35 -0
  72. package/dist/bundle/chunk-YO4CUH5E.js +33 -0
  73. package/dist/bundle/chunk-YPQQ5J4X.js +849 -0
  74. package/dist/bundle/chunk-Z34ICZA3.js +1028 -0
  75. package/dist/bundle/chunk-ZANYM66S.js +58 -0
  76. package/dist/bundle/chunk-ZD3WUGR2.js +142 -0
  77. package/dist/bundle/chunk-ZVVMGPBJ.js +50 -0
  78. package/dist/bundle/command-contract-WU434ZUL.js +34 -0
  79. package/dist/bundle/decode-YB3ZDTES.js +162 -0
  80. package/dist/bundle/dispatch-EUKKT3PD.js +411 -0
  81. package/dist/bundle/dist-A6GKSKFC.js +2072 -0
  82. package/dist/bundle/dist-X36THCOF.js +7577 -0
  83. package/dist/bundle/echarts-YNGCOYHW.js +42501 -0
  84. package/dist/bundle/embed-LWNHIRBQ.js +37 -0
  85. package/dist/bundle/embedder-2LYD3U37.js +110 -0
  86. package/dist/bundle/failure-OAIC5VAP.js +24 -0
  87. package/dist/bundle/first-run-N3HJKGU7.js +27 -0
  88. package/dist/bundle/first-screen-4U2DMV3G.js +32 -0
  89. package/dist/bundle/instructions-GJHHFV64.js +11 -0
  90. package/dist/bundle/mail.js +166 -0
  91. package/dist/bundle/mcp-L7SRVDRN.js +167 -0
  92. package/dist/bundle/node-GFOH6FKP.js +176 -0
  93. package/dist/bundle/node-KM3CUABH.js +2340 -0
  94. package/dist/bundle/node-TLZSIHIJ.js +21 -0
  95. package/dist/bundle/node-sqlite-NBXQXBIU.js +63 -0
  96. package/dist/bundle/oauth-56EFO5AQ.js +19 -0
  97. package/dist/bundle/open-2V7QZQJP.js +21 -0
  98. package/dist/bundle/openai-V3SVACVL.js +251 -0
  99. package/dist/bundle/process-XVDX4SPD.js +91 -0
  100. package/dist/bundle/program-ILID6EAT.js +35542 -0
  101. package/dist/bundle/prompt-YKWAI222.js +14 -0
  102. package/dist/bundle/recognize-PAR66KVM.js +25 -0
  103. package/dist/bundle/remote-CE43TKXC.js +28 -0
  104. package/dist/bundle/rerank-M7S7P2TW.js +51 -0
  105. package/dist/bundle/serve-ENPMIV6J.js +197 -0
  106. package/dist/bundle/server-JRTHUCVY.js +63 -0
  107. package/dist/bundle/server-MBEZLVKZ.js +189 -0
  108. package/dist/bundle/sqlite-runtime-HVGDHBJJ.js +18 -0
  109. package/dist/bundle/state-QZSOSKBD.js +35 -0
  110. package/dist/bundle/store-2BUX6LVX.js +124 -0
  111. package/dist/bundle/store-UJ7SNKXI.js +141 -0
  112. package/dist/bundle/store-maintenance-command-I7V5C44K.js +52 -0
  113. package/dist/commands/account.d.ts +3 -0
  114. package/dist/commands/account.d.ts.map +1 -0
  115. package/dist/commands/account.js +47 -0
  116. package/dist/commands/account.js.map +1 -0
  117. package/dist/commands/context.d.ts +41 -0
  118. package/dist/commands/context.d.ts.map +1 -0
  119. package/dist/commands/context.js +52 -0
  120. package/dist/commands/context.js.map +1 -0
  121. package/dist/commands/doctor.d.ts +77 -0
  122. package/dist/commands/doctor.d.ts.map +1 -0
  123. package/dist/commands/doctor.js +74 -0
  124. package/dist/commands/doctor.js.map +1 -0
  125. package/dist/commands/folders.d.ts +3 -0
  126. package/dist/commands/folders.d.ts.map +1 -0
  127. package/dist/commands/folders.js +36 -0
  128. package/dist/commands/folders.js.map +1 -0
  129. package/dist/commands/login.d.ts +5 -0
  130. package/dist/commands/login.d.ts.map +1 -0
  131. package/dist/commands/login.js +21 -0
  132. package/dist/commands/login.js.map +1 -0
  133. package/dist/commands/mailbox.d.ts +16 -0
  134. package/dist/commands/mailbox.d.ts.map +1 -0
  135. package/dist/commands/mailbox.js +54 -0
  136. package/dist/commands/mailbox.js.map +1 -0
  137. package/dist/commands/mcp.d.ts +3 -0
  138. package/dist/commands/mcp.d.ts.map +1 -0
  139. package/dist/commands/mcp.js +97 -0
  140. package/dist/commands/mcp.js.map +1 -0
  141. package/dist/commands/session.d.ts +3 -0
  142. package/dist/commands/session.d.ts.map +1 -0
  143. package/dist/commands/session.js +211 -0
  144. package/dist/commands/session.js.map +1 -0
  145. package/dist/commands/setup.d.ts +3 -0
  146. package/dist/commands/setup.d.ts.map +1 -0
  147. package/dist/commands/setup.js +156 -0
  148. package/dist/commands/setup.js.map +1 -0
  149. package/dist/commands/status.d.ts +3 -0
  150. package/dist/commands/status.d.ts.map +1 -0
  151. package/dist/commands/status.js +89 -0
  152. package/dist/commands/status.js.map +1 -0
  153. package/dist/commands/sync.d.ts +3 -0
  154. package/dist/commands/sync.d.ts.map +1 -0
  155. package/dist/commands/sync.js +190 -0
  156. package/dist/commands/sync.js.map +1 -0
  157. package/dist/config.d.ts +190 -0
  158. package/dist/config.d.ts.map +1 -0
  159. package/dist/config.js +46 -0
  160. package/dist/config.js.map +1 -0
  161. package/dist/discovery.d.ts +42 -0
  162. package/dist/discovery.d.ts.map +1 -0
  163. package/dist/discovery.js +179 -0
  164. package/dist/discovery.js.map +1 -0
  165. package/dist/identity.d.ts +5 -0
  166. package/dist/identity.d.ts.map +1 -0
  167. package/dist/identity.js +16 -0
  168. package/dist/identity.js.map +1 -0
  169. package/dist/index.d.ts +3 -0
  170. package/dist/index.d.ts.map +1 -0
  171. package/dist/index.js +3 -0
  172. package/dist/index.js.map +1 -0
  173. package/dist/mail/imap-errors.d.ts +4 -0
  174. package/dist/mail/imap-errors.d.ts.map +1 -0
  175. package/dist/mail/imap-errors.js +41 -0
  176. package/dist/mail/imap-errors.js.map +1 -0
  177. package/dist/mail/imap-messages.d.ts +18 -0
  178. package/dist/mail/imap-messages.d.ts.map +1 -0
  179. package/dist/mail/imap-messages.js +66 -0
  180. package/dist/mail/imap-messages.js.map +1 -0
  181. package/dist/mail/imap.d.ts +67 -0
  182. package/dist/mail/imap.d.ts.map +1 -0
  183. package/dist/mail/imap.js +348 -0
  184. package/dist/mail/imap.js.map +1 -0
  185. package/dist/mail/parse.d.ts +18 -0
  186. package/dist/mail/parse.d.ts.map +1 -0
  187. package/dist/mail/parse.js +31 -0
  188. package/dist/mail/parse.js.map +1 -0
  189. package/dist/mail/port.d.ts +50 -0
  190. package/dist/mail/port.d.ts.map +1 -0
  191. package/dist/mail/port.js +4 -0
  192. package/dist/mail/port.js.map +1 -0
  193. package/dist/mcp.d.ts +29 -0
  194. package/dist/mcp.d.ts.map +1 -0
  195. package/dist/mcp.js +98 -0
  196. package/dist/mcp.js.map +1 -0
  197. package/dist/profile.d.ts +16 -0
  198. package/dist/profile.d.ts.map +1 -0
  199. package/dist/profile.js +31 -0
  200. package/dist/profile.js.map +1 -0
  201. package/dist/program.d.ts +6 -0
  202. package/dist/program.d.ts.map +1 -0
  203. package/dist/program.js +52 -0
  204. package/dist/program.js.map +1 -0
  205. package/dist/providers.d.ts +53 -0
  206. package/dist/providers.d.ts.map +1 -0
  207. package/dist/providers.js +106 -0
  208. package/dist/providers.js.map +1 -0
  209. package/dist/secret.d.ts +30 -0
  210. package/dist/secret.d.ts.map +1 -0
  211. package/dist/secret.js +68 -0
  212. package/dist/secret.js.map +1 -0
  213. package/dist/store.d.ts +12 -0
  214. package/dist/store.d.ts.map +1 -0
  215. package/dist/store.js +25 -0
  216. package/dist/store.js.map +1 -0
  217. package/dist/sync.d.ts +26 -0
  218. package/dist/sync.d.ts.map +1 -0
  219. package/dist/sync.js +75 -0
  220. package/dist/sync.js.map +1 -0
  221. package/dist/version.d.ts +2 -0
  222. package/dist/version.d.ts.map +1 -0
  223. package/dist/version.js +2 -0
  224. package/dist/version.js.map +1 -0
  225. package/package.json +83 -4
  226. package/skills/mail-cli/SKILL.md +27 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imap-errors.js","sourceRoot":"","sources":["../../src/mail/imap-errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Listed, Quick } from "@wirecat/cli-core/mail";
2
+ import type { FetchMessageObject, ListResponse } from "imapflow";
3
+ /** The header fields a listing asks for, so a mailing list is told apart from a person's mail. */
4
+ export declare const HEADER_FIELDS: string[];
5
+ export declare const quickOf: (message: FetchMessageObject, folder: string) => Quick;
6
+ /** Without a stable id the Message-ID is the identity; without that, the UID, which means nothing without UIDVALIDITY. */
7
+ export declare const idsOf: (messageId: string | undefined, folder: string, validity: string, uid: string) => {
8
+ messageId: string;
9
+ threadId: string;
10
+ };
11
+ export declare const listedOf: (message: FetchMessageObject, folder: string, validity: string) => Listed;
12
+ /**
13
+ * The Message-ID as the server's ENVELOPE gives it (imapflow trims the value of the first header), so the id of a
14
+ * message read as bytes is the id `list` gives it.
15
+ */
16
+ export declare const messageIdOf: (raw: Uint8Array) => string | undefined;
17
+ export declare const roleOf: (entry: ListResponse) => string | null;
18
+ //# sourceMappingURL=imap-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imap-messages.d.ts","sourceRoot":"","sources":["../../src/mail/imap-messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAe,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEhE,kGAAkG;AAClG,eAAO,MAAM,aAAa,UAAgD,CAAA;AA0B1E,eAAO,MAAM,OAAO,YAAa,kBAAkB,UAAU,MAAM,KAAG,KAYrE,CAAA;AAED,0HAA0H;AAC1H,eAAO,MAAM,KAAK,cAAe,MAAM,GAAG,SAAS,UAAU,MAAM,YAAY,MAAM,OAAO,MAAM;IAEvF,SAAS;IAAoB,QAAQ;CAC/C,CAAA;AAED,eAAO,MAAM,QAAQ,YAAa,kBAAkB,UAAU,MAAM,YAAY,MAAM,KAAG,MAQxF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAS,UAAU,KAAG,MAAM,GAAG,SAOtD,CAAA;AAED,eAAO,MAAM,MAAM,UAAW,YAAY,KAAG,MAAM,GAAG,IAGrD,CAAA"}
@@ -0,0 +1,66 @@
1
+ import { createHash } from "node:crypto";
2
+ /** The header fields a listing asks for, so a mailing list is told apart from a person's mail. */
3
+ export const HEADER_FIELDS = ["list-id", "list-unsubscribe", "precedence"];
4
+ const digest = (id) => `imap:${createHash("sha256").update(id).digest("hex")}`;
5
+ const headersOf = (message) => {
6
+ const from = message.envelope?.from?.[0];
7
+ const raw = message.headers ? message.headers.toString("utf8") : "";
8
+ const field = (name) => new RegExp(`^${name}:[ \\t]*(.*)$`, "im").exec(raw.replace(/\r?\n[ \t]+/g, " "))?.[1]?.trim();
9
+ const listId = field("list-id");
10
+ const bulk = listId !== undefined ||
11
+ field("list-unsubscribe") !== undefined ||
12
+ /^(bulk|list|junk)$/i.test(field("precedence") ?? "");
13
+ return {
14
+ ...(from?.address ? { from: from.address.toLowerCase() } : {}),
15
+ ...(from?.name ? { fromName: from.name } : {}),
16
+ ...(message.envelope?.subject ? { subject: message.envelope.subject } : {}),
17
+ to: [...(message.envelope?.to ?? []), ...(message.envelope?.cc ?? [])].flatMap((a) => a.address ? [a.address.toLowerCase()] : []),
18
+ ...(listId ? { listId } : {}),
19
+ bulk,
20
+ };
21
+ };
22
+ export const quickOf = (message, folder) => {
23
+ const flags = message.flags ?? new Set();
24
+ const received = message.internalDate instanceof Date ? message.internalDate : new Date(message.internalDate ?? 0);
25
+ return {
26
+ uid: String(message.uid),
27
+ receivedAt: received.toISOString(),
28
+ folder,
29
+ ...(message.size === undefined ? {} : { size: message.size }),
30
+ seen: flags.has("\\Seen"),
31
+ flagged: flags.has("\\Flagged"),
32
+ labels: message.labels ? [...message.labels] : flags.has("\\Flagged") ? ["Starred"] : [],
33
+ };
34
+ };
35
+ /** Without a stable id the Message-ID is the identity; without that, the UID, which means nothing without UIDVALIDITY. */
36
+ export const idsOf = (messageId, folder, validity, uid) => {
37
+ const identity = messageId ?? `uid:${folder}:${validity}:${uid}`;
38
+ return { messageId: digest(identity), threadId: digest(identity) };
39
+ };
40
+ export const listedOf = (message, folder, validity) => {
41
+ const ids = idsOf(message.envelope?.messageId, folder, validity, String(message.uid));
42
+ return {
43
+ ...quickOf(message, folder),
44
+ ...(message.emailId ? { messageId: String(message.emailId) } : { messageId: ids.messageId }),
45
+ threadId: message.threadId ? String(message.threadId) : ids.threadId,
46
+ headers: headersOf(message),
47
+ };
48
+ };
49
+ /**
50
+ * The Message-ID as the server's ENVELOPE gives it (imapflow trims the value of the first header), so the id of a
51
+ * message read as bytes is the id `list` gives it.
52
+ */
53
+ export const messageIdOf = (raw) => {
54
+ const bytes = Buffer.from(raw.buffer, raw.byteOffset, raw.byteLength);
55
+ const end = [bytes.indexOf("\r\n\r\n"), bytes.indexOf("\n\n")]
56
+ .filter((at) => at !== -1)
57
+ .reduce((first, at) => Math.min(first, at), bytes.length);
58
+ const head = bytes.subarray(0, end).toString("utf8");
59
+ return /^message-id:[ \t]*(.*)$/im.exec(head.replace(/\r?\n[ \t]+/g, " "))?.[1]?.trim() || undefined;
60
+ };
61
+ export const roleOf = (entry) => {
62
+ if (entry.path.toUpperCase() === "INBOX")
63
+ return "inbox";
64
+ return entry.specialUse ? entry.specialUse.replace(/^\\/, "").toLowerCase() : null;
65
+ };
66
+ //# sourceMappingURL=imap-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imap-messages.js","sourceRoot":"","sources":["../../src/mail/imap-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAIxC,kGAAkG;AAClG,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,kBAAkB,EAAE,YAAY,CAAC,CAAA;AAE1E,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;AAEtF,MAAM,SAAS,GAAG,CAAC,OAA2B,EAAe,EAAE;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACnE,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7B,IAAI,MAAM,CAAC,IAAI,IAAI,eAAe,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAA;IAC/F,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAA;IAC/B,MAAM,IAAI,GACR,MAAM,KAAK,SAAS;QACpB,KAAK,CAAC,kBAAkB,CAAC,KAAK,SAAS;QACvC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAA;IACvD,OAAO;QACL,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACnF,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAC3C;QACD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,IAAI;KACL,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,OAA2B,EAAE,MAAc,EAAS,EAAE;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,GAAG,EAAU,CAAA;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,YAAY,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC,CAAA;IAClH,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;QACxB,UAAU,EAAE,QAAQ,CAAC,WAAW,EAAE;QAClC,MAAM;QACN,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7D,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;QAC/B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;KACzF,CAAA;AACH,CAAC,CAAA;AAED,0HAA0H;AAC1H,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,SAA6B,EAAE,MAAc,EAAE,QAAgB,EAAE,GAAW,EAAE,EAAE;IACpG,MAAM,QAAQ,GAAG,SAAS,IAAI,OAAO,MAAM,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAA;IAChE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAA;AACpE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,OAA2B,EAAE,MAAc,EAAE,QAAgB,EAAU,EAAE;IAChG,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;IACrF,OAAO;QACL,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC;QAC3B,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;QAC5F,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ;QACpE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC;KAC5B,CAAA;AACH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAe,EAAsB,EAAE;IACjE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;IACrE,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAC3D,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;SACzB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IAC3D,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACpD,OAAO,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAA;AACtG,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAmB,EAAiB,EAAE;IAC3D,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO;QAAE,OAAO,OAAO,CAAA;IACxD,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACpF,CAAC,CAAA"}
@@ -0,0 +1,67 @@
1
+ import type { MailSource } from "@wirecat/cli-core/mail";
2
+ export interface ImapEndpoint {
3
+ host: string;
4
+ port: number;
5
+ /** `plain` is for a local test server only; no profile can ask for it. */
6
+ security: "tls" | "starttls" | "plain";
7
+ login: string;
8
+ }
9
+ export interface FolderInfo {
10
+ path: string;
11
+ name: string;
12
+ role: string | null;
13
+ messages: number | null;
14
+ unseen: number | null;
15
+ }
16
+ export interface AccountCheck {
17
+ login: string;
18
+ capabilities: string[];
19
+ features: Record<"idle" | "condstore" | "qresync" | "move" | "uidplus" | "compress" | "x_gm_ext_1" | "objectid", boolean>;
20
+ folders: number;
21
+ }
22
+ export type ImapMailSource = MailSource & {
23
+ check(): Promise<AccountCheck>;
24
+ folderList(): Promise<FolderInfo[]>;
25
+ close(): Promise<void>;
26
+ };
27
+ /**
28
+ * How the source spends a connection. The defaults come from measuring Yandex 360 (cli-testing,
29
+ * performance/mail/yandex-imap-sync): a header FETCH takes 0.1 to 0.7 s per message and the time per message grows with
30
+ * the size of the command, four connections read 2 to 3 times faster than one, and the server sometimes answers one
31
+ * message with `NO [UNAVAILABLE]` and then closes the connection. So a call reads 15 messages on each of 4 connections:
32
+ * a request of the budget (listBatch, fetchBatch) is 60 messages and takes about 9 s.
33
+ */
34
+ export interface ImapTuning {
35
+ /** Messages in one FETCH command. */
36
+ listSize?: number;
37
+ /** UIDs in one FETCH that asks only for flags, date and size. */
38
+ quickSize?: number;
39
+ fetchSize?: number;
40
+ /** Parallel connections one `list` or `fetchRaw` call spreads its commands over. */
41
+ connections?: number;
42
+ /** One command's own limit; the socket limit only catches a dead line. */
43
+ requestTimeoutMs?: number;
44
+ /** Waits before each retry of a command, jittered; the last one repeats. */
45
+ backoffMs?: readonly number[];
46
+ /** A hard ceiling per command; the budget and the deadline usually stop the retries first. */
47
+ maxAttempts?: number;
48
+ /** A retry is a request of the run's budget: false stops the retries. */
49
+ canRetry?: () => boolean;
50
+ /** Time left to the run's deadline; a retry that would not fit is not made. */
51
+ timeLeftMs?: () => number | undefined;
52
+ signal?: AbortSignal;
53
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
54
+ random?: () => number;
55
+ }
56
+ export declare const IMAP_DEFAULTS: {
57
+ readonly listSize: 15;
58
+ readonly quickSize: 500;
59
+ readonly fetchSize: 15;
60
+ readonly connections: 4;
61
+ readonly requestTimeoutMs: 90000;
62
+ readonly backoffMs: readonly [1000, 3000, 10000];
63
+ readonly maxAttempts: 8;
64
+ };
65
+ /** One IMAP source, its connections opened on first use and closed by `close`; the password never leaves this closure. */
66
+ export declare const imapSource: (endpoint: ImapEndpoint, password: string, tuning?: ImapTuning) => ImapMailSource;
67
+ //# sourceMappingURL=imap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imap.d.ts","sourceRoot":"","sources":["../../src/mail/imap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,wBAAwB,CAAA;AAKzE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,0EAA0E;IAC1E,QAAQ,EAAE,KAAK,GAAG,UAAU,GAAG,OAAO,CAAA;IACtC,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,QAAQ,EAAE,MAAM,CACd,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,EAC9F,OAAO,CACR,CAAA;IACD,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC,CAAA;IAC9B,UAAU,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IACnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,8FAA8F;IAC9F,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAA;IACxB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACrC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAA;CACtB;AAED,eAAO,MAAM,aAAa;aACxB,QAAQ,EAAE,EAAE;aACZ,SAAS,EAAE,GAAG;aACd,SAAS,EAAE,EAAE;aACb,WAAW,EAAE,CAAC;aACd,gBAAgB,EAAE,KAAM;aACxB,SAAS,YAAG,IAAK,EAAE,IAAK,EAAE,KAAM;aAChC,WAAW,EAAE,CAAC;CACN,CAAA;AAgBV,0HAA0H;AAC1H,eAAO,MAAM,UAAU,aAAc,YAAY,YAAY,MAAM,WAAU,UAAU,KAAQ,cAkX9F,CAAA"}
@@ -0,0 +1,348 @@
1
+ import { CliError } from "@wirecat/cli-base";
2
+ import { ImapFlow } from "imapflow";
3
+ import { mapImapError } from "./imap-errors.js";
4
+ import { HEADER_FIELDS, idsOf, listedOf, messageIdOf, quickOf, roleOf } from "./imap-messages.js";
5
+ export const IMAP_DEFAULTS = {
6
+ listSize: 15,
7
+ quickSize: 500,
8
+ fetchSize: 15,
9
+ connections: 4,
10
+ requestTimeoutMs: 90_000,
11
+ backoffMs: [1_000, 3_000, 10_000],
12
+ maxAttempts: 8,
13
+ };
14
+ const nap = (ms, signal) => new Promise((resolve, reject) => {
15
+ if (signal?.aborted)
16
+ return reject(signal.reason);
17
+ const timer = setTimeout(resolve, ms);
18
+ signal?.addEventListener("abort", () => {
19
+ clearTimeout(timer);
20
+ reject(signal.reason);
21
+ }, { once: true });
22
+ });
23
+ /** One IMAP source, its connections opened on first use and closed by `close`; the password never leaves this closure. */
24
+ export const imapSource = (endpoint, password, tuning = {}) => {
25
+ const { listSize, quickSize, fetchSize, connections, requestTimeoutMs, backoffMs, maxAttempts } = {
26
+ ...IMAP_DEFAULTS,
27
+ ...tuning,
28
+ };
29
+ const { canRetry, timeLeftMs, signal, sleep = nap, random = Math.random } = tuning;
30
+ const clients = [];
31
+ /** Each folder's UIDVALIDITY as the run first saw it; a reconnect that finds another one stops the run. */
32
+ const validities = new Map();
33
+ const connect = async (slot) => {
34
+ const existing = clients[slot];
35
+ if (existing?.usable)
36
+ return existing;
37
+ const next = new ImapFlow({
38
+ host: endpoint.host,
39
+ port: endpoint.port,
40
+ secure: endpoint.security === "tls",
41
+ doSTARTTLS: endpoint.security === "starttls",
42
+ auth: { user: endpoint.login, pass: password },
43
+ logger: false,
44
+ disableAutoIdle: true,
45
+ connectionTimeout: 15000,
46
+ greetingTimeout: 15000,
47
+ socketTimeout: 120000,
48
+ });
49
+ // An 'error' event with no listener would end the process, and the failing call already rejects.
50
+ next.on("error", () => { });
51
+ await next.connect();
52
+ clients[slot] = next;
53
+ return next;
54
+ };
55
+ const drop = (slot) => {
56
+ const open = clients[slot];
57
+ clients[slot] = undefined;
58
+ try {
59
+ open?.close();
60
+ }
61
+ catch { }
62
+ };
63
+ /** One command's own deadline, cut to the run's: a stuck command closes its connection and fails as a timeout. */
64
+ const limited = async (slot, work) => {
65
+ const left = timeLeftMs?.();
66
+ const ms = left === undefined ? requestTimeoutMs : Math.max(1, Math.min(requestTimeoutMs, left));
67
+ let timer;
68
+ const expired = new Promise((_, reject) => {
69
+ timer = setTimeout(() => {
70
+ drop(slot);
71
+ reject(Object.assign(new Error("request timed out"), { code: "RequestTimeout" }));
72
+ }, ms);
73
+ });
74
+ work.catch(() => { });
75
+ try {
76
+ return await Promise.race([work, expired]);
77
+ }
78
+ finally {
79
+ clearTimeout(timer);
80
+ }
81
+ };
82
+ const once = async (slot, folder, expected, work) => {
83
+ const open = await limited(slot, connect(slot));
84
+ if (folder === undefined)
85
+ return limited(slot, work(open, ""));
86
+ const lock = await limited(slot, open.getMailboxLock(folder, { readOnly: true }));
87
+ try {
88
+ // imapflow clears the selection when a SELECT fails or the server closes the mailbox, and a connection
89
+ // in that state still counts as usable: a command sent on it fails with NoMailboxSelected.
90
+ if (!open.mailbox)
91
+ throw Object.assign(new Error("no mailbox is selected"), { code: "NoMailboxSelected" });
92
+ const validity = String(open.mailbox.uidValidity);
93
+ const was = expected ?? validities.get(folder);
94
+ if (was !== undefined && validity !== was)
95
+ throw new CliError("invalid_response", "UIDVALIDITY changed during the run; run it again", {
96
+ reason: "mail.uidvalidity-changed",
97
+ });
98
+ return await limited(slot, work(open, validity));
99
+ }
100
+ finally {
101
+ try {
102
+ lock.release();
103
+ }
104
+ catch { }
105
+ }
106
+ };
107
+ /**
108
+ * Every call here only reads, so a failed command is safe to send again. A dropped line or a command that timed
109
+ * out closes its connection, waits (jittered backoff) and tries on a fresh one, for as long as the run's budget
110
+ * and deadline allow: a retry is a request of the budget, and none outlives the deadline.
111
+ */
112
+ const retrying = async (slot, command) => {
113
+ for (let attempt = 1;; attempt++) {
114
+ try {
115
+ return await command();
116
+ }
117
+ catch (raw) {
118
+ const error = mapImapError(raw);
119
+ const transient = error.code === "network_error" || error.code === "timeout" || error.code === "provider_unavailable";
120
+ if (transient)
121
+ drop(slot);
122
+ if (!transient || attempt >= maxAttempts || signal?.aborted)
123
+ throw error;
124
+ const base = backoffMs[Math.min(attempt, backoffMs.length) - 1] ?? 10_000;
125
+ const wait = Math.round(base * (0.5 + random()));
126
+ const left = timeLeftMs?.();
127
+ if (left !== undefined && left <= wait)
128
+ throw error;
129
+ if (canRetry && !canRetry())
130
+ throw error;
131
+ await sleep(wait, signal);
132
+ }
133
+ }
134
+ };
135
+ const inFolder = (folder, work, expected, slot = 0) => retrying(slot, () => once(slot, folder, expected, work));
136
+ /** Runs `work` over the batches on up to `connections` connections; the first failure stops the others. */
137
+ const spread = async (folder, batches, work, expected, onError) => {
138
+ const results = new Array(batches.length);
139
+ let next = 0;
140
+ let failure;
141
+ const worker = async (slot) => {
142
+ for (;;) {
143
+ const index = next++;
144
+ if (index >= batches.length || failure !== undefined)
145
+ return;
146
+ const batch = batches[index];
147
+ try {
148
+ results[index] = await inFolder(folder, (open) => work(open, batch), expected, slot);
149
+ }
150
+ catch (error) {
151
+ if (onError === undefined) {
152
+ failure ??= error;
153
+ return;
154
+ }
155
+ try {
156
+ results[index] = onError(error, batch);
157
+ }
158
+ catch (fatal) {
159
+ failure ??= fatal;
160
+ return;
161
+ }
162
+ }
163
+ }
164
+ };
165
+ await Promise.all(Array.from({ length: Math.min(connections, batches.length) }, (_, slot) => worker(slot)));
166
+ if (failure !== undefined)
167
+ throw failure;
168
+ return results;
169
+ };
170
+ const chunks = (items, size) => {
171
+ const out = [];
172
+ for (let start = 0; start < items.length; start += size)
173
+ out.push(items.slice(start, start + size));
174
+ return out;
175
+ };
176
+ const search = async (since, folder) => {
177
+ const found = await inFolder(folder, async (open, validity) => {
178
+ const uids = await open.search({ since }, { uid: true });
179
+ // Message ids come free with OBJECTID and Gmail's extensions; without them the envelope costs a read per message.
180
+ const quick = !open.capabilities.has("OBJECTID") && !open.capabilities.has("X-GM-EXT-1");
181
+ return { ...(validity ? { validity } : {}), uids: (uids || []).map(String), ...(quick ? { quick } : {}) };
182
+ });
183
+ if (found.validity)
184
+ validities.set(folder, found.validity);
185
+ return found;
186
+ };
187
+ const folderList = () => retrying(0, async () => {
188
+ const entries = await limited(0, connect(0).then((open) => open.list({ statusQuery: { messages: true, unseen: true } })));
189
+ return entries
190
+ .filter((entry) => !entry.flags.has("\\Noselect") && !entry.flags.has("\\NonExistent"))
191
+ .map((entry) => ({
192
+ path: entry.path,
193
+ name: entry.name,
194
+ role: roleOf(entry),
195
+ messages: entry.status?.messages ?? null,
196
+ unseen: entry.status?.unseen ?? null,
197
+ }));
198
+ });
199
+ return {
200
+ listBatch: listSize * connections,
201
+ fetchBatch: fetchSize * connections,
202
+ search,
203
+ present: (uids, folder) => inFolder(folder, async (open) => {
204
+ if (uids.length === 0)
205
+ return [];
206
+ const held = new Set((await open.search({ uid: uids.join(",") }, { uid: true })) || []);
207
+ return uids.filter((uid) => held.has(Number(uid)));
208
+ }),
209
+ folders: async () => {
210
+ const entries = await folderList();
211
+ const role = (...names) => entries.find((entry) => entry.role && names.includes(entry.role))?.path;
212
+ return { all: role("all", "archive") ?? "INBOX", trash: role("trash") ?? "Trash" };
213
+ },
214
+ list: async (since, folder, options) => {
215
+ const searched = options?.searched ?? (await search(since, folder));
216
+ if (!searched.validity)
217
+ throw new CliError("invalid_response", "IMAP did not report UIDVALIDITY");
218
+ const validity = searched.validity;
219
+ validities.set(folder, validity);
220
+ // A message the server answers with `NO [UNAVAILABLE]` is simply absent here; the sync asks for it again later.
221
+ const listing = (batches) => spread(folder, batches, (open, batch) => open.fetchAll(batch.join(","), {
222
+ uid: true,
223
+ flags: true,
224
+ internalDate: true,
225
+ size: true,
226
+ envelope: true,
227
+ threadId: true,
228
+ labels: true,
229
+ headers: HEADER_FIELDS,
230
+ }, { uid: true }), validity, (error) => {
231
+ const mapped = mapImapError(error);
232
+ if (mapped.code !== "provider_unavailable")
233
+ throw mapped;
234
+ return mapped;
235
+ });
236
+ const batches = chunks(searched.uids, listSize);
237
+ const parts = await listing(batches);
238
+ const messages = [];
239
+ for (const [index, part] of parts.entries()) {
240
+ if (!(part instanceof Error))
241
+ for (const message of part)
242
+ messages.push(message);
243
+ // Yandex refuses even the headers of a message it can never read, and with it the whole FETCH.
244
+ else if (batches[index].length > 1)
245
+ for (const single of await listing(batches[index].map((uid) => [uid])))
246
+ if (!(single instanceof Error))
247
+ for (const message of single)
248
+ messages.push(message);
249
+ }
250
+ return messages.map((message) => listedOf(message, folder, validity));
251
+ },
252
+ quick: async (_since, folder, { searched }) => {
253
+ if (!searched.validity)
254
+ throw new CliError("invalid_response", "IMAP did not report UIDVALIDITY");
255
+ const validity = searched.validity;
256
+ validities.set(folder, validity);
257
+ const parts = await spread(folder, chunks(searched.uids, quickSize), (open, batch) => open.fetchAll(batch.join(","), { uid: true, flags: true, internalDate: true, size: true }, { uid: true }), validity);
258
+ return parts.flat().map((message) => quickOf(message, folder));
259
+ },
260
+ identify: (raw, item) => {
261
+ const validity = validities.get(item.folder ?? "INBOX") ?? "";
262
+ return idsOf(messageIdOf(raw), item.folder ?? "INBOX", validity, item.uid);
263
+ },
264
+ fetchRaw: async (items) => {
265
+ const read = new Map();
266
+ const byFolder = new Map();
267
+ for (const item of items)
268
+ byFolder.set(item.folder ?? "INBOX", [...(byFolder.get(item.folder ?? "INBOX") ?? []), item]);
269
+ const bodies = (folder, batches) => spread(folder, batches, async (open, batch) => {
270
+ const found = new Map();
271
+ const messages = await open.fetchAll(batch.map(({ uid }) => uid).join(","), { uid: true, source: true }, { uid: true });
272
+ for (const message of messages)
273
+ if (message.source)
274
+ found.set(String(message.uid), message.source);
275
+ return found;
276
+ }, undefined, (error) => {
277
+ // A throttled or dropped connection fails the whole run; one unreadable batch costs only itself.
278
+ const mapped = mapImapError(error);
279
+ if (["rate_limited", "authentication_error", "network_error", "timeout"].includes(mapped.code))
280
+ throw mapped;
281
+ return mapped;
282
+ });
283
+ for (const [folder, group] of byFolder) {
284
+ const batches = chunks(group, fetchSize);
285
+ const answers = await bodies(folder, batches);
286
+ for (const [index, batch] of batches.entries()) {
287
+ let answer = answers[index];
288
+ // Yandex refuses a whole FETCH when one of its messages cannot be read; one by one, only that one is lost.
289
+ if (answer instanceof CliError && answer.code === "provider_unavailable" && batch.length > 1) {
290
+ const singles = await bodies(folder, batch.map((item) => [item]));
291
+ answer = new Map();
292
+ for (const [at, item] of batch.entries()) {
293
+ const single = singles[at];
294
+ if (single instanceof Map && single.has(item.uid))
295
+ answer.set(item.uid, single.get(item.uid));
296
+ else if (single instanceof Error)
297
+ read.set(item, single);
298
+ }
299
+ }
300
+ for (const item of batch) {
301
+ if (read.has(item))
302
+ continue;
303
+ const found = answer instanceof Map ? answer.get(item.uid) : undefined;
304
+ read.set(item, found ??
305
+ (answer instanceof Error ? answer : undefined) ??
306
+ new CliError("not_found", `email ${item.uid} was not returned`, { reason: "mail.not-returned" }));
307
+ }
308
+ }
309
+ }
310
+ return items.map((item) => read.get(item));
311
+ },
312
+ folderList,
313
+ check: () => retrying(0, async () => {
314
+ const open = await limited(0, connect(0));
315
+ const has = (name) => open.capabilities.has(name);
316
+ const folders = (await limited(0, open.list())).length;
317
+ return {
318
+ login: endpoint.login,
319
+ capabilities: [...open.capabilities.keys()].sort(),
320
+ features: {
321
+ idle: has("IDLE"),
322
+ condstore: has("CONDSTORE"),
323
+ qresync: has("QRESYNC"),
324
+ move: has("MOVE"),
325
+ uidplus: has("UIDPLUS"),
326
+ compress: has("COMPRESS=DEFLATE"),
327
+ x_gm_ext_1: has("X-GM-EXT-1"),
328
+ objectid: has("OBJECTID"),
329
+ },
330
+ folders,
331
+ };
332
+ }),
333
+ close: async () => {
334
+ const open = clients.splice(0);
335
+ await Promise.all(open.map(async (one) => {
336
+ if (!one)
337
+ return;
338
+ try {
339
+ await one.logout();
340
+ }
341
+ catch {
342
+ one.close();
343
+ }
344
+ }));
345
+ },
346
+ };
347
+ };
348
+ //# sourceMappingURL=imap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imap.js","sourceRoot":"","sources":["../../src/mail/imap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface Person {
2
+ address: string;
3
+ name: string | null;
4
+ }
5
+ export interface ParsedMail {
6
+ messageId: string | null;
7
+ subject: string | null;
8
+ from: Person | null;
9
+ to: Person[];
10
+ cc: Person[];
11
+ sentAt: number | null;
12
+ inReplyTo: string | null;
13
+ references: string[];
14
+ text: string;
15
+ }
16
+ export declare const MAX_BODY_CHARS = 1000000;
17
+ export declare const parseMail: (raw: Uint8Array) => Promise<ParsedMail>;
18
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/mail/parse.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,EAAE,EAAE,MAAM,EAAE,CAAA;IACZ,EAAE,EAAE,MAAM,EAAE,CAAA;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAGD,eAAO,MAAM,cAAc,UAAY,CAAA;AAkBvC,eAAO,MAAM,SAAS,QAAe,UAAU,KAAG,OAAO,CAAC,UAAU,CAenE,CAAA"}
@@ -0,0 +1,31 @@
1
+ import PostalMime, {} from "postal-mime";
2
+ // A guard against a pasted log, not a design limit.
3
+ export const MAX_BODY_CHARS = 1_000_000;
4
+ const people = (list) => (list ?? [])
5
+ .flatMap((entry) => entry.group ?? [entry])
6
+ .flatMap(({ address, name }) => (address ? [{ address: address.toLowerCase(), name: name || null }] : []));
7
+ const ENTITIES = { nbsp: " ", amp: "&", lt: "<", gt: ">", quot: '"', "#39": "'" };
8
+ // Mail without a text part is read as its HTML with the tags removed; nothing in it is rendered or followed.
9
+ const htmlText = (html) => html
10
+ .replace(/<!--[\s\S]*?(-->|$)/g, "")
11
+ .replace(/<(script|style)[\s\S]*?(<\/\1>|$)/gi, "")
12
+ .replace(/<[^>]*>/g, " ")
13
+ .replace(/&(nbsp|amp|lt|gt|quot|#39);/g, (_, name) => ENTITIES[name] ?? "")
14
+ .replace(/[ \t]+/g, " ");
15
+ export const parseMail = async (raw) => {
16
+ const mail = await PostalMime.parse(raw, { attachmentEncoding: "arraybuffer" });
17
+ const sent = mail.date ? Date.parse(mail.date) : Number.NaN;
18
+ const text = (mail.text ?? (mail.html ? htmlText(mail.html) : "")).slice(0, MAX_BODY_CHARS);
19
+ return {
20
+ messageId: mail.messageId ?? null,
21
+ subject: mail.subject ?? null,
22
+ from: people(mail.from ? [mail.from] : undefined)[0] ?? null,
23
+ to: people(mail.to),
24
+ cc: people(mail.cc),
25
+ sentAt: Number.isNaN(sent) ? null : sent,
26
+ inReplyTo: mail.inReplyTo ?? null,
27
+ references: mail.references?.match(/<[^>]+>/g) ?? [],
28
+ text,
29
+ };
30
+ };
31
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/mail/parse.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,EAAE,EAAgB,MAAM,aAAa,CAAA;AAmBtD,oDAAoD;AACpD,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAA;AAEvC,MAAM,MAAM,GAAG,CAAC,IAA2B,EAAY,EAAE,CACvD,CAAC,IAAI,IAAI,EAAE,CAAC;KACT,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC;KAC1C,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAE9G,MAAM,QAAQ,GAA2B,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAA;AAEzG,6GAA6G;AAC7G,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAU,EAAE,CACxC,IAAI;KACD,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;KACnC,OAAO,CAAC,qCAAqC,EAAE,EAAE,CAAC;KAClD,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;KACxB,OAAO,CAAC,8BAA8B,EAAE,CAAC,CAAC,EAAE,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;KAClF,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;AAE5B,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,GAAe,EAAuB,EAAE;IACtE,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC,CAAA;IAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA;IAC3D,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAA;IAC3F,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;QACjC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;QAC5D,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QACxC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;QACjC,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE;QACpD,IAAI;KACL,CAAA;AACH,CAAC,CAAA"}