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.
- package/README.md +32 -19
- package/bin/imapkit.js +12 -16
- package/dist/cjs/addressparser.d.ts +21 -0
- package/dist/cjs/addressparser.js +271 -0
- package/dist/cjs/arguments.d.ts +31 -0
- package/{lib → dist/cjs}/arguments.js +9 -21
- package/dist/cjs/bodystructure.d.ts +25 -0
- package/dist/cjs/bodystructure.js +150 -0
- package/dist/cjs/cert.d.ts +2 -0
- package/dist/cjs/cert.js +7 -0
- package/dist/cjs/command-states.d.ts +36 -0
- package/dist/cjs/command-states.js +102 -0
- package/dist/cjs/commands/append.d.ts +88 -0
- package/dist/cjs/commands/append.js +299 -0
- package/dist/cjs/commands/capability.d.ts +2 -0
- package/dist/cjs/commands/capability.js +44 -0
- package/dist/cjs/commands/check.d.ts +2 -0
- package/dist/cjs/commands/check.js +28 -0
- package/dist/cjs/commands/close.d.ts +2 -0
- package/dist/cjs/commands/close.js +35 -0
- package/dist/cjs/commands/copy.d.ts +30 -0
- package/dist/cjs/commands/copy.js +107 -0
- package/dist/cjs/commands/create.d.ts +2 -0
- package/dist/cjs/commands/create.js +53 -0
- package/dist/cjs/commands/delete.d.ts +2 -0
- package/dist/cjs/commands/delete.js +63 -0
- package/dist/cjs/commands/examine.d.ts +2 -0
- package/dist/cjs/commands/examine.js +19 -0
- package/dist/cjs/commands/expunge.d.ts +2 -0
- package/dist/cjs/commands/expunge.js +32 -0
- package/dist/cjs/commands/fetch.d.ts +23 -0
- package/dist/cjs/commands/fetch.js +208 -0
- package/dist/cjs/commands/handlers/fetch.d.ts +12 -0
- package/dist/cjs/commands/handlers/fetch.js +195 -0
- package/dist/cjs/commands/handlers/flags.d.ts +17 -0
- package/dist/cjs/commands/handlers/flags.js +39 -0
- package/dist/cjs/commands/handlers/search.d.ts +85 -0
- package/dist/cjs/commands/handlers/search.js +504 -0
- package/dist/cjs/commands/handlers/status.d.ts +34 -0
- package/dist/cjs/commands/handlers/status.js +81 -0
- package/dist/cjs/commands/handlers/store.d.ts +3 -0
- package/dist/cjs/commands/handlers/store.js +117 -0
- package/dist/cjs/commands/index.d.ts +2 -0
- package/dist/cjs/commands/index.js +61 -0
- package/dist/cjs/commands/list.d.ts +2 -0
- package/dist/cjs/commands/list.js +86 -0
- package/dist/cjs/commands/login.d.ts +2 -0
- package/dist/cjs/commands/login.js +62 -0
- package/dist/cjs/commands/logout.d.ts +2 -0
- package/dist/cjs/commands/logout.js +40 -0
- package/dist/cjs/commands/lsub.d.ts +2 -0
- package/dist/cjs/commands/lsub.js +79 -0
- package/dist/cjs/commands/noop.d.ts +2 -0
- package/dist/cjs/commands/noop.js +28 -0
- package/dist/cjs/commands/rename.d.ts +2 -0
- package/dist/cjs/commands/rename.js +98 -0
- package/dist/cjs/commands/search.d.ts +10 -0
- package/dist/cjs/commands/search.js +71 -0
- package/dist/cjs/commands/select.d.ts +19 -0
- package/dist/cjs/commands/select.js +230 -0
- package/dist/cjs/commands/status.d.ts +2 -0
- package/dist/cjs/commands/status.js +57 -0
- package/dist/cjs/commands/store.d.ts +10 -0
- package/dist/cjs/commands/store.js +134 -0
- package/dist/cjs/commands/subscribe.d.ts +2 -0
- package/dist/cjs/commands/subscribe.js +51 -0
- package/dist/cjs/commands/uid-copy.d.ts +2 -0
- package/dist/cjs/commands/uid-copy.js +19 -0
- package/dist/cjs/commands/uid-fetch.d.ts +3 -0
- package/dist/cjs/commands/uid-fetch.js +17 -0
- package/dist/cjs/commands/uid-search.d.ts +3 -0
- package/dist/cjs/commands/uid-search.js +17 -0
- package/dist/cjs/commands/uid-store.d.ts +3 -0
- package/dist/cjs/commands/uid-store.js +17 -0
- package/dist/cjs/commands/unsubscribe.d.ts +2 -0
- package/dist/cjs/commands/unsubscribe.js +50 -0
- package/dist/cjs/dates.d.ts +64 -0
- package/dist/cjs/dates.js +124 -0
- package/dist/cjs/deflate-layer.d.ts +83 -0
- package/dist/cjs/deflate-layer.js +232 -0
- package/dist/cjs/encoded-words.d.ts +15 -0
- package/dist/cjs/encoded-words.js +85 -0
- package/dist/cjs/envelope.d.ts +33 -0
- package/dist/cjs/envelope.js +86 -0
- package/dist/cjs/esearch.d.ts +96 -0
- package/dist/cjs/esearch.js +190 -0
- package/dist/cjs/framing.d.ts +66 -0
- package/{lib → dist/cjs}/framing.js +9 -26
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.js +56 -0
- package/dist/cjs/list-extensions.d.ts +50 -0
- package/dist/cjs/list-extensions.js +35 -0
- package/dist/cjs/load-plugins.d.ts +21 -0
- package/dist/cjs/load-plugins.js +89 -0
- package/dist/cjs/mailbox-name.d.ts +26 -0
- package/dist/cjs/mailbox-name.js +127 -0
- package/dist/cjs/mimeparser.d.ts +137 -0
- package/dist/cjs/mimeparser.js +727 -0
- package/dist/cjs/mock-client.d.ts +39 -0
- package/dist/cjs/mock-client.js +236 -0
- package/dist/cjs/numbers.d.ts +28 -0
- package/dist/cjs/numbers.js +52 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/plugins/acl.d.ts +2 -0
- package/dist/cjs/plugins/acl.js +888 -0
- package/dist/cjs/plugins/appendlimit.d.ts +16 -0
- package/dist/cjs/plugins/appendlimit.js +87 -0
- package/dist/cjs/plugins/auth-plain.d.ts +2 -0
- package/dist/cjs/plugins/auth-plain.js +89 -0
- package/dist/cjs/plugins/binary.d.ts +30 -0
- package/dist/cjs/plugins/binary.js +247 -0
- package/dist/cjs/plugins/catenate.d.ts +14 -0
- package/dist/cjs/plugins/catenate.js +250 -0
- package/dist/cjs/plugins/compress.d.ts +7 -0
- package/dist/cjs/plugins/compress.js +79 -0
- package/dist/cjs/plugins/condstore.d.ts +5 -0
- package/dist/cjs/plugins/condstore.js +492 -0
- package/dist/cjs/plugins/context-search.d.ts +8 -0
- package/dist/cjs/plugins/context-search.js +304 -0
- package/dist/cjs/plugins/context-sort.d.ts +6 -0
- package/dist/cjs/plugins/context-sort.js +32 -0
- package/dist/cjs/plugins/create-special-use.d.ts +7 -0
- package/dist/cjs/plugins/create-special-use.js +101 -0
- package/dist/cjs/plugins/enable.d.ts +23 -0
- package/dist/cjs/plugins/enable.js +127 -0
- package/dist/cjs/plugins/esearch.d.ts +6 -0
- package/dist/cjs/plugins/esearch.js +142 -0
- package/dist/cjs/plugins/esort.d.ts +6 -0
- package/dist/cjs/plugins/esort.js +60 -0
- package/dist/cjs/plugins/id.d.ts +5 -0
- package/dist/cjs/plugins/id.js +123 -0
- package/dist/cjs/plugins/idle.d.ts +5 -0
- package/dist/cjs/plugins/idle.js +85 -0
- package/dist/cjs/plugins/imap4rev2.d.ts +6 -0
- package/dist/cjs/plugins/imap4rev2.js +184 -0
- package/dist/cjs/plugins/index.d.ts +2 -0
- package/dist/cjs/plugins/index.js +119 -0
- package/dist/cjs/plugins/list-extended.d.ts +2 -0
- package/dist/cjs/plugins/list-extended.js +235 -0
- package/dist/cjs/plugins/list-status.d.ts +6 -0
- package/dist/cjs/plugins/list-status.js +42 -0
- package/dist/cjs/plugins/literalminus.d.ts +8 -0
- package/dist/cjs/plugins/literalminus.js +32 -0
- package/dist/cjs/plugins/literalplus.d.ts +6 -0
- package/dist/cjs/plugins/literalplus.js +30 -0
- package/dist/cjs/plugins/logindisabled.d.ts +5 -0
- package/dist/cjs/plugins/logindisabled.js +54 -0
- package/dist/cjs/plugins/messagelimit.d.ts +19 -0
- package/dist/cjs/plugins/messagelimit.js +227 -0
- package/dist/cjs/plugins/metadata-server.d.ts +7 -0
- package/dist/cjs/plugins/metadata-server.js +24 -0
- package/dist/cjs/plugins/metadata.d.ts +11 -0
- package/dist/cjs/plugins/metadata.js +436 -0
- package/dist/cjs/plugins/move.d.ts +11 -0
- package/dist/cjs/plugins/move.js +96 -0
- package/dist/cjs/plugins/multiappend.d.ts +12 -0
- package/dist/cjs/plugins/multiappend.js +38 -0
- package/dist/cjs/plugins/multisearch.d.ts +6 -0
- package/dist/cjs/plugins/multisearch.js +263 -0
- package/dist/cjs/plugins/namespace.d.ts +5 -0
- package/dist/cjs/plugins/namespace.js +57 -0
- package/dist/cjs/plugins/notify.d.ts +2 -0
- package/dist/cjs/plugins/notify.js +628 -0
- package/dist/cjs/plugins/oauthbearer.d.ts +32 -0
- package/dist/cjs/plugins/oauthbearer.js +202 -0
- package/dist/cjs/plugins/objectid.d.ts +23 -0
- package/dist/cjs/plugins/objectid.js +221 -0
- package/dist/cjs/plugins/partial.d.ts +6 -0
- package/dist/cjs/plugins/partial.js +78 -0
- package/dist/cjs/plugins/preview.d.ts +31 -0
- package/dist/cjs/plugins/preview.js +378 -0
- package/dist/cjs/plugins/qresync.d.ts +11 -0
- package/dist/cjs/plugins/qresync.js +473 -0
- package/dist/cjs/plugins/quota.d.ts +18 -0
- package/dist/cjs/plugins/quota.js +254 -0
- package/dist/cjs/plugins/replace.d.ts +14 -0
- package/dist/cjs/plugins/replace.js +130 -0
- package/dist/cjs/plugins/sasl-ir.d.ts +5 -0
- package/dist/cjs/plugins/sasl-ir.js +24 -0
- package/dist/cjs/plugins/savedate.d.ts +17 -0
- package/dist/cjs/plugins/savedate.js +64 -0
- package/dist/cjs/plugins/savelimit.d.ts +10 -0
- package/dist/cjs/plugins/savelimit.js +30 -0
- package/dist/cjs/plugins/searchres.d.ts +6 -0
- package/dist/cjs/plugins/searchres.js +91 -0
- package/dist/cjs/plugins/sort-display.d.ts +11 -0
- package/dist/cjs/plugins/sort-display.js +37 -0
- package/dist/cjs/plugins/sort.d.ts +11 -0
- package/dist/cjs/plugins/sort.js +125 -0
- package/dist/cjs/plugins/special-use.d.ts +10 -0
- package/dist/cjs/plugins/special-use.js +95 -0
- package/dist/cjs/plugins/starttls.d.ts +5 -0
- package/dist/cjs/plugins/starttls.js +55 -0
- package/dist/cjs/plugins/status-size.d.ts +7 -0
- package/dist/cjs/plugins/status-size.js +30 -0
- package/dist/cjs/plugins/thread-orderedsubject.d.ts +11 -0
- package/dist/cjs/plugins/thread-orderedsubject.js +28 -0
- package/dist/cjs/plugins/thread-references.d.ts +11 -0
- package/dist/cjs/plugins/thread-references.js +28 -0
- package/dist/cjs/plugins/uidonly.d.ts +15 -0
- package/dist/cjs/plugins/uidonly.js +126 -0
- package/dist/cjs/plugins/uidplus.d.ts +15 -0
- package/dist/cjs/plugins/uidplus.js +119 -0
- package/dist/cjs/plugins/unauthenticate.d.ts +7 -0
- package/dist/cjs/plugins/unauthenticate.js +32 -0
- package/dist/cjs/plugins/unselect.d.ts +5 -0
- package/dist/cjs/plugins/unselect.js +36 -0
- package/dist/cjs/plugins/utf8-accept.d.ts +6 -0
- package/dist/cjs/plugins/utf8-accept.js +72 -0
- package/dist/cjs/plugins/x-gm-ext-1.d.ts +26 -0
- package/dist/cjs/plugins/x-gm-ext-1.js +422 -0
- package/dist/cjs/plugins/xoauth2.d.ts +2 -0
- package/dist/cjs/plugins/xoauth2.js +155 -0
- package/dist/cjs/plugins/xtoybird.d.ts +2 -0
- package/dist/cjs/plugins/xtoybird.js +236 -0
- package/dist/cjs/server.d.ts +876 -0
- package/dist/cjs/server.js +2597 -0
- package/dist/cjs/smtp-listener.d.ts +13 -0
- package/dist/cjs/smtp-listener.js +47 -0
- package/dist/cjs/sorting.d.ts +77 -0
- package/dist/cjs/sorting.js +290 -0
- package/dist/cjs/threading.d.ts +30 -0
- package/dist/cjs/threading.js +318 -0
- package/dist/cjs/types.d.ts +327 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/utf8-session.d.ts +17 -0
- package/dist/cjs/utf8-session.js +148 -0
- package/dist/cjs/vanished.d.ts +21 -0
- package/dist/cjs/vanished.js +55 -0
- package/dist/esm/addressparser.d.ts +21 -0
- package/{lib → dist/esm}/addressparser.js +106 -133
- package/dist/esm/arguments.d.ts +31 -0
- package/dist/esm/arguments.js +96 -0
- package/dist/esm/bodystructure.d.ts +25 -0
- package/{lib → dist/esm}/bodystructure.js +17 -33
- package/dist/esm/cert.d.ts +2 -0
- package/dist/esm/cert.js +4 -0
- package/dist/esm/command-states.d.ts +36 -0
- package/{lib → dist/esm}/command-states.js +4 -16
- package/dist/esm/commands/append.d.ts +88 -0
- package/{lib → dist/esm}/commands/append.js +47 -85
- package/dist/esm/commands/capability.d.ts +2 -0
- package/dist/esm/commands/capability.js +29 -0
- package/dist/esm/commands/check.d.ts +2 -0
- package/dist/esm/commands/check.js +13 -0
- package/dist/esm/commands/close.d.ts +2 -0
- package/dist/esm/commands/close.js +20 -0
- package/dist/esm/commands/copy.d.ts +30 -0
- package/{lib → dist/esm}/commands/copy.js +31 -55
- package/dist/esm/commands/create.d.ts +2 -0
- package/{lib → dist/esm}/commands/create.js +25 -39
- package/dist/esm/commands/delete.d.ts +2 -0
- package/{lib → dist/esm}/commands/delete.js +25 -41
- package/dist/esm/commands/examine.d.ts +2 -0
- package/dist/esm/commands/examine.js +4 -0
- package/dist/esm/commands/expunge.d.ts +2 -0
- package/dist/esm/commands/expunge.js +17 -0
- package/dist/esm/commands/fetch.d.ts +23 -0
- package/{lib → dist/esm}/commands/fetch.js +33 -74
- package/dist/esm/commands/handlers/fetch.d.ts +12 -0
- package/{lib → dist/esm}/commands/handlers/fetch.js +11 -42
- package/dist/esm/commands/handlers/flags.d.ts +17 -0
- package/{lib → dist/esm}/commands/handlers/flags.js +3 -11
- package/dist/esm/commands/handlers/search.d.ts +85 -0
- package/{lib → dist/esm}/commands/handlers/search.js +33 -71
- package/dist/esm/commands/handlers/status.d.ts +34 -0
- package/{lib → dist/esm}/commands/handlers/status.js +1 -9
- package/dist/esm/commands/handlers/store.d.ts +3 -0
- package/{lib → dist/esm}/commands/handlers/store.js +20 -44
- package/dist/esm/commands/index.d.ts +2 -0
- package/dist/esm/commands/index.js +55 -0
- package/dist/esm/commands/list.d.ts +2 -0
- package/dist/esm/commands/list.js +71 -0
- package/dist/esm/commands/login.d.ts +2 -0
- package/{lib → dist/esm}/commands/login.js +24 -44
- package/dist/esm/commands/logout.d.ts +2 -0
- package/dist/esm/commands/logout.js +25 -0
- package/dist/esm/commands/lsub.d.ts +2 -0
- package/dist/esm/commands/lsub.js +64 -0
- package/dist/esm/commands/noop.d.ts +2 -0
- package/dist/esm/commands/noop.js +13 -0
- package/dist/esm/commands/rename.d.ts +2 -0
- package/{lib → dist/esm}/commands/rename.js +32 -51
- package/dist/esm/commands/search.d.ts +10 -0
- package/dist/esm/commands/search.js +54 -0
- package/dist/esm/commands/select.d.ts +19 -0
- package/dist/esm/commands/select.js +214 -0
- package/dist/esm/commands/status.d.ts +2 -0
- package/{lib → dist/esm}/commands/status.js +18 -39
- package/dist/esm/commands/store.d.ts +10 -0
- package/{lib → dist/esm}/commands/store.js +39 -73
- package/dist/esm/commands/subscribe.d.ts +2 -0
- package/{lib → dist/esm}/commands/subscribe.js +22 -39
- package/dist/esm/commands/uid-copy.d.ts +2 -0
- package/dist/esm/commands/uid-copy.js +4 -0
- package/dist/esm/commands/uid-fetch.d.ts +3 -0
- package/dist/esm/commands/uid-fetch.js +3 -0
- package/dist/esm/commands/uid-search.d.ts +3 -0
- package/dist/esm/commands/uid-search.js +3 -0
- package/dist/esm/commands/uid-store.d.ts +3 -0
- package/dist/esm/commands/uid-store.js +3 -0
- package/dist/esm/commands/unsubscribe.d.ts +2 -0
- package/{lib → dist/esm}/commands/unsubscribe.js +22 -37
- package/dist/esm/dates.d.ts +64 -0
- package/{lib → dist/esm}/dates.js +6 -14
- package/dist/esm/deflate-layer.d.ts +83 -0
- package/{lib → dist/esm}/deflate-layer.js +9 -26
- package/dist/esm/encoded-words.d.ts +15 -0
- package/{lib → dist/esm}/encoded-words.js +9 -25
- package/dist/esm/envelope.d.ts +33 -0
- package/{lib → dist/esm}/envelope.js +8 -19
- package/dist/esm/esearch.d.ts +96 -0
- package/{lib → dist/esm}/esearch.js +12 -39
- package/dist/esm/framing.d.ts +66 -0
- package/dist/esm/framing.js +82 -0
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/list-extensions.d.ts +50 -0
- package/{lib → dist/esm}/list-extensions.js +1 -4
- package/dist/esm/load-plugins.d.ts +21 -0
- package/{lib → dist/esm}/load-plugins.js +9 -43
- package/dist/esm/mailbox-name.d.ts +26 -0
- package/{lib → dist/esm}/mailbox-name.js +5 -26
- package/dist/esm/mimeparser.d.ts +137 -0
- package/{lib → dist/esm}/mimeparser.js +74 -152
- package/dist/esm/mock-client.d.ts +39 -0
- package/{lib → dist/esm}/mock-client.js +26 -40
- package/dist/esm/numbers.d.ts +28 -0
- package/{lib → dist/esm}/numbers.js +1 -8
- package/dist/esm/package.json +3 -0
- package/dist/esm/plugins/acl.d.ts +2 -0
- package/{lib → dist/esm}/plugins/acl.js +146 -240
- package/dist/esm/plugins/appendlimit.d.ts +16 -0
- package/{lib → dist/esm}/plugins/appendlimit.js +5 -16
- package/dist/esm/plugins/auth-plain.d.ts +2 -0
- package/{lib → dist/esm}/plugins/auth-plain.js +11 -31
- package/dist/esm/plugins/binary.d.ts +30 -0
- package/{lib → dist/esm}/plugins/binary.js +17 -43
- package/dist/esm/plugins/catenate.d.ts +14 -0
- package/{lib → dist/esm}/plugins/catenate.js +19 -40
- package/dist/esm/plugins/compress.d.ts +7 -0
- package/dist/esm/plugins/compress.js +61 -0
- package/dist/esm/plugins/condstore.d.ts +5 -0
- package/{lib → dist/esm}/plugins/condstore.js +66 -152
- package/dist/esm/plugins/context-search.d.ts +8 -0
- package/{lib → dist/esm}/plugins/context-search.js +53 -88
- package/dist/esm/plugins/context-sort.d.ts +6 -0
- package/{lib → dist/esm}/plugins/context-sort.js +4 -9
- package/dist/esm/plugins/create-special-use.d.ts +7 -0
- package/{lib → dist/esm}/plugins/create-special-use.js +33 -55
- package/dist/esm/plugins/enable.d.ts +23 -0
- package/dist/esm/plugins/enable.js +111 -0
- package/dist/esm/plugins/esearch.d.ts +6 -0
- package/{lib → dist/esm}/plugins/esearch.js +13 -42
- package/dist/esm/plugins/esort.d.ts +6 -0
- package/{lib → dist/esm}/plugins/esort.js +7 -25
- package/dist/esm/plugins/id.d.ts +5 -0
- package/dist/esm/plugins/id.js +108 -0
- package/dist/esm/plugins/idle.d.ts +5 -0
- package/dist/esm/plugins/idle.js +70 -0
- package/dist/esm/plugins/imap4rev2.d.ts +6 -0
- package/{lib → dist/esm}/plugins/imap4rev2.js +24 -60
- package/dist/esm/plugins/index.d.ts +2 -0
- package/dist/esm/plugins/index.js +113 -0
- package/dist/esm/plugins/list-extended.d.ts +2 -0
- package/{lib → dist/esm}/plugins/list-extended.js +28 -66
- package/dist/esm/plugins/list-status.d.ts +6 -0
- package/{lib → dist/esm}/plugins/list-status.js +5 -12
- package/dist/esm/plugins/literalminus.d.ts +8 -0
- package/{lib → dist/esm}/plugins/literalminus.js +2 -5
- package/dist/esm/plugins/literalplus.d.ts +6 -0
- package/{lib → dist/esm}/plugins/literalplus.js +2 -5
- package/dist/esm/plugins/logindisabled.d.ts +5 -0
- package/dist/esm/plugins/logindisabled.js +39 -0
- package/dist/esm/plugins/messagelimit.d.ts +19 -0
- package/{lib → dist/esm}/plugins/messagelimit.js +18 -41
- package/dist/esm/plugins/metadata-server.d.ts +7 -0
- package/{lib → dist/esm}/plugins/metadata-server.js +3 -7
- package/dist/esm/plugins/metadata.d.ts +11 -0
- package/dist/esm/plugins/metadata.js +421 -0
- package/dist/esm/plugins/move.d.ts +11 -0
- package/{lib → dist/esm}/plugins/move.js +37 -66
- package/dist/esm/plugins/multiappend.d.ts +12 -0
- package/{lib → dist/esm}/plugins/multiappend.js +2 -5
- package/dist/esm/plugins/multisearch.d.ts +6 -0
- package/{lib → dist/esm}/plugins/multisearch.js +24 -48
- package/dist/esm/plugins/namespace.d.ts +5 -0
- package/dist/esm/plugins/namespace.js +42 -0
- package/dist/esm/plugins/notify.d.ts +2 -0
- package/{lib → dist/esm}/plugins/notify.js +90 -134
- package/dist/esm/plugins/oauthbearer.d.ts +32 -0
- package/{lib → dist/esm}/plugins/oauthbearer.js +18 -48
- package/dist/esm/plugins/objectid.d.ts +23 -0
- package/{lib → dist/esm}/plugins/objectid.js +21 -58
- package/dist/esm/plugins/partial.d.ts +6 -0
- package/{lib → dist/esm}/plugins/partial.js +7 -15
- package/dist/esm/plugins/preview.d.ts +31 -0
- package/{lib → dist/esm}/plugins/preview.js +28 -66
- package/dist/esm/plugins/qresync.d.ts +11 -0
- package/{lib → dist/esm}/plugins/qresync.js +64 -134
- package/dist/esm/plugins/quota.d.ts +18 -0
- package/{lib → dist/esm}/plugins/quota.js +89 -135
- package/dist/esm/plugins/replace.d.ts +14 -0
- package/{lib → dist/esm}/plugins/replace.js +21 -51
- package/dist/esm/plugins/sasl-ir.d.ts +5 -0
- package/{lib → dist/esm}/plugins/sasl-ir.js +3 -6
- package/dist/esm/plugins/savedate.d.ts +17 -0
- package/{lib → dist/esm}/plugins/savedate.js +5 -15
- package/dist/esm/plugins/savelimit.d.ts +10 -0
- package/{lib → dist/esm}/plugins/savelimit.js +3 -6
- package/dist/esm/plugins/searchres.d.ts +6 -0
- package/{lib → dist/esm}/plugins/searchres.js +13 -22
- package/dist/esm/plugins/sort-display.d.ts +11 -0
- package/{lib → dist/esm}/plugins/sort-display.js +6 -10
- package/dist/esm/plugins/sort.d.ts +11 -0
- package/{lib → dist/esm}/plugins/sort.js +24 -46
- package/dist/esm/plugins/special-use.d.ts +10 -0
- package/{lib → dist/esm}/plugins/special-use.js +9 -24
- package/dist/esm/plugins/starttls.d.ts +5 -0
- package/{lib → dist/esm}/plugins/starttls.js +20 -37
- package/dist/esm/plugins/status-size.d.ts +7 -0
- package/{lib → dist/esm}/plugins/status-size.js +4 -11
- package/dist/esm/plugins/thread-orderedsubject.d.ts +11 -0
- package/{lib → dist/esm}/plugins/thread-orderedsubject.js +3 -6
- package/dist/esm/plugins/thread-references.d.ts +11 -0
- package/{lib → dist/esm}/plugins/thread-references.js +3 -6
- package/dist/esm/plugins/uidonly.d.ts +15 -0
- package/{lib → dist/esm}/plugins/uidonly.js +11 -35
- package/dist/esm/plugins/uidplus.d.ts +15 -0
- package/{lib → dist/esm}/plugins/uidplus.js +25 -45
- package/dist/esm/plugins/unauthenticate.d.ts +7 -0
- package/dist/esm/plugins/unauthenticate.js +17 -0
- package/dist/esm/plugins/unselect.d.ts +5 -0
- package/dist/esm/plugins/unselect.js +21 -0
- package/dist/esm/plugins/utf8-accept.d.ts +6 -0
- package/{lib → dist/esm}/plugins/utf8-accept.js +10 -21
- package/dist/esm/plugins/x-gm-ext-1.d.ts +26 -0
- package/{lib → dist/esm}/plugins/x-gm-ext-1.js +48 -100
- package/dist/esm/plugins/xoauth2.d.ts +2 -0
- package/dist/esm/plugins/xoauth2.js +140 -0
- package/dist/esm/plugins/xtoybird.d.ts +2 -0
- package/dist/esm/plugins/xtoybird.js +218 -0
- package/dist/esm/server.d.ts +876 -0
- package/dist/esm/server.js +2543 -0
- package/dist/esm/smtp-listener.d.ts +13 -0
- package/{lib → dist/esm}/smtp-listener.js +5 -12
- package/dist/esm/sorting.d.ts +77 -0
- package/{lib → dist/esm}/sorting.js +40 -53
- package/dist/esm/threading.d.ts +30 -0
- package/{lib → dist/esm}/threading.js +29 -70
- package/dist/esm/types.d.ts +327 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/utf8-session.d.ts +17 -0
- package/{lib → dist/esm}/utf8-session.js +15 -25
- package/dist/esm/vanished.d.ts +21 -0
- package/{lib → dist/esm}/vanished.js +16 -21
- package/dist/plugin-help.json +298 -0
- package/package.json +55 -12
- package/lib/commands/capability.js +0 -47
- package/lib/commands/check.js +0 -21
- package/lib/commands/close.js +0 -30
- package/lib/commands/examine.js +0 -7
- package/lib/commands/expunge.js +0 -27
- package/lib/commands/list.js +0 -100
- package/lib/commands/logout.js +0 -41
- package/lib/commands/lsub.js +0 -87
- package/lib/commands/noop.js +0 -21
- package/lib/commands/search.js +0 -76
- package/lib/commands/select.js +0 -289
- package/lib/commands/uid copy.js +0 -7
- package/lib/commands/uid fetch.js +0 -5
- package/lib/commands/uid search.js +0 -5
- package/lib/commands/uid store.js +0 -5
- package/lib/plugins/compress.js +0 -76
- package/lib/plugins/enable.js +0 -155
- package/lib/plugins/id.js +0 -138
- package/lib/plugins/idle.js +0 -105
- package/lib/plugins/logindisabled.js +0 -50
- package/lib/plugins/metadata.js +0 -475
- package/lib/plugins/namespace.js +0 -67
- package/lib/plugins/unauthenticate.js +0 -28
- package/lib/plugins/unselect.js +0 -36
- package/lib/plugins/xoauth2.js +0 -188
- package/lib/plugins/xtoybird.js +0 -282
- package/lib/server.js +0 -2880
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// THREAD and UID THREAD (RFC 5256 section 3) and the ORDEREDSUBJECT and REFERENCES algorithms
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.addThreadAlgorithm = addThreadAlgorithm;
|
|
5
|
+
const command_states_js_1 = require("./command-states.js");
|
|
6
|
+
const mimeparser_js_1 = require("./mimeparser.js");
|
|
7
|
+
const sorting_js_1 = require("./sorting.js");
|
|
8
|
+
/**
|
|
9
|
+
* Creates a thread tree node. A node without a message is a dummy
|
|
10
|
+
*/
|
|
11
|
+
function createNode(entry) {
|
|
12
|
+
return { entry: entry || null, parent: null, children: [] };
|
|
13
|
+
}
|
|
14
|
+
// Sent date order with the sequence number as tie-breaker (RFC 5256 section 2.2). A dummy is
|
|
15
|
+
// ordered by its first child
|
|
16
|
+
function compareNodes(a, b) {
|
|
17
|
+
while (!a.entry && a.children.length) {
|
|
18
|
+
a = a.children[0];
|
|
19
|
+
}
|
|
20
|
+
while (!b.entry && b.children.length) {
|
|
21
|
+
b = b.children[0];
|
|
22
|
+
}
|
|
23
|
+
// pruning leaves no dummy without children, so both have an entry here
|
|
24
|
+
return a.entry.date - b.entry.date || a.entry.seq - b.entry.seq;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Lists the nodes of trees in pre-order (parents before their children). Iterative, as message
|
|
28
|
+
* references can make a thread as deep as the mailbox is large.
|
|
29
|
+
*
|
|
30
|
+
* @param {Array} nodes Top level nodes
|
|
31
|
+
* @return {Array} All nodes
|
|
32
|
+
*/
|
|
33
|
+
function preOrder(nodes) {
|
|
34
|
+
const list = [];
|
|
35
|
+
const stack = nodes.slice().reverse();
|
|
36
|
+
while (stack.length) {
|
|
37
|
+
const node = stack.pop();
|
|
38
|
+
list.push(node);
|
|
39
|
+
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
40
|
+
stack.push(node.children[i]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return list;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Serializes thread nodes (RFC 5256 section 5): every thread is a thread-list, a node is followed by its
|
|
47
|
+
* only child, or by one thread-list per child when it has more. A dummy has no number of its own.
|
|
48
|
+
*
|
|
49
|
+
* @param {Array} roots Top level nodes
|
|
50
|
+
* @param {Boolean} isUid If true, list UIDs instead of sequence numbers
|
|
51
|
+
* @return {String} thread-data without the "THREAD" keyword
|
|
52
|
+
*/
|
|
53
|
+
function formatThreads(roots, isUid) {
|
|
54
|
+
const output = [];
|
|
55
|
+
// strings to write and nodes to expand, the next one is at the end
|
|
56
|
+
const stack = [];
|
|
57
|
+
const pushLists = (nodes) => {
|
|
58
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
59
|
+
stack.push(')', nodes[i], '(');
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
pushLists(roots);
|
|
63
|
+
while (stack.length) {
|
|
64
|
+
const item = stack.pop();
|
|
65
|
+
if (typeof item === 'string') {
|
|
66
|
+
output.push(item);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const children = item.children;
|
|
70
|
+
if (children.length === 1) {
|
|
71
|
+
stack.push(children[0]);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
pushLists(children);
|
|
75
|
+
}
|
|
76
|
+
if (item.entry) {
|
|
77
|
+
if (children.length) {
|
|
78
|
+
stack.push(' ');
|
|
79
|
+
}
|
|
80
|
+
output.push(isUid ? item.entry.message.uid : item.entry.seq);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return output.join('');
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* ORDEREDSUBJECT (RFC 5256 section 3): messages grouped by base subject, every thread is its first
|
|
87
|
+
* message with the others as children, threads ordered by the sent date of their first message
|
|
88
|
+
*
|
|
89
|
+
* @param {Array} entries Searched messages as `{ message, seq, date, subject }`
|
|
90
|
+
* @return {Array} Top level nodes
|
|
91
|
+
*/
|
|
92
|
+
function orderedSubject(entries) {
|
|
93
|
+
const compareSubjects = (a, b) => (a.subject.id < b.subject.id ? -1 : a.subject.id > b.subject.id ? 1 : 0);
|
|
94
|
+
const sorted = entries.slice().sort((a, b) => compareSubjects(a, b) || a.date - b.date || a.seq - b.seq);
|
|
95
|
+
const threads = [];
|
|
96
|
+
let current = null;
|
|
97
|
+
for (const entry of sorted) {
|
|
98
|
+
if (current && current.entry.subject.id === entry.subject.id) {
|
|
99
|
+
current.children.push(createNode(entry));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
current = createNode(entry);
|
|
103
|
+
threads.push(current);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return threads.sort(compareNodes);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* REFERENCES (RFC 5256 section 3), steps 1 to 6
|
|
110
|
+
*
|
|
111
|
+
* @param {Array} entries Searched messages in mailbox order as `{ message, seq, date, subject }`
|
|
112
|
+
* @return {Array} Top level nodes
|
|
113
|
+
*/
|
|
114
|
+
function references(entries) {
|
|
115
|
+
const byId = new Map();
|
|
116
|
+
const all = [];
|
|
117
|
+
const getNode = (id) => {
|
|
118
|
+
if (!byId.has(id)) {
|
|
119
|
+
const node = createNode();
|
|
120
|
+
byId.set(id, node);
|
|
121
|
+
all.push(node);
|
|
122
|
+
}
|
|
123
|
+
return byId.get(id);
|
|
124
|
+
};
|
|
125
|
+
const isDescendant = (node, ancestor) => {
|
|
126
|
+
for (let current = node; current; current = current.parent) {
|
|
127
|
+
if (current === ancestor) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
};
|
|
133
|
+
const unlink = (node) => {
|
|
134
|
+
if (node.parent) {
|
|
135
|
+
node.parent.children.splice(node.parent.children.indexOf(node), 1);
|
|
136
|
+
node.parent = null;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
// links a parent and a child, unless that would introduce a loop. Only a node with children can have
|
|
140
|
+
// the parent as a descendant, so the walk up from the parent is skipped for the others
|
|
141
|
+
const link = (parent, child) => {
|
|
142
|
+
if (parent !== child && (!child.children.length || !isDescendant(parent, child))) {
|
|
143
|
+
parent.children.push(child);
|
|
144
|
+
child.parent = parent;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
// (1) link the messages by their references
|
|
148
|
+
for (const entry of entries) {
|
|
149
|
+
const header = (0, mimeparser_js_1.getMessageData)(entry.message).tree.parsedHeader;
|
|
150
|
+
// (1.A) a message without a valid Message-ID, or with one that an earlier message already has, gets a unique one
|
|
151
|
+
const messageId = (0, sorting_js_1.parseMessageIds)(header['message-id'])[0];
|
|
152
|
+
let node = messageId !== undefined && getNode(messageId);
|
|
153
|
+
if (!node || node.entry) {
|
|
154
|
+
node = createNode();
|
|
155
|
+
all.push(node);
|
|
156
|
+
}
|
|
157
|
+
node.entry = entry;
|
|
158
|
+
// the References header, or else the first Message ID of In-Reply-To
|
|
159
|
+
let refs = (0, sorting_js_1.parseMessageIds)(header.references);
|
|
160
|
+
if (!refs.length) {
|
|
161
|
+
refs = (0, sorting_js_1.parseMessageIds)(header['in-reply-to']).slice(0, 1);
|
|
162
|
+
}
|
|
163
|
+
// (1.A) each reference is the parent of the next one, existing links are kept
|
|
164
|
+
const refNodes = refs.map(getNode);
|
|
165
|
+
for (let i = 1; i < refNodes.length; i++) {
|
|
166
|
+
if (!refNodes[i].parent) {
|
|
167
|
+
link(refNodes[i - 1], refNodes[i]);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// (1.B) the last reference is the parent of the message, replacing an existing link
|
|
171
|
+
const parent = refNodes[refNodes.length - 1] || null;
|
|
172
|
+
if (node.parent !== parent) {
|
|
173
|
+
unlink(node);
|
|
174
|
+
if (parent) {
|
|
175
|
+
link(parent, node);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// (2) messages without a parent are the top level
|
|
180
|
+
const roots = all.filter(node => !node.parent);
|
|
181
|
+
// (3) prune dummies: drop the ones without children, put the children of the others in their place,
|
|
182
|
+
// but not at the top level if there is more than one child
|
|
183
|
+
const replacement = (node, topLevel) => {
|
|
184
|
+
if (node.entry) {
|
|
185
|
+
return [node];
|
|
186
|
+
}
|
|
187
|
+
if (!node.children.length) {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
return topLevel && node.children.length > 1 ? [node] : node.children;
|
|
191
|
+
};
|
|
192
|
+
// children before their parents, so a dummy is replaced by children that are already pruned
|
|
193
|
+
for (const node of preOrder(roots).reverse()) {
|
|
194
|
+
node.children = node.children.flatMap(child => replacement(child, false));
|
|
195
|
+
node.children.forEach(child => {
|
|
196
|
+
child.parent = node;
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
let top = roots.flatMap(node => replacement(node, true));
|
|
200
|
+
top.forEach(node => {
|
|
201
|
+
node.parent = null;
|
|
202
|
+
});
|
|
203
|
+
// (4) sort the top level by sent date, a dummy by its first child
|
|
204
|
+
top.forEach(node => {
|
|
205
|
+
if (!node.entry) {
|
|
206
|
+
node.children.sort(compareNodes);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
top.sort(compareNodes);
|
|
210
|
+
// (5) gather threads with the same base subject, the subject of a dummy is the one of its first child
|
|
211
|
+
const threadSubject = (node) => (node.entry ? node.entry.subject : node.children[0].entry.subject);
|
|
212
|
+
const isReply = (node) => !!node.entry && node.entry.subject.isReply;
|
|
213
|
+
const table = new Map();
|
|
214
|
+
// (5.B) one message per base subject, a dummy or a message that is not a reply or forward is preferred
|
|
215
|
+
for (const node of top) {
|
|
216
|
+
const subject = threadSubject(node);
|
|
217
|
+
if (!subject.id) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
const old = table.get(subject.id);
|
|
221
|
+
if (!old || (old.entry && (!node.entry || (isReply(old) && !isReply(node))))) {
|
|
222
|
+
table.set(subject.id, node);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// (5.C) merge the other threads with the same subject into the one in the table
|
|
226
|
+
const removed = new Set();
|
|
227
|
+
for (const node of top) {
|
|
228
|
+
const subject = threadSubject(node);
|
|
229
|
+
if (!subject.id) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
// (5.B) put a node for every subject in the table
|
|
233
|
+
const other = table.get(subject.id);
|
|
234
|
+
if (other === node) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
removed.add(node);
|
|
238
|
+
if (!other.entry && !node.entry) {
|
|
239
|
+
node.children.forEach(child => link(other, child));
|
|
240
|
+
}
|
|
241
|
+
else if (!other.entry || (isReply(node) && !isReply(other))) {
|
|
242
|
+
link(other, node);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// both become children of a new dummy that takes the place of the message in the table
|
|
246
|
+
const dummy = createNode();
|
|
247
|
+
top[top.indexOf(other)] = dummy;
|
|
248
|
+
link(dummy, other);
|
|
249
|
+
link(dummy, node);
|
|
250
|
+
table.set(subject.id, dummy);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
top = top.filter(node => !removed.has(node));
|
|
254
|
+
// (6) sort all sets of siblings by sent date, the deepest ones first
|
|
255
|
+
for (const node of preOrder(top).reverse()) {
|
|
256
|
+
node.children.sort(compareNodes);
|
|
257
|
+
}
|
|
258
|
+
top.sort(compareNodes);
|
|
259
|
+
return top;
|
|
260
|
+
}
|
|
261
|
+
const ALGORITHMS = {
|
|
262
|
+
ORDEREDSUBJECT: orderedSubject,
|
|
263
|
+
REFERENCES: references
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Adds the THREAD and UID THREAD commands, unless another algorithm plugin did already, and the
|
|
267
|
+
* THREAD=<algorithm> capability
|
|
268
|
+
*
|
|
269
|
+
* @param {Object} server IMAP server
|
|
270
|
+
* @param {String} algorithm "ORDEREDSUBJECT" or "REFERENCES"
|
|
271
|
+
*/
|
|
272
|
+
function addThreadAlgorithm(server, algorithm) {
|
|
273
|
+
server.registerCapability('THREAD=' + algorithm);
|
|
274
|
+
if (server.threadAlgorithms) {
|
|
275
|
+
server.threadAlgorithms[algorithm] = ALGORITHMS[algorithm];
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
server.threadAlgorithms = { [algorithm]: ALGORITHMS[algorithm] };
|
|
279
|
+
const threadHandler = (isUid, connection, parsed, data, callback) => {
|
|
280
|
+
const command = isUid ? 'UID THREAD' : 'THREAD';
|
|
281
|
+
const attributes = parsed.attributes || [];
|
|
282
|
+
// RFC 5256 section 5: thread-alg = "ORDEREDSUBJECT" / "REFERENCES" / thread-alg-ext, an atom
|
|
283
|
+
const name = attributes[0] && attributes[0].type === 'ATOM' ? attributes[0].value.toUpperCase() : '';
|
|
284
|
+
if (!Object.hasOwn(server.threadAlgorithms, name)) {
|
|
285
|
+
connection.sendStatus(parsed, data, 'BAD', name ? 'Unsupported threading algorithm ' + name : command + ' expects a threading algorithm atom', false, command + ' FAILED');
|
|
286
|
+
return callback();
|
|
287
|
+
}
|
|
288
|
+
const result = (0, sorting_js_1.searchMessages)(connection, parsed, data, attributes.slice(1));
|
|
289
|
+
if (!result) {
|
|
290
|
+
return callback();
|
|
291
|
+
}
|
|
292
|
+
// base subjects are compared with the collation (RFC 5256 sections 3 and 7)
|
|
293
|
+
const entries = result.list.map((message) => {
|
|
294
|
+
const base = (0, sorting_js_1.baseSubject)((0, mimeparser_js_1.getMessageData)(message).tree.parsedHeader.subject);
|
|
295
|
+
return {
|
|
296
|
+
message,
|
|
297
|
+
seq: result.numbers[message.uid],
|
|
298
|
+
date: (0, sorting_js_1.sentTime)(message),
|
|
299
|
+
// a binary string of the collation key, these compare like the octets of the key
|
|
300
|
+
subject: { id: (0, sorting_js_1.collationKey)(base.subject).toString('binary'), isReply: base.isReply }
|
|
301
|
+
};
|
|
302
|
+
});
|
|
303
|
+
connection.send({
|
|
304
|
+
tag: '*',
|
|
305
|
+
command: 'THREAD',
|
|
306
|
+
// thread-data has no SP between thread-lists, so it can not be built from nested arrays
|
|
307
|
+
attributes: entries.length ? [{ type: 'TEXT', value: formatThreads(server.threadAlgorithms[name](entries), isUid) }] : []
|
|
308
|
+
}, command, parsed, data,
|
|
309
|
+
// the search result, so CONDSTORE knows about a MODSEQ search key (RFC 7162 section 3.1.9)
|
|
310
|
+
result);
|
|
311
|
+
connection.sendStatus(parsed, data, 'OK', command + ' completed', false, command);
|
|
312
|
+
return callback();
|
|
313
|
+
};
|
|
314
|
+
// RFC 5256 section 3: EXPUNGE responses are not permitted while responding to THREAD, but are during UID THREAD.
|
|
315
|
+
// The search criteria start after the algorithm and the charset
|
|
316
|
+
server.setCommandHandler('THREAD', threadHandler.bind(null, false), { states: command_states_js_1.states.SELECTED, searchCriteria: 2, noExpunge: true });
|
|
317
|
+
server.setCommandHandler('UID THREAD', threadHandler.bind(null, true), { states: command_states_js_1.states.SELECTED, searchCriteria: 2 });
|
|
318
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import type { IMAPServer, IMAPConnection } from './server.js';
|
|
2
|
+
export type { IMAPServer, IMAPConnection };
|
|
3
|
+
/**
|
|
4
|
+
* A value of the parsed command or of a response, as imap-handler parses and compiles it: an
|
|
5
|
+
* `{ type, value, section?, partial? }` node, a list (array), a string, a number or null (NIL).
|
|
6
|
+
* Commands and plugins walk these trees freely, so the type is left open.
|
|
7
|
+
*/
|
|
8
|
+
export type Attribute = any;
|
|
9
|
+
/** A parsed client command, see imap-handler. Plugins add their own properties (e.g. `searchReturn`) */
|
|
10
|
+
export interface ParsedCommand {
|
|
11
|
+
tag: string;
|
|
12
|
+
command: string;
|
|
13
|
+
attributes?: Attribute[] | undefined;
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The command a response answers, as `connection.send()` and `connection.sendStatus()` take it: a parsed
|
|
18
|
+
* command, or only the tag for input that could not be parsed (or `{ tag: '*' }` for an untagged response)
|
|
19
|
+
*/
|
|
20
|
+
export type CommandContext = ParsedCommand | {
|
|
21
|
+
tag: string;
|
|
22
|
+
command?: undefined;
|
|
23
|
+
attributes?: undefined;
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
};
|
|
26
|
+
/** A response written to the client through `connection.send()` */
|
|
27
|
+
export interface IMAPResponse {
|
|
28
|
+
tag: string;
|
|
29
|
+
command?: string | undefined;
|
|
30
|
+
attributes?: Attribute | Attribute[] | undefined;
|
|
31
|
+
/** set by an output handler to drop the response */
|
|
32
|
+
skipResponse?: boolean | undefined;
|
|
33
|
+
/** an unsolicited response from the notification queue, it does not flush the queue */
|
|
34
|
+
notification?: boolean | undefined;
|
|
35
|
+
[key: string]: any;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* An untagged response distributed with `server.notify()`, queued per session in
|
|
39
|
+
* `connection.notificationQueue` until it can be sent
|
|
40
|
+
*/
|
|
41
|
+
export interface Notification extends IMAPResponse {
|
|
42
|
+
/** the session whose command caused the change, null for changes from SMTP */
|
|
43
|
+
origin?: IMAPConnection | null | undefined;
|
|
44
|
+
/** the new message of an EXISTS, or the removed message of an EXPUNGE */
|
|
45
|
+
message?: Message | undefined;
|
|
46
|
+
/** the removed messages of a VANISHED response (QRESYNC) */
|
|
47
|
+
messages?: Message[] | undefined;
|
|
48
|
+
/** the message list as it was before an expunge, for sessions that were not told about it yet */
|
|
49
|
+
mailboxCopy?: Message[] | undefined;
|
|
50
|
+
/** messages whose flags changed, sent as unsolicited FETCH responses */
|
|
51
|
+
flagUpdate?: Message[] | undefined;
|
|
52
|
+
}
|
|
53
|
+
/** The `notify` event of the server, see `server.notify()` */
|
|
54
|
+
export interface NotifyEvent {
|
|
55
|
+
command: Notification;
|
|
56
|
+
/** the mailbox the change is about, false or null for changes that are not about the selected mailbox */
|
|
57
|
+
mailbox: Mailbox | string | false | null | undefined;
|
|
58
|
+
/** the session that does not get the notification */
|
|
59
|
+
ignoreConnection: IMAPConnection | false | null | undefined;
|
|
60
|
+
/** only connections for which it returns true get the notification */
|
|
61
|
+
filter: ((connection: IMAPConnection) => boolean) | false | null | undefined;
|
|
62
|
+
/** the session whose command caused the change, null for changes from outside (e.g. SMTP) */
|
|
63
|
+
origin: IMAPConnection | null;
|
|
64
|
+
[key: string]: any;
|
|
65
|
+
}
|
|
66
|
+
/** The `mailbox` event of the server, see `server.mailboxChanged()` */
|
|
67
|
+
export interface MailboxChangeEvent {
|
|
68
|
+
/** "create", "delete", "rename", "subscribe" or "unsubscribe" */
|
|
69
|
+
type: string;
|
|
70
|
+
path: string;
|
|
71
|
+
oldPath: string | null;
|
|
72
|
+
mailbox: Mailbox | null;
|
|
73
|
+
origin: IMAPConnection | null;
|
|
74
|
+
}
|
|
75
|
+
export type Callback = (err?: any, ...args: any[]) => void;
|
|
76
|
+
/** Handler of an IMAP command, it must send a tagged response and then call the callback */
|
|
77
|
+
export type CommandHandler = (connection: IMAPConnection, parsed: ParsedCommand, data: string, callback: Callback) => void;
|
|
78
|
+
/** Options of a command, see `server.setCommandHandler()` and command-states.ts */
|
|
79
|
+
export interface CommandOptions {
|
|
80
|
+
states?: string[] | string | false | undefined;
|
|
81
|
+
noArguments?: boolean | undefined;
|
|
82
|
+
mailboxArguments?: number[] | number | undefined;
|
|
83
|
+
astringArguments?: number[] | number | undefined;
|
|
84
|
+
searchCriteria?: number | false | undefined;
|
|
85
|
+
sequenceSet?: number | false | undefined;
|
|
86
|
+
noExpunge?: boolean | undefined;
|
|
87
|
+
/** also the name of the capability that allows literal8 (`'BINARY'`) */
|
|
88
|
+
literal8?: boolean | string | undefined;
|
|
89
|
+
noPipelining?: boolean | undefined;
|
|
90
|
+
appendMessage?: boolean | undefined;
|
|
91
|
+
}
|
|
92
|
+
/** A plugin, given as a function in `options.plugins` or built in */
|
|
93
|
+
export interface Plugin {
|
|
94
|
+
(server: IMAPServer): void;
|
|
95
|
+
/** plugins that are loaded before this one, by name */
|
|
96
|
+
requires?: string[] | undefined;
|
|
97
|
+
}
|
|
98
|
+
/** An error that carries the response a command fails with */
|
|
99
|
+
export interface IMAPError extends Error {
|
|
100
|
+
code?: string | undefined;
|
|
101
|
+
imapResponse?: string | undefined;
|
|
102
|
+
responseCode?: Attribute;
|
|
103
|
+
responseCodeArgs?: Attribute;
|
|
104
|
+
[key: string]: any;
|
|
105
|
+
}
|
|
106
|
+
/** Connection states of RFC 3501 section 3, "Logout" after LOGOUT or BYE */
|
|
107
|
+
export type ConnectionState = 'Not Authenticated' | 'Authenticated' | 'Selected' | 'Logout';
|
|
108
|
+
/** A message in a mailbox, plugins keep their own properties on it (MODSEQ, X-GM-LABELS ...) */
|
|
109
|
+
export interface Message {
|
|
110
|
+
uid: number;
|
|
111
|
+
flags: string[];
|
|
112
|
+
internaldate: string;
|
|
113
|
+
/** the message source as a binary string (one char per octet) */
|
|
114
|
+
raw: string;
|
|
115
|
+
recent?: boolean | undefined;
|
|
116
|
+
/** expunged by another session but not yet reported to this one */
|
|
117
|
+
ghost?: boolean | undefined;
|
|
118
|
+
[key: string]: any;
|
|
119
|
+
}
|
|
120
|
+
/** Resolved messages of a sequence set, `[sequence number, message]` pairs */
|
|
121
|
+
export type MessageRange = [number, Message][];
|
|
122
|
+
/** A mailbox, plugins keep their own properties on it (acl, metadata, HIGHESTMODSEQ ...) */
|
|
123
|
+
export interface Mailbox {
|
|
124
|
+
path: string;
|
|
125
|
+
namespace: string;
|
|
126
|
+
uid: number;
|
|
127
|
+
uidvalidity: number;
|
|
128
|
+
uidnext: number;
|
|
129
|
+
flags: string[];
|
|
130
|
+
permanentFlags: string[];
|
|
131
|
+
allowPermanentFlags: boolean;
|
|
132
|
+
messages: Message[];
|
|
133
|
+
/** flags that messages of the mailbox had, they stay in FLAGS and PERMANENTFLAGS, see server.rememberFlags() */
|
|
134
|
+
knownFlags?: string[] | undefined;
|
|
135
|
+
folders?: Record<string, Mailbox> | undefined;
|
|
136
|
+
separator?: string | undefined;
|
|
137
|
+
/** an accessor of `server.subscriptions`, see server.trackSubscription() */
|
|
138
|
+
subscribed?: boolean | undefined;
|
|
139
|
+
[key: string]: any;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* A name that getSubscriptionTree() lists without a mailbox: a subscribed name that is not a mailbox, or a
|
|
143
|
+
* superior hierarchy level of a subscribed name
|
|
144
|
+
*/
|
|
145
|
+
export interface SubscriptionStandIn {
|
|
146
|
+
path: string;
|
|
147
|
+
namespace: string | false;
|
|
148
|
+
flags: string[];
|
|
149
|
+
subscribed: boolean;
|
|
150
|
+
}
|
|
151
|
+
/** The fields of a mailbox (or a stand-in) that LIST pattern matching needs, see server.matchFolders() */
|
|
152
|
+
export interface ListedMailbox {
|
|
153
|
+
path: string;
|
|
154
|
+
namespace: string | false;
|
|
155
|
+
flags: string[];
|
|
156
|
+
}
|
|
157
|
+
/** A message as the storage option gives it, the server fills in the rest. A string is the message source */
|
|
158
|
+
export interface StorageMessage {
|
|
159
|
+
uid?: number | undefined;
|
|
160
|
+
/** a single flag can be given as a string */
|
|
161
|
+
flags?: string | string[] | undefined;
|
|
162
|
+
/** a Date or a date-time string, the current time if not set */
|
|
163
|
+
internaldate?: string | Date | false | undefined;
|
|
164
|
+
raw?: string | Uint8Array | undefined;
|
|
165
|
+
recent?: boolean | undefined;
|
|
166
|
+
[key: string]: any;
|
|
167
|
+
}
|
|
168
|
+
/** A mailbox as the storage option gives it, the server fills in the rest */
|
|
169
|
+
export interface StorageMailbox {
|
|
170
|
+
uid?: number | undefined;
|
|
171
|
+
uidvalidity?: number | undefined;
|
|
172
|
+
uidnext?: number | undefined;
|
|
173
|
+
flags?: string[] | undefined;
|
|
174
|
+
permanentFlags?: string[] | undefined;
|
|
175
|
+
allowPermanentFlags?: boolean | undefined;
|
|
176
|
+
subscribed?: boolean | undefined;
|
|
177
|
+
messages?: (StorageMessage | string)[] | undefined;
|
|
178
|
+
folders?: Record<string, StorageMailbox> | undefined;
|
|
179
|
+
separator?: string | undefined;
|
|
180
|
+
[key: string]: any;
|
|
181
|
+
}
|
|
182
|
+
export type NamespaceType = 'personal' | 'user' | 'shared';
|
|
183
|
+
/** A namespace of the storage option, keyed by its prefix (`"INBOX"`, `""`, `"INBOX."`, ...) */
|
|
184
|
+
export interface StorageNamespace extends StorageMailbox {
|
|
185
|
+
separator?: string | undefined;
|
|
186
|
+
type?: NamespaceType | undefined;
|
|
187
|
+
}
|
|
188
|
+
/** A namespace in `server.storage`, with every key set by the server */
|
|
189
|
+
export interface Namespace {
|
|
190
|
+
separator: string;
|
|
191
|
+
type: NamespaceType;
|
|
192
|
+
folders: Record<string, Mailbox>;
|
|
193
|
+
[key: string]: any;
|
|
194
|
+
}
|
|
195
|
+
/** `server.storage`: the namespaces by prefix, and INBOX, which is a mailbox of its own */
|
|
196
|
+
export type ServerStorage = {
|
|
197
|
+
INBOX: Mailbox;
|
|
198
|
+
} & Record<string, Namespace>;
|
|
199
|
+
/** Mailbox counters of `server.getStatus()` */
|
|
200
|
+
export interface MailboxStatus {
|
|
201
|
+
/** number of messages by flag */
|
|
202
|
+
flags: Record<string, number>;
|
|
203
|
+
seen: number;
|
|
204
|
+
unseen: number;
|
|
205
|
+
recent: number;
|
|
206
|
+
permanentFlags: string[];
|
|
207
|
+
}
|
|
208
|
+
export interface UserData {
|
|
209
|
+
password?: string | undefined;
|
|
210
|
+
xoauth2?: {
|
|
211
|
+
accessToken?: string | undefined;
|
|
212
|
+
sessionTimeout?: number | undefined;
|
|
213
|
+
} | undefined;
|
|
214
|
+
[key: string]: any;
|
|
215
|
+
}
|
|
216
|
+
/** Options of `imapkit(options)` */
|
|
217
|
+
export interface IMAPServerOptions {
|
|
218
|
+
/** the mailbox tree, keyed by namespace */
|
|
219
|
+
storage?: Record<string, StorageNamespace> | undefined;
|
|
220
|
+
/** plugin names (`"IDLE"`, `"LITERAL+"`, ...) or plugin functions */
|
|
221
|
+
plugins?: (string | Plugin)[] | string | Plugin | undefined;
|
|
222
|
+
users?: Record<string, UserData> | undefined;
|
|
223
|
+
secureConnection?: boolean | undefined;
|
|
224
|
+
credentials?: {
|
|
225
|
+
key: string | Buffer;
|
|
226
|
+
cert: string | Buffer;
|
|
227
|
+
} | undefined;
|
|
228
|
+
debug?: boolean | undefined;
|
|
229
|
+
systemFlags?: string[] | undefined;
|
|
230
|
+
/** largest literal accepted after login, in octets */
|
|
231
|
+
maxLiteralSize?: number | undefined;
|
|
232
|
+
[key: string]: any;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* A layer between the socket and the IMAP protocol, such as COMPRESS=DEFLATE. It passes data on with
|
|
236
|
+
* `connection.writeRaw()` and `connection.onData()`
|
|
237
|
+
*/
|
|
238
|
+
export interface Transport {
|
|
239
|
+
write(data: Buffer): void;
|
|
240
|
+
receive(chunk: Buffer): void;
|
|
241
|
+
end(callback: () => void): void;
|
|
242
|
+
destroy(): void;
|
|
243
|
+
}
|
|
244
|
+
/** A response code, or a list for a code with arguments (`['MESSAGELIMIT', 1000]`) */
|
|
245
|
+
export type ResponseCode = string | (string | number)[];
|
|
246
|
+
/** The refusal of a command or a literal, sent as a tagged `command [code] text` */
|
|
247
|
+
export interface Refusal {
|
|
248
|
+
command: string;
|
|
249
|
+
code?: string | undefined;
|
|
250
|
+
text: string;
|
|
251
|
+
}
|
|
252
|
+
/** A refusal of `server.commandChecks`, `command` defaults to BAD */
|
|
253
|
+
export interface CommandRefusal {
|
|
254
|
+
command?: string | undefined;
|
|
255
|
+
code?: ResponseCode | undefined;
|
|
256
|
+
text: string;
|
|
257
|
+
}
|
|
258
|
+
/** A result of `server.appendChecks` (or other checks reported with `connection.applyChecks()`) */
|
|
259
|
+
export interface CheckResult {
|
|
260
|
+
code?: ResponseCode | undefined;
|
|
261
|
+
text: string;
|
|
262
|
+
/** only a warning, sent as an untagged NO */
|
|
263
|
+
soft?: boolean | undefined;
|
|
264
|
+
}
|
|
265
|
+
/** A message that APPEND, REPLACE, COPY or MOVE is about to add to a mailbox */
|
|
266
|
+
export interface AppendMessage {
|
|
267
|
+
raw: string;
|
|
268
|
+
flags?: string[] | undefined;
|
|
269
|
+
internaldate?: string | Date | false | undefined;
|
|
270
|
+
[key: string]: any;
|
|
271
|
+
}
|
|
272
|
+
/** Options of `server.appendChecks`: `{ move, source }` for COPY and MOVE, `{ command, replaced }` for APPEND and REPLACE */
|
|
273
|
+
export interface AppendCheckOptions {
|
|
274
|
+
move?: boolean | undefined;
|
|
275
|
+
source?: Mailbox | false | undefined;
|
|
276
|
+
command?: string | undefined;
|
|
277
|
+
replaced?: Message | null | undefined;
|
|
278
|
+
[key: string]: any;
|
|
279
|
+
}
|
|
280
|
+
type BivariantCallback<T extends (...args: any[]) => any> = {
|
|
281
|
+
bivarianceHack(...args: Parameters<T>): ReturnType<T>;
|
|
282
|
+
}['bivarianceHack'];
|
|
283
|
+
/**
|
|
284
|
+
* `server.outputHandlers`: called with the arguments of every `connection.send()`, can change the response or set
|
|
285
|
+
* `skipResponse`. Handlers may declare narrower parameter types for the responses they act on
|
|
286
|
+
*/
|
|
287
|
+
export type OutputHandler = BivariantCallback<(connection: IMAPConnection, response: IMAPResponse, description: string | undefined, parsed: CommandContext | null | undefined, data: string | null | undefined, ...extra: any[]) => void>;
|
|
288
|
+
/** `server.fetchHandlers`: the value of a FETCH item */
|
|
289
|
+
export interface FetchHandler {
|
|
290
|
+
(connection: IMAPConnection, message: Message, query?: Attribute, ...args: any[]): any;
|
|
291
|
+
/** fetching the item sets \Seen like BODY[] */
|
|
292
|
+
setsSeen?: boolean | undefined;
|
|
293
|
+
}
|
|
294
|
+
/** `server.searchHandlers`: checks a message against a search key, the arguments follow the index */
|
|
295
|
+
export interface SearchHandler {
|
|
296
|
+
(connection: IMAPConnection, message: Message, index: number, ...args: any[]): any;
|
|
297
|
+
/** decides the argument types of the key instead of one string per handler parameter */
|
|
298
|
+
argumentTypes?: ((list: Attribute[]) => any[]) | undefined;
|
|
299
|
+
}
|
|
300
|
+
/** `server.storeHandlers`: applies a STORE item to a message */
|
|
301
|
+
export interface StoreHandler {
|
|
302
|
+
(connection: IMAPConnection, message: Message, values: any, index: number, parsed: ParsedCommand, data: string): any;
|
|
303
|
+
/** the values are astrings (X-GM-LABELS), NIL atoms are kept and literals accepted */
|
|
304
|
+
astringValues?: boolean | undefined;
|
|
305
|
+
}
|
|
306
|
+
/** `server.statusHandlers`: the value of a STATUS item */
|
|
307
|
+
export type StatusHandler = (connection: IMAPConnection, mailbox: Mailbox, status: MailboxStatus) => any;
|
|
308
|
+
/** `server.fetchFilters` and `server.storeFilters`: false leaves a message out */
|
|
309
|
+
export type MessageFilter = (connection: IMAPConnection, message: Message, parsed: ParsedCommand, index: number) => unknown;
|
|
310
|
+
/** `server.appendDataHandlers`: parses an append-data extension and returns the function that builds the message source */
|
|
311
|
+
export type AppendDataHandler = (connection: IMAPConnection, value: Attribute) => () => string;
|
|
312
|
+
export type CapabilityCheck = (connection: IMAPConnection) => boolean;
|
|
313
|
+
export type ConnectionHandler = (connection: IMAPConnection) => void;
|
|
314
|
+
export type MessageHandler = (server: IMAPServer, message: Message, mailbox: Mailbox) => void;
|
|
315
|
+
export type MailboxHandler = (server: IMAPServer, mailbox: Mailbox) => void;
|
|
316
|
+
export type CopyHandler = (server: IMAPServer, source: Message, properties: Record<string, any>, mailbox: Mailbox) => void;
|
|
317
|
+
export type NotifyFilter = (connection: IMAPConnection, event: NotifyEvent) => boolean;
|
|
318
|
+
export type AppendCheck = (connection: IMAPConnection, mailbox: Mailbox, messages: AppendMessage[], options: AppendCheckOptions) => CheckResult | false | null | undefined | void;
|
|
319
|
+
export type LiteralFilter = (connection: IMAPConnection, command: string, line: string, size: number) => Refusal | false | null | undefined;
|
|
320
|
+
export type UrlAccessCheck = (connection: IMAPConnection, mailbox: Mailbox, url: any) => {
|
|
321
|
+
text: string;
|
|
322
|
+
} | false | null | undefined;
|
|
323
|
+
export type SearchAccessCheck = (connection: IMAPConnection, mailbox: Mailbox, named: boolean) => boolean;
|
|
324
|
+
export type CommandCheck = (connection: IMAPConnection, parsed: ParsedCommand) => CommandRefusal | false | null | undefined;
|
|
325
|
+
export type RangeLimit = (connection: IMAPConnection, parsed: ParsedCommand, range: MessageRange) => MessageRange | false | null | undefined;
|
|
326
|
+
export type SearchLimit = (connection: IMAPConnection, messages: Message[], query: any) => Message[] | false | null | undefined;
|
|
327
|
+
export type ClosedCheck = (connection: IMAPConnection) => boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IMAPConnection } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Sets the UTF-8 options of a session from the extensions it has enabled. Run it when the session starts,
|
|
4
|
+
* after ENABLE and after UNAUTHENTICATE (once the ENABLE plugin has cleared `connection.enabled`).
|
|
5
|
+
*
|
|
6
|
+
* - With the UTF8=ACCEPT plugin, quoted strings may hold UTF-8 even before ENABLE (RFC 9755 section 3) and
|
|
7
|
+
* modified UTF-7 names must decode to Net-Unicode. Without it, 8-bit quoted strings are a syntax error until
|
|
8
|
+
* ENABLE IMAP4rev2, like RFC 3501 says
|
|
9
|
+
* - ENABLE UTF8=ACCEPT or IMAP4rev2: mailbox names are UTF-8 in both directions and strings that are valid
|
|
10
|
+
* UTF-8 are sent quoted (RFC 9755 section 3, RFC 9051 sections 4.3 and 5.1)
|
|
11
|
+
* - ENABLE UTF8=ACCEPT: SEARCH strings are UTF-8 and CHARSET is refused (RFC 9755 section 3)
|
|
12
|
+
* - ENABLE IMAP4rev2: SEARCH strings are UTF-8 unless a CHARSET says otherwise (RFC 9051 section 6.4.4)
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} connection IMAP connection
|
|
15
|
+
*/
|
|
16
|
+
declare function updateSession(connection: IMAPConnection): void;
|
|
17
|
+
export { updateSession };
|