apple-mail-mcp 2.19.21 → 2.20.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 +94 -33
- package/build/cli.js +94 -39
- package/build/index.js +336 -90
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,11 +164,11 @@ tool, and troubleshooting. Verify any time by running the **`doctor`** tool.
|
|
|
164
164
|
| **Search Messages** | Search by sender, subject, content, date range, read/flagged status — across all accounts |
|
|
165
165
|
| **Read Messages** | Get full email content (plain text or HTML) |
|
|
166
166
|
| **Read Headers** | Get a message's raw RFC 5322 headers — the author's `Date:`, Message-ID, threading ids, `Received:` trace — without downloading the body |
|
|
167
|
-
| **Send Email** | Compose and send new emails (attach by file path or inline base64 content)
|
|
167
|
+
| **Send Email** | Compose and send new emails (attach by file path or inline base64 content; optional `inReplyTo`/`references` threading over SMTP) |
|
|
168
168
|
| **Send Serial Email** | Mail merge — send personalized emails to a list of recipients with {{placeholder}} support |
|
|
169
|
-
| **Create Draft** | Save emails to Drafts folder (attach by file path or inline base64 content)
|
|
170
|
-
| **Reply** | Reply to messages (with reply-all support)
|
|
171
|
-
| **Forward** | Forward messages to new recipients
|
|
169
|
+
| **Create Draft** | Save emails to Drafts folder (attach by file path or inline base64 content; threaded drafts filed over IMAP) |
|
|
170
|
+
| **Reply** | Reply to messages (with reply-all support and attachments) |
|
|
171
|
+
| **Forward** | Forward messages to new recipients (with extra attachments) |
|
|
172
172
|
| **Get Thread** | Group a conversation by normalized subject (across AppleScript or IMAP) |
|
|
173
173
|
| **Mark Read/Unread** | Change read status (single or batch) |
|
|
174
174
|
| **Flag/Unflag** | Flag or unflag messages (single or batch) |
|
|
@@ -402,16 +402,19 @@ Send a new email immediately.
|
|
|
402
402
|
|
|
403
403
|
**⚠️ Safety:** Sends real mail immediately and cannot be unsent. Confirm the recipients, subject, and body with the user before calling.
|
|
404
404
|
|
|
405
|
-
| Parameter | Type | Required | Description
|
|
406
|
-
| ------------- | --------------------------------------- | -------- |
|
|
407
|
-
| `to` | string[] | Yes | Recipient addresses
|
|
408
|
-
| `subject` | string | Yes | Email subject
|
|
409
|
-
| `body` | string | Yes | Email body (plain text)
|
|
410
|
-
| `cc` | string[] | No | CC recipients
|
|
411
|
-
| `bcc` | string[] | No | BCC recipients
|
|
412
|
-
| `account` | string | No | Mail.app account label, or an email-form SMTP From override. An SMTP override must match `APPLE_MAIL_MCP_SMTP_USER`, `APPLE_MAIL_MCP_SMTP_FROM`, or an address in `APPLE_MAIL_MCP_SMTP_ALLOWED_FROM`
|
|
413
|
-
| `attachments` | (string \| {filename, contentBase64})[] | No | Up to 20 attachments: absolute file paths inside the configured read roots (e.g., `"/Users/me/Documents/report.pdf"`) and/or inline `{filename, contentBase64}` objects up to 25 MiB decoded each
|
|
414
|
-
| `transport` | `"applescript"` \| `"smtp"` | No | Send transport. If omitted, **SMTP is used automatically when configured** (otherwise AppleScript). Pass `"smtp"` to require clean MIME, or `"applescript"` to force the Mail.app path — see [SMTP transport](#smtp-transport)
|
|
405
|
+
| Parameter | Type | Required | Description |
|
|
406
|
+
| ------------- | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
407
|
+
| `to` | string[] | Yes | Recipient addresses |
|
|
408
|
+
| `subject` | string | Yes | Email subject |
|
|
409
|
+
| `body` | string | Yes | Email body (plain text) |
|
|
410
|
+
| `cc` | string[] | No | CC recipients |
|
|
411
|
+
| `bcc` | string[] | No | BCC recipients |
|
|
412
|
+
| `account` | string | No | Mail.app account label, or an email-form SMTP From override. An SMTP override must match `APPLE_MAIL_MCP_SMTP_USER`, `APPLE_MAIL_MCP_SMTP_FROM`, or an address in `APPLE_MAIL_MCP_SMTP_ALLOWED_FROM` |
|
|
413
|
+
| `attachments` | (string \| {filename, contentBase64})[] | No | Up to 20 attachments: absolute file paths inside the configured read roots (e.g., `"/Users/me/Documents/report.pdf"`) and/or inline `{filename, contentBase64}` objects up to 25 MiB decoded each |
|
|
414
|
+
| `transport` | `"applescript"` \| `"smtp"` | No | Send transport. If omitted, **SMTP is used automatically when configured** (otherwise AppleScript). Pass `"smtp"` to require clean MIME, or `"applescript"` to force the Mail.app path — see [SMTP transport](#smtp-transport) |
|
|
415
|
+
| `replyTo` | string | No | SMTP only: `Reply-To` header, when replies should go somewhere other than the From address. Ignored on the AppleScript transport |
|
|
416
|
+
| `inReplyTo` | string | No | SMTP only (2.20.0): thread the message as a reply — the parent's `Message-ID` token with angle brackets, e.g. `"<abc@mail.example.com>"`. Emitted verbatim, never RFC 2047-encoded. See [Threading headers](#threading-headers-inreplyto--references) |
|
|
417
|
+
| `references` | string[] | No | SMTP only (2.20.0): the `References` chain, oldest first (the parent's own `References` + its `Message-ID`). Defaults to `[inReplyTo]` when omitted |
|
|
415
418
|
|
|
416
419
|
**Example:**
|
|
417
420
|
|
|
@@ -425,6 +428,22 @@ Send a new email immediately.
|
|
|
425
428
|
}
|
|
426
429
|
```
|
|
427
430
|
|
|
431
|
+
##### Threading headers (`inReplyTo` / `references`)
|
|
432
|
+
|
|
433
|
+
`send-email` and `create-draft` accept caller-built threading headers (2.20.0, #267) for
|
|
434
|
+
callers that compose the recipients and quoted text themselves. **Prefer
|
|
435
|
+
`reply-to-message`** — it derives recipients, `In-Reply-To`/`References` and the quote
|
|
436
|
+
from the original, and (since 2.20.0) takes attachments too.
|
|
437
|
+
|
|
438
|
+
- Each value must be a single RFC 5322 msg-id token **with** angle brackets
|
|
439
|
+
(`<left@right>`, no whitespace); anything else is rejected by validation.
|
|
440
|
+
- The headers are always emitted as plain `<id>` tokens — never RFC 2047-encoded, even
|
|
441
|
+
for Outlook/Exchange IDs longer than 76 characters (a long header is folded at
|
|
442
|
+
whitespace between tokens, which is legal and does not alter the id).
|
|
443
|
+
- Mail.app's AppleScript cannot set these headers, so they are **never silently
|
|
444
|
+
dropped**: `send-email` refuses them unless the SMTP transport is in use, and
|
|
445
|
+
`create-draft` files a threaded draft over IMAP instead of through Mail.app (below).
|
|
446
|
+
|
|
428
447
|
##### SMTP transport
|
|
429
448
|
|
|
430
449
|
On macOS 15+ (Sequoia/Tahoe), Mail.app wraps any AppleScript-injected body in
|
|
@@ -783,10 +802,24 @@ Save an email to Drafts without sending.
|
|
|
783
802
|
| `body` | string | Yes | Email body (plain text) |
|
|
784
803
|
| `cc` | string[] | No | CC recipients |
|
|
785
804
|
| `bcc` | string[] | No | BCC recipients |
|
|
786
|
-
| `account` | string | No | Account for draft
|
|
805
|
+
| `account` | string | No | Account for draft. With `inReplyTo`/`references` it must name a configured IMAP account (label or login) |
|
|
787
806
|
| `attachments` | (string \| {filename, contentBase64})[] | No | Up to 20 attachments: absolute file paths inside the configured read roots and/or inline `{filename, contentBase64}` objects up to 25 MiB decoded each |
|
|
788
|
-
|
|
789
|
-
|
|
807
|
+
| `inReplyTo` | string | No | (2.20.0) Parent `Message-ID` token, e.g. `"<abc@mail.example.com>"` — makes this a **threaded draft** (see below) |
|
|
808
|
+
| `references` | string[] | No | (2.20.0) `References` chain, oldest first; defaults to `[inReplyTo]` |
|
|
809
|
+
|
|
810
|
+
**Returns:** Confirmation that draft was created, with `transport` (`applescript`, or `imap` for a threaded draft).
|
|
811
|
+
|
|
812
|
+
**Threaded drafts (2.20.0, #267):** Mail.app's `outgoing message` has no header property,
|
|
813
|
+
so a draft with `inReplyTo`/`references` cannot go through AppleScript. Instead the
|
|
814
|
+
server composes it with the same MIME builder as the SMTP send (attachments included) and
|
|
815
|
+
files it over IMAP into the account's Drafts mailbox (SPECIAL-USE `\Drafts`), flagged
|
|
816
|
+
`\Draft`. The account is `account` when given (it must be a configured IMAP account);
|
|
817
|
+
otherwise the IMAP account whose login is the SMTP identity, else the only configured
|
|
818
|
+
IMAP account. When none qualifies — IMAP unconfigured, an unknown `account`, or several
|
|
819
|
+
accounts and no way to choose — the call **fails and files nothing**; it never falls back
|
|
820
|
+
to an unthreaded Mail.app draft. The result names the Drafts `mailbox`, the `account` and
|
|
821
|
+
the draft's `messageId`. Without threading headers, `create-draft` is unchanged
|
|
822
|
+
(AppleScript).
|
|
790
823
|
|
|
791
824
|
#### `get-thread`
|
|
792
825
|
|
|
@@ -832,13 +865,14 @@ Map `imap:` message IDs to their numeric Mail.app IDs, via each message's RFC 53
|
|
|
832
865
|
|
|
833
866
|
Reply to an existing message.
|
|
834
867
|
|
|
835
|
-
| Parameter
|
|
836
|
-
|
|
|
837
|
-
| `id`
|
|
838
|
-
| `body`
|
|
839
|
-
| `replyAll`
|
|
840
|
-
| `send`
|
|
841
|
-
| `transport`
|
|
868
|
+
| Parameter | Type | Required | Description |
|
|
869
|
+
| ------------- | --------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
870
|
+
| `id` | string | Yes | Message ID to reply to |
|
|
871
|
+
| `body` | string | Yes | Reply body (plain text; HTML tags such as `<br>` are not rendered) |
|
|
872
|
+
| `replyAll` | boolean | No | Reply to all recipients (default: false) |
|
|
873
|
+
| `send` | boolean | No | Send immediately (default: true, false = save as draft) |
|
|
874
|
+
| `transport` | string | No | `smtp` or `applescript`; omitted prefers configured SMTP when sending. Drafts use AppleScript. |
|
|
875
|
+
| `attachments` | (string \| {filename, contentBase64})[] | No | Up to 20 attachments, same rules as `send-email`: absolute file paths inside the configured read roots and/or inline `{filename, contentBase64}` objects up to 25 MiB decoded each |
|
|
842
876
|
|
|
843
877
|
**Example - Reply to sender only:**
|
|
844
878
|
|
|
@@ -860,6 +894,30 @@ Reply to an existing message.
|
|
|
860
894
|
}
|
|
861
895
|
```
|
|
862
896
|
|
|
897
|
+
**Example - Reply all with an attachment (2.20.0):**
|
|
898
|
+
|
|
899
|
+
```json
|
|
900
|
+
{
|
|
901
|
+
"id": "imap:eyJhIjoiV29yayIsInAiOiJJTkJPWCIsInUiOjQyfQ",
|
|
902
|
+
"body": "Here is the PDF you asked for.",
|
|
903
|
+
"replyAll": true,
|
|
904
|
+
"attachments": [
|
|
905
|
+
"/Users/me/Documents/quote.pdf",
|
|
906
|
+
{ "filename": "notes.txt", "contentBase64": "SGVsbG8K" }
|
|
907
|
+
]
|
|
908
|
+
}
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
**Attachments (2.20.0, #267):** same schema, limits (20 items, 25 MiB each) and read
|
|
912
|
+
roots as `send-email`, validated before the original is fetched — an out-of-roots path
|
|
913
|
+
fails with exactly `send-email`'s error. Recipients, threading headers and the quote are
|
|
914
|
+
identical to the same call without attachments. Over SMTP the files ride the same
|
|
915
|
+
nodemailer path `send-email` uses, so the Sent-folder copy (`sentCopy`) carries them too.
|
|
916
|
+
On the AppleScript transport they are added with `make new attachment` **after** the
|
|
917
|
+
reply content is set and before `save`/`send` (inline items are written to `0600` temp
|
|
918
|
+
files and removed afterwards), so a `send: false` draft contains both the attachments and
|
|
919
|
+
the quoted original. Results report `attachmentCount`.
|
|
920
|
+
|
|
863
921
|
**Delivery:** `imap:` IDs are read directly from their encoded account, mailbox, and UID. Numeric IDs are read through Mail.app. With SMTP configured, replies use clean MIME with the original `Message-ID` in `In-Reply-To` and the full `References` chain. Only the original plain-text body is quoted; the new text is not. Pass `transport: "smtp"` to require this path, or `transport: "applescript"` to use Mail.app explicitly.
|
|
864
922
|
|
|
865
923
|
**AppleScript transport quoting (v2.19.12):** every draft (`send: false`) and any send that falls back to AppleScript (SMTP not configured) also gets the original quoted — an "On \<date\>, \<sender\> wrote:" attribution line followed by the `> `-prefixed original body, built the same way as the SMTP path. Mail's own `reply`/`forward` AppleScript commands generate this quote internally but expose no way to read it back, so it's built here instead of relying on Mail's (unreadable) copy. Unlike SMTP, this path has no sending-identity restriction — it's read-only source lookup, not sending.
|
|
@@ -868,7 +926,7 @@ Reply to an existing message.
|
|
|
868
926
|
|
|
869
927
|
The direct IMAP source read is bounded to 25 MiB, including MIME attachments. Its account login must match the SMTP login, configured From, or an explicitly configured `APPLE_MAIL_MCP_SMTP_ALLOWED_FROM` identity; otherwise the call fails rather than sending from an unrelated account. The SMTP configuration still represents a single sending identity, not a per-account SMTP registry.
|
|
870
928
|
|
|
871
|
-
Success includes `transport` and, for SMTP when returned by the server, the new `messageId`. SMTP
|
|
929
|
+
Success includes `transport`, `attachmentCount` and, for SMTP when returned by the server, the new `messageId`. Over SMTP a best-effort Sent-folder copy is filed over IMAP exactly as for `send-email` (`sentCopy` / `sentCopyError`, see [SMTP transport](#smtp-transport)). `send-email` is for **new conversations**: adding `Re:` to its subject does not add threading headers. Use this reply tool with the original id instead.
|
|
872
930
|
|
|
873
931
|
**⚠️ Safety:** With the default `send: true`, sends real mail immediately and cannot be unsent. Confirm the recipients, subject, and body with the user before calling (or pass `send: false` to save a draft for review).
|
|
874
932
|
|
|
@@ -878,15 +936,18 @@ Success includes `transport` and, for SMTP when returned by the server, the new
|
|
|
878
936
|
|
|
879
937
|
Forward a message to new recipients.
|
|
880
938
|
|
|
881
|
-
| Parameter
|
|
882
|
-
|
|
|
883
|
-
| `id`
|
|
884
|
-
| `to`
|
|
885
|
-
| `body`
|
|
886
|
-
| `send`
|
|
887
|
-
| `transport`
|
|
939
|
+
| Parameter | Type | Required | Description |
|
|
940
|
+
| ------------- | --------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
941
|
+
| `id` | string | Yes | Message ID to forward |
|
|
942
|
+
| `to` | string[] | Yes | Recipients to forward to |
|
|
943
|
+
| `body` | string | No | Message to prepend (plain text) |
|
|
944
|
+
| `send` | boolean | No | Send immediately (default: true, false = save as draft) |
|
|
945
|
+
| `transport` | string | No | `smtp` or `applescript`; omitted prefers configured SMTP when sending. Drafts use AppleScript. |
|
|
946
|
+
| `attachments` | (string \| {filename, contentBase64})[] | No | Up to 20 additional attachments, same rules as `send-email`: absolute file paths inside the configured read roots and/or inline `{filename, contentBase64}` objects up to 25 MiB decoded each |
|
|
947
|
+
|
|
948
|
+
**Delivery:** uses the same source lookup, transport selection, 25 MiB source limit, account-identity check, and failure behavior as `reply-to-message`. A forward deliberately starts a new conversation, so it has no `In-Reply-To` or `References` headers. The existing plain-text forwarding behavior is unchanged: original attachments are not reattached. See [SMTP transport](#smtp-transport). On the AppleScript transport, a `body` is merged with the forwarded-message header block and original text the same way the SMTP path builds it (see `reply-to-message`'s AppleScript transport quoting note); with no `body`, Mail's own forward content is left untouched — unless `attachments` are given, in which case the forwarded-message block is built the same way so Mail has a paragraph to anchor the new files after.
|
|
888
949
|
|
|
889
|
-
**
|
|
950
|
+
**Attachments (2.20.0, #267):** `attachments` adds new files to the forward, with or without a prepended `body`, under the same rules, validation and per-transport mechanics as `reply-to-message`'s attachments. They are independent of the original's attachments (which the SMTP path still does not reattach).
|
|
890
951
|
|
|
891
952
|
SMTP forwarding requires a readable plain-text original. HTML-only IMAP messages and failed Mail.app body reads return an error before sending instead of silently omitting the original content. Explicitly select `transport: "applescript"` to forward these with Mail.app; no automatic fallback occurs. An intentionally empty plain-text message is still valid.
|
|
892
953
|
|
package/build/cli.js
CHANGED
|
@@ -45149,9 +45149,9 @@ var require_util2 = __commonJS({
|
|
|
45149
45149
|
}
|
|
45150
45150
|
});
|
|
45151
45151
|
|
|
45152
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
45152
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/address-error.js
|
|
45153
45153
|
var require_address_error = __commonJS({
|
|
45154
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
45154
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/address-error.js"(exports) {
|
|
45155
45155
|
"use strict";
|
|
45156
45156
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45157
45157
|
exports.AddressError = void 0;
|
|
@@ -45166,9 +45166,9 @@ var require_address_error = __commonJS({
|
|
|
45166
45166
|
}
|
|
45167
45167
|
});
|
|
45168
45168
|
|
|
45169
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
45169
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/common.js
|
|
45170
45170
|
var require_common = __commonJS({
|
|
45171
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
45171
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/common.js"(exports) {
|
|
45172
45172
|
"use strict";
|
|
45173
45173
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45174
45174
|
exports.isInSubnet = isInSubnet;
|
|
@@ -45189,6 +45189,9 @@ var require_common = __commonJS({
|
|
|
45189
45189
|
return isHostInSubnet.call(this, address);
|
|
45190
45190
|
}
|
|
45191
45191
|
function isHostInSubnet(address) {
|
|
45192
|
+
if (this.binaryZeroPad().length !== address.binaryZeroPad().length) {
|
|
45193
|
+
return false;
|
|
45194
|
+
}
|
|
45192
45195
|
return this.mask(address.subnetMask) === address.mask();
|
|
45193
45196
|
}
|
|
45194
45197
|
function isGloballyReachable(entries) {
|
|
@@ -45266,9 +45269,9 @@ var require_common = __commonJS({
|
|
|
45266
45269
|
}
|
|
45267
45270
|
});
|
|
45268
45271
|
|
|
45269
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
45272
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/v4/constants.js
|
|
45270
45273
|
var require_constants3 = __commonJS({
|
|
45271
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
45274
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/v4/constants.js"(exports) {
|
|
45272
45275
|
"use strict";
|
|
45273
45276
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45274
45277
|
exports.SPECIAL_PURPOSE = exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0;
|
|
@@ -45307,9 +45310,9 @@ var require_constants3 = __commonJS({
|
|
|
45307
45310
|
}
|
|
45308
45311
|
});
|
|
45309
45312
|
|
|
45310
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
45313
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/ipv4.js
|
|
45311
45314
|
var require_ipv4 = __commonJS({
|
|
45312
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
45315
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/ipv4.js"(exports) {
|
|
45313
45316
|
"use strict";
|
|
45314
45317
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
45315
45318
|
if (k2 === void 0) k2 = k;
|
|
@@ -45367,6 +45370,10 @@ var require_ipv4 = __commonJS({
|
|
|
45367
45370
|
}
|
|
45368
45371
|
address = address.replace(constants.RE_SUBNET_STRING, "");
|
|
45369
45372
|
}
|
|
45373
|
+
const longest = constants.GROUPS * 4 - 1;
|
|
45374
|
+
if (address.length > longest) {
|
|
45375
|
+
throw new address_error_1.AddressError(`IPv4 addresses are at most ${longest} characters.`);
|
|
45376
|
+
}
|
|
45370
45377
|
this.addressMinusSuffix = address;
|
|
45371
45378
|
this.parsedAddress = this.parse(address);
|
|
45372
45379
|
}
|
|
@@ -45503,15 +45510,18 @@ var require_ipv4 = __commonJS({
|
|
|
45503
45510
|
return _Address4.fromHex(integer.toString(16).padStart(8, "0"));
|
|
45504
45511
|
}
|
|
45505
45512
|
/**
|
|
45506
|
-
* Return an address from in-addr.arpa form
|
|
45513
|
+
* Return an address from in-addr.arpa form: the four octets reversed, with
|
|
45514
|
+
* or without the `.in-addr.arpa` suffix and root dot, in any case. Throws
|
|
45515
|
+
* `AddressError` unless the reversed labels form a valid IPv4 address, so
|
|
45516
|
+
* `fromArpa(x.reverseForm())` round-trips {@link reverseForm}.
|
|
45507
45517
|
* @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address
|
|
45508
45518
|
* @returns {Adress4}
|
|
45509
45519
|
* @example
|
|
45510
|
-
* var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)
|
|
45520
|
+
* var address = Address4.fromArpa('42.2.0.192.in-addr.arpa.')
|
|
45511
45521
|
* address.correctForm(); // '192.0.2.42'
|
|
45512
45522
|
*/
|
|
45513
45523
|
static fromArpa(arpaFormAddress) {
|
|
45514
|
-
const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)
|
|
45524
|
+
const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.?$/i, "");
|
|
45515
45525
|
const address = leader.split(".").reverse().join(".");
|
|
45516
45526
|
return new _Address4(address);
|
|
45517
45527
|
}
|
|
@@ -45865,9 +45875,9 @@ var require_ipv4 = __commonJS({
|
|
|
45865
45875
|
}
|
|
45866
45876
|
});
|
|
45867
45877
|
|
|
45868
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
45878
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/v6/constants.js
|
|
45869
45879
|
var require_constants4 = __commonJS({
|
|
45870
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
45880
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/v6/constants.js"(exports) {
|
|
45871
45881
|
"use strict";
|
|
45872
45882
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45873
45883
|
exports.SPECIAL_PURPOSE = exports.RE_URL_WITH_PORT = exports.RE_URL = exports.RE_ZONE_STRING = exports.RE_SUBNET_STRING = exports.RE_BAD_ADDRESS = exports.RE_BAD_CHARACTERS = exports.TYPES = exports.SCOPES = exports.GROUPS = exports.BITS = void 0;
|
|
@@ -45955,9 +45965,9 @@ var require_constants4 = __commonJS({
|
|
|
45955
45965
|
}
|
|
45956
45966
|
});
|
|
45957
45967
|
|
|
45958
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
45968
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/v6/helpers.js
|
|
45959
45969
|
var require_helpers = __commonJS({
|
|
45960
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
45970
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/v6/helpers.js"(exports) {
|
|
45961
45971
|
"use strict";
|
|
45962
45972
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45963
45973
|
exports.escapeHtml = escapeHtml;
|
|
@@ -45994,9 +46004,9 @@ var require_helpers = __commonJS({
|
|
|
45994
46004
|
}
|
|
45995
46005
|
});
|
|
45996
46006
|
|
|
45997
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
46007
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/v6/regular-expressions.js
|
|
45998
46008
|
var require_regular_expressions = __commonJS({
|
|
45999
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
46009
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/v6/regular-expressions.js"(exports) {
|
|
46000
46010
|
"use strict";
|
|
46001
46011
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
46002
46012
|
if (k2 === void 0) k2 = k;
|
|
@@ -46086,9 +46096,9 @@ var require_regular_expressions = __commonJS({
|
|
|
46086
46096
|
}
|
|
46087
46097
|
});
|
|
46088
46098
|
|
|
46089
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
46099
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/ipv6.js
|
|
46090
46100
|
var require_ipv6 = __commonJS({
|
|
46091
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
46101
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/ipv6.js"(exports) {
|
|
46092
46102
|
"use strict";
|
|
46093
46103
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
46094
46104
|
if (k2 === void 0) k2 = k;
|
|
@@ -46199,6 +46209,10 @@ var require_ipv6 = __commonJS({
|
|
|
46199
46209
|
this.zone = zone[0];
|
|
46200
46210
|
address = address.replace(constants6.RE_ZONE_STRING, "");
|
|
46201
46211
|
}
|
|
46212
|
+
const longest = this.groups * 5 + 5;
|
|
46213
|
+
if (address.length > longest) {
|
|
46214
|
+
throw new address_error_1.AddressError(`IPv6 addresses are at most ${longest} characters.`);
|
|
46215
|
+
}
|
|
46202
46216
|
this.addressMinusSuffix = address;
|
|
46203
46217
|
this.parsedAddress = this.parse(this.addressMinusSuffix);
|
|
46204
46218
|
}
|
|
@@ -46395,7 +46409,7 @@ var require_ipv6 = __commonJS({
|
|
|
46395
46409
|
* Address6.fromArpa('8.b.d.0.1.0.0.2.ip6.arpa.').networkForm(); // '2001:db8::/32'
|
|
46396
46410
|
*/
|
|
46397
46411
|
static fromArpa(arpaFormAddress) {
|
|
46398
|
-
const nibbles = arpaFormAddress.replace(/(\.ip6\.arpa)
|
|
46412
|
+
const nibbles = arpaFormAddress.replace(/(\.ip6\.arpa)?\.?$/i, "");
|
|
46399
46413
|
if (!/^[0-9a-f](\.[0-9a-f]){0,31}$/i.test(nibbles)) {
|
|
46400
46414
|
throw new address_error_1.AddressError("Invalid 'ip6.arpa' form.");
|
|
46401
46415
|
}
|
|
@@ -47415,9 +47429,9 @@ var require_ipv6 = __commonJS({
|
|
|
47415
47429
|
}
|
|
47416
47430
|
});
|
|
47417
47431
|
|
|
47418
|
-
// node_modules/.pnpm/ip-address@10.7.
|
|
47432
|
+
// node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/ip-address.js
|
|
47419
47433
|
var require_ip_address = __commonJS({
|
|
47420
|
-
"node_modules/.pnpm/ip-address@10.7.
|
|
47434
|
+
"node_modules/.pnpm/ip-address@10.7.2/node_modules/ip-address/dist/ip-address.js"(exports) {
|
|
47421
47435
|
"use strict";
|
|
47422
47436
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
47423
47437
|
if (k2 === void 0) k2 = k;
|
|
@@ -57832,6 +57846,7 @@ __export(imapClient_exports, {
|
|
|
57832
57846
|
decodeImapId: () => decodeImapId,
|
|
57833
57847
|
dropAllPools: () => dropAllPools,
|
|
57834
57848
|
encodeImapId: () => encodeImapId,
|
|
57849
|
+
imapAppendDraft: () => imapAppendDraft,
|
|
57835
57850
|
imapAppendSentCopy: () => imapAppendSentCopy,
|
|
57836
57851
|
imapBatchDelete: () => imapBatchDelete,
|
|
57837
57852
|
imapBatchFlag: () => imapBatchFlag,
|
|
@@ -57869,6 +57884,7 @@ __export(imapClient_exports, {
|
|
|
57869
57884
|
matchMailbox: () => matchMailbox,
|
|
57870
57885
|
normalizeMessageId: () => normalizeMessageId,
|
|
57871
57886
|
omittedNote: () => omittedNote,
|
|
57887
|
+
resolveDraftImapAccount: () => resolveDraftImapAccount,
|
|
57872
57888
|
resolveImapConfig: () => resolveImapConfig,
|
|
57873
57889
|
resolveImapConfigs: () => resolveImapConfigs,
|
|
57874
57890
|
resolveMailboxPath: () => resolveMailboxPath,
|
|
@@ -58926,6 +58942,40 @@ async function imapAppendSentCopy(smtpUser, raw, deps = {}) {
|
|
|
58926
58942
|
return { attempted: true, success: false, error: errText(e) };
|
|
58927
58943
|
}
|
|
58928
58944
|
}
|
|
58945
|
+
function resolveDraftImapAccount(account, smtpUser, env = process.env) {
|
|
58946
|
+
const specs = listImapAccountSpecs(env);
|
|
58947
|
+
const why = "Mail.app's AppleScript cannot set In-Reply-To/References on a draft, so a threaded draft is filed over IMAP into the account's Drafts mailbox";
|
|
58948
|
+
if (specs.length === 0) {
|
|
58949
|
+
throw new Error(
|
|
58950
|
+
`${why}, and IMAP is not configured. Configure IMAP, omit inReplyTo/references, or use reply-to-message with send=false. ${SETUP_HINT}`
|
|
58951
|
+
);
|
|
58952
|
+
}
|
|
58953
|
+
let spec;
|
|
58954
|
+
if (account) {
|
|
58955
|
+
spec = specs.find((s) => specMatchesSelector(s, account));
|
|
58956
|
+
if (!spec) {
|
|
58957
|
+
throw new Error(
|
|
58958
|
+
`${why}, and "${account}" is not a configured IMAP account. Configured: ${specs.map((s) => s.accountLabel).join(", ")}.`
|
|
58959
|
+
);
|
|
58960
|
+
}
|
|
58961
|
+
} else {
|
|
58962
|
+
spec = (smtpUser ? specs.find((s) => specMatchesSelector(s, smtpUser)) : void 0) ?? (specs.length === 1 ? specs[0] : void 0);
|
|
58963
|
+
if (!spec) {
|
|
58964
|
+
throw new Error(
|
|
58965
|
+
`${why}; several IMAP accounts are configured, so pass \`account\` to choose one: ${specs.map((s) => s.accountLabel).join(", ")}.`
|
|
58966
|
+
);
|
|
58967
|
+
}
|
|
58968
|
+
}
|
|
58969
|
+
return { label: spec.accountLabel, user: spec.user };
|
|
58970
|
+
}
|
|
58971
|
+
async function imapAppendDraft(account, raw, deps = {}) {
|
|
58972
|
+
return withClient({ ...deps, account: deps.account ?? account }, async (client, cfg) => {
|
|
58973
|
+
const path3 = await resolveMailboxPath(client, "drafts", "list");
|
|
58974
|
+
const res = await client.append(path3, raw, ["\\Draft", "\\Seen"]);
|
|
58975
|
+
if (!res) throw new Error(`server rejected the APPEND to "${path3}" (IMAP NO/BAD)`);
|
|
58976
|
+
return { mailbox: path3, account: cfg.accountLabel };
|
|
58977
|
+
});
|
|
58978
|
+
}
|
|
58929
58979
|
async function withMailbox(path3, deps, fn) {
|
|
58930
58980
|
return withClient(deps, async (client) => {
|
|
58931
58981
|
const lock = await client.getMailboxLock(path3);
|
|
@@ -59781,6 +59831,27 @@ function buildAttachments(attachments) {
|
|
|
59781
59831
|
return { filename: a.filename, content: decodeInlineAttachment(a.contentBase64) };
|
|
59782
59832
|
});
|
|
59783
59833
|
}
|
|
59834
|
+
function buildMailOptions(opts, from, attachments) {
|
|
59835
|
+
const html = opts.htmlBody?.trim() ? opts.htmlBody : void 0;
|
|
59836
|
+
return {
|
|
59837
|
+
from,
|
|
59838
|
+
to: opts.to,
|
|
59839
|
+
cc: opts.cc,
|
|
59840
|
+
bcc: opts.bcc,
|
|
59841
|
+
subject: opts.subject,
|
|
59842
|
+
text: opts.body,
|
|
59843
|
+
// When present, nodemailer emits multipart/alternative (text + html).
|
|
59844
|
+
html,
|
|
59845
|
+
attachments,
|
|
59846
|
+
// RFC 5322 threading for SMTP replies/forwards (2.5.0). nodemailer treats
|
|
59847
|
+
// In-Reply-To / References as structured msg-id headers and never
|
|
59848
|
+
// RFC 2047-encodes them, however long the id (pinned by a test, #267).
|
|
59849
|
+
inReplyTo: opts.inReplyTo?.trim() || void 0,
|
|
59850
|
+
references: opts.references?.length ? opts.references : void 0,
|
|
59851
|
+
// Reply-To header (2.18.0, issue #220): nodemailer already supports this.
|
|
59852
|
+
replyTo: opts.replyTo?.trim() || void 0
|
|
59853
|
+
};
|
|
59854
|
+
}
|
|
59784
59855
|
async function sendViaSmtp(opts, config, createTransport2 = nodemailer_default.createTransport, appendSentCopy = defaultAppendSentCopy) {
|
|
59785
59856
|
let cfg;
|
|
59786
59857
|
try {
|
|
@@ -59819,23 +59890,7 @@ async function sendViaSmtp(opts, config, createTransport2 = nodemailer_default.c
|
|
|
59819
59890
|
requireTLS,
|
|
59820
59891
|
auth: { user: cfg.user, pass: cfg.pass }
|
|
59821
59892
|
});
|
|
59822
|
-
const
|
|
59823
|
-
const mailOptions = {
|
|
59824
|
-
from: requestedFrom || cfg.from,
|
|
59825
|
-
to: opts.to,
|
|
59826
|
-
cc: opts.cc,
|
|
59827
|
-
bcc: opts.bcc,
|
|
59828
|
-
subject: opts.subject,
|
|
59829
|
-
text: opts.body,
|
|
59830
|
-
// When present, nodemailer emits multipart/alternative (text + html).
|
|
59831
|
-
html,
|
|
59832
|
-
attachments,
|
|
59833
|
-
// RFC 5322 threading for SMTP replies/forwards (2.5.0).
|
|
59834
|
-
inReplyTo: opts.inReplyTo?.trim() || void 0,
|
|
59835
|
-
references: opts.references?.length ? opts.references : void 0,
|
|
59836
|
-
// Reply-To header (2.18.0, issue #220): nodemailer already supports this.
|
|
59837
|
-
replyTo: opts.replyTo?.trim() || void 0
|
|
59838
|
-
};
|
|
59893
|
+
const mailOptions = buildMailOptions(opts, requestedFrom || cfg.from, attachments);
|
|
59839
59894
|
try {
|
|
59840
59895
|
const info = await transporter.sendMail(mailOptions);
|
|
59841
59896
|
let copyFields = {};
|