imapkit 4.0.3 → 4.1.1

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 (485) hide show
  1. package/README.md +32 -19
  2. package/bin/imapkit.js +12 -16
  3. package/dist/cjs/addressparser.d.ts +21 -0
  4. package/dist/cjs/addressparser.js +271 -0
  5. package/dist/cjs/arguments.d.ts +31 -0
  6. package/{lib → dist/cjs}/arguments.js +9 -21
  7. package/dist/cjs/bodystructure.d.ts +25 -0
  8. package/dist/cjs/bodystructure.js +150 -0
  9. package/dist/cjs/cert.d.ts +2 -0
  10. package/dist/cjs/cert.js +7 -0
  11. package/dist/cjs/command-states.d.ts +36 -0
  12. package/dist/cjs/command-states.js +102 -0
  13. package/dist/cjs/commands/append.d.ts +88 -0
  14. package/dist/cjs/commands/append.js +299 -0
  15. package/dist/cjs/commands/capability.d.ts +2 -0
  16. package/dist/cjs/commands/capability.js +44 -0
  17. package/dist/cjs/commands/check.d.ts +2 -0
  18. package/dist/cjs/commands/check.js +28 -0
  19. package/dist/cjs/commands/close.d.ts +2 -0
  20. package/dist/cjs/commands/close.js +35 -0
  21. package/dist/cjs/commands/copy.d.ts +30 -0
  22. package/dist/cjs/commands/copy.js +107 -0
  23. package/dist/cjs/commands/create.d.ts +2 -0
  24. package/dist/cjs/commands/create.js +53 -0
  25. package/dist/cjs/commands/delete.d.ts +2 -0
  26. package/dist/cjs/commands/delete.js +63 -0
  27. package/dist/cjs/commands/examine.d.ts +2 -0
  28. package/dist/cjs/commands/examine.js +19 -0
  29. package/dist/cjs/commands/expunge.d.ts +2 -0
  30. package/dist/cjs/commands/expunge.js +32 -0
  31. package/dist/cjs/commands/fetch.d.ts +23 -0
  32. package/dist/cjs/commands/fetch.js +208 -0
  33. package/dist/cjs/commands/handlers/fetch.d.ts +12 -0
  34. package/dist/cjs/commands/handlers/fetch.js +195 -0
  35. package/dist/cjs/commands/handlers/flags.d.ts +17 -0
  36. package/dist/cjs/commands/handlers/flags.js +39 -0
  37. package/dist/cjs/commands/handlers/search.d.ts +85 -0
  38. package/dist/cjs/commands/handlers/search.js +504 -0
  39. package/dist/cjs/commands/handlers/status.d.ts +34 -0
  40. package/dist/cjs/commands/handlers/status.js +81 -0
  41. package/dist/cjs/commands/handlers/store.d.ts +3 -0
  42. package/dist/cjs/commands/handlers/store.js +117 -0
  43. package/dist/cjs/commands/index.d.ts +2 -0
  44. package/dist/cjs/commands/index.js +61 -0
  45. package/dist/cjs/commands/list.d.ts +2 -0
  46. package/dist/cjs/commands/list.js +86 -0
  47. package/dist/cjs/commands/login.d.ts +2 -0
  48. package/dist/cjs/commands/login.js +62 -0
  49. package/dist/cjs/commands/logout.d.ts +2 -0
  50. package/dist/cjs/commands/logout.js +40 -0
  51. package/dist/cjs/commands/lsub.d.ts +2 -0
  52. package/dist/cjs/commands/lsub.js +79 -0
  53. package/dist/cjs/commands/noop.d.ts +2 -0
  54. package/dist/cjs/commands/noop.js +28 -0
  55. package/dist/cjs/commands/rename.d.ts +2 -0
  56. package/dist/cjs/commands/rename.js +98 -0
  57. package/dist/cjs/commands/search.d.ts +10 -0
  58. package/dist/cjs/commands/search.js +71 -0
  59. package/dist/cjs/commands/select.d.ts +19 -0
  60. package/dist/cjs/commands/select.js +230 -0
  61. package/dist/cjs/commands/status.d.ts +2 -0
  62. package/dist/cjs/commands/status.js +57 -0
  63. package/dist/cjs/commands/store.d.ts +10 -0
  64. package/dist/cjs/commands/store.js +134 -0
  65. package/dist/cjs/commands/subscribe.d.ts +2 -0
  66. package/dist/cjs/commands/subscribe.js +51 -0
  67. package/dist/cjs/commands/uid-copy.d.ts +2 -0
  68. package/dist/cjs/commands/uid-copy.js +19 -0
  69. package/dist/cjs/commands/uid-fetch.d.ts +3 -0
  70. package/dist/cjs/commands/uid-fetch.js +17 -0
  71. package/dist/cjs/commands/uid-search.d.ts +3 -0
  72. package/dist/cjs/commands/uid-search.js +17 -0
  73. package/dist/cjs/commands/uid-store.d.ts +3 -0
  74. package/dist/cjs/commands/uid-store.js +17 -0
  75. package/dist/cjs/commands/unsubscribe.d.ts +2 -0
  76. package/dist/cjs/commands/unsubscribe.js +50 -0
  77. package/dist/cjs/dates.d.ts +64 -0
  78. package/dist/cjs/dates.js +124 -0
  79. package/dist/cjs/deflate-layer.d.ts +83 -0
  80. package/dist/cjs/deflate-layer.js +232 -0
  81. package/dist/cjs/encoded-words.d.ts +15 -0
  82. package/dist/cjs/encoded-words.js +85 -0
  83. package/dist/cjs/envelope.d.ts +33 -0
  84. package/dist/cjs/envelope.js +86 -0
  85. package/dist/cjs/esearch.d.ts +96 -0
  86. package/dist/cjs/esearch.js +190 -0
  87. package/dist/cjs/framing.d.ts +66 -0
  88. package/{lib → dist/cjs}/framing.js +9 -26
  89. package/dist/cjs/index.d.ts +9 -0
  90. package/dist/cjs/index.js +56 -0
  91. package/dist/cjs/list-extensions.d.ts +50 -0
  92. package/dist/cjs/list-extensions.js +35 -0
  93. package/dist/cjs/load-plugins.d.ts +21 -0
  94. package/dist/cjs/load-plugins.js +89 -0
  95. package/dist/cjs/mailbox-name.d.ts +26 -0
  96. package/dist/cjs/mailbox-name.js +127 -0
  97. package/dist/cjs/mimeparser.d.ts +137 -0
  98. package/dist/cjs/mimeparser.js +727 -0
  99. package/dist/cjs/mock-client.d.ts +39 -0
  100. package/dist/cjs/mock-client.js +236 -0
  101. package/dist/cjs/numbers.d.ts +28 -0
  102. package/dist/cjs/numbers.js +52 -0
  103. package/dist/cjs/package.json +3 -0
  104. package/dist/cjs/plugins/acl.d.ts +2 -0
  105. package/dist/cjs/plugins/acl.js +888 -0
  106. package/dist/cjs/plugins/appendlimit.d.ts +16 -0
  107. package/dist/cjs/plugins/appendlimit.js +87 -0
  108. package/dist/cjs/plugins/auth-plain.d.ts +2 -0
  109. package/dist/cjs/plugins/auth-plain.js +89 -0
  110. package/dist/cjs/plugins/binary.d.ts +30 -0
  111. package/dist/cjs/plugins/binary.js +247 -0
  112. package/dist/cjs/plugins/catenate.d.ts +14 -0
  113. package/dist/cjs/plugins/catenate.js +250 -0
  114. package/dist/cjs/plugins/compress.d.ts +7 -0
  115. package/dist/cjs/plugins/compress.js +79 -0
  116. package/dist/cjs/plugins/condstore.d.ts +5 -0
  117. package/dist/cjs/plugins/condstore.js +492 -0
  118. package/dist/cjs/plugins/context-search.d.ts +8 -0
  119. package/dist/cjs/plugins/context-search.js +304 -0
  120. package/dist/cjs/plugins/context-sort.d.ts +6 -0
  121. package/dist/cjs/plugins/context-sort.js +32 -0
  122. package/dist/cjs/plugins/create-special-use.d.ts +7 -0
  123. package/dist/cjs/plugins/create-special-use.js +101 -0
  124. package/dist/cjs/plugins/enable.d.ts +23 -0
  125. package/dist/cjs/plugins/enable.js +127 -0
  126. package/dist/cjs/plugins/esearch.d.ts +6 -0
  127. package/dist/cjs/plugins/esearch.js +142 -0
  128. package/dist/cjs/plugins/esort.d.ts +6 -0
  129. package/dist/cjs/plugins/esort.js +60 -0
  130. package/dist/cjs/plugins/id.d.ts +5 -0
  131. package/dist/cjs/plugins/id.js +123 -0
  132. package/dist/cjs/plugins/idle.d.ts +5 -0
  133. package/dist/cjs/plugins/idle.js +85 -0
  134. package/dist/cjs/plugins/imap4rev2.d.ts +6 -0
  135. package/dist/cjs/plugins/imap4rev2.js +184 -0
  136. package/dist/cjs/plugins/index.d.ts +2 -0
  137. package/dist/cjs/plugins/index.js +119 -0
  138. package/dist/cjs/plugins/list-extended.d.ts +2 -0
  139. package/dist/cjs/plugins/list-extended.js +235 -0
  140. package/dist/cjs/plugins/list-status.d.ts +6 -0
  141. package/dist/cjs/plugins/list-status.js +42 -0
  142. package/dist/cjs/plugins/literalminus.d.ts +8 -0
  143. package/dist/cjs/plugins/literalminus.js +32 -0
  144. package/dist/cjs/plugins/literalplus.d.ts +6 -0
  145. package/dist/cjs/plugins/literalplus.js +30 -0
  146. package/dist/cjs/plugins/logindisabled.d.ts +5 -0
  147. package/dist/cjs/plugins/logindisabled.js +54 -0
  148. package/dist/cjs/plugins/messagelimit.d.ts +19 -0
  149. package/dist/cjs/plugins/messagelimit.js +227 -0
  150. package/dist/cjs/plugins/metadata-server.d.ts +7 -0
  151. package/dist/cjs/plugins/metadata-server.js +24 -0
  152. package/dist/cjs/plugins/metadata.d.ts +11 -0
  153. package/dist/cjs/plugins/metadata.js +436 -0
  154. package/dist/cjs/plugins/move.d.ts +11 -0
  155. package/dist/cjs/plugins/move.js +96 -0
  156. package/dist/cjs/plugins/multiappend.d.ts +12 -0
  157. package/dist/cjs/plugins/multiappend.js +38 -0
  158. package/dist/cjs/plugins/multisearch.d.ts +6 -0
  159. package/dist/cjs/plugins/multisearch.js +263 -0
  160. package/dist/cjs/plugins/namespace.d.ts +5 -0
  161. package/dist/cjs/plugins/namespace.js +57 -0
  162. package/dist/cjs/plugins/notify.d.ts +2 -0
  163. package/dist/cjs/plugins/notify.js +628 -0
  164. package/dist/cjs/plugins/oauthbearer.d.ts +32 -0
  165. package/dist/cjs/plugins/oauthbearer.js +202 -0
  166. package/dist/cjs/plugins/objectid.d.ts +23 -0
  167. package/dist/cjs/plugins/objectid.js +221 -0
  168. package/dist/cjs/plugins/partial.d.ts +6 -0
  169. package/dist/cjs/plugins/partial.js +78 -0
  170. package/dist/cjs/plugins/preview.d.ts +31 -0
  171. package/dist/cjs/plugins/preview.js +378 -0
  172. package/dist/cjs/plugins/qresync.d.ts +11 -0
  173. package/dist/cjs/plugins/qresync.js +473 -0
  174. package/dist/cjs/plugins/quota.d.ts +18 -0
  175. package/dist/cjs/plugins/quota.js +254 -0
  176. package/dist/cjs/plugins/replace.d.ts +14 -0
  177. package/dist/cjs/plugins/replace.js +130 -0
  178. package/dist/cjs/plugins/sasl-ir.d.ts +5 -0
  179. package/dist/cjs/plugins/sasl-ir.js +24 -0
  180. package/dist/cjs/plugins/savedate.d.ts +17 -0
  181. package/dist/cjs/plugins/savedate.js +64 -0
  182. package/dist/cjs/plugins/savelimit.d.ts +10 -0
  183. package/dist/cjs/plugins/savelimit.js +30 -0
  184. package/dist/cjs/plugins/searchres.d.ts +6 -0
  185. package/dist/cjs/plugins/searchres.js +91 -0
  186. package/dist/cjs/plugins/sort-display.d.ts +11 -0
  187. package/dist/cjs/plugins/sort-display.js +37 -0
  188. package/dist/cjs/plugins/sort.d.ts +11 -0
  189. package/dist/cjs/plugins/sort.js +125 -0
  190. package/dist/cjs/plugins/special-use.d.ts +10 -0
  191. package/dist/cjs/plugins/special-use.js +95 -0
  192. package/dist/cjs/plugins/starttls.d.ts +5 -0
  193. package/dist/cjs/plugins/starttls.js +55 -0
  194. package/dist/cjs/plugins/status-size.d.ts +7 -0
  195. package/dist/cjs/plugins/status-size.js +30 -0
  196. package/dist/cjs/plugins/thread-orderedsubject.d.ts +11 -0
  197. package/dist/cjs/plugins/thread-orderedsubject.js +28 -0
  198. package/dist/cjs/plugins/thread-references.d.ts +11 -0
  199. package/dist/cjs/plugins/thread-references.js +28 -0
  200. package/dist/cjs/plugins/uidonly.d.ts +15 -0
  201. package/dist/cjs/plugins/uidonly.js +126 -0
  202. package/dist/cjs/plugins/uidplus.d.ts +15 -0
  203. package/dist/cjs/plugins/uidplus.js +119 -0
  204. package/dist/cjs/plugins/unauthenticate.d.ts +7 -0
  205. package/dist/cjs/plugins/unauthenticate.js +32 -0
  206. package/dist/cjs/plugins/unselect.d.ts +5 -0
  207. package/dist/cjs/plugins/unselect.js +36 -0
  208. package/dist/cjs/plugins/utf8-accept.d.ts +6 -0
  209. package/dist/cjs/plugins/utf8-accept.js +72 -0
  210. package/dist/cjs/plugins/x-gm-ext-1.d.ts +26 -0
  211. package/dist/cjs/plugins/x-gm-ext-1.js +422 -0
  212. package/dist/cjs/plugins/xoauth2.d.ts +2 -0
  213. package/dist/cjs/plugins/xoauth2.js +155 -0
  214. package/dist/cjs/plugins/xtoybird.d.ts +2 -0
  215. package/dist/cjs/plugins/xtoybird.js +236 -0
  216. package/dist/cjs/server.d.ts +876 -0
  217. package/dist/cjs/server.js +2597 -0
  218. package/dist/cjs/smtp-listener.d.ts +13 -0
  219. package/dist/cjs/smtp-listener.js +47 -0
  220. package/dist/cjs/sorting.d.ts +77 -0
  221. package/dist/cjs/sorting.js +290 -0
  222. package/dist/cjs/threading.d.ts +30 -0
  223. package/dist/cjs/threading.js +318 -0
  224. package/dist/cjs/types.d.ts +327 -0
  225. package/dist/cjs/types.js +3 -0
  226. package/dist/cjs/utf8-session.d.ts +17 -0
  227. package/dist/cjs/utf8-session.js +148 -0
  228. package/dist/cjs/vanished.d.ts +21 -0
  229. package/dist/cjs/vanished.js +55 -0
  230. package/dist/esm/addressparser.d.ts +21 -0
  231. package/{lib → dist/esm}/addressparser.js +106 -133
  232. package/dist/esm/arguments.d.ts +31 -0
  233. package/dist/esm/arguments.js +96 -0
  234. package/dist/esm/bodystructure.d.ts +25 -0
  235. package/{lib → dist/esm}/bodystructure.js +17 -33
  236. package/dist/esm/cert.d.ts +2 -0
  237. package/dist/esm/cert.js +4 -0
  238. package/dist/esm/command-states.d.ts +36 -0
  239. package/{lib → dist/esm}/command-states.js +4 -16
  240. package/dist/esm/commands/append.d.ts +88 -0
  241. package/{lib → dist/esm}/commands/append.js +47 -85
  242. package/dist/esm/commands/capability.d.ts +2 -0
  243. package/dist/esm/commands/capability.js +29 -0
  244. package/dist/esm/commands/check.d.ts +2 -0
  245. package/dist/esm/commands/check.js +13 -0
  246. package/dist/esm/commands/close.d.ts +2 -0
  247. package/dist/esm/commands/close.js +20 -0
  248. package/dist/esm/commands/copy.d.ts +30 -0
  249. package/{lib → dist/esm}/commands/copy.js +31 -55
  250. package/dist/esm/commands/create.d.ts +2 -0
  251. package/{lib → dist/esm}/commands/create.js +25 -39
  252. package/dist/esm/commands/delete.d.ts +2 -0
  253. package/{lib → dist/esm}/commands/delete.js +25 -41
  254. package/dist/esm/commands/examine.d.ts +2 -0
  255. package/dist/esm/commands/examine.js +4 -0
  256. package/dist/esm/commands/expunge.d.ts +2 -0
  257. package/dist/esm/commands/expunge.js +17 -0
  258. package/dist/esm/commands/fetch.d.ts +23 -0
  259. package/{lib → dist/esm}/commands/fetch.js +33 -74
  260. package/dist/esm/commands/handlers/fetch.d.ts +12 -0
  261. package/{lib → dist/esm}/commands/handlers/fetch.js +11 -42
  262. package/dist/esm/commands/handlers/flags.d.ts +17 -0
  263. package/{lib → dist/esm}/commands/handlers/flags.js +3 -11
  264. package/dist/esm/commands/handlers/search.d.ts +85 -0
  265. package/{lib → dist/esm}/commands/handlers/search.js +33 -71
  266. package/dist/esm/commands/handlers/status.d.ts +34 -0
  267. package/{lib → dist/esm}/commands/handlers/status.js +1 -9
  268. package/dist/esm/commands/handlers/store.d.ts +3 -0
  269. package/{lib → dist/esm}/commands/handlers/store.js +20 -44
  270. package/dist/esm/commands/index.d.ts +2 -0
  271. package/dist/esm/commands/index.js +55 -0
  272. package/dist/esm/commands/list.d.ts +2 -0
  273. package/dist/esm/commands/list.js +71 -0
  274. package/dist/esm/commands/login.d.ts +2 -0
  275. package/{lib → dist/esm}/commands/login.js +24 -44
  276. package/dist/esm/commands/logout.d.ts +2 -0
  277. package/dist/esm/commands/logout.js +25 -0
  278. package/dist/esm/commands/lsub.d.ts +2 -0
  279. package/dist/esm/commands/lsub.js +64 -0
  280. package/dist/esm/commands/noop.d.ts +2 -0
  281. package/dist/esm/commands/noop.js +13 -0
  282. package/dist/esm/commands/rename.d.ts +2 -0
  283. package/{lib → dist/esm}/commands/rename.js +32 -51
  284. package/dist/esm/commands/search.d.ts +10 -0
  285. package/dist/esm/commands/search.js +54 -0
  286. package/dist/esm/commands/select.d.ts +19 -0
  287. package/dist/esm/commands/select.js +214 -0
  288. package/dist/esm/commands/status.d.ts +2 -0
  289. package/{lib → dist/esm}/commands/status.js +18 -39
  290. package/dist/esm/commands/store.d.ts +10 -0
  291. package/{lib → dist/esm}/commands/store.js +39 -73
  292. package/dist/esm/commands/subscribe.d.ts +2 -0
  293. package/{lib → dist/esm}/commands/subscribe.js +22 -39
  294. package/dist/esm/commands/uid-copy.d.ts +2 -0
  295. package/dist/esm/commands/uid-copy.js +4 -0
  296. package/dist/esm/commands/uid-fetch.d.ts +3 -0
  297. package/dist/esm/commands/uid-fetch.js +3 -0
  298. package/dist/esm/commands/uid-search.d.ts +3 -0
  299. package/dist/esm/commands/uid-search.js +3 -0
  300. package/dist/esm/commands/uid-store.d.ts +3 -0
  301. package/dist/esm/commands/uid-store.js +3 -0
  302. package/dist/esm/commands/unsubscribe.d.ts +2 -0
  303. package/{lib → dist/esm}/commands/unsubscribe.js +22 -37
  304. package/dist/esm/dates.d.ts +64 -0
  305. package/{lib → dist/esm}/dates.js +6 -14
  306. package/dist/esm/deflate-layer.d.ts +83 -0
  307. package/{lib → dist/esm}/deflate-layer.js +9 -26
  308. package/dist/esm/encoded-words.d.ts +15 -0
  309. package/{lib → dist/esm}/encoded-words.js +9 -25
  310. package/dist/esm/envelope.d.ts +33 -0
  311. package/{lib → dist/esm}/envelope.js +8 -19
  312. package/dist/esm/esearch.d.ts +96 -0
  313. package/{lib → dist/esm}/esearch.js +12 -39
  314. package/dist/esm/framing.d.ts +66 -0
  315. package/dist/esm/framing.js +82 -0
  316. package/dist/esm/index.d.ts +9 -0
  317. package/dist/esm/index.js +6 -0
  318. package/dist/esm/list-extensions.d.ts +50 -0
  319. package/{lib → dist/esm}/list-extensions.js +1 -4
  320. package/dist/esm/load-plugins.d.ts +21 -0
  321. package/{lib → dist/esm}/load-plugins.js +9 -43
  322. package/dist/esm/mailbox-name.d.ts +26 -0
  323. package/{lib → dist/esm}/mailbox-name.js +5 -26
  324. package/dist/esm/mimeparser.d.ts +137 -0
  325. package/{lib → dist/esm}/mimeparser.js +74 -152
  326. package/dist/esm/mock-client.d.ts +39 -0
  327. package/{lib → dist/esm}/mock-client.js +26 -40
  328. package/dist/esm/numbers.d.ts +28 -0
  329. package/{lib → dist/esm}/numbers.js +1 -8
  330. package/dist/esm/package.json +3 -0
  331. package/dist/esm/plugins/acl.d.ts +2 -0
  332. package/{lib → dist/esm}/plugins/acl.js +146 -240
  333. package/dist/esm/plugins/appendlimit.d.ts +16 -0
  334. package/{lib → dist/esm}/plugins/appendlimit.js +5 -16
  335. package/dist/esm/plugins/auth-plain.d.ts +2 -0
  336. package/{lib → dist/esm}/plugins/auth-plain.js +11 -31
  337. package/dist/esm/plugins/binary.d.ts +30 -0
  338. package/{lib → dist/esm}/plugins/binary.js +17 -43
  339. package/dist/esm/plugins/catenate.d.ts +14 -0
  340. package/{lib → dist/esm}/plugins/catenate.js +19 -40
  341. package/dist/esm/plugins/compress.d.ts +7 -0
  342. package/dist/esm/plugins/compress.js +61 -0
  343. package/dist/esm/plugins/condstore.d.ts +5 -0
  344. package/{lib → dist/esm}/plugins/condstore.js +66 -152
  345. package/dist/esm/plugins/context-search.d.ts +8 -0
  346. package/{lib → dist/esm}/plugins/context-search.js +53 -88
  347. package/dist/esm/plugins/context-sort.d.ts +6 -0
  348. package/{lib → dist/esm}/plugins/context-sort.js +4 -9
  349. package/dist/esm/plugins/create-special-use.d.ts +7 -0
  350. package/{lib → dist/esm}/plugins/create-special-use.js +33 -55
  351. package/dist/esm/plugins/enable.d.ts +23 -0
  352. package/dist/esm/plugins/enable.js +111 -0
  353. package/dist/esm/plugins/esearch.d.ts +6 -0
  354. package/{lib → dist/esm}/plugins/esearch.js +13 -42
  355. package/dist/esm/plugins/esort.d.ts +6 -0
  356. package/{lib → dist/esm}/plugins/esort.js +7 -25
  357. package/dist/esm/plugins/id.d.ts +5 -0
  358. package/dist/esm/plugins/id.js +108 -0
  359. package/dist/esm/plugins/idle.d.ts +5 -0
  360. package/dist/esm/plugins/idle.js +70 -0
  361. package/dist/esm/plugins/imap4rev2.d.ts +6 -0
  362. package/{lib → dist/esm}/plugins/imap4rev2.js +24 -60
  363. package/dist/esm/plugins/index.d.ts +2 -0
  364. package/dist/esm/plugins/index.js +113 -0
  365. package/dist/esm/plugins/list-extended.d.ts +2 -0
  366. package/{lib → dist/esm}/plugins/list-extended.js +28 -66
  367. package/dist/esm/plugins/list-status.d.ts +6 -0
  368. package/{lib → dist/esm}/plugins/list-status.js +5 -12
  369. package/dist/esm/plugins/literalminus.d.ts +8 -0
  370. package/{lib → dist/esm}/plugins/literalminus.js +2 -5
  371. package/dist/esm/plugins/literalplus.d.ts +6 -0
  372. package/{lib → dist/esm}/plugins/literalplus.js +2 -5
  373. package/dist/esm/plugins/logindisabled.d.ts +5 -0
  374. package/dist/esm/plugins/logindisabled.js +39 -0
  375. package/dist/esm/plugins/messagelimit.d.ts +19 -0
  376. package/{lib → dist/esm}/plugins/messagelimit.js +18 -41
  377. package/dist/esm/plugins/metadata-server.d.ts +7 -0
  378. package/{lib → dist/esm}/plugins/metadata-server.js +3 -7
  379. package/dist/esm/plugins/metadata.d.ts +11 -0
  380. package/dist/esm/plugins/metadata.js +421 -0
  381. package/dist/esm/plugins/move.d.ts +11 -0
  382. package/{lib → dist/esm}/plugins/move.js +37 -66
  383. package/dist/esm/plugins/multiappend.d.ts +12 -0
  384. package/{lib → dist/esm}/plugins/multiappend.js +2 -5
  385. package/dist/esm/plugins/multisearch.d.ts +6 -0
  386. package/{lib → dist/esm}/plugins/multisearch.js +24 -48
  387. package/dist/esm/plugins/namespace.d.ts +5 -0
  388. package/dist/esm/plugins/namespace.js +42 -0
  389. package/dist/esm/plugins/notify.d.ts +2 -0
  390. package/{lib → dist/esm}/plugins/notify.js +90 -134
  391. package/dist/esm/plugins/oauthbearer.d.ts +32 -0
  392. package/{lib → dist/esm}/plugins/oauthbearer.js +18 -48
  393. package/dist/esm/plugins/objectid.d.ts +23 -0
  394. package/{lib → dist/esm}/plugins/objectid.js +21 -58
  395. package/dist/esm/plugins/partial.d.ts +6 -0
  396. package/{lib → dist/esm}/plugins/partial.js +7 -15
  397. package/dist/esm/plugins/preview.d.ts +31 -0
  398. package/{lib → dist/esm}/plugins/preview.js +28 -66
  399. package/dist/esm/plugins/qresync.d.ts +11 -0
  400. package/{lib → dist/esm}/plugins/qresync.js +64 -134
  401. package/dist/esm/plugins/quota.d.ts +18 -0
  402. package/{lib → dist/esm}/plugins/quota.js +89 -135
  403. package/dist/esm/plugins/replace.d.ts +14 -0
  404. package/{lib → dist/esm}/plugins/replace.js +21 -51
  405. package/dist/esm/plugins/sasl-ir.d.ts +5 -0
  406. package/{lib → dist/esm}/plugins/sasl-ir.js +3 -6
  407. package/dist/esm/plugins/savedate.d.ts +17 -0
  408. package/{lib → dist/esm}/plugins/savedate.js +5 -15
  409. package/dist/esm/plugins/savelimit.d.ts +10 -0
  410. package/{lib → dist/esm}/plugins/savelimit.js +3 -6
  411. package/dist/esm/plugins/searchres.d.ts +6 -0
  412. package/{lib → dist/esm}/plugins/searchres.js +13 -22
  413. package/dist/esm/plugins/sort-display.d.ts +11 -0
  414. package/{lib → dist/esm}/plugins/sort-display.js +6 -10
  415. package/dist/esm/plugins/sort.d.ts +11 -0
  416. package/{lib → dist/esm}/plugins/sort.js +24 -46
  417. package/dist/esm/plugins/special-use.d.ts +10 -0
  418. package/{lib → dist/esm}/plugins/special-use.js +9 -24
  419. package/dist/esm/plugins/starttls.d.ts +5 -0
  420. package/{lib → dist/esm}/plugins/starttls.js +20 -37
  421. package/dist/esm/plugins/status-size.d.ts +7 -0
  422. package/{lib → dist/esm}/plugins/status-size.js +4 -11
  423. package/dist/esm/plugins/thread-orderedsubject.d.ts +11 -0
  424. package/{lib → dist/esm}/plugins/thread-orderedsubject.js +3 -6
  425. package/dist/esm/plugins/thread-references.d.ts +11 -0
  426. package/{lib → dist/esm}/plugins/thread-references.js +3 -6
  427. package/dist/esm/plugins/uidonly.d.ts +15 -0
  428. package/{lib → dist/esm}/plugins/uidonly.js +11 -35
  429. package/dist/esm/plugins/uidplus.d.ts +15 -0
  430. package/{lib → dist/esm}/plugins/uidplus.js +25 -45
  431. package/dist/esm/plugins/unauthenticate.d.ts +7 -0
  432. package/dist/esm/plugins/unauthenticate.js +17 -0
  433. package/dist/esm/plugins/unselect.d.ts +5 -0
  434. package/dist/esm/plugins/unselect.js +21 -0
  435. package/dist/esm/plugins/utf8-accept.d.ts +6 -0
  436. package/{lib → dist/esm}/plugins/utf8-accept.js +10 -21
  437. package/dist/esm/plugins/x-gm-ext-1.d.ts +26 -0
  438. package/{lib → dist/esm}/plugins/x-gm-ext-1.js +48 -100
  439. package/dist/esm/plugins/xoauth2.d.ts +2 -0
  440. package/dist/esm/plugins/xoauth2.js +140 -0
  441. package/dist/esm/plugins/xtoybird.d.ts +2 -0
  442. package/dist/esm/plugins/xtoybird.js +218 -0
  443. package/dist/esm/server.d.ts +876 -0
  444. package/dist/esm/server.js +2543 -0
  445. package/dist/esm/smtp-listener.d.ts +13 -0
  446. package/{lib → dist/esm}/smtp-listener.js +5 -12
  447. package/dist/esm/sorting.d.ts +77 -0
  448. package/{lib → dist/esm}/sorting.js +40 -53
  449. package/dist/esm/threading.d.ts +30 -0
  450. package/{lib → dist/esm}/threading.js +29 -70
  451. package/dist/esm/types.d.ts +327 -0
  452. package/dist/esm/types.js +2 -0
  453. package/dist/esm/utf8-session.d.ts +17 -0
  454. package/{lib → dist/esm}/utf8-session.js +15 -25
  455. package/dist/esm/vanished.d.ts +21 -0
  456. package/{lib → dist/esm}/vanished.js +16 -21
  457. package/dist/plugin-help.json +298 -0
  458. package/package.json +55 -12
  459. package/lib/commands/capability.js +0 -47
  460. package/lib/commands/check.js +0 -21
  461. package/lib/commands/close.js +0 -30
  462. package/lib/commands/examine.js +0 -7
  463. package/lib/commands/expunge.js +0 -27
  464. package/lib/commands/list.js +0 -100
  465. package/lib/commands/logout.js +0 -41
  466. package/lib/commands/lsub.js +0 -87
  467. package/lib/commands/noop.js +0 -21
  468. package/lib/commands/search.js +0 -76
  469. package/lib/commands/select.js +0 -289
  470. package/lib/commands/uid copy.js +0 -7
  471. package/lib/commands/uid fetch.js +0 -5
  472. package/lib/commands/uid search.js +0 -5
  473. package/lib/commands/uid store.js +0 -5
  474. package/lib/plugins/compress.js +0 -76
  475. package/lib/plugins/enable.js +0 -155
  476. package/lib/plugins/id.js +0 -138
  477. package/lib/plugins/idle.js +0 -105
  478. package/lib/plugins/logindisabled.js +0 -50
  479. package/lib/plugins/metadata.js +0 -475
  480. package/lib/plugins/namespace.js +0 -67
  481. package/lib/plugins/unauthenticate.js +0 -28
  482. package/lib/plugins/unselect.js +0 -36
  483. package/lib/plugins/xoauth2.js +0 -188
  484. package/lib/plugins/xtoybird.js +0 -282
  485. package/lib/server.js +0 -2880
@@ -1,37 +1,28 @@
1
- 'use strict';
2
-
3
1
  /**
4
2
  * @help Adds QRESYNC [RFC7162] capability, loads CONDSTORE and ENABLE as well
5
3
  * @help After ENABLE QRESYNC: SELECT/EXAMINE (QRESYNC (...)), UID FETCH (CHANGEDSINCE n VANISHED),
6
4
  * @help and VANISHED responses instead of EXPUNGE
7
5
  */
8
-
9
- const fetchHandlers = require('../commands/handlers/fetch');
10
- const { isExpungeNotification, toVanished } = require('../vanished');
11
- const { MAX_NUMBER64, isNumber, isNzNumber, isSequenceSet } = require('../numbers');
12
- const { isAtom } = require('../arguments');
13
- const { registerEnable, isEnabled } = require('./enable');
14
-
6
+ import fetchHandlers from '../commands/handlers/fetch.js';
7
+ import { isExpungeNotification, toVanished } from '../vanished.js';
8
+ import { MAX_NUMBER64, isNumber, isNzNumber, isSequenceSet } from '../numbers.js';
9
+ import { isAtom } from '../arguments.js';
10
+ import { registerEnable, isEnabled } from './enable.js';
15
11
  // commands that report expunged messages, their tagged OK carries the new HIGHESTMODSEQ (RFC 7162 sections 3.2.7
16
12
  // and 3.2.9, RFC 6851 section 4.4). CLOSE MUST NOT (RFC 7162 section 3.2.8)
17
13
  // REPLACE removes the replaced message as if with UID EXPUNGE (RFC 8508 section 4.5)
18
14
  const EXPUNGING_COMMANDS = new Set(['EXPUNGE', 'UID EXPUNGE', 'MOVE', 'UID MOVE', 'REPLACE', 'UID REPLACE']);
19
-
20
- module.exports = function (server) {
15
+ export default function qresyncPlugin(server) {
21
16
  server.registerCapability('QRESYNC');
22
17
  registerEnable(server, 'QRESYNC');
23
-
24
18
  // RFC 8437 section 4.1: UNAUTHENTICATE ends what ENABLE QRESYNC enabled (the ENABLE plugin clears the list)
25
- server.resetHandlers.push(connection => {
19
+ server.resetHandlers.push((connection) => {
26
20
  connection.qresyncExpunged = false;
27
21
  });
28
-
29
22
  // mod-sequence each expunged message was removed with
30
23
  const expungeModseq = new WeakMap();
31
-
32
- const isQresync = connection => isEnabled(connection, 'QRESYNC');
24
+ const isQresync = (connection) => isEnabled(connection, 'QRESYNC');
33
25
  const { isEnabled: isCondstore, getHighestModseq } = server.condstore;
34
-
35
26
  // Expunged UID ranges with their mod-sequences, oldest first (RFC 7162 section 5.3), and the mod-sequence after which
36
27
  // all expunges are remembered. Messages missing from the initial storage were expunged at an unknown time
37
28
  // before. The record belongs to one UIDVALIDITY, as nothing needs to be kept once it changes
@@ -41,27 +32,26 @@ module.exports = function (server) {
41
32
  }
42
33
  return mailbox.qresyncExpunged;
43
34
  };
44
-
45
35
  // start remembering expunges for the mailboxes of the storage once their messages have mod-sequences
46
36
  const indexFolders = server.indexFolders;
47
- server.indexFolders = function () {
48
- const result = indexFolders.apply(this, arguments);
37
+ server.indexFolders = function (...args) {
38
+ const result = indexFolders.apply(this, args);
49
39
  Object.keys(this.folderCache).forEach(path => getExpunged(this.folderCache[path]));
50
40
  return result;
51
41
  };
52
-
53
42
  // CONDSTORE has already incremented HIGHESTMODSEQ for this removal, the expunged UIDs get that value
54
43
  // (RFC 7162 section 3.2)
55
44
  server.on('expunge', (mailbox, messages, connection) => {
56
45
  const modseq = getHighestModseq(mailbox);
57
46
  const list = getExpunged(mailbox, modseq - 1).list;
58
- messages.forEach(message => {
47
+ messages.forEach((message) => {
59
48
  // consecutive UIDs expunged together are kept as one range, so the history stays small even in long test
60
49
  // runs. It is never trimmed: the server keeps everything since it started (RFC 7162 section 5.3)
61
50
  const last = list[list.length - 1];
62
51
  if (last && last.modseq === modseq && last.to + 1 === message.uid) {
63
52
  last.to = message.uid;
64
- } else {
53
+ }
54
+ else {
65
55
  list.push({ from: message.uid, to: message.uid, modseq });
66
56
  }
67
57
  expungeModseq.set(message, modseq);
@@ -70,7 +60,6 @@ module.exports = function (server) {
70
60
  connection.qresyncExpunged = true;
71
61
  }
72
62
  });
73
-
74
63
  /**
75
64
  * Lists the UIDs of a set that were expunged after a mod-sequence (RFC 7162 sections 3.2.5.1 and 3.2.6)
76
65
  *
@@ -83,31 +72,28 @@ module.exports = function (server) {
83
72
  */
84
73
  const getVanished = (mailbox, messages, ranges, modseq, knownUpTo) => {
85
74
  const { since, list } = getExpunged(mailbox);
86
-
87
75
  let candidates;
88
76
  if (modseq >= since) {
89
77
  // all expunges after the client's mod-sequence are remembered. Message sequence match data only helps
90
78
  // when they are not, so it is not used here (RFC 7162 section 5.3)
91
- candidates = intersectRanges(mergeRanges(list.filter(entry => entry.modseq > modseq).map(entry => [entry.from, entry.to])), ranges);
92
- } else {
79
+ candidates = intersectRanges(mergeRanges(list.filter(entry => entry.modseq > modseq).map((entry) => [entry.from, entry.to])), ranges);
80
+ }
81
+ else {
93
82
  // RFC 7162 section 3.2.6: for a mod-sequence older than the remembered expunges, the server MUST behave as
94
83
  // if asked to report all expunged messages of the set: every UID below UIDNEXT that is not in the mailbox,
95
84
  // except what the sequence match data shows the client knows
96
85
  candidates = intersectRanges(ranges, [[(knownUpTo || 0) + 1, mailbox.uidnext - 1]]);
97
86
  }
98
-
99
87
  // messages the session still sees are left out, an expunge that the session has not been told about yet is
100
88
  // reported with VANISHED without EARLIER
101
89
  return subtractUids(candidates, messages)
102
90
  .map(range => (range[0] === range[1] ? String(range[0]) : range[0] + ':' + range[1]))
103
91
  .join(',');
104
92
  };
105
-
106
93
  const sendBad = (connection, parsed, data, callback, message) => {
107
94
  connection.sendStatus(parsed, data, 'BAD', message, false, 'QRESYNC FAILED');
108
95
  return callback();
109
96
  };
110
-
111
97
  // Wraps an existing command handler. Commands that are not available are left alone
112
98
  const wrapHandler = (command, wrapper) => {
113
99
  const prevHandler = server.getCommandHandler(command);
@@ -116,51 +102,44 @@ module.exports = function (server) {
116
102
  }
117
103
  server.setCommandHandler(command, (connection, parsed, data, callback) => wrapper(prevHandler, connection, parsed, data, callback));
118
104
  };
119
-
120
105
  // RFC 7162 section 3.2.5: SELECT/EXAMINE mailbox (QRESYNC (uidvalidity mod-sequence-value [known-uids] [seq-match-data]))
121
106
  const selectWrapper = (prevHandler, connection, parsed, data, callback) => {
122
107
  const params = parsed.attributes && parsed.attributes[1];
123
- const isQresyncParam = param => isAtom(param, 'QRESYNC');
108
+ const isQresyncParam = (param) => isAtom(param, 'QRESYNC');
124
109
  const position = Array.isArray(params) ? params.findIndex(isQresyncParam) : -1;
125
110
  if (position < 0) {
126
111
  return prevHandler(connection, parsed, data, callback);
127
112
  }
128
-
129
113
  if (!isQresync(connection)) {
130
114
  return sendBad(connection, parsed, data, callback, 'QRESYNC parameter requires ENABLE QRESYNC');
131
115
  }
132
116
  if (params.findLastIndex(isQresyncParam) !== position) {
133
117
  return sendBad(connection, parsed, data, callback, 'QRESYNC parameter can be used only once');
134
118
  }
135
-
136
119
  let qresync;
137
120
  try {
138
121
  qresync = parseQresyncParam(params[position + 1]);
139
- } catch (err) {
122
+ }
123
+ catch (err) {
140
124
  return sendBad(connection, parsed, data, callback, err.message);
141
125
  }
142
-
143
126
  params.splice(position, 2);
144
127
  if (!params.length) {
145
128
  parsed.attributes.splice(1, 1);
146
129
  }
147
130
  parsed.qresync = qresync;
148
-
149
131
  prevHandler(connection, parsed, data, callback);
150
132
  };
151
-
152
133
  wrapHandler('SELECT', selectWrapper);
153
134
  wrapHandler('EXAMINE', selectWrapper);
154
-
155
135
  // RFC 7162 section 3.2.6: the VANISHED UID FETCH modifier
156
136
  const fetchWrapper = (isUid, prevHandler, connection, parsed, data, callback) => {
157
137
  const modifiers = parsed.attributes && parsed.attributes[2];
158
- const isVanished = modifier => isAtom(modifier, 'VANISHED');
138
+ const isVanished = (modifier) => isAtom(modifier, 'VANISHED');
159
139
  const position = Array.isArray(modifiers) ? modifiers.findIndex(isVanished) : -1;
160
140
  if (position < 0) {
161
141
  return prevHandler(connection, parsed, data, callback);
162
142
  }
163
-
164
143
  if (!isUid) {
165
144
  return sendBad(connection, parsed, data, callback, 'VANISHED is only allowed with UID FETCH');
166
145
  }
@@ -170,58 +149,46 @@ module.exports = function (server) {
170
149
  if (modifiers.findLastIndex(isVanished) !== position) {
171
150
  return sendBad(connection, parsed, data, callback, 'VANISHED can be used only once');
172
151
  }
173
- if (!modifiers.some(modifier => isAtom(modifier, 'CHANGEDSINCE'))) {
152
+ if (!modifiers.some((modifier) => isAtom(modifier, 'CHANGEDSINCE'))) {
174
153
  return sendBad(connection, parsed, data, callback, 'VANISHED requires CHANGEDSINCE');
175
154
  }
176
-
177
155
  modifiers.splice(position, 1);
178
156
  parsed.qresyncVanished = true;
179
-
180
157
  prevHandler(connection, parsed, data, callback);
181
158
  };
182
-
183
159
  wrapHandler('FETCH', fetchWrapper.bind(null, false));
184
160
  wrapHandler('UID FETCH', fetchWrapper.bind(null, true));
185
-
186
161
  // RFC 7162 section 3.2.10: after ENABLE QRESYNC, expunges are reported with VANISHED instead of EXPUNGE.
187
162
  // Consecutive EXPUNGE notifications become one VANISHED response
188
- server.connectionHandlers.push(connection => {
163
+ server.connectionHandlers.push((connection) => {
189
164
  const prepareNotifications = connection.prepareNotifications;
190
165
  connection.prepareNotifications = function (queue) {
191
166
  queue = prepareNotifications.call(this, queue);
192
167
  return isQresync(this) ? toVanished(queue) : queue;
193
168
  };
194
169
  });
195
-
196
170
  // Sends a VANISHED (EARLIER) response, if there is anything to report
197
171
  const sendVanishedEarlier = (connection, uids, parsed, data) => {
198
172
  if (!uids) {
199
173
  return;
200
174
  }
201
- connection.send(
202
- {
203
- tag: '*',
204
- command: 'VANISHED',
205
- attributes: [[{ type: 'ATOM', value: 'EARLIER' }], { type: 'SEQUENCE', value: uids }]
206
- },
207
- 'VANISHED EARLIER',
208
- parsed,
209
- data
210
- );
175
+ connection.send({
176
+ tag: '*',
177
+ command: 'VANISHED',
178
+ attributes: [[{ type: 'ATOM', value: 'EARLIER' }], { type: 'SEQUENCE', value: uids }]
179
+ }, 'VANISHED EARLIER', parsed, data);
211
180
  };
212
-
213
181
  // RFC 7162 section 3.2.5.1: after SELECT/EXAMINE (QRESYNC), expunges and flag changes since the given mod-sequence
214
182
  const sendQresyncChanges = (connection, parsed, data) => {
183
+ // only called with a mailbox selected
215
184
  const mailbox = connection.selectedMailbox;
216
185
  const qresync = parsed.qresync;
217
186
  if (qresync.uidvalidity !== mailbox.uidvalidity) {
218
187
  // RFC 7162 section 3.2.5: ignore the remaining parameters if UIDVALIDITY does not match
219
188
  return;
220
189
  }
221
-
222
190
  // without known UIDs, the client is treated as if it sent 1:<UIDNEXT - 1>, nothing for an unused mailbox
223
191
  const ranges = qresync.knownUids || (mailbox.uidnext > 1 ? [[1, mailbox.uidnext - 1]] : []);
224
-
225
192
  // RFC 7162 section 3.2.5.2: the last pair of sequence number and UID that still match tells up to which
226
193
  // UID the client knows about all expunges, the first pair that does not match ends the comparison
227
194
  let knownUpTo = 0;
@@ -236,51 +203,41 @@ module.exports = function (server) {
236
203
  knownUpTo = uid;
237
204
  }
238
205
  }
239
-
240
206
  // VANISHED (EARLIER) MUST come before the FETCH responses (RFC 7162 section 3.2.6)
241
207
  sendVanishedEarlier(connection, getVanished(mailbox, mailbox.messages, ranges, qresync.modseq, knownUpTo), parsed, data);
242
-
243
208
  const getFlags = server.fetchHandlers.FLAGS || fetchHandlers.FLAGS;
244
209
  mailbox.messages.forEach((message, i) => {
245
210
  if (message.MODSEQ <= qresync.modseq || !inRanges(ranges, message.uid)) {
246
211
  return;
247
212
  }
248
213
  // flag changes MUST include the UID (RFC 7162 section 3.2.5.1)
249
- connection.send(
250
- {
251
- tag: '*',
252
- attributes: [
253
- i + 1,
254
- { type: 'ATOM', value: 'FETCH' },
255
- [
256
- { type: 'ATOM', value: 'UID' },
257
- message.uid,
258
- { type: 'ATOM', value: 'FLAGS' },
259
- getFlags(connection, message, { type: 'ATOM', value: 'FLAGS' }),
260
- { type: 'ATOM', value: 'MODSEQ' },
261
- [message.MODSEQ]
262
- ]
214
+ connection.send({
215
+ tag: '*',
216
+ attributes: [
217
+ i + 1,
218
+ { type: 'ATOM', value: 'FETCH' },
219
+ [
220
+ { type: 'ATOM', value: 'UID' },
221
+ message.uid,
222
+ { type: 'ATOM', value: 'FLAGS' },
223
+ getFlags(connection, message, { type: 'ATOM', value: 'FLAGS' }),
224
+ { type: 'ATOM', value: 'MODSEQ' },
225
+ [message.MODSEQ]
263
226
  ]
264
- },
265
- 'QRESYNC FETCH',
266
- parsed,
267
- data,
268
- message
269
- );
227
+ ]
228
+ }, 'QRESYNC FETCH', parsed, data, message);
270
229
  });
271
230
  };
272
-
273
- const highestModseqCode = modseq => ({ type: 'SECTION', section: [{ type: 'ATOM', value: 'HIGHESTMODSEQ' }, modseq] });
274
-
231
+ const highestModseqCode = (modseq) => ({ type: 'SECTION', section: [{ type: 'ATOM', value: 'HIGHESTMODSEQ' }, modseq] });
275
232
  server.outputHandlers.push((connection, response, description, parsed, data) => {
276
233
  if (!parsed || !response || response.tag === '+') {
277
234
  return;
278
235
  }
279
236
  const isTagged = response.tag !== '*' && response.tag === parsed.tag;
280
-
281
237
  // UID FETCH (VANISHED): VANISHED (EARLIER) comes before the first FETCH response, or before the tagged OK
282
238
  if (parsed.qresyncVanished && ((response.tag === '*' && description === 'UID FETCH') || (isTagged && response.command === 'OK'))) {
283
239
  parsed.qresyncVanished = false;
240
+ // UID FETCH runs in the Selected state
284
241
  const mailbox = connection.selectedMailbox;
285
242
  const ranges = parseUidSet(parsed.attributes[0].value, mailbox.uidnext - 1);
286
243
  if (ranges) {
@@ -288,61 +245,48 @@ module.exports = function (server) {
288
245
  }
289
246
  return;
290
247
  }
291
-
292
248
  if (!isTagged) {
293
249
  return;
294
250
  }
295
-
296
251
  if (parsed.qresync && response.command === 'OK' && (description === 'SELECT' || description === 'EXAMINE') && connection.selectedMailbox) {
297
252
  sendQresyncChanges(connection, parsed, data);
298
253
  return;
299
254
  }
300
-
301
255
  const expunged = connection.qresyncExpunged;
302
256
  connection.qresyncExpunged = false;
303
-
304
257
  // HIGHESTMODSEQ in the tagged OK once messages were expunged, RFC 7162 sections 3.2.7 and 3.2.9 require it
305
258
  // with QRESYNC enabled, RFC 6851 section 4.4 for MOVE
306
- if (
307
- expunged &&
259
+ if (expunged &&
308
260
  response.command === 'OK' &&
309
261
  EXPUNGING_COMMANDS.has(String(parsed.command).toUpperCase()) &&
310
262
  connection.selectedMailbox &&
311
- isCondstore(connection)
312
- ) {
263
+ isCondstore(connection)) {
313
264
  const hasCode = response.attributes && response.attributes[0] && response.attributes[0].type === 'SECTION';
314
265
  if (!hasCode) {
315
266
  response.attributes = [highestModseqCode(getHighestModseq(connection.selectedMailbox))].concat(response.attributes || []);
316
267
  }
317
268
  return;
318
269
  }
319
-
320
270
  // RFC 7162 section 3.2: while expunges are held back (FETCH, STORE, SEARCH), the client must not take a
321
271
  // MODSEQ it got as the new HIGHESTMODSEQ, so tell it a value below the mod-sequence of the pending expunges
322
272
  if (isCondstore(connection)) {
323
273
  let lowest = 0;
324
- connection.notificationQueue.forEach(notification => {
325
- const modseq = isExpungeNotification(notification) && expungeModseq.get(notification.message);
274
+ connection.notificationQueue.forEach((notification) => {
275
+ const modseq = isExpungeNotification(notification) && notification.message && expungeModseq.get(notification.message);
326
276
  if (modseq && (!lowest || modseq < lowest)) {
327
277
  lowest = modseq;
328
278
  }
329
279
  });
330
280
  if (lowest > 1) {
331
- connection.send(
332
- {
333
- tag: '*',
334
- command: 'OK',
335
- attributes: [highestModseqCode(lowest - 1), { type: 'TEXT', value: 'Expunges not reported yet' }]
336
- },
337
- 'QRESYNC HIGHESTMODSEQ',
338
- parsed,
339
- data
340
- );
281
+ connection.send({
282
+ tag: '*',
283
+ command: 'OK',
284
+ attributes: [highestModseqCode(lowest - 1), { type: 'TEXT', value: 'Expunges not reported yet' }]
285
+ }, 'QRESYNC HIGHESTMODSEQ', parsed, data);
341
286
  }
342
287
  }
343
288
  });
344
- };
345
-
289
+ }
346
290
  /**
347
291
  * Parses a sequence set without "*" into [from, to] ranges as written
348
292
  *
@@ -354,12 +298,11 @@ function parseSequenceSet(value, name) {
354
298
  if (!value || Array.isArray(value) || ['ATOM', 'SEQUENCE'].indexOf(value.type) < 0 || !isSequenceSet(value.value, true)) {
355
299
  throw new Error('Invalid QRESYNC ' + name + ', a sequence set without "*" expected');
356
300
  }
357
- return value.value.split(',').map(part => {
301
+ return value.value.split(',').map((part) => {
358
302
  const range = part.split(':').map(Number);
359
303
  return [range[0], range.length > 1 ? range[1] : range[0]];
360
304
  });
361
305
  }
362
-
363
306
  /**
364
307
  * Parses the UID set of UID FETCH, "*" stands for the highest UID the mailbox may have used
365
308
  *
@@ -371,13 +314,10 @@ function parseUidSet(value, star) {
371
314
  if (!/^[\d*:,]+$/.test(String(value))) {
372
315
  return false;
373
316
  }
374
- return mergeRanges(
375
- String(value)
376
- .split(',')
377
- .map(part => part.split(':').map(number => (number === '*' ? star : Number(number))))
378
- );
317
+ return mergeRanges(String(value)
318
+ .split(',')
319
+ .map(part => part.split(':').map(number => (number === '*' ? star : Number(number)))));
379
320
  }
380
-
381
321
  // Intersection of two lists of ascending, non-overlapping ranges
382
322
  function intersectRanges(a, b) {
383
323
  const result = [];
@@ -391,13 +331,13 @@ function intersectRanges(a, b) {
391
331
  }
392
332
  if (a[i][1] < b[j][1]) {
393
333
  i++;
394
- } else {
334
+ }
335
+ else {
395
336
  j++;
396
337
  }
397
338
  }
398
339
  return result;
399
340
  }
400
-
401
341
  // Removes the UIDs of messages (ordered by UID) from ascending ranges, walking both lists once
402
342
  function subtractUids(ranges, messages) {
403
343
  const result = [];
@@ -419,7 +359,6 @@ function subtractUids(ranges, messages) {
419
359
  });
420
360
  return result;
421
361
  }
422
-
423
362
  /**
424
363
  * Orders the ends of every range and merges overlapping or adjacent ranges, so that a UID is listed once
425
364
  *
@@ -427,19 +366,19 @@ function subtractUids(ranges, messages) {
427
366
  * @return {Array} ascending [low, high] ranges
428
367
  */
429
368
  function mergeRanges(ranges) {
430
- const sorted = ranges.map(range => [Math.min(...range), Math.max(...range)]).sort((a, b) => a[0] - b[0]);
369
+ const sorted = ranges.map((range) => [Math.min(...range), Math.max(...range)]).sort((a, b) => a[0] - b[0]);
431
370
  const result = [];
432
371
  sorted.forEach(range => {
433
372
  const last = result[result.length - 1];
434
373
  if (last && range[0] <= last[1] + 1) {
435
374
  last[1] = Math.max(last[1], range[1]);
436
- } else {
375
+ }
376
+ else {
437
377
  result.push(range);
438
378
  }
439
379
  });
440
380
  return result;
441
381
  }
442
-
443
382
  // Lists the numbers of ascending ranges one by one
444
383
  function* iterateRanges(ranges) {
445
384
  for (const [from, to] of ranges) {
@@ -448,7 +387,6 @@ function* iterateRanges(ranges) {
448
387
  }
449
388
  }
450
389
  }
451
-
452
390
  /**
453
391
  * Checks that a sequence set lists its numbers in ascending order and counts them
454
392
  */
@@ -464,7 +402,6 @@ function countAscending(ranges, name) {
464
402
  });
465
403
  return count;
466
404
  }
467
-
468
405
  /**
469
406
  * Validates the value of the QRESYNC SELECT/EXAMINE parameter (RFC 7162 section 7):
470
407
  * "(" uidvalidity SP mod-sequence-value [SP known-uids] [SP seq-match-data] ")"
@@ -476,7 +413,6 @@ function parseQresyncParam(value) {
476
413
  if (!Array.isArray(value) || value.length < 2 || value.length > 4) {
477
414
  throw new Error('QRESYNC expects (uidvalidity modseq [known-uids] [(known-sequence-set known-uid-set)])');
478
415
  }
479
-
480
416
  const [uidvalidity, modseq] = value;
481
417
  // uidvalidity = nz-number
482
418
  if (!isAtom(uidvalidity) || !isNzNumber(uidvalidity.value)) {
@@ -486,19 +422,16 @@ function parseQresyncParam(value) {
486
422
  if (!isAtom(modseq) || !isNumber(modseq.value, MAX_NUMBER64) || BigInt(modseq.value) < 1n) {
487
423
  throw new Error('Invalid QRESYNC mod-sequence, a positive number expected');
488
424
  }
489
-
490
425
  const result = {
491
426
  uidvalidity: Number(uidvalidity.value),
492
427
  modseq: Number(modseq.value),
493
428
  knownUids: false,
494
429
  seqMatch: false
495
430
  };
496
-
497
431
  const rest = value.slice(2);
498
432
  if (rest.length && !Array.isArray(rest[0])) {
499
433
  result.knownUids = mergeRanges(parseSequenceSet(rest.shift(), 'known-uids'));
500
434
  }
501
-
502
435
  if (rest.length) {
503
436
  const seqMatch = rest.shift();
504
437
  if (!Array.isArray(seqMatch) || seqMatch.length !== 2 || rest.length) {
@@ -513,13 +446,10 @@ function parseQresyncParam(value) {
513
446
  }
514
447
  result.seqMatch = { sequences, uids };
515
448
  }
516
-
517
449
  return result;
518
450
  }
519
-
520
451
  function inRanges(ranges, uid) {
521
452
  return ranges.some(range => uid >= range[0] && uid <= range[1]);
522
453
  }
523
-
524
454
  // RFC 7162 section 3.2.3: a QRESYNC server implements CONDSTORE and ENABLE, these are loaded first
525
- module.exports.requires = ['ENABLE', 'CONDSTORE'];
455
+ qresyncPlugin.requires = ['ENABLE', 'CONDSTORE'];
@@ -0,0 +1,18 @@
1
+ import type { IMAPServer } from '../types.js';
2
+ /**
3
+ * @help Adds QUOTA [RFC9208] capability with the STORAGE, MESSAGE and MAILBOX
4
+ * @help resources and SETQUOTA. All personal mailboxes share one quota root, set
5
+ * @help with the "quota" server option, eg. {"root": "User quota",
6
+ * @help "STORAGE": 10240, "MESSAGE": 1000, "MAILBOX": 100, "soft": false}.
7
+ * @help STORAGE is in units of 1024 octets. Hard limits make APPEND, COPY, MOVE
8
+ * @help and CREATE fail with NO [OVERQUOTA], soft limits only send a warning
9
+ *
10
+ * QUOTA: https://www.rfc-editor.org/rfc/rfc9208.txt
11
+ *
12
+ * Additional commands:
13
+ * - GETQUOTA, GETQUOTAROOT, SETQUOTA
14
+ *
15
+ * Additional STATUS items:
16
+ * - DELETED, DELETED-STORAGE
17
+ */
18
+ export default function quotaPlugin(server: IMAPServer): void;