# IMAP
`deft/imap` is an IMAP4rev1 client over the native `net/*` namespace with
a literal-aware incremental parser, plus MIME message decoding. Every
command is an `@async` function to `await`. It is a nested package
inside stdext and mounts as its own top-level package.
import "deft/imap" as imap import "deft/imap/message" as msg
## Client
| Def | Signature | Description |
|---|---|---|
| `connect` | `{| host port opts |}` | Connect (implicit TLS by default, port 993) |
| `logout` / `disconnect` | `{| client |}` | Close the session |
| `capability` / `has-capability?` | `{| client … |}` | Server capabilities |
| `list` / `lsub` | `{| client reference pattern |}` | Mailbox listings |
| `status` | `{| client mailbox items |}` | Mailbox counts as a keyword map |
| `select` / `examine` | `{| client mailbox |}` | Open a mailbox |
| `search` / `uid-search` | `{| client criteria |}` | Search messages |
| `fetch` / `uid-fetch` | `{| client range items opts |}` | Fetch message data |
| `store` / `uid-store` | `{| client range op flags |}` | Update flags |
| `copy` / `move` (+ `uid-`) | `{| client … |}` | Copy/move messages |
| `expunge` | `{| client |}` | Permanently remove deleted messages |
| `append` | `{| client mailbox message opts |}` | Append a message |
| `on-update` | `{| client handler |}` | Receive untagged responses as they arrive |
`connect` options: `:tls` (default `true`), `:starttls`, `:user`,
`:pass`, `:auth` (`:login` / `:plain`), `:timeout`. One command is in
flight per connection; untagged responses during a command are returned
with it and pushed to the `on-update` handler.
def cli [await [imap/connect "imap.example.com" 993 %{ :user "me" :pass "secret" }]] def hits [await [imap/search $cli "UNSEEN"]] def msgs [await [imap/uid-fetch $cli "1:*" @{ "UID" "FLAGS" "BODY.PEEK[HEADER]" }]] set raw [get [nth $msgs~messages 0]~data "body[header]"] [await [imap/logout $cli]]
Fetch data keys are lowercase strings (`"uid"`, `"flags"`, `"envelope"`,
`"body[]"`, `"body[header]"`, `"rfc822.size"`); literals arrive decoded.
## Message Decoding
`deft/imap/message` parses raw messages: folded headers, RFC 2047
encoded words, multipart bodies, base64 / quoted-printable.
set m [msg/parse [get $data "body[]"]] echo [msg/header $m "subject"] echo [msg/text-body $m] for a in [msg/attachments $m] { echo $a~filename $a~content-type }
| Def | Description |
|---|---|
| `parse` | `%{ headers body content-type parts }` (recursive) |
| `header` / `raw-header` | Header access (lowercase keys) |
| `text-body` / `html-body` / `body-of-type` | Body selection |
| `attachments` | `@{ %{ filename content-type data } }` |
| `decode-transfer` / `decode-quoted-printable` | Transfer decoding |
`deft/imap/parser` is the incremental response framer (`drain`,
`make`, token helpers, predicates); it handles `{N}` literals that split
across reads.
## See Also
- SMTP — the sending side; its message builder round-trips with this decoder
- Mail app help — the client built on these
- Network — the `net/*` primitives underneath