@dawnlit/outlook-bridge 1.0.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/LICENSE +190 -0
- package/README.md +253 -0
- package/dist/OutlookService.d.ts +43 -0
- package/dist/OutlookService.js +137 -0
- package/dist/OutlookService.js.map +1 -0
- package/dist/errors.d.ts +112 -0
- package/dist/errors.js +140 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/mac/accounts.d.ts +5 -0
- package/dist/mac/accounts.js +17 -0
- package/dist/mac/accounts.js.map +1 -0
- package/dist/mac/attachments.d.ts +28 -0
- package/dist/mac/attachments.js +120 -0
- package/dist/mac/attachments.js.map +1 -0
- package/dist/mac/bounces.d.ts +32 -0
- package/dist/mac/bounces.js +285 -0
- package/dist/mac/bounces.js.map +1 -0
- package/dist/mac/cleanup.d.ts +29 -0
- package/dist/mac/cleanup.js +219 -0
- package/dist/mac/cleanup.js.map +1 -0
- package/dist/mac/drafts.d.ts +27 -0
- package/dist/mac/drafts.js +214 -0
- package/dist/mac/drafts.js.map +1 -0
- package/dist/mac/folders.d.ts +28 -0
- package/dist/mac/folders.js +127 -0
- package/dist/mac/folders.js.map +1 -0
- package/dist/mac/index.d.ts +22 -0
- package/dist/mac/index.js +119 -0
- package/dist/mac/index.js.map +1 -0
- package/dist/mac/read.d.ts +46 -0
- package/dist/mac/read.js +406 -0
- package/dist/mac/read.js.map +1 -0
- package/dist/mac/run.d.ts +64 -0
- package/dist/mac/run.js +250 -0
- package/dist/mac/run.js.map +1 -0
- package/dist/mac/scripts.d.ts +137 -0
- package/dist/mac/scripts.js +337 -0
- package/dist/mac/scripts.js.map +1 -0
- package/dist/mac/send.d.ts +23 -0
- package/dist/mac/send.js +135 -0
- package/dist/mac/send.js.map +1 -0
- package/dist/mac/signatures.d.ts +4 -0
- package/dist/mac/signatures.js +36 -0
- package/dist/mac/signatures.js.map +1 -0
- package/dist/mac/templates.d.ts +34 -0
- package/dist/mac/templates.js +266 -0
- package/dist/mac/templates.js.map +1 -0
- package/dist/mail.d.ts +72 -0
- package/dist/mail.js +131 -0
- package/dist/mail.js.map +1 -0
- package/dist/outlookTemplateSections.d.ts +62 -0
- package/dist/outlookTemplateSections.js +313 -0
- package/dist/outlookTemplateSections.js.map +1 -0
- package/dist/runtime.d.ts +76 -0
- package/dist/runtime.js +123 -0
- package/dist/runtime.js.map +1 -0
- package/dist/shared/attachmentMatch.d.ts +32 -0
- package/dist/shared/attachmentMatch.js +50 -0
- package/dist/shared/attachmentMatch.js.map +1 -0
- package/dist/shared/bounceRules.d.ts +33 -0
- package/dist/shared/bounceRules.js +104 -0
- package/dist/shared/bounceRules.js.map +1 -0
- package/dist/shared/capabilities.d.ts +3 -0
- package/dist/shared/capabilities.js +9 -0
- package/dist/shared/capabilities.js.map +1 -0
- package/dist/shared/json.d.ts +11 -0
- package/dist/shared/json.js +45 -0
- package/dist/shared/json.js.map +1 -0
- package/dist/shared/replyBody.d.ts +49 -0
- package/dist/shared/replyBody.js +113 -0
- package/dist/shared/replyBody.js.map +1 -0
- package/dist/types.d.ts +365 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/dist/windows/accounts.d.ts +2 -0
- package/dist/windows/accounts.js +22 -0
- package/dist/windows/accounts.js.map +1 -0
- package/dist/windows/attachments.d.ts +28 -0
- package/dist/windows/attachments.js +141 -0
- package/dist/windows/attachments.js.map +1 -0
- package/dist/windows/bounces.d.ts +34 -0
- package/dist/windows/bounces.js +267 -0
- package/dist/windows/bounces.js.map +1 -0
- package/dist/windows/cleanup.d.ts +29 -0
- package/dist/windows/cleanup.js +165 -0
- package/dist/windows/cleanup.js.map +1 -0
- package/dist/windows/drafts.d.ts +29 -0
- package/dist/windows/drafts.js +253 -0
- package/dist/windows/drafts.js.map +1 -0
- package/dist/windows/folders.d.ts +16 -0
- package/dist/windows/folders.js +88 -0
- package/dist/windows/folders.js.map +1 -0
- package/dist/windows/index.d.ts +27 -0
- package/dist/windows/index.js +100 -0
- package/dist/windows/index.js.map +1 -0
- package/dist/windows/read.d.ts +54 -0
- package/dist/windows/read.js +372 -0
- package/dist/windows/read.js.map +1 -0
- package/dist/windows/run.d.ts +54 -0
- package/dist/windows/run.js +161 -0
- package/dist/windows/run.js.map +1 -0
- package/dist/windows/scripts.d.ts +56 -0
- package/dist/windows/scripts.js +163 -0
- package/dist/windows/scripts.js.map +1 -0
- package/dist/windows/send.d.ts +11 -0
- package/dist/windows/send.js +114 -0
- package/dist/windows/send.js.map +1 -0
- package/dist/windows/signatures.d.ts +14 -0
- package/dist/windows/signatures.js +69 -0
- package/dist/windows/signatures.js.map +1 -0
- package/dist/windows/templates.d.ts +25 -0
- package/dist/windows/templates.js +246 -0
- package/dist/windows/templates.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LIST_ACCOUNTS_SNIPPET = exports.FIND_FOLDER_HANDLER = exports.MessageDetail = exports.MAC_ROOT_TERMS = void 0;
|
|
4
|
+
exports.accountLookupSnippet = accountLookupSnippet;
|
|
5
|
+
exports.dateProperty = dateProperty;
|
|
6
|
+
exports.macFolderPath = macFolderPath;
|
|
7
|
+
exports.rootTerm = rootTerm;
|
|
8
|
+
exports.mailScopeSnippet = mailScopeSnippet;
|
|
9
|
+
exports.macMessageId = macMessageId;
|
|
10
|
+
exports.partitionMessageIds = partitionMessageIds;
|
|
11
|
+
exports.messageLookupSnippet = messageLookupSnippet;
|
|
12
|
+
exports.senderSnippet = senderSnippet;
|
|
13
|
+
exports.messageDetailSnippet = messageDetailSnippet;
|
|
14
|
+
exports.messageDetailFields = messageDetailFields;
|
|
15
|
+
exports.firstRecipientSnippet = firstRecipientSnippet;
|
|
16
|
+
exports.allRecipientsSnippet = allRecipientsSnippet;
|
|
17
|
+
// The AppleScript fragments more than one macOS operation is built from.
|
|
18
|
+
const run_1 = require("./run");
|
|
19
|
+
const errors_1 = require("../errors");
|
|
20
|
+
const mail_1 = require("../mail");
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the account whose SMTP address matches, or raise. Emitted into a
|
|
23
|
+
* `tell application "Microsoft Outlook"` block; binds `targetAcct`.
|
|
24
|
+
*
|
|
25
|
+
* `every account` errors even in legacy mode, so probe the typed classes. A
|
|
26
|
+
* `whose email address is ...` filter can't be used either: `email address` is
|
|
27
|
+
* also a class name, and AppleScript resolves it as one ("into type specifier").
|
|
28
|
+
*
|
|
29
|
+
* The thrown sentence is the one `classifyRunFailure` recognises to raise
|
|
30
|
+
* `AccountNotFoundError`, so its wording is load-bearing.
|
|
31
|
+
*/
|
|
32
|
+
function accountLookupSnippet(emailAccount) {
|
|
33
|
+
return ` set targetAcct to missing value
|
|
34
|
+
try
|
|
35
|
+
repeat with a in (exchange accounts & imap accounts & pop accounts)
|
|
36
|
+
if (email address of a as string) is "${(0, run_1.asEscape)(emailAccount)}" then
|
|
37
|
+
set targetAcct to a
|
|
38
|
+
exit repeat
|
|
39
|
+
end if
|
|
40
|
+
end repeat
|
|
41
|
+
end try
|
|
42
|
+
if targetAcct is missing value then error "Account '${(0, run_1.asEscape)(emailAccount)}' not found"`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Outlook for Mac's dictionary term for each well-known root, keyed by the
|
|
46
|
+
* olDefaultFolders id `mailFolderRef` resolves.
|
|
47
|
+
*
|
|
48
|
+
* Verified against the running app. The terms are NOT the ones the Windows ids
|
|
49
|
+
* suggest — `sent mail` and `junk email` do not compile at all, while
|
|
50
|
+
* `sent items` and `junk mail` do, and a bad term fails the whole script at
|
|
51
|
+
* compile time rather than at the offending line.
|
|
52
|
+
*/
|
|
53
|
+
exports.MAC_ROOT_TERMS = {
|
|
54
|
+
6: 'inbox',
|
|
55
|
+
5: 'sent items',
|
|
56
|
+
16: 'drafts',
|
|
57
|
+
3: 'deleted items',
|
|
58
|
+
4: 'outbox',
|
|
59
|
+
23: 'junk mail',
|
|
60
|
+
};
|
|
61
|
+
/** The date property a folder's items actually carry. */
|
|
62
|
+
function dateProperty(rootId) {
|
|
63
|
+
return (0, mail_1.isOutgoingRoot)(rootId) ? 'time sent' : 'time received';
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The Windows `FolderPath` shape (`\\mailbox\Inbox\Invoices`), built here rather
|
|
67
|
+
* than in AppleScript — escaping backslashes through a template literal and then
|
|
68
|
+
* an AppleScript literal is unreadable, and TS already knows the parts.
|
|
69
|
+
*/
|
|
70
|
+
function macFolderPath(emailAccount, rootLabel, segments) {
|
|
71
|
+
return ['\\\\' + emailAccount, rootLabel, ...segments].join('\\');
|
|
72
|
+
}
|
|
73
|
+
/** The dictionary term for a root, or a NOT_IMPLEMENTED naming what was asked. */
|
|
74
|
+
function rootTerm(ref, folderLabel = '') {
|
|
75
|
+
const term = exports.MAC_ROOT_TERMS[ref.rootId];
|
|
76
|
+
if (!term) {
|
|
77
|
+
const asked = folderLabel ? ` (asked for '${folderLabel}')` : '';
|
|
78
|
+
throw new errors_1.NotImplementedError(`folder root '${ref.rootLabel}'${asked}`, `macOS — readable roots are ${Object.values(exports.MAC_ROOT_TERMS).join(', ')}`);
|
|
79
|
+
}
|
|
80
|
+
return term;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Emit the AppleScript that resolves `scopeFolder` from `targetAcct`, walking a
|
|
84
|
+
* well-known root down through any further path segments. Also binds
|
|
85
|
+
* `scopeCreated`.
|
|
86
|
+
*
|
|
87
|
+
* Folder names are compared with `is`, which is case-insensitive in AppleScript —
|
|
88
|
+
* matching the Windows walk's `-ieq` so 'invoices' finds 'Invoices' on both.
|
|
89
|
+
* A missing segment errors by name instead of falling back to the root: silently
|
|
90
|
+
* returning the Inbox for a caller that scoped to one folder hands back the wrong
|
|
91
|
+
* emails under a name that says otherwise. `createMissing` builds the whole
|
|
92
|
+
* chain instead, so a nested destination is one call.
|
|
93
|
+
*/
|
|
94
|
+
function mailScopeSnippet(ref, folderLabel = '', createMissing = false) {
|
|
95
|
+
const term = rootTerm(ref, folderLabel);
|
|
96
|
+
const walk = ref.segments.map(seg => `
|
|
97
|
+
set foundFolder to missing value
|
|
98
|
+
repeat with sf in (mail folders of scopeFolder)
|
|
99
|
+
if (name of sf as string) is "${(0, run_1.asEscape)(seg)}" then
|
|
100
|
+
set foundFolder to sf
|
|
101
|
+
exit repeat
|
|
102
|
+
end if
|
|
103
|
+
end repeat
|
|
104
|
+
if foundFolder is missing value then
|
|
105
|
+
if ${(0, run_1.asBool)(createMissing)} then
|
|
106
|
+
set foundFolder to (make new mail folder at scopeFolder with properties {name:"${(0, run_1.asEscape)(seg)}"})
|
|
107
|
+
set scopeCreated to true
|
|
108
|
+
else
|
|
109
|
+
error "Folder '${(0, run_1.asEscape)(seg)}' not found under '${(0, run_1.asEscape)(ref.rootLabel)}'"
|
|
110
|
+
end if
|
|
111
|
+
end if
|
|
112
|
+
set scopeFolder to foundFolder`).join('');
|
|
113
|
+
return ` set scopeCreated to false
|
|
114
|
+
set scopeFolder to ${term} of targetAcct${walk}`;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The message-id text for a script, or an InvalidRequestError.
|
|
118
|
+
*
|
|
119
|
+
* Outlook for Mac ids are small integers; a Windows MAPI EntryID is rejected up
|
|
120
|
+
* front rather than left to fail as a confusing "not found", because a caller
|
|
121
|
+
* that persisted one from a Windows run needs to be told exactly that.
|
|
122
|
+
*/
|
|
123
|
+
function macMessageId(entryId) {
|
|
124
|
+
const id = String(entryId ?? '').trim();
|
|
125
|
+
if (!/^\d+$/.test(id)) {
|
|
126
|
+
throw new errors_1.InvalidRequestError(`'${entryId}' is not an Outlook for Mac message id. Mac ids are small integers `
|
|
127
|
+
+ `(e.g. "1263") returned by readInboxEmails on this machine; a Windows MAPI `
|
|
128
|
+
+ `EntryID cannot be resolved here.`);
|
|
129
|
+
}
|
|
130
|
+
return id;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Split ids into the ones a script can look up and the ones that can only fail.
|
|
134
|
+
*
|
|
135
|
+
* The per-id operations report failures rather than throwing, so an unusable id
|
|
136
|
+
* belongs in the result's `failed` list beside a genuine lookup miss — not as an
|
|
137
|
+
* exception that discards the ids that would have worked.
|
|
138
|
+
*/
|
|
139
|
+
function partitionMessageIds(entryIds) {
|
|
140
|
+
const valid = [];
|
|
141
|
+
const invalid = [];
|
|
142
|
+
for (const entryId of entryIds) {
|
|
143
|
+
try {
|
|
144
|
+
valid.push(macMessageId(entryId));
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
invalid.push({ entryId: String(entryId), error: error.message });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return { valid, invalid };
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Resolve `theMsg` from a macOS message id, or raise.
|
|
154
|
+
*
|
|
155
|
+
* `message id N` resolves against the application rather than one folder, so the
|
|
156
|
+
* message is found wherever it currently sits — including a subfolder.
|
|
157
|
+
*/
|
|
158
|
+
function messageLookupSnippet(id, variable = 'theMsg') {
|
|
159
|
+
return ` set ${variable} to missing value
|
|
160
|
+
try
|
|
161
|
+
set ${variable} to message id ${id}
|
|
162
|
+
end try
|
|
163
|
+
if ${variable} is missing value then error "Email not found for message id '${id}'"`;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The sender's display name and address, as `sndName` / `sndAddr`.
|
|
167
|
+
*
|
|
168
|
+
* `sender` yields a record, and `address of sender of m` fails to coerce, so the
|
|
169
|
+
* record has to be bound first. `name` is absent when there is no display name.
|
|
170
|
+
*/
|
|
171
|
+
function senderSnippet(messageVariable = 'theMsg', indent = ' ') {
|
|
172
|
+
return `${indent}set sndName to ""
|
|
173
|
+
${indent}set sndAddr to ""
|
|
174
|
+
${indent}try
|
|
175
|
+
${indent} set snd to sender of ${messageVariable}
|
|
176
|
+
${indent} try
|
|
177
|
+
${indent} set sndAddr to (address of snd) as string
|
|
178
|
+
${indent} end try
|
|
179
|
+
${indent} try
|
|
180
|
+
${indent} set sndName to (name of snd) as string
|
|
181
|
+
${indent} end try
|
|
182
|
+
${indent}end try`;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Everything a reader wants off ONE message already bound to `theMsg`, and the
|
|
186
|
+
* row it produces — emitted together so the read order and the positions the
|
|
187
|
+
* TypeScript decoders index into cannot drift apart.
|
|
188
|
+
*
|
|
189
|
+
* Three callers share it (`readEmailBody`, `readSelectedEmail`, and the
|
|
190
|
+
* attachment resolver) and differ only in how they bind `theMsg`. They used to
|
|
191
|
+
* share it by copy: thirty lines repeated, with the `time received` → `time sent`
|
|
192
|
+
* fallback and the field order restated each time, so a dictionary fix reached
|
|
193
|
+
* one reader and not the others.
|
|
194
|
+
*
|
|
195
|
+
* `bodyText` is emitted LAST when asked for, so a stray separator in an earlier
|
|
196
|
+
* field cannot shift it.
|
|
197
|
+
*/
|
|
198
|
+
function messageDetailSnippet(withBody = false, indent = ' ') {
|
|
199
|
+
return `${indent}set subj to ""
|
|
200
|
+
${indent}try
|
|
201
|
+
${indent} set subj to (subject of theMsg) as string
|
|
202
|
+
${indent}end try
|
|
203
|
+
${senderSnippet('theMsg', indent)}
|
|
204
|
+
${indent}set recvd to ""
|
|
205
|
+
${indent}try
|
|
206
|
+
${indent} set recvd to my isoDate(time received of theMsg)
|
|
207
|
+
${indent}on error
|
|
208
|
+
${indent} try
|
|
209
|
+
${indent} set recvd to my isoDate(time sent of theMsg)
|
|
210
|
+
${indent} end try
|
|
211
|
+
${indent}end try
|
|
212
|
+
${indent}set attNames to {}
|
|
213
|
+
${indent}try
|
|
214
|
+
${indent} set attNames to name of every attachment of theMsg
|
|
215
|
+
${indent}end try` + (withBody ? `
|
|
216
|
+
${indent}set bodyText to ""
|
|
217
|
+
${indent}try
|
|
218
|
+
${indent} set bodyText to (plain text content of theMsg) as string
|
|
219
|
+
${indent}end try` : '');
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* The fields `messageDetailSnippet` fills, in row order. The decoders read them
|
|
223
|
+
* back by the positions in `MessageDetail`.
|
|
224
|
+
*/
|
|
225
|
+
function messageDetailFields(withBody = false) {
|
|
226
|
+
const fields = [
|
|
227
|
+
'(id of theMsg as string)',
|
|
228
|
+
'subj',
|
|
229
|
+
'sndName',
|
|
230
|
+
'sndAddr',
|
|
231
|
+
'recvd',
|
|
232
|
+
'my sanitizeList(attNames)',
|
|
233
|
+
];
|
|
234
|
+
if (withBody)
|
|
235
|
+
fields.push('bodyText');
|
|
236
|
+
return fields;
|
|
237
|
+
}
|
|
238
|
+
/** Where each of those fields lands in the emitted row. */
|
|
239
|
+
exports.MessageDetail = {
|
|
240
|
+
id: 0,
|
|
241
|
+
subject: 1,
|
|
242
|
+
senderName: 2,
|
|
243
|
+
senderEmail: 3,
|
|
244
|
+
receivedTime: 4,
|
|
245
|
+
attachmentNames: 5,
|
|
246
|
+
body: 6,
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* The first recipient's name and address, as `sndName` / `sndAddr` — what
|
|
250
|
+
* outgoing mail reports in place of a sender, matching the Windows reader's
|
|
251
|
+
* contract for Sent Items (a folder of mail from yourself is unreadable).
|
|
252
|
+
*/
|
|
253
|
+
function firstRecipientSnippet(messageVariable = 'theMsg', indent = ' ') {
|
|
254
|
+
return `${indent}set sndName to ""
|
|
255
|
+
${indent}set sndAddr to ""
|
|
256
|
+
${indent}try
|
|
257
|
+
${indent} set rcps to to recipients of ${messageVariable}
|
|
258
|
+
${indent} if (count of rcps) > 0 then
|
|
259
|
+
${indent} set ea to email address of (item 1 of rcps)
|
|
260
|
+
${indent} try
|
|
261
|
+
${indent} set sndAddr to (address of ea) as string
|
|
262
|
+
${indent} end try
|
|
263
|
+
${indent} try
|
|
264
|
+
${indent} set sndName to (name of ea) as string
|
|
265
|
+
${indent} end try
|
|
266
|
+
${indent} end if
|
|
267
|
+
${indent}end try`;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Every SMTP address a message was addressed to, as the list `addrList`.
|
|
271
|
+
*
|
|
272
|
+
* `every recipient` covers To, CC and BCC — the full set, which is the whole
|
|
273
|
+
* point of readSentRecipientGroups.
|
|
274
|
+
*/
|
|
275
|
+
function allRecipientsSnippet(messageVariable = 'theMsg', indent = ' ') {
|
|
276
|
+
return `${indent}set addrList to {}
|
|
277
|
+
${indent}try
|
|
278
|
+
${indent} repeat with r in (every recipient of ${messageVariable})
|
|
279
|
+
${indent} try
|
|
280
|
+
${indent} -- The record has to be bound before its field is read: a nested
|
|
281
|
+
${indent} -- 'address of (email address of r)' does not coerce, and fails
|
|
282
|
+
${indent} -- inside the try as an empty recipient list rather than an error.
|
|
283
|
+
${indent} set ea to email address of r
|
|
284
|
+
${indent} set oneAddr to (address of ea) as string
|
|
285
|
+
${indent} if oneAddr is not "" then set end of addrList to oneAddr
|
|
286
|
+
${indent} end try
|
|
287
|
+
${indent} end repeat
|
|
288
|
+
${indent}end try`;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Recursive folder-by-name search from `startFolder`, case-insensitive and
|
|
292
|
+
* depth-capped — the macOS counterpart of the Windows Find-FolderByName, used to
|
|
293
|
+
* resolve a template folder anywhere in the mailbox tree.
|
|
294
|
+
*/
|
|
295
|
+
exports.FIND_FOLDER_HANDLER = `
|
|
296
|
+
on findFolderByName(startFolder, wantedName, depth)
|
|
297
|
+
tell application "Microsoft Outlook"
|
|
298
|
+
set subs to mail folders of startFolder
|
|
299
|
+
end tell
|
|
300
|
+
repeat with f in subs
|
|
301
|
+
if (name of f as string) is wantedName then return f
|
|
302
|
+
end repeat
|
|
303
|
+
if depth is less than or equal to 1 then return missing value
|
|
304
|
+
repeat with f in subs
|
|
305
|
+
set hit to my findFolderByName(f, wantedName, depth - 1)
|
|
306
|
+
if hit is not missing value then return hit
|
|
307
|
+
end repeat
|
|
308
|
+
return missing value
|
|
309
|
+
end findFolderByName
|
|
310
|
+
`;
|
|
311
|
+
/**
|
|
312
|
+
* Account enumeration only works when Outlook runs in legacy mode; New Outlook
|
|
313
|
+
* errors on `every account` and returns empty lists for the typed classes, so
|
|
314
|
+
* each class is probed independently and failures are ignored.
|
|
315
|
+
*/
|
|
316
|
+
exports.LIST_ACCOUNTS_SNIPPET = `
|
|
317
|
+
set acctList to {}
|
|
318
|
+
tell application "Microsoft Outlook"
|
|
319
|
+
repeat with acctClass in {"exchange", "imap", "pop"}
|
|
320
|
+
try
|
|
321
|
+
if (acctClass as string) is "exchange" then
|
|
322
|
+
set accts to exchange accounts
|
|
323
|
+
else if (acctClass as string) is "imap" then
|
|
324
|
+
set accts to imap accounts
|
|
325
|
+
else
|
|
326
|
+
set accts to pop accounts
|
|
327
|
+
end if
|
|
328
|
+
repeat with a in accts
|
|
329
|
+
try
|
|
330
|
+
set end of acctList to (email address of a as string)
|
|
331
|
+
end try
|
|
332
|
+
end repeat
|
|
333
|
+
end try
|
|
334
|
+
end repeat
|
|
335
|
+
end tell
|
|
336
|
+
`;
|
|
337
|
+
//# sourceMappingURL=scripts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scripts.js","sourceRoot":"","sources":["../../src/mac/scripts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ReplyEmailParams, ReplyEmailResult, SendEmailParams } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Create an Outlook email as a draft window (or send it) via AppleScript.
|
|
4
|
+
* Mirrors the Windows COM contract from windows/send.ts.
|
|
5
|
+
*/
|
|
6
|
+
export declare function sendOutlookEmail(params: SendEmailParams): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Reply to an email, inserting the caller's HTML above the quoted original.
|
|
9
|
+
*
|
|
10
|
+
* `entryId` is Outlook for Mac's small integer message id (see readInboxEmails),
|
|
11
|
+
* not a Windows MAPI EntryID; `storeId` is accepted for signature parity and
|
|
12
|
+
* ignored, since macOS has no StoreID and `message id N` resolves against the
|
|
13
|
+
* application rather than one folder.
|
|
14
|
+
*
|
|
15
|
+
* `reply to` builds the quoted body Outlook itself would have — the same thing
|
|
16
|
+
* COM's Reply() returns — so the insertion point is the one place the two
|
|
17
|
+
* platforms have to agree, and both look for WordSection1 then `<body>`.
|
|
18
|
+
*
|
|
19
|
+
* The `to` line is the reply's resolved recipient addresses rather than the
|
|
20
|
+
* display-name string Windows reports: Outlook for Mac exposes recipients as
|
|
21
|
+
* records, and an address is the more useful half to verify against.
|
|
22
|
+
*/
|
|
23
|
+
export declare function replyOutlookEmail(params: ReplyEmailParams): Promise<ReplyEmailResult>;
|
package/dist/mac/send.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendOutlookEmail = sendOutlookEmail;
|
|
4
|
+
exports.replyOutlookEmail = replyOutlookEmail;
|
|
5
|
+
// Composing outgoing mail on macOS: a new email, and a reply to an existing one.
|
|
6
|
+
const run_1 = require("./run");
|
|
7
|
+
const scripts_1 = require("./scripts");
|
|
8
|
+
const replyBody_1 = require("../shared/replyBody");
|
|
9
|
+
const signatures_1 = require("./signatures");
|
|
10
|
+
const templates_1 = require("./templates");
|
|
11
|
+
/** Split a To/CC string the way the Windows contract accepts it. */
|
|
12
|
+
function splitAddresses(s) {
|
|
13
|
+
return s.split(/[,;]+/).map(x => x.trim()).filter(Boolean);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* What to do with a composed item.
|
|
17
|
+
*
|
|
18
|
+
* A new outgoing message lands in Temporary Items, not Drafts — `open` is what
|
|
19
|
+
* surfaces it, so a windowless draft has to be moved into the Drafts folder
|
|
20
|
+
* explicitly. (`save` is no help: it demands a file destination, not a folder.)
|
|
21
|
+
* `move` reports success even where it silently does nothing, so the folder is
|
|
22
|
+
* confirmed to have grown rather than risk reporting a draft that doesn't exist.
|
|
23
|
+
*/
|
|
24
|
+
function composeAction(variable, sendImmediately, openDraftWindow) {
|
|
25
|
+
if (sendImmediately)
|
|
26
|
+
return { prelude: '', action: ` send ${variable}` };
|
|
27
|
+
if (openDraftWindow !== false)
|
|
28
|
+
return { prelude: '', action: ` open ${variable}` };
|
|
29
|
+
return {
|
|
30
|
+
prelude: ` set draftsFolder to drafts of targetAcct
|
|
31
|
+
set draftsBefore to count of messages of draftsFolder`,
|
|
32
|
+
action: ` move ${variable} to draftsFolder
|
|
33
|
+
if (count of messages of draftsFolder) is not greater than draftsBefore then error "Outlook did not file the draft in the Drafts folder."`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create an Outlook email as a draft window (or send it) via AppleScript.
|
|
38
|
+
* Mirrors the Windows COM contract from windows/send.ts.
|
|
39
|
+
*/
|
|
40
|
+
async function sendOutlookEmail(params) {
|
|
41
|
+
// Same safety property as Windows: never silently send from the wrong mailbox.
|
|
42
|
+
// The account lookup raises when the address doesn't resolve, so there's no
|
|
43
|
+
// pre-flight getOutlookAccounts() round-trip — it cost an extra osascript
|
|
44
|
+
// launch on every email in a batch.
|
|
45
|
+
const recipientLines = [
|
|
46
|
+
...splitAddresses(params.to).map(addr => ` make new to recipient at newMsg with properties {email address:{address:"${(0, run_1.asEscape)(addr)}"}}`),
|
|
47
|
+
...splitAddresses(params.cc || '').map(addr => ` make new cc recipient at newMsg with properties {email address:{address:"${(0, run_1.asEscape)(addr)}"}}`),
|
|
48
|
+
].join('\n');
|
|
49
|
+
const attachLine = params.attachmentPath
|
|
50
|
+
? ` make new attachment at newMsg with properties {file:POSIX file "${(0, run_1.asEscape)(params.attachmentPath)}"}`
|
|
51
|
+
: '';
|
|
52
|
+
const { prelude, action } = composeAction('newMsg', params.sendImmediately, params.openDraftWindow);
|
|
53
|
+
const script = `
|
|
54
|
+
tell application "Microsoft Outlook"
|
|
55
|
+
${(0, scripts_1.accountLookupSnippet)(params.emailAccount)}
|
|
56
|
+
${prelude}
|
|
57
|
+
set newMsg to make new outgoing message with properties {subject:"${(0, run_1.asEscape)(params.subject)}", content:"${(0, run_1.asEscape)(params.htmlBody)}"}
|
|
58
|
+
${recipientLines}
|
|
59
|
+
set account of newMsg to targetAcct
|
|
60
|
+
${attachLine}
|
|
61
|
+
${action}
|
|
62
|
+
end tell`;
|
|
63
|
+
await (0, run_1.runOsaScript)(script, 120000);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Reply to an email, inserting the caller's HTML above the quoted original.
|
|
67
|
+
*
|
|
68
|
+
* `entryId` is Outlook for Mac's small integer message id (see readInboxEmails),
|
|
69
|
+
* not a Windows MAPI EntryID; `storeId` is accepted for signature parity and
|
|
70
|
+
* ignored, since macOS has no StoreID and `message id N` resolves against the
|
|
71
|
+
* application rather than one folder.
|
|
72
|
+
*
|
|
73
|
+
* `reply to` builds the quoted body Outlook itself would have — the same thing
|
|
74
|
+
* COM's Reply() returns — so the insertion point is the one place the two
|
|
75
|
+
* platforms have to agree, and both look for WordSection1 then `<body>`.
|
|
76
|
+
*
|
|
77
|
+
* The `to` line is the reply's resolved recipient addresses rather than the
|
|
78
|
+
* display-name string Windows reports: Outlook for Mac exposes recipients as
|
|
79
|
+
* records, and an address is the more useful half to verify against.
|
|
80
|
+
*/
|
|
81
|
+
async function replyOutlookEmail(params) {
|
|
82
|
+
const id = (0, scripts_1.macMessageId)(params.entryId);
|
|
83
|
+
const insertHtml = await (0, replyBody_1.composeReplyHtml)(params, {
|
|
84
|
+
readTemplateEmails: templates_1.readTemplateEmails,
|
|
85
|
+
readOutlookSignatureHtml: signatures_1.readOutlookSignatureHtml,
|
|
86
|
+
listOutlookSignatures: signatures_1.listOutlookSignatures,
|
|
87
|
+
});
|
|
88
|
+
const { prelude, action } = composeAction('theReply', params.sendImmediately, params.openDraftWindow);
|
|
89
|
+
const replyAll = params.replyAll ? 'reply to all true' : 'without reply to all';
|
|
90
|
+
const script = `tell application "Microsoft Outlook"
|
|
91
|
+
${(0, scripts_1.accountLookupSnippet)(params.emailAccount)}
|
|
92
|
+
${(0, scripts_1.messageLookupSnippet)(id)}
|
|
93
|
+
set repliedTo to ""
|
|
94
|
+
try
|
|
95
|
+
-- Bind the record before reading its field: a nested
|
|
96
|
+
-- 'address of (sender of theMsg)' does not coerce.
|
|
97
|
+
set origSender to sender of theMsg
|
|
98
|
+
set repliedTo to (address of origSender) as string
|
|
99
|
+
end try
|
|
100
|
+
${prelude}
|
|
101
|
+
set theReply to reply to theMsg opening window false ${replyAll}
|
|
102
|
+
-- Neither of these is wrapped in a try, and both would read more defensively
|
|
103
|
+
-- if they were. A swallowed account assignment sends from whichever mailbox
|
|
104
|
+
-- Outlook considers default, and a swallowed insertion files a reply with the
|
|
105
|
+
-- caller's text missing — the two failures this package exists to prevent,
|
|
106
|
+
-- both of them invisible to the caller if tolerated here.
|
|
107
|
+
set account of theReply to targetAcct
|
|
108
|
+
set content of theReply to my insertAboveQuoted(content of theReply, "${(0, run_1.asEscape)(insertHtml)}")
|
|
109
|
+
-- Read the outgoing fields BEFORE acting: sending moves the item, after which
|
|
110
|
+
-- the reference is no longer readable.
|
|
111
|
+
set toList to {}
|
|
112
|
+
try
|
|
113
|
+
repeat with r in (every to recipient of theReply)
|
|
114
|
+
try
|
|
115
|
+
set ea to email address of r
|
|
116
|
+
set end of toList to (address of ea) as string
|
|
117
|
+
end try
|
|
118
|
+
end repeat
|
|
119
|
+
end try
|
|
120
|
+
set toLine to my joinList(toList, ", ")
|
|
121
|
+
set subj to ""
|
|
122
|
+
try
|
|
123
|
+
set subj to (subject of theReply) as string
|
|
124
|
+
end try
|
|
125
|
+
${action}
|
|
126
|
+
return my sanitize(toLine) & (character id 31) & my sanitize(subj) & (character id 31) & my sanitize(repliedTo)
|
|
127
|
+
end tell`;
|
|
128
|
+
const parts = (0, run_1.splitFields)(await (0, run_1.runOsaScript)(script, 120000));
|
|
129
|
+
return {
|
|
130
|
+
to: (0, run_1.field)(parts, 0),
|
|
131
|
+
subject: (0, run_1.field)(parts, 1),
|
|
132
|
+
repliedToSender: (0, run_1.field)(parts, 2),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=send.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/mac/send.ts"],"names":[],"mappings":";;AAyCA,4CA4BC;AAkBD,8CAqDC;AA5ID,iFAAiF;AACjF,+BAAmE;AACnE,uCAAqF;AACrF,mDAAuD;AACvD,6CAA+E;AAC/E,2CAAiD;AAGjD,oEAAoE;AACpE,SAAS,cAAc,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,aAAa,CAClB,QAAgB,EAChB,eAAoC,EACpC,eAAoC;IAEpC,IAAI,eAAe;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,QAAQ,EAAE,EAAE,CAAC;IAC5E,IAAI,eAAe,KAAK,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,QAAQ,EAAE,EAAE,CAAC;IACtF,OAAO;QACH,OAAO,EAAE;0DACyC;QAClD,MAAM,EAAE,YAAY,QAAQ;8IAC0G;KACzI,CAAC;AACN,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,gBAAgB,CAAC,MAAuB;IAC1D,+EAA+E;IAC/E,4EAA4E;IAC5E,0EAA0E;IAC1E,oCAAoC;IACpC,MAAM,cAAc,GAAG;QACnB,GAAG,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACpC,gFAAgF,IAAA,cAAQ,EAAC,IAAI,CAAC,KAAK,CAAC;QACxG,GAAG,cAAc,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC1C,gFAAgF,IAAA,cAAQ,EAAC,IAAI,CAAC,KAAK,CAAC;KAC3G,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,UAAU,GAAG,MAAM,CAAC,cAAc;QACpC,CAAC,CAAC,uEAAuE,IAAA,cAAQ,EAAC,MAAM,CAAC,cAAc,CAAC,IAAI;QAC5G,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACpG,MAAM,MAAM,GAAG;;EAEjB,IAAA,8BAAoB,EAAC,MAAM,CAAC,YAAY,CAAC;EACzC,OAAO;wEAC+D,IAAA,cAAQ,EAAC,MAAM,CAAC,OAAO,CAAC,eAAe,IAAA,cAAQ,EAAC,MAAM,CAAC,QAAQ,CAAC;EACtI,cAAc;;EAEd,UAAU;EACV,MAAM;SACC,CAAC;IACN,MAAM,IAAA,kBAAY,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACI,KAAK,UAAU,iBAAiB,CAAC,MAAwB;IAC5D,MAAM,EAAE,GAAG,IAAA,sBAAY,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,MAAM,IAAA,4BAAgB,EAAC,MAAM,EAAE;QAC9C,kBAAkB,EAAlB,8BAAkB;QAClB,wBAAwB,EAAxB,qCAAwB;QACxB,qBAAqB,EAArB,kCAAqB;KACxB,CAAC,CAAC;IACH,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACtG,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,sBAAsB,CAAC;IAChF,MAAM,MAAM,GAAG;EACjB,IAAA,8BAAoB,EAAC,MAAM,CAAC,YAAY,CAAC;EACzC,IAAA,8BAAoB,EAAC,EAAE,CAAC;;;;;;;;EAQxB,OAAO;2DACkD,QAAQ;;;;;;;4EAOS,IAAA,cAAQ,EAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;EAiB9F,MAAM;;SAEC,CAAC;IACN,MAAM,KAAK,GAAG,IAAA,iBAAW,EAAC,MAAM,IAAA,kBAAY,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,OAAO;QACH,EAAE,EAAE,IAAA,WAAK,EAAC,KAAK,EAAE,CAAC,CAAC;QACnB,OAAO,EAAE,IAAA,WAAK,EAAC,KAAK,EAAE,CAAC,CAAC;QACxB,eAAe,EAAE,IAAA,WAAK,EAAC,KAAK,EAAE,CAAC,CAAC;KACnC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Names of the user's Outlook signatures. */
|
|
2
|
+
export declare function listOutlookSignatures(): Promise<string[]>;
|
|
3
|
+
/** Read a named signature's HTML. Returns '' if the signature can't be found. */
|
|
4
|
+
export declare function readOutlookSignatureHtml(name: string): Promise<string>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listOutlookSignatures = listOutlookSignatures;
|
|
4
|
+
exports.readOutlookSignatureHtml = readOutlookSignatureHtml;
|
|
5
|
+
// Unlike Windows (files on disk), Outlook for Mac serves signature content
|
|
6
|
+
// directly through AppleScript, images included (inline data or remote refs).
|
|
7
|
+
const run_1 = require("./run");
|
|
8
|
+
/** Names of the user's Outlook signatures. */
|
|
9
|
+
async function listOutlookSignatures() {
|
|
10
|
+
const script = `
|
|
11
|
+
set sigNames to {}
|
|
12
|
+
tell application "Microsoft Outlook"
|
|
13
|
+
try
|
|
14
|
+
repeat with s in signatures
|
|
15
|
+
set end of sigNames to (name of s as string)
|
|
16
|
+
end repeat
|
|
17
|
+
end try
|
|
18
|
+
end tell
|
|
19
|
+
set AppleScript's text item delimiters to linefeed
|
|
20
|
+
return sigNames as string`;
|
|
21
|
+
const raw = await (0, run_1.runOsaScript)(script, 15000);
|
|
22
|
+
return raw.split('\n').map(s => s.trim()).filter(Boolean).sort((a, b) => a.localeCompare(b));
|
|
23
|
+
}
|
|
24
|
+
/** Read a named signature's HTML. Returns '' if the signature can't be found. */
|
|
25
|
+
async function readOutlookSignatureHtml(name) {
|
|
26
|
+
const script = `
|
|
27
|
+
tell application "Microsoft Outlook"
|
|
28
|
+
try
|
|
29
|
+
return content of (first signature whose name is "${(0, run_1.asEscape)(name)}")
|
|
30
|
+
on error
|
|
31
|
+
return ""
|
|
32
|
+
end try
|
|
33
|
+
end tell`;
|
|
34
|
+
return (0, run_1.runOsaScript)(script, 15000);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=signatures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signatures.js","sourceRoot":"","sources":["../../src/mac/signatures.ts"],"names":[],"mappings":";;AAKA,sDAcC;AAGD,4DAUC;AAhCD,2EAA2E;AAC3E,8EAA8E;AAC9E,+BAA+C;AAE/C,8CAA8C;AACvC,KAAK,UAAU,qBAAqB;IACvC,MAAM,MAAM,GAAG;;;;;;;;;;0BAUO,CAAC;IACvB,MAAM,GAAG,GAAG,MAAM,IAAA,kBAAY,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9C,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AACjG,CAAC;AAED,iFAAiF;AAC1E,KAAK,UAAU,wBAAwB,CAAC,IAAY;IACvD,MAAM,MAAM,GAAG;;;4DAGyC,IAAA,cAAQ,EAAC,IAAI,CAAC;;;;SAIjE,CAAC;IACN,OAAO,IAAA,kBAAY,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { SaveTemplateResult, TemplateFolderResult } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Read the template emails saved in a mailbox folder (default "Templates"),
|
|
4
|
+
* returning each item's full HTML body. When the folder doesn't exist, returns
|
|
5
|
+
* folderFound:false plus the mailbox's folder names instead of throwing, so the
|
|
6
|
+
* caller can ask the user whether to create it rather than fail.
|
|
7
|
+
*
|
|
8
|
+
* Bodies are read in a second pass, for the chosen templates only. That is not
|
|
9
|
+
* a micro-optimisation: a folder of Word-sized templates is megabytes, and
|
|
10
|
+
* pulling all of them through stdout on a call that wanted one is what overruns
|
|
11
|
+
* the buffer — the same reason the Windows reader filters before reading.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readTemplateEmails(emailAccount: string, folderName?: string, limit?: number, includeBody?: boolean, subject?: string): Promise<TemplateFolderResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Save a new template email into a mailbox folder (default "Templates"),
|
|
16
|
+
* creating the folder at the mailbox root if it doesn't exist. The item is a
|
|
17
|
+
* plain unsent mail (subject + HTML body) that can be edited in Outlook.
|
|
18
|
+
* Never overwrites an existing item — it always adds a new one, so check with
|
|
19
|
+
* readTemplateEmails first and only call after the user has agreed to create it.
|
|
20
|
+
*/
|
|
21
|
+
export declare function saveTemplateEmail(emailAccount: string, subject: string, htmlBody: string, folderName?: string): Promise<SaveTemplateResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Open an Outlook compose window pre-filled with `currentHtml`, wait for the
|
|
24
|
+
* user to close it, and return the HTML they saved.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately unbounded: the run lasts as long as the person is editing. Give
|
|
27
|
+
* it an AbortSignal (`bridge.withOptions({ signal })`) if the caller needs a way
|
|
28
|
+
* to give up on them.
|
|
29
|
+
*
|
|
30
|
+
* The macOS half of the round trip differs from Windows in one visible way: an
|
|
31
|
+
* edited draft is filed by answering Outlook's own "save this message?" prompt
|
|
32
|
+
* on close, so the subject tells the user to save rather than to press a key.
|
|
33
|
+
*/
|
|
34
|
+
export declare function editEmailTemplate(label: string, currentHtml: string): Promise<string>;
|