@dawnlit/outlook-bridge 1.1.1 → 2.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/README.md +150 -183
- package/dist/backend.d.ts +151 -0
- package/dist/backend.js +3 -0
- package/dist/backend.js.map +1 -0
- package/dist/bridge.d.ts +56 -0
- package/dist/bridge.js +507 -0
- package/dist/bridge.js.map +1 -0
- package/dist/errors.d.ts +81 -43
- package/dist/errors.js +98 -52
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +25 -52
- package/dist/index.js.map +1 -1
- package/dist/mac/accounts.d.ts +7 -2
- package/dist/mac/accounts.js +23 -6
- package/dist/mac/accounts.js.map +1 -1
- package/dist/mac/attachments.d.ts +5 -25
- package/dist/mac/attachments.js +40 -99
- package/dist/mac/attachments.js.map +1 -1
- package/dist/mac/bounces.d.ts +12 -27
- package/dist/mac/bounces.js +95 -112
- package/dist/mac/bounces.js.map +1 -1
- package/dist/mac/cleanup.d.ts +11 -25
- package/dist/mac/cleanup.js +50 -76
- package/dist/mac/cleanup.js.map +1 -1
- package/dist/mac/drafts.d.ts +13 -34
- package/dist/mac/drafts.js +95 -169
- package/dist/mac/drafts.js.map +1 -1
- package/dist/mac/folders.d.ts +10 -21
- package/dist/mac/folders.js +33 -47
- package/dist/mac/folders.js.map +1 -1
- package/dist/mac/index.d.ts +2 -22
- package/dist/mac/index.js +19 -81
- package/dist/mac/index.js.map +1 -1
- package/dist/mac/profile.d.ts +13 -0
- package/dist/mac/profile.js +149 -0
- package/dist/mac/profile.js.map +1 -0
- package/dist/mac/read.d.ts +18 -38
- package/dist/mac/read.js +154 -210
- package/dist/mac/read.js.map +1 -1
- package/dist/mac/run.d.ts +35 -39
- package/dist/mac/run.js +97 -102
- package/dist/mac/run.js.map +1 -1
- package/dist/mac/scripts.d.ts +78 -86
- package/dist/mac/scripts.js +125 -115
- package/dist/mac/scripts.js.map +1 -1
- package/dist/mac/send.d.ts +10 -20
- package/dist/mac/send.js +64 -86
- package/dist/mac/send.js.map +1 -1
- package/dist/mac/signatures.d.ts +2 -2
- package/dist/mac/signatures.js +9 -11
- package/dist/mac/signatures.js.map +1 -1
- package/dist/mac/templates.d.ts +14 -26
- package/dist/mac/templates.js +75 -113
- package/dist/mac/templates.js.map +1 -1
- package/dist/mail.d.ts +77 -45
- package/dist/mail.js +166 -73
- package/dist/mail.js.map +1 -1
- package/dist/runtime.d.ts +76 -43
- package/dist/runtime.js +103 -48
- package/dist/runtime.js.map +1 -1
- package/dist/shared/args.d.ts +48 -0
- package/dist/shared/args.js +216 -0
- package/dist/shared/args.js.map +1 -0
- package/dist/shared/attachmentMatch.d.ts +28 -16
- package/dist/shared/attachmentMatch.js +60 -22
- package/dist/shared/attachmentMatch.js.map +1 -1
- package/dist/shared/bounceReport.d.ts +11 -0
- package/dist/shared/bounceReport.js +45 -0
- package/dist/shared/bounceReport.js.map +1 -0
- package/dist/shared/bounceRules.d.ts +38 -10
- package/dist/shared/bounceRules.js +50 -32
- package/dist/shared/bounceRules.js.map +1 -1
- package/dist/shared/exec.d.ts +21 -0
- package/dist/shared/exec.js +47 -0
- package/dist/shared/exec.js.map +1 -0
- package/dist/shared/json.d.ts +12 -6
- package/dist/shared/json.js +29 -23
- package/dist/shared/json.js.map +1 -1
- package/dist/shared/locate.d.ts +39 -0
- package/dist/shared/locate.js +129 -0
- package/dist/shared/locate.js.map +1 -0
- package/dist/shared/replyBody.d.ts +42 -32
- package/dist/shared/replyBody.js +84 -71
- package/dist/shared/replyBody.js.map +1 -1
- package/dist/templateBody.d.ts +63 -0
- package/dist/{outlookTemplateSections.js → templateBody.js} +72 -72
- package/dist/templateBody.js.map +1 -0
- package/dist/types.d.ts +360 -167
- package/dist/types.js +8 -9
- package/dist/types.js.map +1 -1
- package/dist/windows/accounts.d.ts +7 -12
- package/dist/windows/accounts.js +19 -34
- package/dist/windows/accounts.js.map +1 -1
- package/dist/windows/attachments.d.ts +9 -24
- package/dist/windows/attachments.js +94 -119
- package/dist/windows/attachments.js.map +1 -1
- package/dist/windows/bounces.d.ts +13 -26
- package/dist/windows/bounces.js +168 -200
- package/dist/windows/bounces.js.map +1 -1
- package/dist/windows/cleanup.d.ts +19 -23
- package/dist/windows/cleanup.js +92 -111
- package/dist/windows/cleanup.js.map +1 -1
- package/dist/windows/drafts.d.ts +16 -35
- package/dist/windows/drafts.js +167 -253
- package/dist/windows/drafts.js.map +1 -1
- package/dist/windows/folders.d.ts +8 -13
- package/dist/windows/folders.js +44 -52
- package/dist/windows/folders.js.map +1 -1
- package/dist/windows/index.d.ts +2 -27
- package/dist/windows/index.js +11 -66
- package/dist/windows/index.js.map +1 -1
- package/dist/windows/read.d.ts +24 -60
- package/dist/windows/read.js +261 -306
- package/dist/windows/read.js.map +1 -1
- package/dist/windows/run.d.ts +39 -39
- package/dist/windows/run.js +151 -111
- package/dist/windows/run.js.map +1 -1
- package/dist/windows/scripts.d.ts +65 -55
- package/dist/windows/scripts.js +109 -85
- package/dist/windows/scripts.js.map +1 -1
- package/dist/windows/send.d.ts +6 -11
- package/dist/windows/send.js +68 -88
- package/dist/windows/send.js.map +1 -1
- package/dist/windows/signatures.d.ts +4 -10
- package/dist/windows/signatures.js +30 -37
- package/dist/windows/signatures.js.map +1 -1
- package/dist/windows/templates.d.ts +12 -18
- package/dist/windows/templates.js +122 -149
- package/dist/windows/templates.js.map +1 -1
- package/package.json +4 -3
- package/dist/OutlookService.d.ts +0 -43
- package/dist/OutlookService.js +0 -137
- package/dist/OutlookService.js.map +0 -1
- package/dist/outlookTemplateSections.d.ts +0 -62
- package/dist/outlookTemplateSections.js.map +0 -1
- package/dist/shared/capabilities.d.ts +0 -3
- package/dist/shared/capabilities.js +0 -9
- package/dist/shared/capabilities.js.map +0 -1
package/dist/types.d.ts
CHANGED
|
@@ -1,123 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where an email lives, as a listing reported it.
|
|
3
|
+
*
|
|
4
|
+
* Every listing row (`InboxEmail`, `InboxSearchMatch`, `SelectedEmail`, …)
|
|
5
|
+
* carries both fields, so a row can be passed straight back in wherever an
|
|
6
|
+
* `EmailRef` is accepted — which is also the reliable way to keep the two ids
|
|
7
|
+
* from different rows apart.
|
|
8
|
+
*/
|
|
9
|
+
export interface EmailLocator {
|
|
10
|
+
/** Windows: the MAPI EntryID. macOS: Outlook for Mac's integer message id. */
|
|
11
|
+
readonly entryId: string;
|
|
12
|
+
/**
|
|
13
|
+
* Windows: the StoreID the email was listed from, which lets it resolve in
|
|
14
|
+
* any mounted mailbox rather than only the default one. macOS has no
|
|
15
|
+
* equivalent and ignores it.
|
|
16
|
+
*/
|
|
17
|
+
readonly storeId?: string;
|
|
18
|
+
}
|
|
19
|
+
/** An email to act on: its entry id alone, or anything carrying a locator. */
|
|
20
|
+
export type EmailRef = string | EmailLocator;
|
|
21
|
+
/**
|
|
22
|
+
* Recipients: one address, a comma- or semicolon-separated list, or an array.
|
|
23
|
+
* Display-name forms such as `"Doe, Jo" <jo@example.com>` are kept whole.
|
|
24
|
+
*/
|
|
25
|
+
export type Recipients = string | readonly string[];
|
|
1
26
|
export interface SendEmailParams {
|
|
2
|
-
/** SMTP address of the
|
|
3
|
-
* account — an address that doesn't resolve is an error
|
|
27
|
+
/** SMTP address of the mailbox to send from. Never falls back to the
|
|
28
|
+
* default account — an address that doesn't resolve is an error. */
|
|
4
29
|
emailAccount: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
30
|
+
to?: Recipients;
|
|
31
|
+
cc?: Recipients;
|
|
32
|
+
bcc?: Recipients;
|
|
8
33
|
subject: string;
|
|
9
34
|
htmlBody: string;
|
|
10
|
-
|
|
11
|
-
|
|
35
|
+
/** Absolute paths of files to attach. Each has to exist. */
|
|
36
|
+
attachments?: readonly string[];
|
|
37
|
+
/**
|
|
38
|
+
* An Outlook signature, by the name listOutlookSignatures reports, added to
|
|
39
|
+
* the body: in its `{{SIGNATURE}}` placeholder when it has one, otherwise
|
|
40
|
+
* at the end. Outlook adds no signature of its own to a body set this way,
|
|
41
|
+
* so this is how a composed email gets one.
|
|
42
|
+
*/
|
|
43
|
+
signatureName?: string;
|
|
44
|
+
/** Send now. Default false: the email is staged as a draft instead. */
|
|
45
|
+
sendImmediately?: boolean;
|
|
12
46
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Defaults to true, matching the single-email callers that rely on the window.
|
|
47
|
+
* Drafts only. True (the default) opens an Outlook compose window; false
|
|
48
|
+
* files the draft silently into Drafts — the workable choice for batches.
|
|
16
49
|
*/
|
|
17
50
|
openDraftWindow?: boolean;
|
|
18
51
|
}
|
|
19
|
-
export interface ReplyEmailParams {
|
|
52
|
+
export interface ReplyEmailParams extends EmailLocator {
|
|
53
|
+
/** SMTP address of the mailbox to reply from. */
|
|
20
54
|
emailAccount: string;
|
|
21
|
-
entryId: string;
|
|
22
|
-
/** StoreID from the same listing row — disambiguates across mailboxes. */
|
|
23
|
-
storeId?: string;
|
|
24
55
|
/**
|
|
25
|
-
* HTML inserted above the quoted original (a full document is reduced to
|
|
26
|
-
* content). Optional when `templateSubject` is given
|
|
27
|
-
* the saved template server-side, so the caller never has to carry the (often large,
|
|
28
|
-
* Word-generated) template HTML.
|
|
56
|
+
* HTML inserted above the quoted original (a full document is reduced to
|
|
57
|
+
* its <body> content). Optional when `templateSubject` is given.
|
|
29
58
|
*/
|
|
30
59
|
htmlBody?: string;
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
60
|
+
/**
|
|
61
|
+
* Reply with a template email saved in the mailbox, found by subject, so
|
|
62
|
+
* the caller never carries a large template's HTML itself.
|
|
63
|
+
*/
|
|
33
64
|
templateSubject?: string;
|
|
34
|
-
/** Folder holding the template
|
|
65
|
+
/** Folder holding the template. Default 'Templates'. */
|
|
35
66
|
templateFolder?: string;
|
|
36
67
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* all markers are stripped before the reply is built.
|
|
68
|
+
* The [[SECTION]] of the template to keep, when one template holds several
|
|
69
|
+
* reply variants (see composeTemplateBody). Required if it has sections.
|
|
40
70
|
*/
|
|
41
71
|
templateSection?: string;
|
|
42
72
|
/** `{{PLACEHOLDER}}` → HTML substituted into the composed body. */
|
|
43
|
-
templatePlaceholders?: Record<string, string
|
|
73
|
+
templatePlaceholders?: Readonly<Record<string, string>>;
|
|
44
74
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
75
|
+
* An Outlook signature (by the name listOutlookSignatures reports), put in
|
|
76
|
+
* the body's `{{SIGNATURE}}` placeholder, or below the new text when there
|
|
77
|
+
* is none. Resolved here, so the signature's HTML never crosses the
|
|
78
|
+
* caller's boundary.
|
|
48
79
|
*/
|
|
49
80
|
signatureName?: string;
|
|
50
81
|
/**
|
|
51
|
-
* Answer every recipient of the original
|
|
52
|
-
*
|
|
53
|
-
* be taken back, so it has to be asked for.
|
|
82
|
+
* Answer every recipient of the original instead of only its sender.
|
|
83
|
+
* Default false: widening a reply cannot be taken back, so it is opt-in.
|
|
54
84
|
*/
|
|
55
85
|
replyAll?: boolean;
|
|
86
|
+
/** Send now. Default false. */
|
|
56
87
|
sendImmediately?: boolean;
|
|
88
|
+
/** Drafts only: open a compose window (the default) or file silently. */
|
|
57
89
|
openDraftWindow?: boolean;
|
|
58
90
|
}
|
|
59
91
|
export interface ReplyEmailResult {
|
|
92
|
+
/** Who the reply is addressed to. Windows reports Outlook's To line
|
|
93
|
+
* (display names); macOS the resolved addresses. */
|
|
60
94
|
to: string;
|
|
61
95
|
subject: string;
|
|
62
|
-
/** The original email's sender —
|
|
96
|
+
/** The original email's sender — check it is who you meant to answer. */
|
|
63
97
|
repliedToSender: string;
|
|
64
98
|
}
|
|
65
|
-
/** One
|
|
66
|
-
export interface
|
|
99
|
+
/** One item a batch operation could not handle, and why. */
|
|
100
|
+
export interface ItemFailure {
|
|
101
|
+
entryId: string;
|
|
102
|
+
/** The item's subject when it could be read, else ''. */
|
|
67
103
|
subject: string;
|
|
68
104
|
error: string;
|
|
69
105
|
}
|
|
70
|
-
export interface SendAllDraftsResult {
|
|
71
|
-
sent: number;
|
|
72
|
-
failed: DraftSendFailure[];
|
|
73
|
-
}
|
|
74
106
|
/** One mail draft belonging to an account. */
|
|
75
107
|
export interface OutlookDraft {
|
|
76
108
|
entryId: string;
|
|
77
109
|
subject: string;
|
|
78
|
-
/** The To line as Outlook renders it
|
|
110
|
+
/** The To line as Outlook renders it. */
|
|
79
111
|
to: string;
|
|
80
|
-
/** Recipient addresses, best
|
|
112
|
+
/** Recipient addresses, best effort — an unresolved Exchange entry falls back to its name. */
|
|
81
113
|
toEmails: string[];
|
|
82
|
-
/** Short plain-text preview
|
|
114
|
+
/** Short plain-text preview, enough to tell similar drafts apart. */
|
|
83
115
|
bodyPreview: string;
|
|
84
116
|
hasAttachments: boolean;
|
|
85
117
|
lastModified: string;
|
|
86
|
-
/**
|
|
118
|
+
/** The Drafts folder it sits in; one account's drafts can span two. */
|
|
87
119
|
folderPath: string;
|
|
88
120
|
}
|
|
121
|
+
export interface ListDraftsOptions {
|
|
122
|
+
/** Newest-first cap on the drafts returned. Default 100. */
|
|
123
|
+
limit?: number;
|
|
124
|
+
/** Characters of body preview per draft. Default 300; 0 omits it. */
|
|
125
|
+
previewChars?: number;
|
|
126
|
+
}
|
|
89
127
|
export interface ListDraftsResult {
|
|
90
128
|
account: string;
|
|
91
129
|
/** The Drafts folders scanned, in scan order. */
|
|
92
130
|
foldersScanned: string[];
|
|
93
|
-
/**
|
|
131
|
+
/** Matching drafts found, before `limit` was applied. */
|
|
94
132
|
count: number;
|
|
95
133
|
truncated: boolean;
|
|
96
134
|
drafts: OutlookDraft[];
|
|
97
135
|
}
|
|
136
|
+
export interface SendDraftsResult {
|
|
137
|
+
sent: number;
|
|
138
|
+
failed: ItemFailure[];
|
|
139
|
+
}
|
|
98
140
|
export interface DeleteDraftsResult {
|
|
99
141
|
deleted: number;
|
|
100
|
-
failed:
|
|
101
|
-
entryId: string;
|
|
102
|
-
error: string;
|
|
103
|
-
}[];
|
|
104
|
-
}
|
|
105
|
-
/** One draft that couldn't be sent in a selective send, identified by both id and
|
|
106
|
-
* subject — id for the caller to retry or reconcile, subject for a human report. */
|
|
107
|
-
export interface SendDraftsFailure {
|
|
108
|
-
entryId: string;
|
|
109
|
-
subject: string;
|
|
110
|
-
error: string;
|
|
142
|
+
failed: ItemFailure[];
|
|
111
143
|
}
|
|
112
|
-
export interface
|
|
113
|
-
|
|
114
|
-
|
|
144
|
+
export interface DeleteMailOptions {
|
|
145
|
+
/** Lift the refusal to touch Inbox and Sent Items (and their subfolders). */
|
|
146
|
+
allowProtected?: boolean;
|
|
147
|
+
/** Resolve and report every id without deleting anything. */
|
|
148
|
+
dryRun?: boolean;
|
|
115
149
|
}
|
|
116
150
|
/** What happened to one id in a deleteOutlookEmails call. */
|
|
117
151
|
export interface DeleteMailOutcome {
|
|
118
152
|
entryId: string;
|
|
119
153
|
subject: string;
|
|
120
|
-
/** The folder the item was actually in — the audit trail for
|
|
154
|
+
/** The folder the item was actually in — the audit trail for a wrong id. */
|
|
121
155
|
folderPath: string;
|
|
122
156
|
status: 'deleted' | 'would-delete' | 'refused' | 'failed';
|
|
123
157
|
reason: string;
|
|
@@ -129,10 +163,10 @@ export interface DeleteMailResult {
|
|
|
129
163
|
failed: number;
|
|
130
164
|
items: DeleteMailOutcome[];
|
|
131
165
|
}
|
|
132
|
-
export interface
|
|
133
|
-
/**
|
|
134
|
-
|
|
135
|
-
/**
|
|
166
|
+
export interface PurgeDeletedItemsOptions {
|
|
167
|
+
/** Keep items newer than this many days. Default 0: purge everything. */
|
|
168
|
+
olderThanDays?: number;
|
|
169
|
+
/** Count what would be purged without destroying anything. */
|
|
136
170
|
dryRun?: boolean;
|
|
137
171
|
}
|
|
138
172
|
export interface PurgeDeletedItemsResult {
|
|
@@ -145,86 +179,194 @@ export interface PurgeDeletedItemsResult {
|
|
|
145
179
|
kept: number;
|
|
146
180
|
failed: number;
|
|
147
181
|
}
|
|
148
|
-
/** One bounce-back / non-delivery message found in
|
|
182
|
+
/** One bounce-back / non-delivery message found in a mailbox. */
|
|
149
183
|
export interface UndeliverableEmail {
|
|
150
184
|
entryId: string;
|
|
151
185
|
subject: string;
|
|
152
186
|
senderName: string;
|
|
153
187
|
senderEmail: string;
|
|
154
188
|
receivedTime: string;
|
|
155
|
-
/** Which rule flagged it
|
|
189
|
+
/** Which rule flagged it: an NDR message class, a mail-daemon sender, or a bounce subject phrase. */
|
|
156
190
|
matchedReason: string;
|
|
157
|
-
/** Best-effort
|
|
191
|
+
/** Best-effort addresses parsed from the bounce body — the sends that failed. */
|
|
158
192
|
failedRecipients: string[];
|
|
159
193
|
}
|
|
194
|
+
export interface CleanUndeliverableOptions {
|
|
195
|
+
/** How far back to scan. Default 30. */
|
|
196
|
+
daysBack?: number;
|
|
197
|
+
/** Report without deleting. Default TRUE — deleting has to be asked for. */
|
|
198
|
+
dryRun?: boolean;
|
|
199
|
+
}
|
|
160
200
|
export interface CleanUndeliverableResult {
|
|
161
201
|
account: string;
|
|
162
202
|
scannedDays: number;
|
|
163
|
-
/** True when nothing was deleted (preview run). */
|
|
164
203
|
dryRun: boolean;
|
|
165
204
|
matchedCount: number;
|
|
166
205
|
deletedCount: number;
|
|
167
206
|
matched: UndeliverableEmail[];
|
|
168
|
-
/** Matched items that could not be deleted (
|
|
169
|
-
failed:
|
|
207
|
+
/** Matched items that could not be deleted (a delete run only). */
|
|
208
|
+
failed: ItemFailure[];
|
|
209
|
+
}
|
|
210
|
+
export interface CollectBouncedRecipientsOptions {
|
|
211
|
+
/** How far back to scan. Default 30. */
|
|
212
|
+
daysBack?: number;
|
|
213
|
+
/** Scan Deleted Items too, so bounces already cleaned away still count. Default true. */
|
|
214
|
+
includeDeletedItems?: boolean;
|
|
170
215
|
}
|
|
171
|
-
|
|
216
|
+
export interface SentRecipientGroupsOptions {
|
|
217
|
+
/** How far back to read Sent Items. Default 30. */
|
|
218
|
+
daysBack?: number;
|
|
219
|
+
/** Newest-first cap on messages. Default 3000. */
|
|
220
|
+
limit?: number;
|
|
221
|
+
}
|
|
222
|
+
/** One sent message and every SMTP address it went to (To, CC and BCC). */
|
|
172
223
|
export interface SentRecipientGroup {
|
|
173
224
|
entryId: string;
|
|
174
225
|
subject: string;
|
|
175
226
|
sentOn: string;
|
|
176
227
|
recipients: string[];
|
|
177
228
|
}
|
|
178
|
-
export interface
|
|
229
|
+
export interface BounceReportOptions {
|
|
230
|
+
/** How far back to read bounce-backs and Sent Items. Default 30. */
|
|
231
|
+
daysBack?: number;
|
|
232
|
+
/** Count bounces already moved to Deleted Items too. Default true. */
|
|
233
|
+
includeDeletedItems?: boolean;
|
|
234
|
+
}
|
|
235
|
+
/** A sent message that at least one of its recipients bounced back from. */
|
|
236
|
+
export interface BouncedSend {
|
|
237
|
+
entryId: string;
|
|
238
|
+
subject: string;
|
|
239
|
+
sentOn: string;
|
|
240
|
+
/** Every address it went to, lower-cased and deduplicated. */
|
|
241
|
+
recipients: string[];
|
|
242
|
+
/** The recipients a bounce-back reported as failed. */
|
|
243
|
+
failedRecipients: string[];
|
|
244
|
+
/** True when every recipient failed: the message reached nobody. */
|
|
245
|
+
allFailed: boolean;
|
|
246
|
+
}
|
|
247
|
+
export interface BounceReport {
|
|
248
|
+
account: string;
|
|
249
|
+
scannedDays: number;
|
|
250
|
+
/** Every distinct address the bounce-backs reported, lower-cased. */
|
|
251
|
+
bouncedAddresses: string[];
|
|
252
|
+
/** The sent messages with a bounced recipient, newest first. */
|
|
253
|
+
sends: BouncedSend[];
|
|
254
|
+
/**
|
|
255
|
+
* Bounced addresses no sent message in the window went to: an alias the
|
|
256
|
+
* server expanded, or a send older than the window.
|
|
257
|
+
*/
|
|
258
|
+
unmatchedAddresses: string[];
|
|
259
|
+
}
|
|
260
|
+
export interface ReadInboxOptions {
|
|
261
|
+
/**
|
|
262
|
+
* Read this folder instead of the Inbox root: a folder under the Inbox by
|
|
263
|
+
* name or path, a well-known folder ('Sent Items', 'Drafts', …), or a full
|
|
264
|
+
* folder path — see mailFolderRef. Only that folder is read, not its
|
|
265
|
+
* subfolders.
|
|
266
|
+
*/
|
|
267
|
+
folder?: string;
|
|
268
|
+
/** Only mail from the last this-many days. Default 60. */
|
|
269
|
+
daysBack?: number;
|
|
270
|
+
/** Newest-first cap on rows. Default 50. */
|
|
271
|
+
limit?: number;
|
|
272
|
+
/** Characters of plain-text body per row. Default 600; 0 skips reading bodies. */
|
|
273
|
+
previewChars?: number;
|
|
274
|
+
}
|
|
275
|
+
export interface InboxEmail extends EmailLocator {
|
|
179
276
|
entryId: string;
|
|
180
277
|
storeId: string;
|
|
181
278
|
subject: string;
|
|
279
|
+
/** For outgoing folders (Sent Items, Outbox, Drafts) these carry the
|
|
280
|
+
* RECIPIENT, since a folder of mail "from" its own owner says nothing. */
|
|
182
281
|
senderName: string;
|
|
183
282
|
senderEmail: string;
|
|
184
283
|
receivedTime: string;
|
|
185
284
|
bodyPreview: string;
|
|
186
285
|
attachmentNames: string[];
|
|
187
286
|
attachmentCount: number;
|
|
188
|
-
/**
|
|
189
|
-
|
|
190
|
-
* Populated on both platforms. */
|
|
191
|
-
folderPath?: string;
|
|
287
|
+
/** The folder the email was read from. */
|
|
288
|
+
folderPath: string;
|
|
192
289
|
}
|
|
193
290
|
export interface InboxSearchFilter {
|
|
194
|
-
/**
|
|
195
|
-
*
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
*
|
|
291
|
+
/** Only mail from the last this-many days. Default 60 — a scan has no
|
|
292
|
+
* unbounded mode; ask for 365 to reach back a year. */
|
|
293
|
+
daysBack?: number;
|
|
294
|
+
/** Glob-style subject pattern: `*` matches any run, `?` one character,
|
|
295
|
+
* case-insensitive, e.g. '*invoice*'. */
|
|
199
296
|
subjectLike?: string;
|
|
200
|
-
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
|
|
297
|
+
/**
|
|
298
|
+
* Regular expression tested against each subject, case-insensitively
|
|
299
|
+
* whatever the RegExp's own flags. On Windows the pattern runs in .NET's
|
|
300
|
+
* regex engine, so keep to syntax JavaScript and .NET share.
|
|
301
|
+
*/
|
|
205
302
|
subjectPattern?: RegExp;
|
|
206
|
-
/** Drop subjects
|
|
303
|
+
/** Drop subjects carrying a reply or forward prefix (RE:, FW:, AW:, 回复:, …). */
|
|
207
304
|
excludeReplies?: boolean;
|
|
208
|
-
/** Only return
|
|
305
|
+
/** Only return mail with at least one attachment. */
|
|
209
306
|
requireAttachment?: boolean;
|
|
307
|
+
/**
|
|
308
|
+
* Folders under the Inbox to leave out, by full folder path or bare name,
|
|
309
|
+
* case-insensitively. An excluded folder takes its whole subtree with it.
|
|
310
|
+
* Sent, Drafts, Deleted and Junk are always skipped, even where the profile
|
|
311
|
+
* nests them under the Inbox. macOS matches the leaf name only.
|
|
312
|
+
*/
|
|
313
|
+
excludeFolders?: readonly string[];
|
|
314
|
+
/**
|
|
315
|
+
* Scan only these folders, given the same way. Matched exactly: naming a
|
|
316
|
+
* folder does not bring its children, and the Inbox root is included only
|
|
317
|
+
* when named. Exclusion wins where the two overlap.
|
|
318
|
+
*/
|
|
319
|
+
includeFolders?: readonly string[];
|
|
320
|
+
/** Return each match's full plain-text body. Default true; false makes a
|
|
321
|
+
* scan much lighter when only the metadata is needed. */
|
|
322
|
+
includeBody?: boolean;
|
|
210
323
|
}
|
|
211
|
-
export interface InboxSearchMatch {
|
|
324
|
+
export interface InboxSearchMatch extends EmailLocator {
|
|
212
325
|
entryId: string;
|
|
213
|
-
/** Store the item lives in — pass alongside entryId so it resolves unambiguously
|
|
214
|
-
* across mailboxes (replyOutlookEmail, saveEmailAttachments). */
|
|
215
326
|
storeId: string;
|
|
216
327
|
subject: string;
|
|
217
328
|
senderName: string;
|
|
218
|
-
/** SMTP address
|
|
329
|
+
/** SMTP address, resolved from the Exchange DN where the sender is an Exchange user. */
|
|
219
330
|
senderEmail: string;
|
|
220
|
-
/** 'yyyy-MM-dd HH:mm'. */
|
|
221
331
|
receivedTime: string;
|
|
332
|
+
/** The plain-text body; '' when the search asked for no bodies. */
|
|
222
333
|
body: string;
|
|
223
|
-
/** Not saved to disk — pass the ones you want
|
|
334
|
+
/** Not saved to disk — pass the ones you want to saveEmailAttachments. */
|
|
224
335
|
attachmentNames: string[];
|
|
225
336
|
folderPath: string;
|
|
226
337
|
}
|
|
227
|
-
|
|
338
|
+
/**
|
|
339
|
+
* What was kept about an email besides its id, for finding it again once the
|
|
340
|
+
* id no longer resolves: Outlook rewrites an email's id whenever it moves, and
|
|
341
|
+
* an id from one platform means nothing on the other.
|
|
342
|
+
*
|
|
343
|
+
* At least two of `subject`, `sender` and `receivedTime` are needed, since a
|
|
344
|
+
* subject alone names every message in a thread.
|
|
345
|
+
*/
|
|
346
|
+
export interface EmailDescription {
|
|
347
|
+
/** Compared without reply and forward prefixes, spacing or case. */
|
|
348
|
+
subject?: string;
|
|
349
|
+
/**
|
|
350
|
+
* An address, a display name, or both (`Jo Doe <jo@example.com>`). An
|
|
351
|
+
* address is compared as an address; a bare name only against the
|
|
352
|
+
* sender's display name.
|
|
353
|
+
*/
|
|
354
|
+
sender?: string;
|
|
355
|
+
/** `yyyy-MM-dd HH:mm` as a listing reported it, or just the day. */
|
|
356
|
+
receivedTime?: string;
|
|
357
|
+
/** The mailbox to search. Default: every account, the one `folderPath` names first. */
|
|
358
|
+
emailAccount?: string;
|
|
359
|
+
/**
|
|
360
|
+
* The folderPath a listing reported (`\\team@example.com\Inbox\Invoices`).
|
|
361
|
+
* Only decides which mailbox is searched first.
|
|
362
|
+
*/
|
|
363
|
+
folderPath?: string;
|
|
364
|
+
}
|
|
365
|
+
export interface LocateEmailOptions {
|
|
366
|
+
/** How far back to search when the description has no receivedTime. Default 60. */
|
|
367
|
+
daysBack?: number;
|
|
368
|
+
}
|
|
369
|
+
export interface SelectedEmail extends EmailLocator {
|
|
228
370
|
entryId: string;
|
|
229
371
|
storeId: string;
|
|
230
372
|
subject: string;
|
|
@@ -232,9 +374,17 @@ export interface SelectedEmail {
|
|
|
232
374
|
senderEmail: string;
|
|
233
375
|
receivedTime: string;
|
|
234
376
|
body: string;
|
|
235
|
-
/** Not saved to disk — pass the ones you want
|
|
377
|
+
/** Not saved to disk — pass the ones you want to saveEmailAttachments. */
|
|
236
378
|
attachmentNames: string[];
|
|
237
379
|
}
|
|
380
|
+
export interface ReadEmailBodyOptions {
|
|
381
|
+
/** Cap on the returned body. Default 8000. */
|
|
382
|
+
maxChars?: number;
|
|
383
|
+
/** Also return the quoted thread below the reply. Default false. */
|
|
384
|
+
includeQuoted?: boolean;
|
|
385
|
+
/** Cap on the quoted thread when it is returned. Default 4000. */
|
|
386
|
+
maxQuotedChars?: number;
|
|
387
|
+
}
|
|
238
388
|
export interface EmailBodyResult {
|
|
239
389
|
entryId: string;
|
|
240
390
|
subject: string;
|
|
@@ -243,144 +393,187 @@ export interface EmailBodyResult {
|
|
|
243
393
|
receivedTime: string;
|
|
244
394
|
/** The sender's own new text — everything above the quoted thread. */
|
|
245
395
|
body: string;
|
|
246
|
-
/** True when `body`
|
|
396
|
+
/** True when `body` was cut at maxChars. */
|
|
247
397
|
truncated: boolean;
|
|
248
|
-
/** Length of the sender's new text before any
|
|
398
|
+
/** Length of the sender's new text before any cut. */
|
|
249
399
|
bodyLength: number;
|
|
250
|
-
/** What the quoted thread was split on
|
|
400
|
+
/** What the quoted thread was split on; '' when none was found. */
|
|
251
401
|
quoteSeparator: string;
|
|
252
402
|
/** Length of the quoted thread, reported even when it isn't returned. */
|
|
253
403
|
quotedLength: number;
|
|
254
|
-
/** The quoted thread — only
|
|
404
|
+
/** The quoted thread — only when asked for. */
|
|
255
405
|
quotedOriginal: string;
|
|
256
406
|
attachmentNames: string[];
|
|
257
407
|
attachmentCount: number;
|
|
258
408
|
}
|
|
259
409
|
export interface MailFolderRef {
|
|
260
|
-
/** olDefaultFolders id of the root the
|
|
410
|
+
/** olDefaultFolders id of the well-known root the path starts from. */
|
|
261
411
|
rootId: number;
|
|
262
|
-
/** That root
|
|
412
|
+
/** That root as the caller spelled it, for messages. */
|
|
263
413
|
rootLabel: string;
|
|
264
414
|
/** Path segments below the root. */
|
|
265
415
|
segments: string[];
|
|
266
416
|
}
|
|
417
|
+
export interface ListFoldersOptions {
|
|
418
|
+
/** How many levels below the Inbox to list, 1–10. Default 2. */
|
|
419
|
+
maxDepth?: number;
|
|
420
|
+
}
|
|
267
421
|
export interface InboxFolderInfo {
|
|
268
422
|
name: string;
|
|
269
|
-
/** Outlook folder path, e.g.
|
|
423
|
+
/** Outlook folder path, e.g. `\\mailbox\Inbox\Invoices`. */
|
|
270
424
|
folderPath: string;
|
|
271
425
|
itemCount: number;
|
|
272
|
-
/** 1 = direct child of Inbox, 2 = grandchild, … */
|
|
426
|
+
/** 1 = direct child of the Inbox, 2 = grandchild, … */
|
|
273
427
|
depth: number;
|
|
274
428
|
}
|
|
429
|
+
export interface MoveEmailsOptions {
|
|
430
|
+
/** Create the destination — the whole missing chain — when absent. Default false. */
|
|
431
|
+
createIfMissing?: boolean;
|
|
432
|
+
}
|
|
275
433
|
export interface MoveEmailsResult {
|
|
276
434
|
folderPath: string;
|
|
277
435
|
folderCreated: boolean;
|
|
278
436
|
moved: number;
|
|
279
|
-
failed:
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
437
|
+
failed: ItemFailure[];
|
|
438
|
+
}
|
|
439
|
+
export interface SaveAttachmentOptions {
|
|
440
|
+
/**
|
|
441
|
+
* Directory to save into, created if absent. Without one, each call saves
|
|
442
|
+
* into a fresh private directory, so two emails that both carry
|
|
443
|
+
* 'invoice.pdf' can never overwrite each other.
|
|
444
|
+
*/
|
|
445
|
+
destDir?: string;
|
|
283
446
|
}
|
|
284
447
|
export interface SavedAttachment {
|
|
448
|
+
/** Where the file was written. A name already taken in the directory gets
|
|
449
|
+
* a numbered suffix rather than overwriting what is there. */
|
|
285
450
|
path: string;
|
|
451
|
+
/** The attachment's name as the email carries it. */
|
|
452
|
+
fileName: string;
|
|
453
|
+
/** Who the email was from — confirm it is the email you meant. */
|
|
286
454
|
subject: string;
|
|
287
455
|
senderName: string;
|
|
288
456
|
senderEmail: string;
|
|
289
457
|
receivedTime: string;
|
|
290
458
|
}
|
|
459
|
+
export interface ReadTemplatesOptions {
|
|
460
|
+
/** Mailbox folder holding the templates, searched up to 3 levels deep. Default 'Templates'. */
|
|
461
|
+
folder?: string;
|
|
462
|
+
/** Return only the template with this subject (case-insensitive). */
|
|
463
|
+
subject?: string;
|
|
464
|
+
/** Return each full HTML body. Default true; false returns previews. */
|
|
465
|
+
includeBody?: boolean;
|
|
466
|
+
/** Newest-first cap on templates, 1–200. Default 20. */
|
|
467
|
+
limit?: number;
|
|
468
|
+
}
|
|
291
469
|
/** One template email stored in a mailbox folder. */
|
|
292
470
|
export interface TemplateEmail {
|
|
293
471
|
entryId: string;
|
|
294
472
|
subject: string;
|
|
295
|
-
/** Full HTML body
|
|
296
|
-
* listing was requested without bodies (includeBody:false). */
|
|
473
|
+
/** Full HTML body with embedded (cid:) images removed; '' without includeBody. */
|
|
297
474
|
htmlBody: string;
|
|
298
|
-
/** Short plain-text preview
|
|
299
|
-
bodyPreview
|
|
300
|
-
/** [[SECTION]] names
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
/** `{{PLACEHOLDER}}` names the template expects to have filled in. */
|
|
305
|
-
placeholders?: string[];
|
|
475
|
+
/** Short plain-text preview; '' with includeBody. */
|
|
476
|
+
bodyPreview: string;
|
|
477
|
+
/** [[SECTION]] names, returned with or without the body. */
|
|
478
|
+
sections: string[];
|
|
479
|
+
/** `{{PLACEHOLDER}}` names the template expects filled. */
|
|
480
|
+
placeholders: string[];
|
|
306
481
|
lastModified: string;
|
|
307
482
|
}
|
|
308
483
|
export interface TemplateFolderResult {
|
|
309
484
|
folderFound: boolean;
|
|
310
|
-
/**
|
|
485
|
+
/** The folder's path when found. */
|
|
311
486
|
folderPath: string;
|
|
312
487
|
templates: TemplateEmail[];
|
|
313
|
-
/** When the folder wasn't found: the mailbox's folder names
|
|
488
|
+
/** When the folder wasn't found: the mailbox's top-level folder names. */
|
|
314
489
|
availableFolders: string[];
|
|
315
490
|
}
|
|
491
|
+
export interface SaveTemplateParams {
|
|
492
|
+
subject: string;
|
|
493
|
+
htmlBody: string;
|
|
494
|
+
/** Folder to save into, created at the mailbox root if absent. Default 'Templates'. */
|
|
495
|
+
folder?: string;
|
|
496
|
+
}
|
|
316
497
|
export interface SaveTemplateResult {
|
|
317
498
|
folderPath: string;
|
|
318
499
|
folderCreated: boolean;
|
|
319
500
|
}
|
|
320
501
|
/**
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
* Not everything is implemented everywhere — macOS in particular still throws for
|
|
325
|
-
* a good part of this. That is a runtime answer ("not implemented on this
|
|
326
|
-
* platform"), deliberately not a type-level one: a consumer writing against the
|
|
327
|
-
* package should see one signature per function, not a per-platform subset they
|
|
328
|
-
* have to narrow.
|
|
502
|
+
* Everything the package does, under one signature per operation whatever the
|
|
503
|
+
* platform. A platform that cannot do something says so at run time — see
|
|
504
|
+
* `CapabilityMap` — rather than through a narrower type.
|
|
329
505
|
*/
|
|
330
506
|
export interface OutlookBridge {
|
|
507
|
+
/** Every mailbox this Outlook profile can reach, as SMTP addresses. */
|
|
331
508
|
getOutlookAccounts(): Promise<string[]>;
|
|
509
|
+
/** Send an email, or stage it as a draft. */
|
|
332
510
|
sendOutlookEmail(params: SendEmailParams): Promise<void>;
|
|
511
|
+
/** Reply to an email, with the new text above the quoted original. */
|
|
333
512
|
replyOutlookEmail(params: ReplyEmailParams): Promise<ReplyEmailResult>;
|
|
334
|
-
|
|
335
|
-
readInboxEmails(emailAccount: string,
|
|
336
|
-
|
|
513
|
+
/** Recent mail from the Inbox root or one named folder, newest first. */
|
|
514
|
+
readInboxEmails(emailAccount: string, options?: ReadInboxOptions): Promise<InboxEmail[]>;
|
|
515
|
+
/** Walk every folder under the Inbox for the mail matching `filter`. */
|
|
516
|
+
searchInboxByFilter(emailAccount: string, filter?: InboxSearchFilter): Promise<InboxSearchMatch[]>;
|
|
517
|
+
/** The email currently selected, or open, in Outlook. */
|
|
337
518
|
readSelectedEmail(): Promise<SelectedEmail>;
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
listOutlookDrafts(emailAccount: string, limit?: number, previewChars?: number): Promise<ListDraftsResult>;
|
|
343
|
-
deleteOutlookDrafts(emailAccount: string, entryIds: string[]): Promise<DeleteDraftsResult>;
|
|
519
|
+
/** One email's plain-text body, split from the thread it quotes. */
|
|
520
|
+
readEmailBody(email: EmailRef, options?: ReadEmailBodyOptions): Promise<EmailBodyResult>;
|
|
521
|
+
/** Open an email in Outlook. */
|
|
522
|
+
openOutlookEmail(email: EmailRef): Promise<void>;
|
|
344
523
|
/**
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
* `deleteOutlookDrafts`: an id pointing at ordinary mail, or at another
|
|
349
|
-
* account's draft, is refused and reported rather than sent.
|
|
524
|
+
* Find an email again from what was kept about it, when its id no longer
|
|
525
|
+
* resolves. Searches the Inbox and its subfolders, and returns null rather
|
|
526
|
+
* than a guess: every field the description gives has to agree.
|
|
350
527
|
*/
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
528
|
+
locateEmail(description: EmailDescription, options?: LocateEmailOptions): Promise<InboxSearchMatch | null>;
|
|
529
|
+
/** The folders under an account's Inbox. */
|
|
530
|
+
listInboxFolders(emailAccount: string, options?: ListFoldersOptions): Promise<InboxFolderInfo[]>;
|
|
531
|
+
/** File emails into a folder. Moving rewrites each email's entry id. */
|
|
532
|
+
moveOutlookEmails(emailAccount: string, entryIds: readonly string[], folder: string, options?: MoveEmailsOptions): Promise<MoveEmailsResult>;
|
|
533
|
+
/** The mail drafts bound to an account, newest first. */
|
|
534
|
+
listOutlookDrafts(emailAccount: string, options?: ListDraftsOptions): Promise<ListDraftsResult>;
|
|
535
|
+
/** Send the named drafts — each has to be one of this account's drafts. */
|
|
536
|
+
sendDrafts(emailAccount: string, entryIds: readonly string[]): Promise<SendDraftsResult>;
|
|
537
|
+
/** Send every draft bound to an account. */
|
|
538
|
+
sendAllDrafts(emailAccount: string): Promise<SendDraftsResult>;
|
|
539
|
+
/** Delete the named drafts (into Deleted Items) — each has to be one of this account's drafts. */
|
|
540
|
+
deleteOutlookDrafts(emailAccount: string, entryIds: readonly string[]): Promise<DeleteDraftsResult>;
|
|
541
|
+
/** Delete mail by id into Deleted Items, refusing received and sent mail unless allowed. */
|
|
542
|
+
deleteOutlookEmails(emailAccount: string, entryIds: readonly string[], options?: DeleteMailOptions): Promise<DeleteMailResult>;
|
|
543
|
+
/** Permanently empty an account's Deleted Items. The one irreversible operation. */
|
|
544
|
+
purgeDeletedItems(emailAccount: string, options?: PurgeDeletedItemsOptions): Promise<PurgeDeletedItemsResult>;
|
|
545
|
+
/** Save one attachment to disk. */
|
|
546
|
+
saveEmailAttachment(email: EmailRef, fileName: string, options?: SaveAttachmentOptions): Promise<SavedAttachment>;
|
|
547
|
+
/** Save several attachments from one email, in the order named. */
|
|
548
|
+
saveEmailAttachments(email: EmailRef, fileNames: readonly string[], options?: SaveAttachmentOptions): Promise<SavedAttachment[]>;
|
|
549
|
+
/** Find bounce-backs in the Inbox and, unless dry-running, delete them. */
|
|
550
|
+
cleanUndeliverableEmails(emailAccount: string, options?: CleanUndeliverableOptions): Promise<CleanUndeliverableResult>;
|
|
551
|
+
/** The addresses bounce-backs report as having failed, deduplicated. */
|
|
552
|
+
collectBouncedRecipients(emailAccount: string, options?: CollectBouncedRecipientsOptions): Promise<string[]>;
|
|
553
|
+
/** Sent Items, each message with the full set of addresses it went to. */
|
|
554
|
+
readSentRecipientGroups(emailAccount: string, options?: SentRecipientGroupsOptions): Promise<SentRecipientGroup[]>;
|
|
555
|
+
/** Which sent messages bounced, and for which of their recipients. */
|
|
556
|
+
readBounceReport(emailAccount: string, options?: BounceReportOptions): Promise<BounceReport>;
|
|
557
|
+
/** The names of the Outlook signatures on this machine. */
|
|
360
558
|
listOutlookSignatures(): Promise<string[]>;
|
|
559
|
+
/** A signature's HTML, or '' when there is no signature by that name. */
|
|
361
560
|
readOutlookSignatureHtml(name: string): Promise<string>;
|
|
362
|
-
|
|
363
|
-
|
|
561
|
+
/** The template emails saved in a mailbox folder. */
|
|
562
|
+
readTemplateEmails(emailAccount: string, options?: ReadTemplatesOptions): Promise<TemplateFolderResult>;
|
|
563
|
+
/** Save a new template email. Always adds; never overwrites. */
|
|
564
|
+
saveTemplateEmail(emailAccount: string, template: SaveTemplateParams): Promise<SaveTemplateResult>;
|
|
565
|
+
/**
|
|
566
|
+
* Open HTML in an Outlook compose window, wait for the person editing it to
|
|
567
|
+
* save and close, and return what they saved. Has no timeout; cancel it
|
|
568
|
+
* with an AbortSignal.
|
|
569
|
+
*/
|
|
364
570
|
editEmailTemplate(label: string, currentHtml: string): Promise<string>;
|
|
365
571
|
}
|
|
366
572
|
/** Every operation whose availability can be asked about. */
|
|
367
573
|
export type BridgeCapability = keyof OutlookBridge;
|
|
368
574
|
/**
|
|
369
|
-
* Which operations
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
* learn a gap existed except by calling into it. A UI can now gray out the
|
|
373
|
-
* buttons it can't back rather than discovering the gap when the user clicks one.
|
|
374
|
-
*
|
|
375
|
-
* Windows and macOS both answer the whole contract today, so every flag is
|
|
376
|
-
* `true` on either; the map earns its place on the third case — any other OS,
|
|
377
|
-
* where all of them are `false` and every call rejects with
|
|
378
|
-
* `UNSUPPORTED_PLATFORM`. `false` is also how a platform would announce the
|
|
379
|
-
* softer gap, an operation that answers emptily rather than throwing, so an
|
|
380
|
-
* empty result there means "can't" rather than "none found".
|
|
381
|
-
*
|
|
382
|
-
* Each platform derives its map from its bridge object minus an explicit
|
|
383
|
-
* not-ported list (see `shared/capabilities.ts`), and the key type is
|
|
384
|
-
* `keyof OutlookBridge`, so a new function in the contract cannot be missed.
|
|
575
|
+
* Which operations work on this machine: all of them on Windows and macOS,
|
|
576
|
+
* none anywhere else. Lets a UI disable what it cannot back instead of
|
|
577
|
+
* discovering the gap when a user clicks.
|
|
385
578
|
*/
|
|
386
579
|
export type CapabilityMap = Readonly<Record<BridgeCapability, boolean>>;
|