imapkit 4.0.3 → 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.
- package/README.md +32 -19
- package/bin/imapkit.js +12 -16
- package/dist/cjs/addressparser.d.ts +21 -0
- package/dist/cjs/addressparser.js +277 -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 +102 -123
- 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 +54 -11
- 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,96 @@
|
|
|
1
|
+
import type { SearchResult } from './commands/handlers/search.js';
|
|
2
|
+
import type { Attribute, IMAPResponse, IMAPServer, Mailbox, Message } from './types.js';
|
|
3
|
+
/** A parsed PARTIAL range, see parsePartialRange() */
|
|
4
|
+
export interface PartialRange {
|
|
5
|
+
/** the argument as the client sent it */
|
|
6
|
+
range: string;
|
|
7
|
+
from: number;
|
|
8
|
+
to: number;
|
|
9
|
+
/** partial-range-last, counted from the last result */
|
|
10
|
+
fromEnd: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** Upper case result option names to their arguments (`parsed.searchReturn`), PARTIAL has its parsed range */
|
|
13
|
+
export type SearchReturn = Map<string, any>;
|
|
14
|
+
/** The parts of a search result that the ESEARCH response is built from */
|
|
15
|
+
export type EsearchResult = Pick<SearchResult, 'list' | 'numbers'>;
|
|
16
|
+
/**
|
|
17
|
+
* ESEARCH response helpers (RFC 4731, RFC 4466 section 2.6.2). Used by the ESEARCH, SEARCHRES, PARTIAL,
|
|
18
|
+
* CONTEXT=SEARCH and MULTISEARCH plugins, and meant to be reused where SEARCH always answers with ESEARCH (IMAP4rev2, RFC 9051).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Formats a list of numbers as a compact sequence-set, e.g. [1, 2, 3, 5] becomes "1:3,5"
|
|
22
|
+
*
|
|
23
|
+
* @param {Array} numbers List of nz-numbers, in any order
|
|
24
|
+
* @return {String} sequence-set, empty for an empty list
|
|
25
|
+
*/
|
|
26
|
+
declare function toSequenceSet(numbers: Iterable<number>): string;
|
|
27
|
+
/**
|
|
28
|
+
* Formats a list of numbers as a sequence-set that keeps their order, for SORT results (RFC 5267
|
|
29
|
+
* section 3.2): only runs of ascending consecutive numbers become ranges, e.g. [5, 3, 4, 2] becomes "5,3:4,2"
|
|
30
|
+
*
|
|
31
|
+
* @param {Array} numbers List of nz-numbers in the requested order
|
|
32
|
+
* @return {String} sequence-set, empty for an empty list
|
|
33
|
+
*/
|
|
34
|
+
declare function toOrderedSet(numbers: number[]): string;
|
|
35
|
+
/**
|
|
36
|
+
* Parses the argument of the PARTIAL search return option (RFC 5267 section 4.4, RFC 9394 section 4):
|
|
37
|
+
* partial-range-first = nz-number ":" nz-number, partial-range-last = "-" nz-number ":" "-" nz-number.
|
|
38
|
+
* "*" is not allowed, and 500:400 is the same as 400:500
|
|
39
|
+
*
|
|
40
|
+
* @param {Object} item Parsed argument
|
|
41
|
+
* @param {Boolean} allowLast If true, the partial-range-last form of RFC 9394 is accepted
|
|
42
|
+
* @return {Object} `{ range, from, to, fromEnd }`, `range` is the argument as the client sent it
|
|
43
|
+
*/
|
|
44
|
+
declare function parsePartialRange(item: Attribute, allowLast: boolean): PartialRange;
|
|
45
|
+
/**
|
|
46
|
+
* Picks the results that a PARTIAL range refers to. The first result is 1, and -1 is the last one
|
|
47
|
+
* (RFC 9394 section 3.1). Results outside the list are left out
|
|
48
|
+
*
|
|
49
|
+
* @param {Array} list Results in mailbox order
|
|
50
|
+
* @param {Object} partial Parsed range, see parsePartialRange
|
|
51
|
+
* @return {Array} results in the range, in mailbox order
|
|
52
|
+
*/
|
|
53
|
+
declare function selectPartial<T>(list: T[], partial: PartialRange): T[];
|
|
54
|
+
/**
|
|
55
|
+
* Registers the PARTIAL search return option, shared by the PARTIAL and CONTEXT=SEARCH plugins. The
|
|
56
|
+
* partial-range-last form (-1:-100) is only valid with the PARTIAL capability (RFC 9394 section 4)
|
|
57
|
+
*
|
|
58
|
+
* @param {Object} server IMAP server, with the ESEARCH plugin loaded
|
|
59
|
+
*/
|
|
60
|
+
declare function registerPartialOption(server: IMAPServer): void;
|
|
61
|
+
/**
|
|
62
|
+
* Picks the messages that the requested result options return. With COUNT or ALL, or without
|
|
63
|
+
* MIN, MAX and PARTIAL, these are all matching messages, otherwise the lowest and/or the highest
|
|
64
|
+
* matching message and the ones in the PARTIAL range. This is the set that the MODSEQ result
|
|
65
|
+
* option describes (RFC 4731 section 3.2) and that SAVE stores (RFC 5182 section 2.4, RFC 9394
|
|
66
|
+
* section 3.2)
|
|
67
|
+
*
|
|
68
|
+
* @param {Array} list Matching messages, in mailbox order
|
|
69
|
+
* @param {Map} options Upper case result option names to their arguments, an empty map stands for ALL
|
|
70
|
+
* @return {Array} returned messages, in mailbox order
|
|
71
|
+
*/
|
|
72
|
+
declare function selectReturned<T>(list: T[], options: SearchReturn): T[];
|
|
73
|
+
/**
|
|
74
|
+
* Builds the search correlator (RFC 4466 section 2.6.2), with the MAILBOX and UIDVALIDITY
|
|
75
|
+
* correlators of RFC 7377 section 4 if a mailbox is given
|
|
76
|
+
*
|
|
77
|
+
* @param {String} tag Tag of the command
|
|
78
|
+
* @param {Object} [mailbox] Mailbox the response is about
|
|
79
|
+
* @return {Array} correlator list
|
|
80
|
+
*/
|
|
81
|
+
declare function buildCorrelator(tag: string, mailbox?: Mailbox | null): Attribute[];
|
|
82
|
+
/**
|
|
83
|
+
* Builds an ESEARCH response (RFC 4466 section 2.6.2) with the RFC 4731 section 3.1 return data
|
|
84
|
+
* and PARTIAL (RFC 5267 section 4.4, RFC 9394 section 3.1)
|
|
85
|
+
*
|
|
86
|
+
* @param {String} tag Tag of the command, for the search correlator
|
|
87
|
+
* @param {Boolean} isUid If true, the response lists UIDs and has the UID indicator
|
|
88
|
+
* @param {Object} result Search result, `{ list, numbers }` (see src/commands/handlers/search.ts)
|
|
89
|
+
* @param {Map} options Upper case result option names to their arguments, an empty map stands for ALL (RFC 4731 section 3.1)
|
|
90
|
+
* @param {Object} [mailbox] Adds the MAILBOX and UIDVALIDITY correlators of RFC 7377 for this mailbox
|
|
91
|
+
* @param {Array} [sorted] The matching messages in sort order, for an extended SORT (RFC 5267 section 3.1): MIN and MAX are
|
|
92
|
+
* the first and the last sorted message, ALL and PARTIAL list the results in sort order
|
|
93
|
+
* @return {Object} response for connection.send()
|
|
94
|
+
*/
|
|
95
|
+
declare function buildEsearchResponse(tag: string, isUid: boolean, result: EsearchResult, options: SearchReturn, mailbox?: Mailbox | null, sorted?: Message[] | null): IMAPResponse;
|
|
96
|
+
export { toSequenceSet, toOrderedSet, selectReturned, selectPartial, parsePartialRange, registerPartialOption, buildCorrelator, buildEsearchResponse };
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { badError } = require('./commands/handlers/search');
|
|
4
|
-
const { MAX_NUMBER } = require('./numbers');
|
|
5
|
-
|
|
1
|
+
import { badError } from './commands/handlers/search.js';
|
|
2
|
+
import { MAX_NUMBER } from './numbers.js';
|
|
6
3
|
/**
|
|
7
4
|
* ESEARCH response helpers (RFC 4731, RFC 4466 section 2.6.2). Used by the ESEARCH, SEARCHRES, PARTIAL,
|
|
8
5
|
* CONTEXT=SEARCH and MULTISEARCH plugins, and meant to be reused where SEARCH always answers with ESEARCH (IMAP4rev2, RFC 9051).
|
|
9
6
|
*/
|
|
10
|
-
|
|
11
7
|
/**
|
|
12
8
|
* Formats a list of numbers as a compact sequence-set, e.g. [1, 2, 3, 5] becomes "1:3,5"
|
|
13
9
|
*
|
|
@@ -17,7 +13,6 @@ const { MAX_NUMBER } = require('./numbers');
|
|
|
17
13
|
function toSequenceSet(numbers) {
|
|
18
14
|
return toOrderedSet(Array.from(new Set(numbers)).sort((a, b) => a - b));
|
|
19
15
|
}
|
|
20
|
-
|
|
21
16
|
/**
|
|
22
17
|
* Formats a list of numbers as a sequence-set that keeps their order, for SORT results (RFC 5267
|
|
23
18
|
* section 3.2): only runs of ascending consecutive numbers become ranges, e.g. [5, 3, 4, 2] becomes "5,3:4,2"
|
|
@@ -31,13 +26,13 @@ function toOrderedSet(numbers) {
|
|
|
31
26
|
const last = ranges[ranges.length - 1];
|
|
32
27
|
if (last && last[1] + 1 === nr) {
|
|
33
28
|
last[1] = nr;
|
|
34
|
-
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
35
31
|
ranges.push([nr, nr]);
|
|
36
32
|
}
|
|
37
33
|
});
|
|
38
34
|
return ranges.map(range => (range[0] === range[1] ? String(range[0]) : range[0] + ':' + range[1])).join(',');
|
|
39
35
|
}
|
|
40
|
-
|
|
41
36
|
/**
|
|
42
37
|
* Parses the argument of the PARTIAL search return option (RFC 5267 section 4.4, RFC 9394 section 4):
|
|
43
38
|
* partial-range-first = nz-number ":" nz-number, partial-range-last = "-" nz-number ":" "-" nz-number.
|
|
@@ -60,7 +55,6 @@ function parsePartialRange(item, allowLast) {
|
|
|
60
55
|
}
|
|
61
56
|
return { range: value, from: Math.min(first, last), to: Math.max(first, last), fromEnd: !!match[1] };
|
|
62
57
|
}
|
|
63
|
-
|
|
64
58
|
/**
|
|
65
59
|
* Picks the results that a PARTIAL range refers to. The first result is 1, and -1 is the last one
|
|
66
60
|
* (RFC 9394 section 3.1). Results outside the list are left out
|
|
@@ -75,7 +69,6 @@ function selectPartial(list, partial) {
|
|
|
75
69
|
}
|
|
76
70
|
return list.slice(Math.max(list.length - partial.to, 0), Math.max(list.length - partial.from + 1, 0));
|
|
77
71
|
}
|
|
78
|
-
|
|
79
72
|
/**
|
|
80
73
|
* Registers the PARTIAL search return option, shared by the PARTIAL and CONTEXT=SEARCH plugins. The
|
|
81
74
|
* partial-range-last form (-1:-100) is only valid with the PARTIAL capability (RFC 9394 section 4)
|
|
@@ -86,12 +79,11 @@ function registerPartialOption(server) {
|
|
|
86
79
|
if (server.searchReturnOptions.has('PARTIAL')) {
|
|
87
80
|
return;
|
|
88
81
|
}
|
|
89
|
-
server.searchReturnOptions.set('PARTIAL', { data: true, once: true, parse: item => parsePartialRange(item, !!server.partialRangeLast) });
|
|
82
|
+
server.searchReturnOptions.set('PARTIAL', { data: true, once: true, parse: (item) => parsePartialRange(item, !!server.partialRangeLast) });
|
|
90
83
|
// RFC 5267 section 4.4 and RFC 9394 section 3.1: a command MUST NOT contain more than one PARTIAL or ALL
|
|
91
84
|
server.searchReturnOptions.set('ALL', Object.assign({}, server.searchReturnOptions.get('ALL'), { once: true }));
|
|
92
|
-
server.searchReturnChecks.push(options => options.has('PARTIAL') && options.has('ALL') && 'PARTIAL and ALL can not be used together');
|
|
85
|
+
server.searchReturnChecks.push((options) => options.has('PARTIAL') && options.has('ALL') && 'PARTIAL and ALL can not be used together');
|
|
93
86
|
}
|
|
94
|
-
|
|
95
87
|
/**
|
|
96
88
|
* Picks the messages that the requested result options return. With COUNT or ALL, or without
|
|
97
89
|
* MIN, MAX and PARTIAL, these are all matching messages, otherwise the lowest and/or the highest
|
|
@@ -117,7 +109,6 @@ function selectReturned(list, options) {
|
|
|
117
109
|
}
|
|
118
110
|
return list.filter(message => returned.has(message));
|
|
119
111
|
}
|
|
120
|
-
|
|
121
112
|
/**
|
|
122
113
|
* Builds the search correlator (RFC 4466 section 2.6.2), with the MAILBOX and UIDVALIDITY
|
|
123
114
|
* correlators of RFC 7377 section 4 if a mailbox is given
|
|
@@ -132,24 +123,19 @@ function buildCorrelator(tag, mailbox) {
|
|
|
132
123
|
{ type: 'STRING', value: tag }
|
|
133
124
|
];
|
|
134
125
|
if (mailbox) {
|
|
135
|
-
correlator.push(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
{ type: 'MAILBOX', value: mailbox.path },
|
|
139
|
-
{ type: 'ATOM', value: 'UIDVALIDITY' },
|
|
140
|
-
mailbox.uidvalidity
|
|
141
|
-
);
|
|
126
|
+
correlator.push({ type: 'ATOM', value: 'MAILBOX' },
|
|
127
|
+
// send() puts in the form of the name that the session uses
|
|
128
|
+
{ type: 'MAILBOX', value: mailbox.path }, { type: 'ATOM', value: 'UIDVALIDITY' }, mailbox.uidvalidity);
|
|
142
129
|
}
|
|
143
130
|
return correlator;
|
|
144
131
|
}
|
|
145
|
-
|
|
146
132
|
/**
|
|
147
133
|
* Builds an ESEARCH response (RFC 4466 section 2.6.2) with the RFC 4731 section 3.1 return data
|
|
148
134
|
* and PARTIAL (RFC 5267 section 4.4, RFC 9394 section 3.1)
|
|
149
135
|
*
|
|
150
136
|
* @param {String} tag Tag of the command, for the search correlator
|
|
151
137
|
* @param {Boolean} isUid If true, the response lists UIDs and has the UID indicator
|
|
152
|
-
* @param {Object} result Search result, `{ list, numbers }` (see
|
|
138
|
+
* @param {Object} result Search result, `{ list, numbers }` (see src/commands/handlers/search.ts)
|
|
153
139
|
* @param {Map} options Upper case result option names to their arguments, an empty map stands for ALL (RFC 4731 section 3.1)
|
|
154
140
|
* @param {Object} [mailbox] Adds the MAILBOX and UIDVALIDITY correlators of RFC 7377 for this mailbox
|
|
155
141
|
* @param {Array} [sorted] The matching messages in sort order, for an extended SORT (RFC 5267 section 3.1): MIN and MAX are
|
|
@@ -157,17 +143,15 @@ function buildCorrelator(tag, mailbox) {
|
|
|
157
143
|
* @return {Object} response for connection.send()
|
|
158
144
|
*/
|
|
159
145
|
function buildEsearchResponse(tag, isUid, result, options, mailbox, sorted) {
|
|
160
|
-
const values = (sorted || result.list).map(message => (isUid ? message.uid : result.numbers[message.uid]));
|
|
146
|
+
const values = (sorted || result.list).map((message) => (isUid ? message.uid : result.numbers[message.uid]));
|
|
161
147
|
if (!sorted) {
|
|
162
148
|
values.sort((a, b) => a - b);
|
|
163
149
|
}
|
|
164
150
|
const toSet = sorted ? toOrderedSet : toSequenceSet;
|
|
165
|
-
|
|
166
151
|
const attributes = [buildCorrelator(tag, mailbox)];
|
|
167
152
|
if (isUid) {
|
|
168
153
|
attributes.push({ type: 'ATOM', value: 'UID' });
|
|
169
154
|
}
|
|
170
|
-
|
|
171
155
|
const add = (name, value) => attributes.push({ type: 'ATOM', value: name }, value);
|
|
172
156
|
// MIN, MAX and ALL are left out when nothing matched, COUNT is always included (RFC 4731 section 3.1)
|
|
173
157
|
if (values.length && options.has('MIN')) {
|
|
@@ -188,21 +172,10 @@ function buildEsearchResponse(tag, isUid, result, options, mailbox, sorted) {
|
|
|
188
172
|
if (options.has('COUNT')) {
|
|
189
173
|
add('COUNT', values.length);
|
|
190
174
|
}
|
|
191
|
-
|
|
192
175
|
return {
|
|
193
176
|
tag: '*',
|
|
194
177
|
command: 'ESEARCH',
|
|
195
178
|
attributes
|
|
196
179
|
};
|
|
197
180
|
}
|
|
198
|
-
|
|
199
|
-
module.exports = {
|
|
200
|
-
toSequenceSet,
|
|
201
|
-
toOrderedSet,
|
|
202
|
-
selectReturned,
|
|
203
|
-
selectPartial,
|
|
204
|
-
parsePartialRange,
|
|
205
|
-
registerPartialOption,
|
|
206
|
-
buildCorrelator,
|
|
207
|
-
buildEsearchResponse
|
|
208
|
-
};
|
|
181
|
+
export { toSequenceSet, toOrderedSet, selectReturned, selectPartial, parsePartialRange, registerPartialOption, buildCorrelator, buildEsearchResponse };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMAP framing helpers shared by the mock client, the test helpers and the compare tool.
|
|
3
|
+
* Both functions take a Buffer or a binary string (one character per octet).
|
|
4
|
+
*/
|
|
5
|
+
/** A line of a response: `end` excludes the CR before the LF, `lf` is the offset of the LF */
|
|
6
|
+
export interface FrameLine {
|
|
7
|
+
start: number;
|
|
8
|
+
end: number;
|
|
9
|
+
lf: number;
|
|
10
|
+
}
|
|
11
|
+
/** The data of a literal in a response */
|
|
12
|
+
export interface FrameLiteral {
|
|
13
|
+
start: number;
|
|
14
|
+
end: number;
|
|
15
|
+
literal8: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** A complete response, its lines and the literals between them */
|
|
18
|
+
export interface FramedResponse {
|
|
19
|
+
start: number;
|
|
20
|
+
end: number;
|
|
21
|
+
lines: FrameLine[];
|
|
22
|
+
literals: FrameLiteral[];
|
|
23
|
+
}
|
|
24
|
+
/** An unfinished response at the end of the data, see splitResponses() */
|
|
25
|
+
export interface FrameIncomplete {
|
|
26
|
+
reason: 'line' | 'literal' | 'response';
|
|
27
|
+
lines: FrameLine[];
|
|
28
|
+
/** size of the literal that is cut short */
|
|
29
|
+
size?: number;
|
|
30
|
+
/** octets of that literal that were received */
|
|
31
|
+
available?: number;
|
|
32
|
+
}
|
|
33
|
+
/** Result of splitResponses() */
|
|
34
|
+
export interface SplitResponses {
|
|
35
|
+
responses: FramedResponse[];
|
|
36
|
+
end: number;
|
|
37
|
+
incomplete: FrameIncomplete | false;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Splits received server data into responses. A response is one line, or a line that ends with a
|
|
41
|
+
* literal marker `{n}` or `~{n}` (RFC 3516 literal8), followed by n octets and the rest of the
|
|
42
|
+
* response. Lenient: lines end at LF, a CR before it is not required. Callers that need strict
|
|
43
|
+
* framing check the line ends themselves.
|
|
44
|
+
*
|
|
45
|
+
* @param {Buffer|String} data Received data, possibly ending with an incomplete response
|
|
46
|
+
* @return {Object} `{ responses, end, incomplete }`. Every response is `{ start, end, lines, literals }`,
|
|
47
|
+
* where `lines` lists `{ start, end, lf }` (end excludes the CR before the LF, `lf` is the
|
|
48
|
+
* offset of the LF) and `literals` lists `{ start, end, literal8 }`. `end` is the offset right
|
|
49
|
+
* after the last complete response. `incomplete` is false when all data was used, otherwise
|
|
50
|
+
* `{ reason, lines }` with the complete lines of the unfinished response, where reason is
|
|
51
|
+
* 'line' for a line without LF, 'literal' for literal data that is cut short (with `size`
|
|
52
|
+
* and `available`), or 'response' when the data ends right after literal data.
|
|
53
|
+
*/
|
|
54
|
+
declare function splitResponses(data: Buffer | string): SplitResponses;
|
|
55
|
+
/**
|
|
56
|
+
* Splits an outgoing command after every synchronizing literal marker, as a client must wait for the
|
|
57
|
+
* continuation request before it sends the literal data (RFC 3501 section 4.3). The data of every
|
|
58
|
+
* literal, synchronizing or not ({n+}, RFC 7888), is skipped, so markers inside it are not matched.
|
|
59
|
+
*
|
|
60
|
+
* @param {Buffer|String} payload Command, as a Buffer or a binary string
|
|
61
|
+
* @return {Array} Chunks to send, of the same type as the payload
|
|
62
|
+
*/
|
|
63
|
+
declare function splitAtLiterals(payload: Buffer): Buffer[];
|
|
64
|
+
declare function splitAtLiterals(payload: string): string[];
|
|
65
|
+
declare function splitAtLiterals(payload: Buffer | string): (Buffer | string)[];
|
|
66
|
+
export { splitResponses, splitAtLiterals };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMAP framing helpers shared by the mock client, the test helpers and the compare tool.
|
|
3
|
+
* Both functions take a Buffer or a binary string (one character per octet).
|
|
4
|
+
*/
|
|
5
|
+
const LF = 0x0a;
|
|
6
|
+
const CR = 0x0d;
|
|
7
|
+
/**
|
|
8
|
+
* Splits received server data into responses. A response is one line, or a line that ends with a
|
|
9
|
+
* literal marker `{n}` or `~{n}` (RFC 3516 literal8), followed by n octets and the rest of the
|
|
10
|
+
* response. Lenient: lines end at LF, a CR before it is not required. Callers that need strict
|
|
11
|
+
* framing check the line ends themselves.
|
|
12
|
+
*
|
|
13
|
+
* @param {Buffer|String} data Received data, possibly ending with an incomplete response
|
|
14
|
+
* @return {Object} `{ responses, end, incomplete }`. Every response is `{ start, end, lines, literals }`,
|
|
15
|
+
* where `lines` lists `{ start, end, lf }` (end excludes the CR before the LF, `lf` is the
|
|
16
|
+
* offset of the LF) and `literals` lists `{ start, end, literal8 }`. `end` is the offset right
|
|
17
|
+
* after the last complete response. `incomplete` is false when all data was used, otherwise
|
|
18
|
+
* `{ reason, lines }` with the complete lines of the unfinished response, where reason is
|
|
19
|
+
* 'line' for a line without LF, 'literal' for literal data that is cut short (with `size`
|
|
20
|
+
* and `available`), or 'response' when the data ends right after literal data.
|
|
21
|
+
*/
|
|
22
|
+
function splitResponses(data) {
|
|
23
|
+
const isBuffer = Buffer.isBuffer(data);
|
|
24
|
+
const length = data.length;
|
|
25
|
+
const charAt = isBuffer ? (i) => data[i] : (i) => data.charCodeAt(i);
|
|
26
|
+
const slice = isBuffer
|
|
27
|
+
? (start, end) => data.toString('binary', start, end)
|
|
28
|
+
: (start, end) => data.slice(start, end);
|
|
29
|
+
const responses = [];
|
|
30
|
+
let pos = 0;
|
|
31
|
+
let end = 0;
|
|
32
|
+
let current = null;
|
|
33
|
+
while (pos < length) {
|
|
34
|
+
const lf = isBuffer ? data.indexOf(LF, pos) : data.indexOf('\n', pos);
|
|
35
|
+
if (lf < 0) {
|
|
36
|
+
return { responses, end, incomplete: { reason: 'line', lines: current ? current.lines : [] } };
|
|
37
|
+
}
|
|
38
|
+
const lineStart = pos;
|
|
39
|
+
const lineEnd = lf > pos && charAt(lf - 1) === CR ? lf - 1 : lf;
|
|
40
|
+
if (!current) {
|
|
41
|
+
current = { start: pos, end: 0, lines: [], literals: [] };
|
|
42
|
+
}
|
|
43
|
+
current.lines.push({ start: lineStart, end: lineEnd, lf });
|
|
44
|
+
pos = lf + 1;
|
|
45
|
+
// only lines that end with "}" can carry a literal marker, so most lines are not sliced
|
|
46
|
+
const marker = lineEnd > lineStart && charAt(lineEnd - 1) === 0x7d && slice(Math.max(lineEnd - 32, lineStart), lineEnd).match(/(~?)\{(\d+)\}$/);
|
|
47
|
+
if (marker) {
|
|
48
|
+
const size = Number(marker[2]);
|
|
49
|
+
if (pos + size > length) {
|
|
50
|
+
return { responses, end, incomplete: { reason: 'literal', size, available: length - pos, lines: current.lines } };
|
|
51
|
+
}
|
|
52
|
+
current.literals.push({ start: pos, end: pos + size, literal8: !!marker[1] });
|
|
53
|
+
pos += size;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
current.end = end = pos;
|
|
57
|
+
responses.push(current);
|
|
58
|
+
current = null;
|
|
59
|
+
}
|
|
60
|
+
// the data ended right after a literal, the rest of the response is missing
|
|
61
|
+
return { responses, end, incomplete: current ? { reason: 'response', lines: current.lines } : false };
|
|
62
|
+
}
|
|
63
|
+
function splitAtLiterals(payload) {
|
|
64
|
+
const isBuffer = Buffer.isBuffer(payload);
|
|
65
|
+
const str = isBuffer ? payload.toString('binary') : String(payload);
|
|
66
|
+
const cut = (start, end) => (isBuffer ? payload.subarray(start, end) : str.slice(start, end));
|
|
67
|
+
const chunks = [];
|
|
68
|
+
const re = /~?\{(\d+)(\+?)\}\r\n/g;
|
|
69
|
+
let start = 0;
|
|
70
|
+
let match;
|
|
71
|
+
while ((match = re.exec(str))) {
|
|
72
|
+
const end = match.index + match[0].length;
|
|
73
|
+
if (!match[2]) {
|
|
74
|
+
chunks.push(cut(start, end));
|
|
75
|
+
start = end;
|
|
76
|
+
}
|
|
77
|
+
re.lastIndex = end + Number(match[1]);
|
|
78
|
+
}
|
|
79
|
+
chunks.push(cut(start));
|
|
80
|
+
return chunks.filter(chunk => chunk.length);
|
|
81
|
+
}
|
|
82
|
+
export { splitResponses, splitAtLiterals };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import createServer, { TAG_REGEX, IMAPServer, IMAPConnection } from './server.js';
|
|
2
|
+
export { TAG_REGEX, IMAPServer, IMAPConnection };
|
|
3
|
+
export type { Attribute, ParsedCommand, IMAPResponse, Notification, Callback, CommandHandler, CommandOptions, Plugin, IMAPError, Message, Mailbox, StorageNamespace, UserData, IMAPServerOptions } from './types.js';
|
|
4
|
+
declare const imapkit: typeof createServer & {
|
|
5
|
+
TAG_REGEX: RegExp;
|
|
6
|
+
IMAPServer: typeof IMAPServer;
|
|
7
|
+
IMAPConnection: typeof IMAPConnection;
|
|
8
|
+
};
|
|
9
|
+
export default imapkit;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import createServer, { TAG_REGEX, IMAPServer, IMAPConnection } from './server.js';
|
|
2
|
+
export { TAG_REGEX, IMAPServer, IMAPConnection };
|
|
3
|
+
// `imapkit(options)` creates a server. TAG_REGEX was a property of the CommonJS export, it and the
|
|
4
|
+
// classes are properties of the factory with both module formats
|
|
5
|
+
const imapkit = Object.assign(createServer, { TAG_REGEX, IMAPServer, IMAPConnection });
|
|
6
|
+
export default imapkit;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Attribute, IMAPConnection, IMAPServer, Mailbox, ParsedCommand } from './types.js';
|
|
2
|
+
/** An extended LIST selection option, see getListExtensions() */
|
|
3
|
+
export interface ListSelectionOption {
|
|
4
|
+
type: 'base' | 'independent' | 'modifier';
|
|
5
|
+
returnOption?: string;
|
|
6
|
+
includeNonExistent?: boolean;
|
|
7
|
+
match?: (folder: Mailbox, connection: IMAPConnection) => boolean;
|
|
8
|
+
}
|
|
9
|
+
/** What onItem() of a return option learns about a listed mailbox */
|
|
10
|
+
export interface ListItemInfo {
|
|
11
|
+
/** the mailbox matched the selection criteria */
|
|
12
|
+
matched: boolean;
|
|
13
|
+
/** the mailbox is not \NonExistent */
|
|
14
|
+
exists: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** An extended LIST return option, see getListExtensions() */
|
|
17
|
+
export interface ListReturnOption {
|
|
18
|
+
parse?: (list: Attribute, connection: IMAPConnection) => any;
|
|
19
|
+
onItem?: (connection: IMAPConnection, folder: Mailbox, value: any, info: ListItemInfo, parsed: ParsedCommand, data: string) => void;
|
|
20
|
+
}
|
|
21
|
+
/** The registry of extended LIST options */
|
|
22
|
+
export interface ListExtensions {
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
selectionOptions: Record<string, ListSelectionOption>;
|
|
25
|
+
returnOptions: Record<string, ListReturnOption>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns the registry of extended LIST options (RFC 5258 section 3), shared by the LIST-EXTENDED
|
|
29
|
+
* plugin and the plugins that add their own options (SPECIAL-USE, LIST-STATUS). These can be loaded
|
|
30
|
+
* in any order, so whichever comes first creates the registry. Options are only accepted when the
|
|
31
|
+
* LIST-EXTENDED plugin is loaded (`enabled`).
|
|
32
|
+
*
|
|
33
|
+
* Selection options: `{ type, returnOption, includeNonExistent, match(folder, connection) }`
|
|
34
|
+
* - `type` is "base", "independent" or "modifier" (list-select-base-opt, list-select-independent-opt
|
|
35
|
+
* and list-select-mod-opt in the RFC 5258 section 6 grammar)
|
|
36
|
+
* - `returnOption` is the return option the selection option implies
|
|
37
|
+
* - `match` is the filter the mailboxes must pass, `includeNonExistent` if it can select mailbox
|
|
38
|
+
* names that do not exist (like SUBSCRIBED)
|
|
39
|
+
*
|
|
40
|
+
* Return options: `{ parse(list, connection), onItem(connection, folder, value, info, parsed, data) }`
|
|
41
|
+
* - `parse` is set for options that take a value (option-value), it returns the parsed value or
|
|
42
|
+
* throws an Error with a message for the BAD response
|
|
43
|
+
* - `onItem` runs after the LIST response of every listed mailbox. `info.matched` is true if the
|
|
44
|
+
* mailbox matched the selection criteria, `info.exists` if it is not \NonExistent
|
|
45
|
+
*
|
|
46
|
+
* @param {Object} server IMAPServer instance
|
|
47
|
+
* @return {Object} `{ enabled, selectionOptions, returnOptions }`
|
|
48
|
+
*/
|
|
49
|
+
declare function getListExtensions(server: IMAPServer): ListExtensions;
|
|
50
|
+
export { getListExtensions };
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Returns the registry of extended LIST options (RFC 5258 section 3), shared by the LIST-EXTENDED
|
|
5
3
|
* plugin and the plugins that add their own options (SPECIAL-USE, LIST-STATUS). These can be loaded
|
|
@@ -32,5 +30,4 @@ function getListExtensions(server) {
|
|
|
32
30
|
}
|
|
33
31
|
return server.listExtensions;
|
|
34
32
|
}
|
|
35
|
-
|
|
36
|
-
module.exports = { getListExtensions };
|
|
33
|
+
export { getListExtensions };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IMAPServer, Plugin } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Lists the names of the built-in plugins (file names without extension)
|
|
4
|
+
*
|
|
5
|
+
* @return {Array} plugin names
|
|
6
|
+
*/
|
|
7
|
+
declare function listPlugins(): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Loads plugins for a server instance. Built-in plugins are referenced by name,
|
|
10
|
+
* custom plugins are functions. Unknown names throw, repeated plugins are loaded only once.
|
|
11
|
+
* A plugin that needs another plugin lists its name in `plugin.requires`, the required
|
|
12
|
+
* plugin is then loaded first. Once every plugin is loaded, the server emits `pluginsLoaded`: a plugin
|
|
13
|
+
* that has to wrap what other plugins set up (commands, output handlers), whatever the load order,
|
|
14
|
+
* does that in a `server.once('pluginsLoaded', ...)` listener. Listeners run in plugin load order.
|
|
15
|
+
*
|
|
16
|
+
* @param {Object} server IMAPServer instance
|
|
17
|
+
* @param {Array|String|Function} plugins List of plugins to load
|
|
18
|
+
*/
|
|
19
|
+
declare function loadPlugins(server: IMAPServer, plugins: (string | Plugin)[] | string | Plugin | null | undefined): void;
|
|
20
|
+
export default loadPlugins;
|
|
21
|
+
export { listPlugins };
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
const PLUGINS_DIR = path.join(__dirname, 'plugins');
|
|
7
|
-
|
|
1
|
+
import { plugins as builtinPlugins } from './plugins/index.js';
|
|
8
2
|
// Capability spellings that do not match a plugin file name
|
|
9
3
|
const ALIASES = {
|
|
10
4
|
'literal+': 'literalplus',
|
|
@@ -21,34 +15,14 @@ const ALIASES = {
|
|
|
21
15
|
'context=search': 'context-search',
|
|
22
16
|
'context=sort': 'context-sort'
|
|
23
17
|
};
|
|
24
|
-
|
|
25
|
-
let available = null;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Lists the modules of a directory (file names without the .js extension)
|
|
29
|
-
*
|
|
30
|
-
* @param {String} dir Directory path
|
|
31
|
-
* @return {Array} module names
|
|
32
|
-
*/
|
|
33
|
-
function listModules(dir) {
|
|
34
|
-
return fs
|
|
35
|
-
.readdirSync(dir)
|
|
36
|
-
.filter(fileName => /\.js$/.test(fileName))
|
|
37
|
-
.map(fileName => fileName.replace(/\.js$/, ''));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
18
|
/**
|
|
41
19
|
* Lists the names of the built-in plugins (file names without extension)
|
|
42
20
|
*
|
|
43
21
|
* @return {Array} plugin names
|
|
44
22
|
*/
|
|
45
23
|
function listPlugins() {
|
|
46
|
-
|
|
47
|
-
available = listModules(PLUGINS_DIR);
|
|
48
|
-
}
|
|
49
|
-
return available;
|
|
24
|
+
return Object.keys(builtinPlugins);
|
|
50
25
|
}
|
|
51
|
-
|
|
52
26
|
/**
|
|
53
27
|
* Resolves a plugin name, as given in options.plugins, to a built-in plugin
|
|
54
28
|
*
|
|
@@ -57,12 +31,11 @@ function listPlugins() {
|
|
|
57
31
|
*/
|
|
58
32
|
function resolvePlugin(name) {
|
|
59
33
|
let key = String(name).trim().toLowerCase();
|
|
60
|
-
if (Object.
|
|
34
|
+
if (Object.hasOwn(ALIASES, key)) {
|
|
61
35
|
key = ALIASES[key];
|
|
62
36
|
}
|
|
63
|
-
return
|
|
37
|
+
return Object.hasOwn(builtinPlugins, key) ? key : false;
|
|
64
38
|
}
|
|
65
|
-
|
|
66
39
|
/**
|
|
67
40
|
* Loads plugins for a server instance. Built-in plugins are referenced by name,
|
|
68
41
|
* custom plugins are functions. Unknown names throw, repeated plugins are loaded only once.
|
|
@@ -76,34 +49,27 @@ function resolvePlugin(name) {
|
|
|
76
49
|
*/
|
|
77
50
|
function loadPlugins(server, plugins) {
|
|
78
51
|
const loaded = new Set();
|
|
79
|
-
|
|
80
|
-
|
|
52
|
+
const load = (entry) => {
|
|
53
|
+
let plugin = entry;
|
|
81
54
|
if (typeof plugin === 'string') {
|
|
82
55
|
const name = resolvePlugin(plugin);
|
|
83
56
|
if (!name) {
|
|
84
57
|
throw new Error('Unknown plugin "' + plugin + '". Available plugins: ' + listPlugins().join(', '));
|
|
85
58
|
}
|
|
86
|
-
plugin =
|
|
59
|
+
plugin = builtinPlugins[name];
|
|
87
60
|
}
|
|
88
|
-
|
|
89
61
|
if (typeof plugin !== 'function') {
|
|
90
62
|
throw new TypeError('Invalid plugin, expecting a plugin name or a function');
|
|
91
63
|
}
|
|
92
|
-
|
|
93
64
|
if (loaded.has(plugin)) {
|
|
94
65
|
return;
|
|
95
66
|
}
|
|
96
67
|
loaded.add(plugin);
|
|
97
|
-
|
|
98
68
|
[].concat(plugin.requires || []).forEach(load);
|
|
99
|
-
|
|
100
69
|
plugin(server);
|
|
101
70
|
};
|
|
102
|
-
|
|
103
71
|
[].concat(plugins || []).forEach(load);
|
|
104
|
-
|
|
105
72
|
server.emit('pluginsLoaded');
|
|
106
73
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
module.exports.listModules = listModules;
|
|
74
|
+
export default loadPlugins;
|
|
75
|
+
export { listPlugins };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks a mailbox name against the modified UTF-7 rules of RFC 3501 section 5.1.3:
|
|
3
|
+
* printable US-ASCII represents itself, "&" is written as "&-", everything else
|
|
4
|
+
* is encoded in modified BASE64 between "&" and "-", without superfluous shifts
|
|
5
|
+
* and without encoding printable US-ASCII.
|
|
6
|
+
*
|
|
7
|
+
* @param {String} name Mailbox name as a binary string
|
|
8
|
+
* @return {String|Boolean} Description of the problem, or false if the name is valid
|
|
9
|
+
*/
|
|
10
|
+
declare function validateMailboxName(name: unknown): string | false;
|
|
11
|
+
/**
|
|
12
|
+
* Encodes a mailbox name in modified UTF-7 (RFC 3501 section 5.1.3)
|
|
13
|
+
*
|
|
14
|
+
* @param {String} name Mailbox name as a unicode string
|
|
15
|
+
* @return {String} Modified UTF-7 name
|
|
16
|
+
*/
|
|
17
|
+
declare function encodeMailboxName(name: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Decodes a modified UTF-7 mailbox name (RFC 3501 section 5.1.3)
|
|
20
|
+
*
|
|
21
|
+
* @param {String} name Mailbox name as a binary string
|
|
22
|
+
* @return {String|Boolean} Mailbox name as a unicode string, or false if the name is not valid modified UTF-7
|
|
23
|
+
*/
|
|
24
|
+
declare function decodeMailboxName(name: string): string | false;
|
|
25
|
+
export default validateMailboxName;
|
|
26
|
+
export { encodeMailboxName as encode, decodeMailboxName as decode, encodeMailboxName };
|