imapkit 4.0.2 → 4.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 (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 +277 -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 +102 -123
  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 +34 -75
  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 +54 -11
  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
@@ -0,0 +1,85 @@
1
+ import type { Attribute, IMAPConnection, IMAPError, IMAPServer, Message, MessageRange, ParsedCommand } from '../../types.js';
2
+ /** The type of a search key argument: a type name, or a function that parses the value and throws for an invalid one */
3
+ export type SearchArgumentType = string | ((value: string) => any);
4
+ /** The argument types of a search key, or a function that decides them from the criteria that follow the key */
5
+ export type SearchKeyTypes = SearchArgumentType[] | ((list: Attribute[]) => SearchArgumentType[]);
6
+ /** A node of the query tree that the search builds from the criteria */
7
+ export interface SearchNode {
8
+ key: string;
9
+ args: any[];
10
+ /** the messages of a sequence set (`_SEQ`) or a UID set */
11
+ set?: Set<Message> | undefined;
12
+ /** the lower cased string to look for */
13
+ needle?: string | undefined;
14
+ }
15
+ /** Resolves a sequence set of the criteria */
16
+ export type RangeResolver = (range: string, isUid: boolean) => MessageRange;
17
+ /** The result of a search */
18
+ export interface SearchResult {
19
+ /** the matching messages */
20
+ list: Message[];
21
+ /** sequence numbers by UID */
22
+ numbers: Record<number, number>;
23
+ /** the search keys used in the criteria, other than sequence sets */
24
+ keys: Set<string>;
25
+ /** checks a message against the same criteria later */
26
+ matches: (message: Message, index: number) => boolean;
27
+ }
28
+ /**
29
+ * Creates an error that is reported to the client as BAD
30
+ */
31
+ declare function badError(message: string): IMAPError;
32
+ /**
33
+ * Date of a date-time value, disregarding time and timezone, as a comparable YYYY-MM-DD string,
34
+ * or false when it can not be parsed
35
+ *
36
+ * @param {String} dateTime Date-time value, e.g. "14-Sep-2013 21:22:28 -0300"
37
+ * @return {String|Boolean} date or false
38
+ */
39
+ declare function getDateKey(dateTime: string): string | false;
40
+ /**
41
+ * Converts the parsed search criteria of a command to the values the search takes, parenthesized lists stay nested
42
+ *
43
+ * @param {Array} attributes Parsed arguments
44
+ * @return {Array} values
45
+ * @throws {Error} BAD error for an argument that can not be a search key or its value
46
+ */
47
+ declare function criteriaValues(attributes: Attribute[]): any[];
48
+ /**
49
+ * Answers a failed search with NO, or BAD for `err.imapResponse` "BAD": the BADCHARSET response code with the
50
+ * supported charsets (RFC 3501 section 7.1, RFC 5256 section 3), or the response code a search limit set
51
+ * (`err.responseCode`), and the text
52
+ *
53
+ * @param {Object} connection IMAP connection
54
+ * @param {Object} parsed Parsed command
55
+ * @param {String} data Raw command
56
+ * @param {Error} err Search error
57
+ * @param {String} description Description for output handlers
58
+ */
59
+ declare function sendSearchError(connection: IMAPConnection, parsed: ParsedCommand, data: string, err: IMAPError, description: string): void;
60
+ /**
61
+ * Checks if SEARCH criteria refer to messages by sequence number (RFC 3501 section 5.5), that is,
62
+ * if a sequence set is used as a search key. Arguments of search keys, like the UID set of UID
63
+ * or a string that looks like a number, are not search keys.
64
+ *
65
+ * @param {Object} server IMAP server
66
+ * @param {Array} attributes Parsed SEARCH arguments, nested lists are arrays
67
+ * @return {Boolean} true if a sequence set key occurs
68
+ */
69
+ declare function hasSequenceSetKey(server: IMAPServer, attributes: Attribute[]): boolean;
70
+ /**
71
+ * Searches messages. Errors thrown for the client are answered with BAD when `imapResponse` is "BAD",
72
+ * otherwise NO. SORT and THREAD send `responseCode` (a list of atoms) as the response code
73
+ *
74
+ * @param {Object} connection IMAP connection
75
+ * @param {Array} messageSource Messages of the selected mailbox, as the session sees them
76
+ * @param {Array} params Search criteria: strings, and arrays for parenthesized lists
77
+ * @param {Function} [getMessageRange] Resolves the sequence sets of the criteria, `(range, isUid)`, defaults to
78
+ * the selected mailbox of the connection. Used to search a mailbox that is not selected
79
+ * @return {Object} `{ list, numbers, keys, matches }`, the matching messages, the sequence numbers by UID,
80
+ * the set of search keys used in the criteria and a `matches(message, index)` function that checks
81
+ * a message against the same criteria later. Sequence sets in the criteria stay as they were resolved
82
+ * now, they are not evaluated again
83
+ */
84
+ export default function searchHandlers(connection: IMAPConnection, messageSource: Message[], params: any, getMessageRange?: RangeResolver | null): SearchResult;
85
+ export { hasSequenceSetKey, getDateKey, badError, criteriaValues, sendSearchError };
@@ -0,0 +1,504 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = searchHandlers;
4
+ exports.hasSequenceSetKey = hasSequenceSetKey;
5
+ exports.getDateKey = getDateKey;
6
+ exports.badError = badError;
7
+ exports.criteriaValues = criteriaValues;
8
+ exports.sendSearchError = sendSearchError;
9
+ const node_buffer_1 = require("node:buffer");
10
+ const mimeparser_js_1 = require("../../mimeparser.js");
11
+ const dates_js_1 = require("../../dates.js");
12
+ const numbers_js_1 = require("../../numbers.js");
13
+ const encoded_words_js_1 = require("../../encoded-words.js");
14
+ // RFC 3501 6.4.4 search keys and their arguments
15
+ const searchKeys = {
16
+ ALL: [],
17
+ ANSWERED: [],
18
+ BCC: ['string'],
19
+ BEFORE: ['date'],
20
+ BODY: ['string'],
21
+ CC: ['string'],
22
+ DELETED: [],
23
+ DRAFT: [],
24
+ FLAGGED: [],
25
+ FROM: ['string'],
26
+ HEADER: ['string', 'string'],
27
+ KEYWORD: ['string'],
28
+ LARGER: ['number64'],
29
+ NEW: [],
30
+ NOT: ['key'],
31
+ OLD: [],
32
+ ON: ['date'],
33
+ OR: ['key', 'key'],
34
+ RECENT: [],
35
+ SEEN: [],
36
+ SENTBEFORE: ['date'],
37
+ SENTON: ['date'],
38
+ SENTSINCE: ['date'],
39
+ SINCE: ['date'],
40
+ SMALLER: ['number64'],
41
+ SUBJECT: ['string'],
42
+ TEXT: ['string'],
43
+ TO: ['string'],
44
+ UID: ['sequence'],
45
+ UNANSWERED: [],
46
+ UNDELETED: [],
47
+ UNDRAFT: [],
48
+ UNFLAGGED: [],
49
+ UNKEYWORD: ['string'],
50
+ UNSEEN: []
51
+ };
52
+ // Charsets accepted for the CHARSET argument (RFC 3501 6.4.4: US-ASCII must be supported)
53
+ const charsets = ['US-ASCII', 'UTF-8'];
54
+ /**
55
+ * Creates an error that is reported to the client as BAD
56
+ */
57
+ function badError(message) {
58
+ const err = new Error(message);
59
+ err.imapResponse = 'BAD';
60
+ return err;
61
+ }
62
+ /**
63
+ * Parses an RFC 3501 date argument (date-day "-" date-month "-" date-year) to a comparable YYYY-MM-DD string
64
+ */
65
+ function parseQueryDate(value) {
66
+ const match = (value || '').toString().match(/^(\d{1,2})-([A-Za-z]{3})-(\d{4})$/);
67
+ const date = match && (0, dates_js_1.dateKey)(Number(match[1]), (0, dates_js_1.monthIndex)(match[2]), Number(match[3]));
68
+ if (!date) {
69
+ throw badError('Invalid date argument ' + value);
70
+ }
71
+ return date;
72
+ }
73
+ /**
74
+ * Date of a date-time value, disregarding time and timezone, as a comparable YYYY-MM-DD string,
75
+ * or false when it can not be parsed
76
+ *
77
+ * @param {String} dateTime Date-time value, e.g. "14-Sep-2013 21:22:28 -0300"
78
+ * @return {String|Boolean} date or false
79
+ */
80
+ function getDateKey(dateTime) {
81
+ const date = (0, dates_js_1.parseDateTime)(dateTime);
82
+ return date ? (0, dates_js_1.dateKey)(date.day, date.month, date.year) : false;
83
+ }
84
+ /**
85
+ * Date of the internal date of a message, disregarding time and timezone, or false when it can not be parsed
86
+ */
87
+ function getInternalDate(message) {
88
+ return getDateKey(message.internaldate);
89
+ }
90
+ /**
91
+ * Date of the Date header of a message, disregarding time and timezone (RFC 3501 section 6.4.4, unlike the
92
+ * sent date of SORT it is not adjusted to UTC). Falls back to the internal date
93
+ */
94
+ function getSentDate(message) {
95
+ const date = (0, dates_js_1.parseHeaderDate)((0, mimeparser_js_1.getMessageData)(message).tree.parsedHeader.date);
96
+ return date ? (0, dates_js_1.dateKey)(date.day, date.month, date.year) : getInternalDate(message);
97
+ }
98
+ /**
99
+ * Converts the parsed search criteria of a command to the values the search takes, parenthesized lists stay nested
100
+ *
101
+ * @param {Array} attributes Parsed arguments
102
+ * @return {Array} values
103
+ * @throws {Error} BAD error for an argument that can not be a search key or its value
104
+ */
105
+ function criteriaValues(attributes) {
106
+ const convert = (argument, i) => {
107
+ if (Array.isArray(argument)) {
108
+ return argument.map(convert);
109
+ }
110
+ if (!argument || ['STRING', 'ATOM', 'LITERAL', 'SEQUENCE'].indexOf(argument.type) < 0) {
111
+ throw badError('Invalid search criteria argument #' + (i + 1));
112
+ }
113
+ return argument.value;
114
+ };
115
+ return attributes.map(convert);
116
+ }
117
+ /**
118
+ * Answers a failed search with NO, or BAD for `err.imapResponse` "BAD": the BADCHARSET response code with the
119
+ * supported charsets (RFC 3501 section 7.1, RFC 5256 section 3), or the response code a search limit set
120
+ * (`err.responseCode`), and the text
121
+ *
122
+ * @param {Object} connection IMAP connection
123
+ * @param {Object} parsed Parsed command
124
+ * @param {String} data Raw command
125
+ * @param {Error} err Search error
126
+ * @param {String} description Description for output handlers
127
+ */
128
+ function sendSearchError(connection, parsed, data, err, description) {
129
+ const attributes = [];
130
+ if (err.code === 'BADCHARSET') {
131
+ attributes.push({
132
+ type: 'SECTION',
133
+ section: [{ type: 'ATOM', value: 'BADCHARSET' }, err.charsets.map((value) => ({ type: 'ATOM', value }))]
134
+ });
135
+ }
136
+ else if (err.responseCode) {
137
+ attributes.push({ type: 'SECTION', section: err.responseCode.map((value) => ({ type: 'ATOM', value: String(value) })) });
138
+ }
139
+ attributes.push({ type: 'TEXT', value: err.message });
140
+ connection.send({ tag: parsed.tag, command: err.imapResponse === 'BAD' ? 'BAD' : 'NO', attributes }, description, parsed, data);
141
+ }
142
+ /**
143
+ * Lower cases ASCII letters only, so that 8-bit octets in binary strings stay intact. RFC 9051
144
+ * section 6.4.4 asks for case insensitive matching only within the ASCII range
145
+ */
146
+ function asciiLowerCase(str) {
147
+ return str.replace(/[A-Z]+/g, chars => chars.toLowerCase());
148
+ }
149
+ /**
150
+ * Checks if a string contains another one, ignoring ASCII case
151
+ *
152
+ * @param {String} haystack String to search in
153
+ * @param {String} needle String to look for, already lower cased with asciiLowerCase
154
+ */
155
+ function contains(haystack, needle) {
156
+ return asciiLowerCase(haystack).indexOf(needle) >= 0;
157
+ }
158
+ /**
159
+ * Returns the search keys with the types of their arguments, including the keys that plugins
160
+ * define in `server.searchHandlers`. If a plugin handler takes more than 3 params
161
+ * (connection, message, index), the remaining ones are its arguments. A plugin handler can
162
+ * describe its arguments instead with an `argumentTypes(list)` method, that gets the criteria
163
+ * following the key and returns the list of types. A type can also be a function that gets the
164
+ * argument value and returns the parsed value, or throws for an invalid one.
165
+ *
166
+ * @param {Object} server IMAP server
167
+ * @return {Object} search key to list of argument types, or to a function that returns the list
168
+ */
169
+ function getSearchKeys(server) {
170
+ const keys = Object.assign({}, searchKeys);
171
+ const pluginHandlers = server.searchHandlers;
172
+ Object.keys(pluginHandlers).forEach(key => {
173
+ if (!(key in keys)) {
174
+ const handler = pluginHandlers[key];
175
+ keys[key] = typeof handler.argumentTypes === 'function' ? handler.argumentTypes : new Array(Math.max(handler.length - 3, 0)).fill('string');
176
+ }
177
+ });
178
+ return keys;
179
+ }
180
+ /**
181
+ * Checks if SEARCH criteria refer to messages by sequence number (RFC 3501 section 5.5), that is,
182
+ * if a sequence set is used as a search key. Arguments of search keys, like the UID set of UID
183
+ * or a string that looks like a number, are not search keys.
184
+ *
185
+ * @param {Object} server IMAP server
186
+ * @param {Array} attributes Parsed SEARCH arguments, nested lists are arrays
187
+ * @return {Boolean} true if a sequence set key occurs
188
+ */
189
+ function hasSequenceSetKey(server, attributes) {
190
+ const keys = getSearchKeys(server);
191
+ const walk = (list) => {
192
+ // arguments of the previous key that are values, not keys
193
+ let skip = 0;
194
+ return list.some((item, i) => {
195
+ if (Array.isArray(item)) {
196
+ return walk(item);
197
+ }
198
+ if (skip) {
199
+ skip--;
200
+ return false;
201
+ }
202
+ const value = ((item && item.value) || '').toString();
203
+ const key = value.toUpperCase();
204
+ if (key === 'CHARSET' && i === 0) {
205
+ skip = 1;
206
+ }
207
+ else if (Object.hasOwn(keys, key)) {
208
+ // NOT and OR take keys as arguments, these are checked as keys
209
+ let types = keys[key];
210
+ if (typeof types === 'function') {
211
+ types = types(list.slice(i + 1).map(next => (Array.isArray(next) ? next : ((next && next.value) || '').toString())));
212
+ }
213
+ skip = types.filter((type) => type !== 'key').length;
214
+ }
215
+ else if (/^[\d*][\d*,:]*$/.test(value)) {
216
+ return true;
217
+ }
218
+ return false;
219
+ });
220
+ };
221
+ return walk([].concat(attributes || []));
222
+ }
223
+ /**
224
+ * Searches messages. Errors thrown for the client are answered with BAD when `imapResponse` is "BAD",
225
+ * otherwise NO. SORT and THREAD send `responseCode` (a list of atoms) as the response code
226
+ *
227
+ * @param {Object} connection IMAP connection
228
+ * @param {Array} messageSource Messages of the selected mailbox, as the session sees them
229
+ * @param {Array} params Search criteria: strings, and arrays for parenthesized lists
230
+ * @param {Function} [getMessageRange] Resolves the sequence sets of the criteria, `(range, isUid)`, defaults to
231
+ * the selected mailbox of the connection. Used to search a mailbox that is not selected
232
+ * @return {Object} `{ list, numbers, keys, matches }`, the matching messages, the sequence numbers by UID,
233
+ * the set of search keys used in the criteria and a `matches(message, index)` function that checks
234
+ * a message against the same criteria later. Sequence sets in the criteria stay as they were resolved
235
+ * now, they are not evaluated again
236
+ */
237
+ function searchHandlers(connection, messageSource, params, getMessageRange) {
238
+ const resolveRange = getMessageRange || ((range, isUid) => connection.getMessageRange(range, isUid));
239
+ const numbers = {};
240
+ // search keys used in the criteria, other than sequence sets
241
+ const usedKeys = new Set();
242
+ const keys = getSearchKeys(connection.server);
243
+ const pluginHandlers = connection.server.searchHandlers;
244
+ params = [].concat(params || []);
245
+ // IMAP4rev1 search strings are US-ASCII unless a CHARSET is given (RFC 3501 6.4.4). A plugin can
246
+ // fix the charset of a session with connection.searchCharset, e.g. UTF-8 after ENABLE UTF8=ACCEPT,
247
+ // or change the default with connection.defaultSearchCharset (IMAP4rev2 assumes UTF-8, RFC 9051 6.4.4)
248
+ let searchCharset = connection.searchCharset || connection.defaultSearchCharset || 'US-ASCII';
249
+ if (typeof params[0] === 'string' && params[0].toUpperCase() === 'CHARSET') {
250
+ if (connection.searchCharset) {
251
+ // RFC 9755 section 3: a CHARSET conflicts with the charset of the session
252
+ throw badError('CHARSET is not allowed, search strings are always ' + connection.searchCharset + ' in this session');
253
+ }
254
+ params.shift();
255
+ const charset = params.shift();
256
+ if (typeof charset !== 'string') {
257
+ throw badError('CHARSET expects a charset name');
258
+ }
259
+ if (charsets.indexOf(charset.toUpperCase()) < 0) {
260
+ const err = new Error('Unsupported charset ' + charset);
261
+ err.imapResponse = 'NO';
262
+ err.code = 'BADCHARSET';
263
+ err.charsets = charsets;
264
+ throw err;
265
+ }
266
+ searchCharset = charset.toUpperCase();
267
+ }
268
+ // strings must be valid in the declared charset, a client must not send 8-bit text as US-ASCII
269
+ const checkString = (key, value) => {
270
+ if (searchCharset === 'US-ASCII' && /[\u0080-\u00ff]/.test(value)) {
271
+ throw badError(key + ' argument has 8-bit characters, use CHARSET UTF-8');
272
+ }
273
+ if (searchCharset === 'UTF-8' && !(0, node_buffer_1.isUtf8)(Buffer.from(value, 'binary'))) {
274
+ throw badError(key + ' argument is not valid UTF-8');
275
+ }
276
+ return value;
277
+ };
278
+ if (!params.length) {
279
+ throw badError('SEARCH expects search criteria, empty query given');
280
+ }
281
+ // Parses one search key and its arguments from a list of criteria into a node of the query tree
282
+ const parseKey = (list) => {
283
+ if (!list.length) {
284
+ throw badError('Unexpected end of search criteria');
285
+ }
286
+ const param = list.shift();
287
+ if (Array.isArray(param)) {
288
+ // a parenthesized list of keys that all must match
289
+ return { key: 'AND', args: parseList([].concat(param)) };
290
+ }
291
+ const key = param.toUpperCase();
292
+ // a plugin can remove keys from a session, e.g. NEW, OLD and RECENT are not in the IMAP4rev2 grammar
293
+ if (!Object.prototype.hasOwnProperty.call(keys, key) || (connection.disabledSearchKeys && connection.disabledSearchKeys.has(key))) {
294
+ // a sequence set, plugins may support other forms of it than numbers
295
+ let range;
296
+ try {
297
+ range = resolveRange(param, false);
298
+ }
299
+ catch (E) {
300
+ throw /^[\d,:*]+$/.test(param) ? E : badError('Invalid search key ' + param);
301
+ }
302
+ return { key: '_SEQ', args: [range] };
303
+ }
304
+ usedKeys.add(key);
305
+ const keyTypes = keys[key];
306
+ const types = typeof keyTypes === 'function' ? keyTypes(list) : keyTypes;
307
+ const args = types.map((type) => {
308
+ if (type === 'key') {
309
+ return parseKey(list);
310
+ }
311
+ if (!list.length || typeof list[0] !== 'string') {
312
+ throw badError(key + ' expects ' + types.length + ' argument' + (types.length > 1 ? 's' : ''));
313
+ }
314
+ const value = list.shift();
315
+ if (typeof type === 'function') {
316
+ return type(value);
317
+ }
318
+ switch (type) {
319
+ case 'date':
320
+ return parseQueryDate(value);
321
+ case 'number':
322
+ case 'number64': {
323
+ // RFC 3501 section 9: number is 32-bit. LARGER and SMALLER take a number64 in IMAP4rev2 (RFC 9051
324
+ // section 9), so in a session with connection.number64 set
325
+ const number64 = type === 'number64' && connection.number64;
326
+ if (!(0, numbers_js_1.isNumber)(value, number64 ? numbers_js_1.MAX_NUMBER64 : numbers_js_1.MAX_NUMBER)) {
327
+ throw badError(key + ' expects a number' + (number64 ? '64' : ''));
328
+ }
329
+ return Number(value);
330
+ }
331
+ case 'sequence':
332
+ return resolveRange(value, true);
333
+ default:
334
+ return checkString(key, value);
335
+ }
336
+ });
337
+ return { key, args };
338
+ };
339
+ const parseList = (list) => {
340
+ if (!list.length) {
341
+ throw badError('Empty search criteria list');
342
+ }
343
+ const nodes = [];
344
+ while (list.length) {
345
+ nodes.push(parseKey(list));
346
+ }
347
+ return nodes;
348
+ };
349
+ const query = { key: 'AND', args: parseList(params) };
350
+ // a sequence set argument resolves to [number, message] pairs, turn these into a lookup set
351
+ const toMessageSet = (range) => new Set(range.map(item => item[1]));
352
+ const prepare = (node) => {
353
+ if (node.key === '_SEQ' || node.key === 'UID') {
354
+ node.set = toMessageSet(node.args[0]);
355
+ }
356
+ // lower case the string to look for once, not for every message. Header values are compared
357
+ // as Unicode text after decoding their encoded words, so the UTF-8 octets of the string are
358
+ // decoded too (RFC 9051 section 6.4.4)
359
+ if (['BODY', 'TEXT'].indexOf(node.key) >= 0) {
360
+ node.needle = asciiLowerCase(node.args[0]);
361
+ }
362
+ else if (['BCC', 'CC', 'FROM', 'HEADER', 'SUBJECT', 'TO'].indexOf(node.key) >= 0) {
363
+ node.needle = asciiLowerCase((0, encoded_words_js_1.decodeUtf8)(node.args[node.key === 'HEADER' ? 1 : 0]));
364
+ }
365
+ node.args.forEach((arg) => {
366
+ if (arg && typeof arg === 'object' && arg.key) {
367
+ prepare(arg);
368
+ }
369
+ });
370
+ };
371
+ prepare(query);
372
+ const hasFlag = (message, flag) => message.flags.indexOf(flag) >= 0;
373
+ // compares the unfolded values of the header lines with that name, after decoding their encoded
374
+ // words. RFC 3501 and RFC 9051 section 6.4.4: [MIME-HDRS] strings in headers MUST be decoded before comparing text
375
+ const matchHeader = (message, name, needle) => {
376
+ name = name.toLowerCase();
377
+ return ((0, mimeparser_js_1.getMessageData)(message).tree.header || []).some((line) => {
378
+ const colon = line.indexOf(':');
379
+ const lineName = (colon < 0 ? line : line.substr(0, colon)).trim().toLowerCase();
380
+ const value = colon < 0 ? '' : line.substr(colon + 1).replace(/\r?\n(?=[ \t])/g, '');
381
+ return lineName === name && contains((0, encoded_words_js_1.decodeHeader)(value), needle);
382
+ });
383
+ };
384
+ const matches = (node, message, index) => {
385
+ const args = node.args;
386
+ if (Object.prototype.hasOwnProperty.call(pluginHandlers, node.key)) {
387
+ // plugin defined search key, which may also override a built-in one
388
+ return !!pluginHandlers[node.key](connection, message, index, ...args);
389
+ }
390
+ switch (node.key) {
391
+ case 'AND':
392
+ return args.every((arg) => matches(arg, message, index));
393
+ case '_SEQ':
394
+ case 'UID':
395
+ return node.set.has(message);
396
+ case 'ALL':
397
+ return true;
398
+ case 'ANSWERED':
399
+ return hasFlag(message, '\\Answered');
400
+ case 'BCC':
401
+ case 'CC':
402
+ case 'FROM':
403
+ case 'SUBJECT':
404
+ case 'TO':
405
+ return matchHeader(message, node.key, node.needle);
406
+ case 'HEADER':
407
+ return matchHeader(message, args[0], node.needle);
408
+ case 'BEFORE': {
409
+ const date = getInternalDate(message);
410
+ return !!date && date < args[0];
411
+ }
412
+ case 'ON':
413
+ return getInternalDate(message) === args[0];
414
+ case 'SINCE': {
415
+ const date = getInternalDate(message);
416
+ return !!date && date >= args[0];
417
+ }
418
+ case 'SENTBEFORE': {
419
+ const date = getSentDate(message);
420
+ return !!date && date < args[0];
421
+ }
422
+ case 'SENTON':
423
+ return getSentDate(message) === args[0];
424
+ case 'SENTSINCE': {
425
+ const date = getSentDate(message);
426
+ return !!date && date >= args[0];
427
+ }
428
+ case 'BODY':
429
+ return contains((0, mimeparser_js_1.render)((0, mimeparser_js_1.getMessageData)(message).tree, true), node.needle);
430
+ case 'TEXT':
431
+ return contains((0, mimeparser_js_1.getMessageData)(message).raw, node.needle);
432
+ case 'DELETED':
433
+ return hasFlag(message, '\\Deleted');
434
+ case 'DRAFT':
435
+ return hasFlag(message, '\\Draft');
436
+ case 'FLAGGED':
437
+ return hasFlag(message, '\\Flagged');
438
+ case 'KEYWORD':
439
+ return hasFlag(message, args[0]);
440
+ case 'LARGER':
441
+ return (0, mimeparser_js_1.getMessageData)(message).raw.length > args[0];
442
+ case 'SMALLER':
443
+ return (0, mimeparser_js_1.getMessageData)(message).raw.length < args[0];
444
+ // \Recent is a session flag, see IMAPConnection#isRecent
445
+ case 'NEW':
446
+ return connection.isRecent(message) && !hasFlag(message, '\\Seen');
447
+ case 'OLD':
448
+ return !connection.isRecent(message);
449
+ case 'RECENT':
450
+ return connection.isRecent(message);
451
+ case 'SEEN':
452
+ return hasFlag(message, '\\Seen');
453
+ case 'NOT':
454
+ return !matches(args[0], message, index);
455
+ case 'OR':
456
+ return matches(args[0], message, index) || matches(args[1], message, index);
457
+ case 'UNANSWERED':
458
+ return !hasFlag(message, '\\Answered');
459
+ case 'UNDELETED':
460
+ return !hasFlag(message, '\\Deleted');
461
+ case 'UNDRAFT':
462
+ return !hasFlag(message, '\\Draft');
463
+ case 'UNFLAGGED':
464
+ return !hasFlag(message, '\\Flagged');
465
+ case 'UNKEYWORD':
466
+ return !hasFlag(message, args[0]);
467
+ case 'UNSEEN':
468
+ return !hasFlag(message, '\\Seen');
469
+ default:
470
+ return false;
471
+ }
472
+ };
473
+ // plugins can narrow down the messages that are looked at (server.searchLimits), sequence numbers stay as they are
474
+ const searched = connection.server.searchLimits.reduce((messages, limit) => limit(connection, messages, query) || messages, messageSource);
475
+ const searchedSet = searched !== messageSource && new Set(searched);
476
+ const list = [];
477
+ messageSource.forEach((message, i) => {
478
+ if (searchedSet && !searchedSet.has(message)) {
479
+ return;
480
+ }
481
+ if (matches(query, message, i + 1)) {
482
+ numbers[message.uid] = i + 1;
483
+ list.push(message);
484
+ }
485
+ });
486
+ return {
487
+ list,
488
+ numbers,
489
+ keys: usedKeys,
490
+ matches: (message, index) => matches(query, message, index)
491
+ };
492
+ }
493
+ {
494
+ const defaultExport = exports.default;
495
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
496
+ for (const key of Object.keys(exports)) {
497
+ if (key !== 'default' && !(key in defaultExport)) {
498
+ defaultExport[key] = exports[key];
499
+ }
500
+ }
501
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
502
+ module.exports = defaultExport;
503
+ }
504
+ }
@@ -0,0 +1,34 @@
1
+ import type { Attribute, IMAPConnection, IMAPResponse, IMAPServer, Mailbox, ParsedCommand } from '../../types.js';
2
+ /**
3
+ * Validates a list of STATUS data item names (RFC 3501 section 9, "(" status-att *(SP status-att) ")")
4
+ *
5
+ * @param {Object} server IMAPServer instance
6
+ * @param {Array} list Parsed list of status items
7
+ * @param {Object} [connection] IMAP connection, its `disabledStatusItems` set lists items the session can not use,
8
+ * `addedStatusItems` the items only this session can use (DELETED after ENABLE IMAP4rev2)
9
+ * @return {Array} upper case item names
10
+ * @throws {Error} if the list is empty or has an invalid item, the message is for the BAD response
11
+ */
12
+ declare function parseStatusItems(server: IMAPServer, list: Attribute, connection?: IMAPConnection | null): string[];
13
+ /**
14
+ * Sends an untagged STATUS response
15
+ *
16
+ * @param {Object} connection IMAPConnection instance
17
+ * @param {String} path Storage name of the mailbox
18
+ * @param {Object} mailbox Mailbox object
19
+ * @param {Array} items Upper case item names from parseStatusItems
20
+ * @param {Object} parsed Parsed command
21
+ * @param {Object} data Command data
22
+ */
23
+ declare function sendStatus(connection: IMAPConnection, path: string, mailbox: Mailbox, items: string[], parsed: ParsedCommand, data: string): void;
24
+ /**
25
+ * Builds an untagged STATUS response
26
+ *
27
+ * @param {Object} connection IMAPConnection instance
28
+ * @param {String} path Storage name of the mailbox
29
+ * @param {Object} mailbox Mailbox object
30
+ * @param {Array} items Upper case item names
31
+ * @return {Object} STATUS response
32
+ */
33
+ declare function statusResponse(connection: IMAPConnection, path: string, mailbox: Mailbox, items: string[]): IMAPResponse;
34
+ export { parseStatusItems, sendStatus, statusResponse };