@dawnlit/outlook-bridge 1.1.0 → 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 -36
- package/dist/mac/read.js +154 -208
- 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 -165
- package/dist/types.js +8 -9
- package/dist/types.js.map +1 -1
- package/dist/windows/accounts.d.ts +10 -1
- package/dist/windows/accounts.js +25 -13
- 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 +169 -200
- package/dist/windows/bounces.js.map +1 -1
- package/dist/windows/cleanup.d.ts +19 -23
- package/dist/windows/cleanup.js +93 -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 +45 -52
- package/dist/windows/folders.js.map +1 -1
- package/dist/windows/index.d.ts +2 -27
- package/dist/windows/index.js +11 -65
- package/dist/windows/index.js.map +1 -1
- package/dist/windows/read.d.ts +24 -45
- package/dist/windows/read.js +266 -279
- 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 +71 -38
- package/dist/windows/scripts.js +123 -71
- package/dist/windows/scripts.js.map +1 -1
- package/dist/windows/send.d.ts +6 -11
- package/dist/windows/send.js +70 -79
- 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 +126 -151
- package/dist/windows/templates.js.map +1 -1
- package/package.json +5 -4
- 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/mac/read.js
CHANGED
|
@@ -8,49 +8,31 @@ exports.openOutlookEmail = openOutlookEmail;
|
|
|
8
8
|
// Reading mail on macOS: one folder, one item, a whole Inbox tree, or whatever
|
|
9
9
|
// is selected in the running Outlook.
|
|
10
10
|
//
|
|
11
|
-
// Every reader
|
|
12
|
-
//
|
|
11
|
+
// Every reader is two passes. Pass 1 indexes a folder with bulk property reads
|
|
12
|
+
// (one Apple event each); pass 2 fetches the expensive fields — body,
|
|
13
13
|
// attachments, sender — only for the messages that survived. Reading
|
|
14
14
|
// per-message in a loop costs an event per property and is unusably slow on a
|
|
15
15
|
// real mailbox, which is the whole reason for the shape.
|
|
16
16
|
const run_1 = require("./run");
|
|
17
17
|
const scripts_1 = require("./scripts");
|
|
18
|
-
const mail_1 = require("../mail");
|
|
19
18
|
const errors_1 = require("../errors");
|
|
20
|
-
|
|
21
|
-
const PREVIEW_CHARS = 600;
|
|
19
|
+
const mail_1 = require("../mail");
|
|
22
20
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* `entryId` here is Outlook for Mac's small integer message id (e.g. "779"), not
|
|
26
|
-
* the MAPI EntryID string Windows returns. The two are not interchangeable, so
|
|
27
|
-
* don't persist one and look it up on the other platform.
|
|
21
|
+
* Recent mail from the Inbox root or one folder, newest first. Entry ids here
|
|
22
|
+
* are Outlook for Mac's integer message ids, not Windows EntryIDs.
|
|
28
23
|
*/
|
|
29
|
-
async function readInboxEmails(
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (folder && folder.trim() && ref.segments.length === 0 && ref.rootId === 6
|
|
39
|
-
&& folder.trim().toLowerCase() !== 'inbox') {
|
|
40
|
-
throw new errors_1.NotFoundError('folder', `Folder '${folder}' does not name a folder under the Inbox.`);
|
|
41
|
-
}
|
|
42
|
-
const resolveScope = (0, scripts_1.mailScopeSnippet)(ref, folder || '');
|
|
43
|
-
const folderPath = (0, scripts_1.macFolderPath)(emailAccount, ref.rootLabel, ref.segments);
|
|
44
|
-
const isOutgoing = (0, mail_1.isOutgoingRoot)(ref.rootId);
|
|
45
|
-
// Pass 1 — index the folder. Folder order isn't documented, so sort here
|
|
46
|
-
// rather than trusting Outlook to hand back newest-first.
|
|
47
|
-
const indexScript = `tell application "Microsoft Outlook"
|
|
48
|
-
${(0, scripts_1.accountLookupSnippet)(emailAccount)}
|
|
49
|
-
${resolveScope}
|
|
50
|
-
set cutoff to (current date) - (${days} * days)
|
|
24
|
+
async function readInboxEmails(request) {
|
|
25
|
+
const acct = await (0, scripts_1.resolveMacAccount)(request.account);
|
|
26
|
+
const folderPath = (0, scripts_1.macFolderPath)(request.account, request.folder.rootLabel, request.folder.segments);
|
|
27
|
+
const outgoing = (0, mail_1.isOutgoingRoot)(request.folder.rootId);
|
|
28
|
+
// Pass 1 — index the folder. Its order isn't documented, so it is sorted here.
|
|
29
|
+
const index = (await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
|
|
30
|
+
${(0, scripts_1.accountLookupSnippet)(acct)}
|
|
31
|
+
${(0, scripts_1.mailScopeSnippet)(acct, request.folder, request.folderLabel)}
|
|
32
|
+
set cutoff to (current date) - (${(0, run_1.asInt)(request.daysBack)} * days)
|
|
51
33
|
set idList to id of every message of scopeFolder
|
|
52
34
|
try
|
|
53
|
-
set timeList to ${(0, scripts_1.dateProperty)(
|
|
35
|
+
set timeList to ${(0, scripts_1.dateProperty)(request.folder.rootId)} of every message of scopeFolder
|
|
54
36
|
on error
|
|
55
37
|
set timeList to {}
|
|
56
38
|
end try
|
|
@@ -59,16 +41,14 @@ ${resolveScope}
|
|
|
59
41
|
repeat with i from 1 to (count of idList)
|
|
60
42
|
set d to missing value
|
|
61
43
|
if hasTimes then set d to item i of timeList
|
|
62
|
-
-- An item
|
|
63
|
-
-- mail folder) is skipped
|
|
64
|
-
-- Windows Restrict on the same property does with it.
|
|
44
|
+
-- An item with no timestamp of its own (an unsent draft filed into a
|
|
45
|
+
-- mail folder) is skipped, as the Windows date filter skips it.
|
|
65
46
|
if d is not missing value and d is greater than or equal to cutoff then
|
|
66
47
|
set out to out & (item i of idList as string) & tab & my isoDate(d) & linefeed
|
|
67
48
|
end if
|
|
68
49
|
end repeat
|
|
69
50
|
return out
|
|
70
|
-
end tell
|
|
71
|
-
const index = (await (0, run_1.runOsaScript)(indexScript, 60000))
|
|
51
|
+
end tell`, 'standard'))
|
|
72
52
|
.split('\n')
|
|
73
53
|
.map(line => line.trim())
|
|
74
54
|
.filter(Boolean)
|
|
@@ -76,59 +56,54 @@ end tell`;
|
|
|
76
56
|
const [id, receivedTime] = line.split('\t');
|
|
77
57
|
return { id, receivedTime: receivedTime || '' };
|
|
78
58
|
});
|
|
79
|
-
// 'yyyy-MM-dd HH:mm'
|
|
59
|
+
// 'yyyy-MM-dd HH:mm' sorts correctly as a string.
|
|
80
60
|
index.sort((a, b) => b.receivedTime.localeCompare(a.receivedTime));
|
|
81
|
-
const chosen = index.slice(0,
|
|
61
|
+
const chosen = index.slice(0, request.limit);
|
|
82
62
|
if (chosen.length === 0)
|
|
83
63
|
return [];
|
|
84
|
-
// Pass 2 — the expensive reads, only for messages
|
|
85
|
-
const
|
|
86
|
-
|
|
64
|
+
// Pass 2 — the expensive reads, only for the messages kept.
|
|
65
|
+
const preview = request.previewChars > 0
|
|
66
|
+
? ` set bodyText to ""
|
|
67
|
+
try
|
|
68
|
+
set bodyText to (plain text content of theMsg) as string
|
|
69
|
+
end try
|
|
70
|
+
if (length of bodyText) > ${(0, run_1.asInt)(request.previewChars)} then set bodyText to text 1 thru ${(0, run_1.asInt)(request.previewChars)} of bodyText`
|
|
71
|
+
: ' set bodyText to ""';
|
|
72
|
+
const raw = await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
|
|
87
73
|
set out to ""
|
|
88
|
-
repeat with
|
|
74
|
+
repeat with theId in ${(0, run_1.asIdList)(chosen.map(c => c.id))}
|
|
89
75
|
set theMsg to missing value
|
|
90
76
|
try
|
|
91
|
-
set theMsg to message id
|
|
77
|
+
set theMsg to message id theId
|
|
92
78
|
end try
|
|
93
79
|
if theMsg is not missing value then
|
|
94
80
|
set subj to ""
|
|
95
81
|
try
|
|
96
82
|
set subj to (subject of theMsg) as string
|
|
97
83
|
end try
|
|
98
|
-
${
|
|
99
|
-
|
|
100
|
-
try
|
|
101
|
-
set bodyText to (plain text content of theMsg) as string
|
|
102
|
-
end try
|
|
103
|
-
if (length of bodyText) > ${PREVIEW_CHARS} then set bodyText to text 1 thru ${PREVIEW_CHARS} of bodyText
|
|
84
|
+
${outgoing ? (0, scripts_1.firstRecipientSnippet)('theMsg', ' ') : (0, scripts_1.senderSnippet)('theMsg', ' ')}
|
|
85
|
+
${preview}
|
|
104
86
|
set attNames to {}
|
|
105
87
|
try
|
|
106
88
|
set attNames to name of every attachment of theMsg
|
|
107
89
|
end try
|
|
108
|
-
set out to out & ${(0, run_1.asRow)([
|
|
109
|
-
'(id of theMsg as string)',
|
|
110
|
-
'subj',
|
|
111
|
-
'sndName',
|
|
112
|
-
'sndAddr',
|
|
113
|
-
'bodyText',
|
|
114
|
-
'my sanitizeList(attNames)',
|
|
115
|
-
])}
|
|
90
|
+
set out to out & ${(0, run_1.asRow)(['(id of theMsg as string)', 'subj', 'sndName', 'sndAddr', 'bodyText', 'my sanitizeList(attNames)'])}
|
|
116
91
|
end if
|
|
117
92
|
end repeat
|
|
118
93
|
return out
|
|
119
|
-
end tell
|
|
120
|
-
const
|
|
121
|
-
return (0, run_1.splitRecords)(
|
|
94
|
+
end tell`, 'standard');
|
|
95
|
+
const receivedById = new Map(chosen.map(c => [c.id, c.receivedTime]));
|
|
96
|
+
return (0, run_1.splitRecords)(raw).map(record => {
|
|
122
97
|
const parts = (0, run_1.splitFields)(record);
|
|
123
98
|
const id = (0, run_1.field)(parts, 0);
|
|
124
99
|
const attachmentNames = (0, run_1.splitList)((0, run_1.field)(parts, 5));
|
|
125
100
|
return {
|
|
126
101
|
entryId: id,
|
|
127
|
-
storeId: '',
|
|
102
|
+
storeId: '',
|
|
128
103
|
subject: (0, run_1.field)(parts, 1).trim(),
|
|
129
104
|
senderName: (0, run_1.field)(parts, 2),
|
|
130
105
|
senderEmail: (0, run_1.field)(parts, 3),
|
|
131
|
-
receivedTime:
|
|
106
|
+
receivedTime: receivedById.get(id) || '',
|
|
132
107
|
bodyPreview: (0, run_1.field)(parts, 4),
|
|
133
108
|
attachmentNames,
|
|
134
109
|
attachmentCount: attachmentNames.length,
|
|
@@ -137,172 +112,160 @@ end tell`;
|
|
|
137
112
|
});
|
|
138
113
|
}
|
|
139
114
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* `storeId` is accepted for signature parity and ignored: macOS has no StoreID,
|
|
143
|
-
* and `message id N` resolves against the application rather than one folder, so
|
|
144
|
-
* the message is found wherever it currently sits — including a subfolder.
|
|
145
|
-
*
|
|
146
|
-
* Uses `plain text content`, matching the Windows reader's use of `.Body`: the
|
|
147
|
-
* same tradeoff applies, so an HTML table's rows flatten and tabular figures are
|
|
148
|
-
* better read from an attachment.
|
|
115
|
+
* One email's full plain-text body. `storeId` has no macOS meaning: `message id
|
|
116
|
+
* N` resolves against the application, wherever the message sits.
|
|
149
117
|
*/
|
|
150
|
-
async function readEmailBody(
|
|
151
|
-
const id = (0, scripts_1.macMessageId)(entryId);
|
|
152
|
-
const
|
|
118
|
+
async function readEmailBody(email) {
|
|
119
|
+
const id = (0, scripts_1.macMessageId)(email.entryId);
|
|
120
|
+
const parts = (0, run_1.summaryFields)(await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
|
|
153
121
|
${(0, scripts_1.messageLookupSnippet)(id)}
|
|
154
122
|
${(0, scripts_1.messageDetailSnippet)(true)}
|
|
155
123
|
return ${(0, run_1.asRow)((0, scripts_1.messageDetailFields)(true))}
|
|
156
|
-
end tell
|
|
157
|
-
// The body is emitted LAST so a stray separator in earlier fields can't shift it.
|
|
158
|
-
const parts = (0, run_1.summaryFields)(await (0, run_1.runOsaScript)(script, 60000));
|
|
159
|
-
const attachmentNames = (0, run_1.splitList)((0, run_1.field)(parts, scripts_1.MessageDetail.attachmentNames));
|
|
160
|
-
const { body, quoted, separator } = (0, mail_1.splitQuotedOriginal)((0, run_1.field)(parts, scripts_1.MessageDetail.body));
|
|
161
|
-
// The quoted thread is context, never the priced content, so it is capped
|
|
162
|
-
// harder than the reply itself — matching the Windows reader.
|
|
163
|
-
const quotedCap = Math.min(maxChars, 4000);
|
|
124
|
+
end tell`, 'quick'));
|
|
164
125
|
return {
|
|
165
126
|
entryId: (0, run_1.field)(parts, scripts_1.MessageDetail.id) || id,
|
|
166
127
|
subject: (0, run_1.field)(parts, scripts_1.MessageDetail.subject).trim(),
|
|
167
128
|
senderName: (0, run_1.field)(parts, scripts_1.MessageDetail.senderName),
|
|
168
129
|
senderEmail: (0, run_1.field)(parts, scripts_1.MessageDetail.senderEmail),
|
|
169
130
|
receivedTime: (0, run_1.field)(parts, scripts_1.MessageDetail.receivedTime),
|
|
170
|
-
body:
|
|
171
|
-
|
|
172
|
-
bodyLength: body.length,
|
|
173
|
-
quoteSeparator: separator,
|
|
174
|
-
quotedLength: quoted.length,
|
|
175
|
-
quotedOriginal: includeQuoted ? quoted.slice(0, quotedCap) : '',
|
|
176
|
-
attachmentNames,
|
|
177
|
-
attachmentCount: attachmentNames.length,
|
|
131
|
+
body: (0, run_1.field)(parts, scripts_1.MessageDetail.body),
|
|
132
|
+
attachmentNames: (0, run_1.splitList)((0, run_1.field)(parts, scripts_1.MessageDetail.attachmentNames)),
|
|
178
133
|
};
|
|
179
134
|
}
|
|
180
135
|
/**
|
|
181
|
-
*
|
|
136
|
+
* Walk every folder under the Inbox for the mail matching the request.
|
|
182
137
|
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
138
|
+
* The filtering happens here rather than in Outlook: there is no AppleScript
|
|
139
|
+
* counterpart to COM's server-side `Items.Restrict`, so each folder is indexed in
|
|
140
|
+
* bulk reads and the subject and date tests run on the index. The results match
|
|
141
|
+
* Windows; the cost doesn't, and a wide window over a big tree is heavier here.
|
|
187
142
|
*/
|
|
188
|
-
function
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
* facility with no AppleScript counterpart, so the folder walk indexes each
|
|
207
|
-
* folder in two bulk reads and the subject/date tests run on the index. The
|
|
208
|
-
* observable contract is the same; the cost profile is not, and a `daysBack` of
|
|
209
|
-
* 0 over a large mailbox tree is correspondingly heavier here.
|
|
210
|
-
*
|
|
211
|
-
* `subjectPattern` is applied case-insensitively regardless of the RegExp's own
|
|
212
|
-
* flags, matching PowerShell's `-match`.
|
|
213
|
-
*/
|
|
214
|
-
async function searchInboxByFilter(emailAccount, filter = {}, daysBack = 0) {
|
|
215
|
-
const days = Math.max(0, Math.floor(daysBack));
|
|
143
|
+
async function searchInboxByFilter(request) {
|
|
144
|
+
const acct = await (0, scripts_1.resolveMacAccount)(request.account);
|
|
145
|
+
// AppleScript reaches a child folder by name, so a path entry narrows to its leaf.
|
|
146
|
+
const asNameList = (list) => `{${list.map(mail_1.folderLeafName).filter(Boolean).map(run_1.asString).join(', ')}}`;
|
|
147
|
+
const rootInScope = request.includeFolders.length === 0 ? 'true' : 'false';
|
|
148
|
+
// Sent, Drafts, Deleted and Junk hang UNDER the Inbox on an IMAP profile, so
|
|
149
|
+
// their ids are collected first and the walk never descends into them — by
|
|
150
|
+
// the profile's own id where it records one, through the account otherwise.
|
|
151
|
+
const skipIds = ['sent items', 'deleted items', 'drafts', 'junk mail']
|
|
152
|
+
.map(term => {
|
|
153
|
+
const id = acct.folderIds?.[term];
|
|
154
|
+
return id !== undefined
|
|
155
|
+
? ` set end of skipIds to ${id}`
|
|
156
|
+
: ` try
|
|
157
|
+
set end of skipIds to (id of (${term} of targetAcct))
|
|
158
|
+
end try`;
|
|
159
|
+
})
|
|
160
|
+
.join('\n');
|
|
216
161
|
// Pass 1 — index every folder under the Inbox: path, id, subject, received.
|
|
217
|
-
const
|
|
162
|
+
const indexed = (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(`on scanFolder(theFolder, prefix, cutoff, skipIds, skipNames, onlyNames, inScope)
|
|
218
163
|
set out to ""
|
|
164
|
+
set idList to {}
|
|
165
|
+
set subjList to {}
|
|
166
|
+
set timeList to {}
|
|
167
|
+
-- A folder the walk only passes through is never read: the bulk reads are
|
|
168
|
+
-- the expensive part.
|
|
169
|
+
if inScope then
|
|
170
|
+
tell application "Microsoft Outlook"
|
|
171
|
+
set idList to id of every message of theFolder
|
|
172
|
+
set subjList to subject of every message of theFolder
|
|
173
|
+
try
|
|
174
|
+
set timeList to time received of every message of theFolder
|
|
175
|
+
on error
|
|
176
|
+
set timeList to {}
|
|
177
|
+
end try
|
|
178
|
+
end tell
|
|
179
|
+
end if
|
|
219
180
|
tell application "Microsoft Outlook"
|
|
220
|
-
set idList to id of every message of theFolder
|
|
221
|
-
set subjList to subject of every message of theFolder
|
|
222
|
-
try
|
|
223
|
-
set timeList to time received of every message of theFolder
|
|
224
|
-
on error
|
|
225
|
-
set timeList to {}
|
|
226
|
-
end try
|
|
227
181
|
set subs to mail folders of theFolder
|
|
228
182
|
end tell
|
|
229
183
|
set hasTimes to ((count of timeList) is (count of idList))
|
|
230
184
|
repeat with i from 1 to (count of idList)
|
|
231
185
|
set d to missing value
|
|
232
186
|
if hasTimes then set d to item i of timeList
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
-- it would look exactly like an empty folder.
|
|
238
|
-
set keep to not useCutoff
|
|
239
|
-
else if useCutoff and d is less than cutoff then
|
|
240
|
-
set keep to false
|
|
241
|
-
end if
|
|
242
|
-
if keep then
|
|
243
|
-
set out to out & ${(0, run_1.asRow)([
|
|
244
|
-
'prefix',
|
|
245
|
-
'(item i of idList as string)',
|
|
246
|
-
'(item i of subjList)',
|
|
247
|
-
'my isoDate(d)',
|
|
248
|
-
])}
|
|
187
|
+
-- An item with no readable receive time is kept whatever the window
|
|
188
|
+
-- says; dropping it would make a folder of them look empty.
|
|
189
|
+
if d is missing value or d is not less than cutoff then
|
|
190
|
+
set out to out & ${(0, run_1.asRow)(['prefix', '(item i of idList as string)', '(item i of subjList)', 'my isoDate(d)'])}
|
|
249
191
|
end if
|
|
250
192
|
end repeat
|
|
251
193
|
repeat with f in subs
|
|
252
|
-
set
|
|
194
|
+
set skipThis to false
|
|
253
195
|
try
|
|
254
|
-
|
|
196
|
+
if skipIds contains (id of f) then set skipThis to true
|
|
255
197
|
end try
|
|
256
|
-
|
|
198
|
+
try
|
|
199
|
+
if skipNames contains ((name of f) as string) then set skipThis to true
|
|
200
|
+
end try
|
|
201
|
+
if not skipThis then
|
|
202
|
+
set childName to ""
|
|
203
|
+
try
|
|
204
|
+
set childName to (name of f) as string
|
|
205
|
+
end try
|
|
206
|
+
set childScope to (count of onlyNames) is 0
|
|
207
|
+
try
|
|
208
|
+
if onlyNames contains childName then set childScope to true
|
|
209
|
+
end try
|
|
210
|
+
set out to out & my scanFolder(f, prefix & ${run_1.AS_LIST_SEP} & childName, cutoff, skipIds, skipNames, onlyNames, childScope)
|
|
211
|
+
end if
|
|
257
212
|
end repeat
|
|
258
213
|
return out
|
|
259
214
|
end scanFolder
|
|
260
215
|
|
|
261
216
|
tell application "Microsoft Outlook"
|
|
262
|
-
${(0, scripts_1.accountLookupSnippet)(
|
|
263
|
-
|
|
217
|
+
${(0, scripts_1.accountLookupSnippet)(acct)}
|
|
218
|
+
${(0, scripts_1.rootFolderSnippet)(acct, 'inbox', 'rootInbox')}
|
|
264
219
|
set rootName to (name of rootInbox) as string
|
|
220
|
+
set skipIds to {}
|
|
221
|
+
${skipIds}
|
|
222
|
+
set skipNames to ${asNameList(request.excludeFolders)}
|
|
223
|
+
set onlyNames to ${asNameList(request.includeFolders)}
|
|
265
224
|
end tell
|
|
266
|
-
set cutoff to (current date) - (${
|
|
267
|
-
return my scanFolder(rootInbox, rootName, cutoff,
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
//
|
|
271
|
-
const patternRe =
|
|
272
|
-
|
|
273
|
-
: null;
|
|
274
|
-
const candidates = (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(indexScript, 300000))
|
|
225
|
+
set cutoff to (current date) - (${(0, run_1.asInt)(request.daysBack)} * days)
|
|
226
|
+
return my scanFolder(rootInbox, rootName, cutoff, skipIds, skipNames, onlyNames, ${rootInScope})`, 'scan'));
|
|
227
|
+
const subjectFiltered = !!(request.subjectLike || request.subjectPattern || request.excludeReplies);
|
|
228
|
+
const likeRe = request.subjectLike ? new RegExp((0, mail_1.subjectGlobSource)(request.subjectLike), 'i') : null;
|
|
229
|
+
// PowerShell's -match is case-insensitive, so the Windows test is too.
|
|
230
|
+
const patternRe = request.subjectPattern ? new RegExp(request.subjectPattern.source, 'i') : null;
|
|
231
|
+
const candidates = indexed
|
|
275
232
|
.map(record => {
|
|
276
233
|
const parts = (0, run_1.splitFields)(record);
|
|
277
234
|
const segments = (0, run_1.splitList)((0, run_1.field)(parts, 0));
|
|
278
235
|
return {
|
|
279
|
-
folderPath: (0, scripts_1.macFolderPath)(
|
|
236
|
+
folderPath: (0, scripts_1.macFolderPath)(request.account, segments[0] || 'Inbox', segments.slice(1)),
|
|
280
237
|
id: (0, run_1.field)(parts, 1),
|
|
281
238
|
subject: (0, run_1.field)(parts, 2).trim(),
|
|
282
239
|
receivedTime: (0, run_1.field)(parts, 3),
|
|
283
240
|
};
|
|
284
241
|
})
|
|
285
242
|
.filter(candidate => {
|
|
286
|
-
if (!candidate.subject)
|
|
243
|
+
if (subjectFiltered && !candidate.subject)
|
|
287
244
|
return false;
|
|
288
245
|
if (likeRe && !likeRe.test(candidate.subject))
|
|
289
246
|
return false;
|
|
290
247
|
if (patternRe && !patternRe.test(candidate.subject))
|
|
291
248
|
return false;
|
|
292
|
-
if (
|
|
249
|
+
if (request.excludeReplies && mail_1.REPLY_PREFIX.test(candidate.subject))
|
|
293
250
|
return false;
|
|
294
251
|
return true;
|
|
295
252
|
});
|
|
296
253
|
if (candidates.length === 0)
|
|
297
254
|
return [];
|
|
298
|
-
// Pass 2 —
|
|
299
|
-
const
|
|
300
|
-
|
|
255
|
+
// Pass 2 — senders, attachment names and (when asked) bodies, for the survivors only.
|
|
256
|
+
const body = request.includeBody
|
|
257
|
+
? ` set bodyText to ""
|
|
258
|
+
try
|
|
259
|
+
set bodyText to (plain text content of theMsg) as string
|
|
260
|
+
end try`
|
|
261
|
+
: ' set bodyText to ""';
|
|
262
|
+
const details = new Map();
|
|
263
|
+
const raw = await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
|
|
301
264
|
set out to ""
|
|
302
|
-
repeat with
|
|
265
|
+
repeat with theId in ${(0, run_1.asIdList)(candidates.map(c => c.id))}
|
|
303
266
|
set theMsg to missing value
|
|
304
267
|
try
|
|
305
|
-
set theMsg to message id
|
|
268
|
+
set theMsg to message id theId
|
|
306
269
|
end try
|
|
307
270
|
if theMsg is not missing value then
|
|
308
271
|
${(0, scripts_1.senderSnippet)('theMsg', ' ')}
|
|
@@ -310,23 +273,13 @@ ${(0, scripts_1.senderSnippet)('theMsg', ' ')}
|
|
|
310
273
|
try
|
|
311
274
|
set attNames to name of every attachment of theMsg
|
|
312
275
|
end try
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
set bodyText to (plain text content of theMsg) as string
|
|
316
|
-
end try
|
|
317
|
-
set out to out & ${(0, run_1.asRow)([
|
|
318
|
-
'(id of theMsg as string)',
|
|
319
|
-
'sndName',
|
|
320
|
-
'sndAddr',
|
|
321
|
-
'my sanitizeList(attNames)',
|
|
322
|
-
'bodyText',
|
|
323
|
-
])}
|
|
276
|
+
${body}
|
|
277
|
+
set out to out & ${(0, run_1.asRow)(['(id of theMsg as string)', 'sndName', 'sndAddr', 'my sanitizeList(attNames)', 'bodyText'])}
|
|
324
278
|
end if
|
|
325
279
|
end repeat
|
|
326
280
|
return out
|
|
327
|
-
end tell
|
|
328
|
-
const
|
|
329
|
-
for (const record of (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(detailScript, 300000))) {
|
|
281
|
+
end tell`, 'scan');
|
|
282
|
+
for (const record of (0, run_1.splitRecords)(raw)) {
|
|
330
283
|
const parts = (0, run_1.splitFields)(record);
|
|
331
284
|
details.set((0, run_1.field)(parts, 0), {
|
|
332
285
|
senderName: (0, run_1.field)(parts, 1),
|
|
@@ -340,13 +293,12 @@ end tell`;
|
|
|
340
293
|
const detail = details.get(candidate.id);
|
|
341
294
|
if (!detail)
|
|
342
295
|
continue;
|
|
343
|
-
//
|
|
344
|
-
|
|
345
|
-
if (filter.requireAttachment && detail.attachmentNames.length === 0)
|
|
296
|
+
// Attachment names only arrive with the details, so this test waits for them.
|
|
297
|
+
if (request.requireAttachment && detail.attachmentNames.length === 0)
|
|
346
298
|
continue;
|
|
347
299
|
matches.push({
|
|
348
300
|
entryId: candidate.id,
|
|
349
|
-
storeId: '',
|
|
301
|
+
storeId: '',
|
|
350
302
|
subject: candidate.subject,
|
|
351
303
|
senderName: detail.senderName,
|
|
352
304
|
senderEmail: detail.senderEmail,
|
|
@@ -359,31 +311,26 @@ end tell`;
|
|
|
359
311
|
return matches;
|
|
360
312
|
}
|
|
361
313
|
/**
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
* `current messages` covers both cases the Windows reader handles separately
|
|
366
|
-
* (an explorer selection and an open item), so there is no second lookup here.
|
|
314
|
+
* The email currently selected — or open — in Outlook. `current messages`
|
|
315
|
+
* covers both cases the Windows reader handles separately.
|
|
367
316
|
*/
|
|
368
317
|
async function readSelectedEmail() {
|
|
369
|
-
const
|
|
318
|
+
const records = (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
|
|
370
319
|
set sel to {}
|
|
371
320
|
try
|
|
372
321
|
set sel to current messages
|
|
373
322
|
end try
|
|
374
|
-
if (count of sel) is 0 then error
|
|
323
|
+
if (count of sel) is 0 then error ${(0, run_1.asString)(`${(0, errors_1.failureTag)('NOT_FOUND', 'email')}No email is selected in Outlook. Select or open an email, then try again.`)}
|
|
375
324
|
set theMsg to item 1 of sel
|
|
376
325
|
${(0, scripts_1.messageDetailSnippet)(true)}
|
|
377
326
|
return ${(0, run_1.asRow)((0, scripts_1.messageDetailFields)(true))}
|
|
378
|
-
end tell
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
throw new errors_1.NotFoundError('email', 'Failed to read the selected Outlook email.');
|
|
382
|
-
}
|
|
327
|
+
end tell`, 'quick'));
|
|
328
|
+
if (records.length === 0)
|
|
329
|
+
throw new errors_1.NotFoundError('email', 'Outlook reported no selected email.');
|
|
383
330
|
const parts = (0, run_1.splitFields)(records[0]);
|
|
384
331
|
return {
|
|
385
332
|
entryId: (0, run_1.field)(parts, scripts_1.MessageDetail.id),
|
|
386
|
-
storeId: '',
|
|
333
|
+
storeId: '',
|
|
387
334
|
subject: (0, run_1.field)(parts, scripts_1.MessageDetail.subject).trim(),
|
|
388
335
|
senderName: (0, run_1.field)(parts, scripts_1.MessageDetail.senderName),
|
|
389
336
|
senderEmail: (0, run_1.field)(parts, scripts_1.MessageDetail.senderEmail),
|
|
@@ -392,15 +339,14 @@ end tell`;
|
|
|
392
339
|
attachmentNames: (0, run_1.splitList)((0, run_1.field)(parts, scripts_1.MessageDetail.attachmentNames)),
|
|
393
340
|
};
|
|
394
341
|
}
|
|
395
|
-
/** Open an email in Outlook
|
|
396
|
-
async function openOutlookEmail(
|
|
397
|
-
const id = (0, scripts_1.macMessageId)(entryId);
|
|
398
|
-
|
|
342
|
+
/** Open an email in Outlook and bring Outlook forward. */
|
|
343
|
+
async function openOutlookEmail(email) {
|
|
344
|
+
const id = (0, scripts_1.macMessageId)(email.entryId);
|
|
345
|
+
await (0, run_1.runOsaScript)(`
|
|
399
346
|
tell application "Microsoft Outlook"
|
|
400
347
|
${(0, scripts_1.messageLookupSnippet)(id)}
|
|
401
348
|
open theMsg
|
|
402
349
|
activate
|
|
403
|
-
end tell
|
|
404
|
-
await (0, run_1.runOsaScript)(script, 30000);
|
|
350
|
+
end tell`, 'quick');
|
|
405
351
|
}
|
|
406
352
|
//# sourceMappingURL=read.js.map
|
package/dist/mac/read.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/mac/read.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/mac/read.ts"],"names":[],"mappings":"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","sourcesContent":["// Reading mail on macOS: one folder, one item, a whole Inbox tree, or whatever\n// is selected in the running Outlook.\n//\n// Every reader is two passes. Pass 1 indexes a folder with bulk property reads\n// (one Apple event each); pass 2 fetches the expensive fields — body,\n// attachments, sender — only for the messages that survived. Reading\n// per-message in a loop costs an event per property and is unusably slow on a\n// real mailbox, which is the whole reason for the shape.\nimport {\n AS_LIST_SEP,\n asIdList,\n asInt,\n asRow,\n asString,\n field,\n runOsaScript,\n splitFields,\n splitList,\n splitRecords,\n summaryFields\n} from './run';\nimport {\n accountLookupSnippet,\n dateProperty,\n firstRecipientSnippet,\n macFolderPath,\n macMessageId,\n mailScopeSnippet,\n MessageDetail,\n messageDetailFields,\n messageDetailSnippet,\n messageLookupSnippet,\n resolveMacAccount,\n rootFolderSnippet,\n senderSnippet,\n} from './scripts';\nimport { failureTag, NotFoundError } from '../errors';\nimport { folderLeafName, isOutgoingRoot, REPLY_PREFIX, subjectGlobSource } from '../mail';\nimport type { RawEmail, ReadInboxRequest, SearchRequest } from '../backend';\nimport type { EmailLocator, InboxEmail, InboxSearchMatch, SelectedEmail } from '../types';\n\n/**\n * Recent mail from the Inbox root or one folder, newest first. Entry ids here\n * are Outlook for Mac's integer message ids, not Windows EntryIDs.\n */\nexport async function readInboxEmails(request: ReadInboxRequest): Promise<InboxEmail[]> {\n const acct = await resolveMacAccount(request.account);\n const folderPath = macFolderPath(request.account, request.folder.rootLabel, request.folder.segments);\n const outgoing = isOutgoingRoot(request.folder.rootId);\n\n // Pass 1 — index the folder. Its order isn't documented, so it is sorted here.\n const index = (await runOsaScript(`tell application \"Microsoft Outlook\"\n${accountLookupSnippet(acct)}\n${mailScopeSnippet(acct, request.folder, request.folderLabel)}\n set cutoff to (current date) - (${asInt(request.daysBack)} * days)\n set idList to id of every message of scopeFolder\n try\n set timeList to ${dateProperty(request.folder.rootId)} of every message of scopeFolder\n on error\n set timeList to {}\n end try\n set hasTimes to ((count of timeList) is (count of idList))\n set out to \"\"\n repeat with i from 1 to (count of idList)\n set d to missing value\n if hasTimes then set d to item i of timeList\n -- An item with no timestamp of its own (an unsent draft filed into a\n -- mail folder) is skipped, as the Windows date filter skips it.\n if d is not missing value and d is greater than or equal to cutoff then\n set out to out & (item i of idList as string) & tab & my isoDate(d) & linefeed\n end if\n end repeat\n return out\nend tell`, 'standard'))\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => {\n const [id, receivedTime] = line.split('\\t');\n return {id, receivedTime: receivedTime || ''};\n });\n // 'yyyy-MM-dd HH:mm' sorts correctly as a string.\n index.sort((a, b) => b.receivedTime.localeCompare(a.receivedTime));\n const chosen = index.slice(0, request.limit);\n if (chosen.length === 0) return [];\n\n // Pass 2 — the expensive reads, only for the messages kept.\n const preview = request.previewChars > 0\n ? ` set bodyText to \"\"\n try\n set bodyText to (plain text content of theMsg) as string\n end try\n if (length of bodyText) > ${asInt(request.previewChars)} then set bodyText to text 1 thru ${asInt(request.previewChars)} of bodyText`\n : ' set bodyText to \"\"';\n const raw = await runOsaScript(`tell application \"Microsoft Outlook\"\n set out to \"\"\n repeat with theId in ${asIdList(chosen.map(c => c.id))}\n set theMsg to missing value\n try\n set theMsg to message id theId\n end try\n if theMsg is not missing value then\n set subj to \"\"\n try\n set subj to (subject of theMsg) as string\n end try\n${outgoing ? firstRecipientSnippet('theMsg', ' ') : senderSnippet('theMsg', ' ')}\n${preview}\n set attNames to {}\n try\n set attNames to name of every attachment of theMsg\n end try\n set out to out & ${asRow(['(id of theMsg as string)', 'subj', 'sndName', 'sndAddr', 'bodyText', 'my sanitizeList(attNames)'])}\n end if\n end repeat\n return out\nend tell`, 'standard');\n\n const receivedById = new Map(chosen.map(c => [c.id, c.receivedTime]));\n return splitRecords(raw).map(record => {\n const parts = splitFields(record);\n const id = field(parts, 0);\n const attachmentNames = splitList(field(parts, 5));\n return {\n entryId: id,\n storeId: '',\n subject: field(parts, 1).trim(),\n senderName: field(parts, 2),\n senderEmail: field(parts, 3),\n receivedTime: receivedById.get(id) || '',\n bodyPreview: field(parts, 4),\n attachmentNames,\n attachmentCount: attachmentNames.length,\n folderPath,\n };\n });\n}\n\n/**\n * One email's full plain-text body. `storeId` has no macOS meaning: `message id\n * N` resolves against the application, wherever the message sits.\n */\nexport async function readEmailBody(email: EmailLocator): Promise<RawEmail> {\n const id = macMessageId(email.entryId);\n const parts = summaryFields(await runOsaScript(`tell application \"Microsoft Outlook\"\n${messageLookupSnippet(id)}\n${messageDetailSnippet(true)}\n return ${asRow(messageDetailFields(true))}\nend tell`, 'quick'));\n return {\n entryId: field(parts, MessageDetail.id) || id,\n subject: field(parts, MessageDetail.subject).trim(),\n senderName: field(parts, MessageDetail.senderName),\n senderEmail: field(parts, MessageDetail.senderEmail),\n receivedTime: field(parts, MessageDetail.receivedTime),\n body: field(parts, MessageDetail.body),\n attachmentNames: splitList(field(parts, MessageDetail.attachmentNames)),\n };\n}\n\n/**\n * Walk every folder under the Inbox for the mail matching the request.\n *\n * The filtering happens here rather than in Outlook: there is no AppleScript\n * counterpart to COM's server-side `Items.Restrict`, so each folder is indexed in\n * bulk reads and the subject and date tests run on the index. The results match\n * Windows; the cost doesn't, and a wide window over a big tree is heavier here.\n */\nexport async function searchInboxByFilter(request: SearchRequest): Promise<InboxSearchMatch[]> {\n const acct = await resolveMacAccount(request.account);\n // AppleScript reaches a child folder by name, so a path entry narrows to its leaf.\n const asNameList = (list: readonly string[]) => `{${list.map(folderLeafName).filter(Boolean).map(asString).join(', ')}}`;\n const rootInScope = request.includeFolders.length === 0 ? 'true' : 'false';\n // Sent, Drafts, Deleted and Junk hang UNDER the Inbox on an IMAP profile, so\n // their ids are collected first and the walk never descends into them — by\n // the profile's own id where it records one, through the account otherwise.\n const skipIds = ['sent items', 'deleted items', 'drafts', 'junk mail']\n .map(term => {\n const id = acct.folderIds?.[term];\n return id !== undefined\n ? ` set end of skipIds to ${id}`\n : ` try\n set end of skipIds to (id of (${term} of targetAcct))\n end try`;\n })\n .join('\\n');\n\n // Pass 1 — index every folder under the Inbox: path, id, subject, received.\n const indexed = splitRecords(await runOsaScript(`on scanFolder(theFolder, prefix, cutoff, skipIds, skipNames, onlyNames, inScope)\n set out to \"\"\n set idList to {}\n set subjList to {}\n set timeList to {}\n -- A folder the walk only passes through is never read: the bulk reads are\n -- the expensive part.\n if inScope then\n tell application \"Microsoft Outlook\"\n set idList to id of every message of theFolder\n set subjList to subject of every message of theFolder\n try\n set timeList to time received of every message of theFolder\n on error\n set timeList to {}\n end try\n end tell\n end if\n tell application \"Microsoft Outlook\"\n set subs to mail folders of theFolder\n end tell\n set hasTimes to ((count of timeList) is (count of idList))\n repeat with i from 1 to (count of idList)\n set d to missing value\n if hasTimes then set d to item i of timeList\n -- An item with no readable receive time is kept whatever the window\n -- says; dropping it would make a folder of them look empty.\n if d is missing value or d is not less than cutoff then\n set out to out & ${asRow(['prefix', '(item i of idList as string)', '(item i of subjList)', 'my isoDate(d)'])}\n end if\n end repeat\n repeat with f in subs\n set skipThis to false\n try\n if skipIds contains (id of f) then set skipThis to true\n end try\n try\n if skipNames contains ((name of f) as string) then set skipThis to true\n end try\n if not skipThis then\n set childName to \"\"\n try\n set childName to (name of f) as string\n end try\n set childScope to (count of onlyNames) is 0\n try\n if onlyNames contains childName then set childScope to true\n end try\n set out to out & my scanFolder(f, prefix & ${AS_LIST_SEP} & childName, cutoff, skipIds, skipNames, onlyNames, childScope)\n end if\n end repeat\n return out\nend scanFolder\n\ntell application \"Microsoft Outlook\"\n${accountLookupSnippet(acct)}\n${rootFolderSnippet(acct, 'inbox', 'rootInbox')}\n set rootName to (name of rootInbox) as string\n set skipIds to {}\n${skipIds}\n set skipNames to ${asNameList(request.excludeFolders)}\n set onlyNames to ${asNameList(request.includeFolders)}\nend tell\nset cutoff to (current date) - (${asInt(request.daysBack)} * days)\nreturn my scanFolder(rootInbox, rootName, cutoff, skipIds, skipNames, onlyNames, ${rootInScope})`, 'scan'));\n\n const subjectFiltered = !!(request.subjectLike || request.subjectPattern || request.excludeReplies);\n const likeRe = request.subjectLike ? new RegExp(subjectGlobSource(request.subjectLike), 'i') : null;\n // PowerShell's -match is case-insensitive, so the Windows test is too.\n const patternRe = request.subjectPattern ? new RegExp(request.subjectPattern.source, 'i') : null;\n const candidates = indexed\n .map(record => {\n const parts = splitFields(record);\n const segments = splitList(field(parts, 0));\n return {\n folderPath: macFolderPath(request.account, segments[0] || 'Inbox', segments.slice(1)),\n id: field(parts, 1),\n subject: field(parts, 2).trim(),\n receivedTime: field(parts, 3),\n };\n })\n .filter(candidate => {\n if (subjectFiltered && !candidate.subject) return false;\n if (likeRe && !likeRe.test(candidate.subject)) return false;\n if (patternRe && !patternRe.test(candidate.subject)) return false;\n if (request.excludeReplies && REPLY_PREFIX.test(candidate.subject)) return false;\n return true;\n });\n if (candidates.length === 0) return [];\n\n // Pass 2 — senders, attachment names and (when asked) bodies, for the survivors only.\n const body = request.includeBody\n ? ` set bodyText to \"\"\n try\n set bodyText to (plain text content of theMsg) as string\n end try`\n : ' set bodyText to \"\"';\n const details = new Map<string, {\n senderName: string;\n senderEmail: string;\n attachmentNames: string[];\n body: string\n }>();\n const raw = await runOsaScript(`tell application \"Microsoft Outlook\"\n set out to \"\"\n repeat with theId in ${asIdList(candidates.map(c => c.id))}\n set theMsg to missing value\n try\n set theMsg to message id theId\n end try\n if theMsg is not missing value then\n${senderSnippet('theMsg', ' ')}\n set attNames to {}\n try\n set attNames to name of every attachment of theMsg\n end try\n${body}\n set out to out & ${asRow(['(id of theMsg as string)', 'sndName', 'sndAddr', 'my sanitizeList(attNames)', 'bodyText'])}\n end if\n end repeat\n return out\nend tell`, 'scan');\n for (const record of splitRecords(raw)) {\n const parts = splitFields(record);\n details.set(field(parts, 0), {\n senderName: field(parts, 1),\n senderEmail: field(parts, 2),\n attachmentNames: splitList(field(parts, 3)),\n body: field(parts, 4),\n });\n }\n\n const matches: InboxSearchMatch[] = [];\n for (const candidate of candidates) {\n const detail = details.get(candidate.id);\n if (!detail) continue;\n // Attachment names only arrive with the details, so this test waits for them.\n if (request.requireAttachment && detail.attachmentNames.length === 0) continue;\n matches.push({\n entryId: candidate.id,\n storeId: '',\n subject: candidate.subject,\n senderName: detail.senderName,\n senderEmail: detail.senderEmail,\n receivedTime: candidate.receivedTime,\n body: detail.body,\n attachmentNames: detail.attachmentNames,\n folderPath: candidate.folderPath,\n });\n }\n return matches;\n}\n\n/**\n * The email currently selected — or open — in Outlook. `current messages`\n * covers both cases the Windows reader handles separately.\n */\nexport async function readSelectedEmail(): Promise<SelectedEmail> {\n const records = splitRecords(await runOsaScript(`tell application \"Microsoft Outlook\"\n set sel to {}\n try\n set sel to current messages\n end try\n if (count of sel) is 0 then error ${asString(`${failureTag('NOT_FOUND', 'email')}No email is selected in Outlook. Select or open an email, then try again.`)}\n set theMsg to item 1 of sel\n${messageDetailSnippet(true)}\n return ${asRow(messageDetailFields(true))}\nend tell`, 'quick'));\n if (records.length === 0) throw new NotFoundError('email', 'Outlook reported no selected email.');\n const parts = splitFields(records[0]);\n return {\n entryId: field(parts, MessageDetail.id),\n storeId: '',\n subject: field(parts, MessageDetail.subject).trim(),\n senderName: field(parts, MessageDetail.senderName),\n senderEmail: field(parts, MessageDetail.senderEmail),\n receivedTime: field(parts, MessageDetail.receivedTime),\n body: field(parts, MessageDetail.body),\n attachmentNames: splitList(field(parts, MessageDetail.attachmentNames)),\n };\n}\n\n/** Open an email in Outlook and bring Outlook forward. */\nexport async function openOutlookEmail(email: EmailLocator): Promise<void> {\n const id = macMessageId(email.entryId);\n await runOsaScript(`\ntell application \"Microsoft Outlook\"\n${messageLookupSnippet(id)}\n open theMsg\n activate\nend tell`, 'quick');\n}\n"]}
|