@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.
Files changed (139) hide show
  1. package/README.md +150 -183
  2. package/dist/backend.d.ts +151 -0
  3. package/dist/backend.js +3 -0
  4. package/dist/backend.js.map +1 -0
  5. package/dist/bridge.d.ts +56 -0
  6. package/dist/bridge.js +507 -0
  7. package/dist/bridge.js.map +1 -0
  8. package/dist/errors.d.ts +81 -43
  9. package/dist/errors.js +98 -52
  10. package/dist/errors.js.map +1 -1
  11. package/dist/index.d.ts +10 -10
  12. package/dist/index.js +25 -52
  13. package/dist/index.js.map +1 -1
  14. package/dist/mac/accounts.d.ts +7 -2
  15. package/dist/mac/accounts.js +23 -6
  16. package/dist/mac/accounts.js.map +1 -1
  17. package/dist/mac/attachments.d.ts +5 -25
  18. package/dist/mac/attachments.js +40 -99
  19. package/dist/mac/attachments.js.map +1 -1
  20. package/dist/mac/bounces.d.ts +12 -27
  21. package/dist/mac/bounces.js +95 -112
  22. package/dist/mac/bounces.js.map +1 -1
  23. package/dist/mac/cleanup.d.ts +11 -25
  24. package/dist/mac/cleanup.js +50 -76
  25. package/dist/mac/cleanup.js.map +1 -1
  26. package/dist/mac/drafts.d.ts +13 -34
  27. package/dist/mac/drafts.js +95 -169
  28. package/dist/mac/drafts.js.map +1 -1
  29. package/dist/mac/folders.d.ts +10 -21
  30. package/dist/mac/folders.js +33 -47
  31. package/dist/mac/folders.js.map +1 -1
  32. package/dist/mac/index.d.ts +2 -22
  33. package/dist/mac/index.js +19 -81
  34. package/dist/mac/index.js.map +1 -1
  35. package/dist/mac/profile.d.ts +13 -0
  36. package/dist/mac/profile.js +149 -0
  37. package/dist/mac/profile.js.map +1 -0
  38. package/dist/mac/read.d.ts +18 -36
  39. package/dist/mac/read.js +154 -208
  40. package/dist/mac/read.js.map +1 -1
  41. package/dist/mac/run.d.ts +35 -39
  42. package/dist/mac/run.js +97 -102
  43. package/dist/mac/run.js.map +1 -1
  44. package/dist/mac/scripts.d.ts +78 -86
  45. package/dist/mac/scripts.js +125 -115
  46. package/dist/mac/scripts.js.map +1 -1
  47. package/dist/mac/send.d.ts +10 -20
  48. package/dist/mac/send.js +64 -86
  49. package/dist/mac/send.js.map +1 -1
  50. package/dist/mac/signatures.d.ts +2 -2
  51. package/dist/mac/signatures.js +9 -11
  52. package/dist/mac/signatures.js.map +1 -1
  53. package/dist/mac/templates.d.ts +14 -26
  54. package/dist/mac/templates.js +75 -113
  55. package/dist/mac/templates.js.map +1 -1
  56. package/dist/mail.d.ts +77 -45
  57. package/dist/mail.js +166 -73
  58. package/dist/mail.js.map +1 -1
  59. package/dist/runtime.d.ts +76 -43
  60. package/dist/runtime.js +103 -48
  61. package/dist/runtime.js.map +1 -1
  62. package/dist/shared/args.d.ts +48 -0
  63. package/dist/shared/args.js +216 -0
  64. package/dist/shared/args.js.map +1 -0
  65. package/dist/shared/attachmentMatch.d.ts +28 -16
  66. package/dist/shared/attachmentMatch.js +60 -22
  67. package/dist/shared/attachmentMatch.js.map +1 -1
  68. package/dist/shared/bounceReport.d.ts +11 -0
  69. package/dist/shared/bounceReport.js +45 -0
  70. package/dist/shared/bounceReport.js.map +1 -0
  71. package/dist/shared/bounceRules.d.ts +38 -10
  72. package/dist/shared/bounceRules.js +50 -32
  73. package/dist/shared/bounceRules.js.map +1 -1
  74. package/dist/shared/exec.d.ts +21 -0
  75. package/dist/shared/exec.js +47 -0
  76. package/dist/shared/exec.js.map +1 -0
  77. package/dist/shared/json.d.ts +12 -6
  78. package/dist/shared/json.js +29 -23
  79. package/dist/shared/json.js.map +1 -1
  80. package/dist/shared/locate.d.ts +39 -0
  81. package/dist/shared/locate.js +129 -0
  82. package/dist/shared/locate.js.map +1 -0
  83. package/dist/shared/replyBody.d.ts +42 -32
  84. package/dist/shared/replyBody.js +84 -71
  85. package/dist/shared/replyBody.js.map +1 -1
  86. package/dist/templateBody.d.ts +63 -0
  87. package/dist/{outlookTemplateSections.js → templateBody.js} +72 -72
  88. package/dist/templateBody.js.map +1 -0
  89. package/dist/types.d.ts +360 -165
  90. package/dist/types.js +8 -9
  91. package/dist/types.js.map +1 -1
  92. package/dist/windows/accounts.d.ts +10 -1
  93. package/dist/windows/accounts.js +25 -13
  94. package/dist/windows/accounts.js.map +1 -1
  95. package/dist/windows/attachments.d.ts +9 -24
  96. package/dist/windows/attachments.js +94 -119
  97. package/dist/windows/attachments.js.map +1 -1
  98. package/dist/windows/bounces.d.ts +13 -26
  99. package/dist/windows/bounces.js +169 -200
  100. package/dist/windows/bounces.js.map +1 -1
  101. package/dist/windows/cleanup.d.ts +19 -23
  102. package/dist/windows/cleanup.js +93 -111
  103. package/dist/windows/cleanup.js.map +1 -1
  104. package/dist/windows/drafts.d.ts +16 -35
  105. package/dist/windows/drafts.js +167 -253
  106. package/dist/windows/drafts.js.map +1 -1
  107. package/dist/windows/folders.d.ts +8 -13
  108. package/dist/windows/folders.js +45 -52
  109. package/dist/windows/folders.js.map +1 -1
  110. package/dist/windows/index.d.ts +2 -27
  111. package/dist/windows/index.js +11 -65
  112. package/dist/windows/index.js.map +1 -1
  113. package/dist/windows/read.d.ts +24 -45
  114. package/dist/windows/read.js +266 -279
  115. package/dist/windows/read.js.map +1 -1
  116. package/dist/windows/run.d.ts +39 -39
  117. package/dist/windows/run.js +151 -111
  118. package/dist/windows/run.js.map +1 -1
  119. package/dist/windows/scripts.d.ts +71 -38
  120. package/dist/windows/scripts.js +123 -71
  121. package/dist/windows/scripts.js.map +1 -1
  122. package/dist/windows/send.d.ts +6 -11
  123. package/dist/windows/send.js +70 -79
  124. package/dist/windows/send.js.map +1 -1
  125. package/dist/windows/signatures.d.ts +4 -10
  126. package/dist/windows/signatures.js +30 -37
  127. package/dist/windows/signatures.js.map +1 -1
  128. package/dist/windows/templates.d.ts +12 -18
  129. package/dist/windows/templates.js +126 -151
  130. package/dist/windows/templates.js.map +1 -1
  131. package/package.json +5 -4
  132. package/dist/OutlookService.d.ts +0 -43
  133. package/dist/OutlookService.js +0 -137
  134. package/dist/OutlookService.js.map +0 -1
  135. package/dist/outlookTemplateSections.d.ts +0 -62
  136. package/dist/outlookTemplateSections.js.map +0 -1
  137. package/dist/shared/capabilities.d.ts +0 -3
  138. package/dist/shared/capabilities.js +0 -9
  139. package/dist/shared/capabilities.js.map +0 -1
@@ -1,34 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listOutlookDrafts = listOutlookDrafts;
4
- exports.sendAllDrafts = sendAllDrafts;
5
- exports.deleteOutlookDrafts = deleteOutlookDrafts;
6
4
  exports.sendDrafts = sendDrafts;
7
- // Drafts: which ones belong to an account, and sending, listing or deleting them.
5
+ exports.deleteOutlookDrafts = deleteOutlookDrafts;
6
+ exports.sendAllDrafts = sendAllDrafts;
7
+ // Drafts: which ones belong to an account, and listing, sending or deleting them.
8
+ //
9
+ // Where Windows scans two Drafts folders and proves each item's sending
10
+ // account, macOS resolves the one Drafts folder belonging to the account —
11
+ // through the account object, or by the folder's own id for a mailbox the
12
+ // dictionary won't name (see profile.ts) — so a draft found there belongs to
13
+ // the account by construction.
8
14
  //
9
- // Where Windows has to scan two Drafts folders and prove each item's
10
- // SendUsingAccount, macOS asks the account for its own Drafts folder directly —
11
- // `drafts of targetAcct` is already account-scoped, so a draft found there
12
- // belongs to this account by construction. That is the same rule the Windows
13
- // scan reaches by a longer route, not a weaker one.
15
+ // What the folder can't vouch for is an item's own binding, which is why the
16
+ // guards compare against the requested address as a literal rather than asking
17
+ // `targetAcct`: there may be no account object to ask.
14
18
  const run_1 = require("./run");
15
19
  const scripts_1 = require("./scripts");
16
- /** The Drafts folder path this account's drafts are reported under. */
17
- function draftsPath(emailAccount) {
18
- return (0, scripts_1.macFolderPath)(emailAccount, 'Drafts', []);
19
- }
20
- /**
21
- * List the mail drafts belonging to `emailAccount`, newest first.
22
- *
23
- * Bodies are previewed, never returned whole — a templated reply body runs to
24
- * tens of thousands of characters and a folder's worth would blow the cap.
25
- */
26
- async function listOutlookDrafts(emailAccount, limit = 100, previewChars = 300) {
27
- const cap = Math.max(1, Math.floor(limit));
28
- const preview = Math.max(1, Math.floor(previewChars));
29
- const script = `tell application "Microsoft Outlook"
30
- ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
31
- set draftsFolder to drafts of targetAcct
20
+ /** The account's drafts, newest first. Bodies are previewed, never returned whole. */
21
+ async function listOutlookDrafts(request) {
22
+ const acct = await (0, scripts_1.resolveMacAccount)(request.account);
23
+ const preview = request.previewChars > 0
24
+ ? ` set bodyText to ""
25
+ try
26
+ set bodyText to (plain text content of theMsg) as string
27
+ end try
28
+ 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`
29
+ : ' set bodyText to ""';
30
+ const raw = await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
31
+ ${(0, scripts_1.accountLookupSnippet)(acct)}
32
+ ${(0, scripts_1.rootFolderSnippet)(acct, 'drafts', 'draftsFolder')}
32
33
  set out to ""
33
34
  repeat with theMsg in (messages of draftsFolder)
34
35
  set subj to ""
@@ -55,11 +56,7 @@ ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
55
56
  end try
56
57
  end repeat
57
58
  end try
58
- set bodyText to ""
59
- try
60
- set bodyText to (plain text content of theMsg) as string
61
- end try
62
- if (length of bodyText) > ${preview} then set bodyText to text 1 thru ${preview} of bodyText
59
+ ${preview}
63
60
  set attCount to 0
64
61
  try
65
62
  set attCount to count of attachments of theMsg
@@ -68,21 +65,12 @@ ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
68
65
  try
69
66
  set modAt to my isoDate(modification date of theMsg)
70
67
  end try
71
- set out to out & ${(0, run_1.asRow)([
72
- '(id of theMsg as string)',
73
- 'subj',
74
- 'my joinList(toNames, ", ")',
75
- 'my sanitizeList(toAddrs)',
76
- 'bodyText',
77
- '(attCount as string)',
78
- 'modAt',
79
- ])}
68
+ set out to out & ${(0, run_1.asRow)(['(id of theMsg as string)', 'subj', 'my joinList(toNames, ", ")', 'my sanitizeList(toAddrs)', 'bodyText', '(attCount as string)', 'modAt'])}
80
69
  end repeat
81
70
  return out
82
- end tell`;
83
- // One string for every row, rather than rebuilt per draft.
84
- const folderPath = draftsPath(emailAccount);
85
- const drafts = (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(script, 120000)).map(record => {
71
+ end tell`, 'standard');
72
+ const folderPath = (0, scripts_1.macFolderPath)(request.account, 'Drafts', []);
73
+ const drafts = (0, run_1.splitRecords)(raw).map(record => {
86
74
  const parts = (0, run_1.splitFields)(record);
87
75
  return {
88
76
  entryId: (0, run_1.field)(parts, 0),
@@ -95,173 +83,114 @@ end tell`;
95
83
  folderPath,
96
84
  };
97
85
  });
98
- // 'yyyy-MM-dd HH:mm' is lexicographically ordered, so a string compare sorts it.
99
86
  drafts.sort((a, b) => b.lastModified.localeCompare(a.lastModified));
100
87
  return {
101
- account: emailAccount,
88
+ account: request.account,
102
89
  foldersScanned: [folderPath],
103
90
  count: drafts.length,
104
- truncated: drafts.length > cap,
105
- drafts: drafts.slice(0, cap),
91
+ truncated: drafts.length > request.limit,
92
+ drafts: drafts.slice(0, request.limit),
106
93
  };
107
94
  }
108
95
  /**
109
- * Send the mail drafts that belong to `emailAccount`.
110
- *
111
- * The ids are snapshotted before the first send: sending moves an item out of
112
- * Drafts, and mutating the collection mid-enumeration would skip every other one
113
- * — the same trap the Windows implementation avoids by snapshotting item refs.
96
+ * The AppleScript that proves `theMsg` is one of this account's drafts before
97
+ * `verb` happens to it: it sits in the account's Drafts folder, and it is bound
98
+ * to this account or to none.
114
99
  */
115
- async function sendAllDrafts(emailAccount) {
116
- const script = `tell application "Microsoft Outlook"
117
- ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
118
- set draftsFolder to drafts of targetAcct
119
- set wanted to id of every message of draftsFolder
120
- set sentCount to 0
121
- set out to ""
122
- repeat with theId in wanted
123
- set subj to ""
124
- try
125
- set theMsg to missing value
100
+ function ownDraftGuard(emailAccount, verb) {
101
+ return ` set inFolder to ""
126
102
  try
127
- set theMsg to message id theId
103
+ set inFolder to (name of (folder of theMsg)) as string
128
104
  end try
129
- if theMsg is missing value then error "draft is no longer in the Drafts folder"
105
+ if inFolder is not draftsName or draftIds does not contain (id of theMsg) then error "item is not in this account's Drafts folder - refusing to ${verb}"
106
+ set boundTo to ""
130
107
  try
131
- set subj to (subject of theMsg) as string
108
+ set boundTo to (email address of (account of theMsg)) as string
132
109
  end try
133
- send theMsg
134
- set sentCount to sentCount + 1
135
- on error errText
136
- set out to out & ${(0, run_1.asRow)(['subj', 'errText'])}
137
- end try
138
- end repeat
139
- return ${(0, run_1.asRow)(['(sentCount as string)'])} & out
140
- end tell`;
141
- const records = (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(script, 300000));
142
- return {
143
- sent: (0, run_1.intField)((0, run_1.splitFields)(records[0] || ''), 0),
144
- failed: records.slice(1).map(record => {
145
- const parts = (0, run_1.splitFields)(record);
146
- return { subject: (0, run_1.field)(parts, 0), error: (0, run_1.field)(parts, 1) };
147
- }),
148
- };
110
+ if boundTo is not "" and boundTo is not ${(0, run_1.asString)(emailAccount)} then error "draft is not bound to this account - refusing to ${verb}"`;
149
111
  }
150
- /**
151
- * Delete mail drafts by message id. `delete` files the item in Deleted Items
152
- * rather than destroying it, so a mistaken call stays recoverable from there —
153
- * matching the Windows contract.
154
- *
155
- * Every id must resolve to a message sitting in THIS account's Drafts folder
156
- * before anything is deleted; an id pointing at ordinary mail, or at another
157
- * account's draft, is refused and reported. Without that gate this would be a
158
- * general-purpose "delete any email by id" tool, which is not what it is for.
159
- */
160
- async function deleteOutlookDrafts(emailAccount, entryIds) {
161
- if (entryIds.length === 0)
162
- return { deleted: 0, failed: [] };
163
- const { valid, invalid } = (0, scripts_1.partitionMessageIds)(entryIds);
112
+ /** Run `verb` over named drafts of the account, each proved to be its own first. */
113
+ async function actOnDrafts(request, verb) {
114
+ const { valid, invalid } = (0, scripts_1.partitionMessageIds)(request.entryIds);
164
115
  if (valid.length === 0)
165
- return { deleted: 0, failed: invalid };
166
- const script = `tell application "Microsoft Outlook"
167
- ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
168
- set draftsFolder to drafts of targetAcct
116
+ return { done: 0, failed: invalid };
117
+ const acct = await (0, scripts_1.resolveMacAccount)(request.account);
118
+ const raw = await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
119
+ ${(0, scripts_1.accountLookupSnippet)(acct)}
120
+ ${(0, scripts_1.rootFolderSnippet)(acct, 'drafts', 'draftsFolder')}
169
121
  set draftsName to (name of draftsFolder) as string
170
122
  set draftIds to id of every message of draftsFolder
171
- set deletedCount to 0
123
+ set doneCount to 0
172
124
  set out to ""
173
- repeat with theId in {${valid.join(', ')}}
125
+ repeat with theId in ${(0, run_1.asIdList)(valid)}
126
+ set subj to ""
174
127
  try
175
128
  set theMsg to missing value
176
129
  try
177
130
  set theMsg to message id theId
178
131
  end try
179
132
  if theMsg is missing value then error "no such item in this account's Drafts folder"
180
- -- Prove it is in THIS account's Drafts before deleting: the folder it
181
- -- currently sits in, and the account it is bound to, must both match.
182
- set inFolder to ""
183
- try
184
- set inFolder to (name of (folder of theMsg)) as string
185
- end try
186
- if inFolder is not draftsName then error "item is not in this account's Drafts folder - refusing to delete"
187
- if draftIds does not contain (id of theMsg) then error "item is not in this account's Drafts folder - refusing to delete"
188
- set boundTo to ""
189
133
  try
190
- set boundTo to (email address of (account of theMsg)) as string
134
+ set subj to (subject of theMsg) as string
191
135
  end try
192
- if boundTo is not "" and boundTo is not (email address of targetAcct) then
193
- error "draft is not bound to this account - refusing to delete"
194
- end if
195
- delete theMsg
196
- set deletedCount to deletedCount + 1
136
+ ${ownDraftGuard(request.account, verb)}
137
+ ${verb} theMsg
138
+ set doneCount to doneCount + 1
197
139
  on error errText
198
- set out to out & ${(0, run_1.asRow)(['(theId as string)', 'errText'])}
140
+ set out to out & ${(0, run_1.asRow)(['(theId as string)', 'subj', 'errText'])}
199
141
  end try
200
142
  end repeat
201
- return ${(0, run_1.asRow)(['(deletedCount as string)'])} & out
202
- end tell`;
203
- const records = (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(script, 300000));
143
+ return ${(0, run_1.asRow)(['(doneCount as string)'])} & out
144
+ end tell`, 'scan');
145
+ const records = (0, run_1.splitRecords)(raw);
204
146
  return {
205
- deleted: (0, run_1.intField)((0, run_1.splitFields)(records[0] || ''), 0),
147
+ done: (0, run_1.intField)((0, run_1.splitFields)(records[0] ?? ''), 0),
206
148
  failed: [
207
149
  ...invalid,
208
150
  ...records.slice(1).map(record => {
209
151
  const parts = (0, run_1.splitFields)(record);
210
- return { entryId: (0, run_1.field)(parts, 0), error: (0, run_1.field)(parts, 1) };
152
+ return { entryId: (0, run_1.field)(parts, 0), subject: (0, run_1.field)(parts, 1), error: (0, run_1.field)(parts, 2) };
211
153
  }),
212
154
  ],
213
155
  };
214
156
  }
157
+ /** Send the named drafts. */
158
+ async function sendDrafts(request) {
159
+ const { done, failed } = await actOnDrafts(request, 'send');
160
+ return { sent: done, failed };
161
+ }
215
162
  /**
216
- * Send a chosen subset of `emailAccount`'s drafts by message id — e.g. after
217
- * `listOutlookDrafts` and a user review pass — instead of `sendAllDrafts`'s
218
- * account-wide sweep.
219
- *
220
- * Same ownership gate as `deleteOutlookDrafts`: every id must resolve to a
221
- * message sitting in THIS account's Drafts folder before anything is sent. An
222
- * id pointing at ordinary mail, or at another account's draft, is refused and
223
- * reported rather than sent.
163
+ * Delete the named drafts. `delete` files an item in Deleted Items, so a
164
+ * mistaken call stays recoverable.
224
165
  */
225
- async function sendDrafts(emailAccount, entryIds) {
226
- if (entryIds.length === 0)
227
- return { sent: 0, failed: [] };
228
- const { valid, invalid } = (0, scripts_1.partitionMessageIds)(entryIds);
229
- if (valid.length === 0) {
230
- return { sent: 0, failed: invalid.map(f => ({ entryId: f.entryId, subject: '', error: f.error })) };
231
- }
232
- const script = `tell application "Microsoft Outlook"
233
- ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
234
- set draftsFolder to drafts of targetAcct
235
- set draftsName to (name of draftsFolder) as string
236
- set draftIds to id of every message of draftsFolder
166
+ async function deleteOutlookDrafts(request) {
167
+ const { done, failed } = await actOnDrafts(request, 'delete');
168
+ return { deleted: done, failed };
169
+ }
170
+ /**
171
+ * Send every draft belonging to the account. The ids are snapshotted before the
172
+ * first send: sending moves an item out of Drafts, and mutating the collection
173
+ * mid-enumeration would skip every other one.
174
+ */
175
+ async function sendAllDrafts(request) {
176
+ const acct = await (0, scripts_1.resolveMacAccount)(request.account);
177
+ const raw = await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
178
+ ${(0, scripts_1.accountLookupSnippet)(acct)}
179
+ ${(0, scripts_1.rootFolderSnippet)(acct, 'drafts', 'draftsFolder')}
180
+ set wanted to id of every message of draftsFolder
237
181
  set sentCount to 0
238
182
  set out to ""
239
- repeat with theId in {${valid.join(', ')}}
183
+ repeat with theId in wanted
240
184
  set subj to ""
241
185
  try
242
186
  set theMsg to missing value
243
187
  try
244
188
  set theMsg to message id theId
245
189
  end try
246
- if theMsg is missing value then error "no such item in this account's Drafts folder"
190
+ if theMsg is missing value then error "draft is no longer in the Drafts folder"
247
191
  try
248
192
  set subj to (subject of theMsg) as string
249
193
  end try
250
- -- Prove it is in THIS account's Drafts before sending: the folder it
251
- -- currently sits in, and the account it is bound to, must both match.
252
- set inFolder to ""
253
- try
254
- set inFolder to (name of (folder of theMsg)) as string
255
- end try
256
- if inFolder is not draftsName then error "item is not in this account's Drafts folder - refusing to send"
257
- if draftIds does not contain (id of theMsg) then error "item is not in this account's Drafts folder - refusing to send"
258
- set boundTo to ""
259
- try
260
- set boundTo to (email address of (account of theMsg)) as string
261
- end try
262
- if boundTo is not "" and boundTo is not (email address of targetAcct) then
263
- error "draft is not bound to this account - refusing to send"
264
- end if
265
194
  send theMsg
266
195
  set sentCount to sentCount + 1
267
196
  on error errText
@@ -269,17 +198,14 @@ ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
269
198
  end try
270
199
  end repeat
271
200
  return ${(0, run_1.asRow)(['(sentCount as string)'])} & out
272
- end tell`;
273
- const records = (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(script, 300000));
201
+ end tell`, 'scan');
202
+ const records = (0, run_1.splitRecords)(raw);
274
203
  return {
275
- sent: (0, run_1.intField)((0, run_1.splitFields)(records[0] || ''), 0),
276
- failed: [
277
- ...invalid.map(f => ({ entryId: f.entryId, subject: '', error: f.error })),
278
- ...records.slice(1).map(record => {
279
- const parts = (0, run_1.splitFields)(record);
280
- return { entryId: (0, run_1.field)(parts, 0), subject: (0, run_1.field)(parts, 1), error: (0, run_1.field)(parts, 2) };
281
- }),
282
- ],
204
+ sent: (0, run_1.intField)((0, run_1.splitFields)(records[0] ?? ''), 0),
205
+ failed: records.slice(1).map(record => {
206
+ const parts = (0, run_1.splitFields)(record);
207
+ return { entryId: (0, run_1.field)(parts, 0), subject: (0, run_1.field)(parts, 1), error: (0, run_1.field)(parts, 2) };
208
+ }),
283
209
  };
284
210
  }
285
211
  //# sourceMappingURL=drafts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"drafts.js","sourceRoot":"","sources":["../../src/mac/drafts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"drafts.js","sourceRoot":"","sources":["../../src/mac/drafts.ts"],"names":[],"mappings":"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","sourcesContent":["// Drafts: which ones belong to an account, and listing, sending or deleting them.\n//\n// Where Windows scans two Drafts folders and proves each item's sending\n// account, macOS resolves the one Drafts folder belonging to the account —\n// through the account object, or by the folder's own id for a mailbox the\n// dictionary won't name (see profile.ts) — so a draft found there belongs to\n// the account by construction.\n//\n// What the folder can't vouch for is an item's own binding, which is why the\n// guards compare against the requested address as a literal rather than asking\n// `targetAcct`: there may be no account object to ask.\nimport {\n asIdList,\n asInt,\n asRow,\n asString,\n field,\n intField,\n runOsaScript,\n splitFields,\n splitList,\n splitRecords\n} from './run';\nimport {\n accountLookupSnippet,\n macFolderPath,\n partitionMessageIds,\n resolveMacAccount,\n rootFolderSnippet\n} from './scripts';\nimport type { AccountRequest, EntryIdsRequest, ListDraftsRequest } from '../backend';\nimport type { DeleteDraftsResult, ItemFailure, ListDraftsResult, SendDraftsResult } from '../types';\n\n/** The account's drafts, newest first. Bodies are previewed, never returned whole. */\nexport async function listOutlookDrafts(request: ListDraftsRequest): Promise<ListDraftsResult> {\n const acct = await resolveMacAccount(request.account);\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${accountLookupSnippet(acct)}\n${rootFolderSnippet(acct, 'drafts', 'draftsFolder')}\n set out to \"\"\n repeat with theMsg in (messages of draftsFolder)\n set subj to \"\"\n try\n set subj to (subject of theMsg) as string\n end try\n set toNames to {}\n set toAddrs to {}\n try\n repeat with r in (every to recipient of theMsg)\n try\n set ea to email address of r\n set oneAddr to \"\"\n set oneName to \"\"\n try\n set oneAddr to (address of ea) as string\n end try\n try\n set oneName to (name of ea) as string\n end try\n if oneName is \"\" then set oneName to oneAddr\n if oneName is not \"\" then set end of toNames to oneName\n if oneAddr is not \"\" then set end of toAddrs to oneAddr\n end try\n end repeat\n end try\n${preview}\n set attCount to 0\n try\n set attCount to count of attachments of theMsg\n end try\n set modAt to \"\"\n try\n set modAt to my isoDate(modification date of theMsg)\n end try\n set out to out & ${asRow(['(id of theMsg as string)', 'subj', 'my joinList(toNames, \", \")', 'my sanitizeList(toAddrs)', 'bodyText', '(attCount as string)', 'modAt'])}\n end repeat\n return out\nend tell`, 'standard');\n\n const folderPath = macFolderPath(request.account, 'Drafts', []);\n const drafts = splitRecords(raw).map(record => {\n const parts = splitFields(record);\n return {\n entryId: field(parts, 0),\n subject: field(parts, 1),\n to: field(parts, 2),\n toEmails: splitList(field(parts, 3)),\n bodyPreview: field(parts, 4).replace(/\\s+/g, ' ').trim(),\n hasAttachments: intField(parts, 5) > 0,\n lastModified: field(parts, 6),\n folderPath,\n };\n });\n drafts.sort((a, b) => b.lastModified.localeCompare(a.lastModified));\n return {\n account: request.account,\n foldersScanned: [folderPath],\n count: drafts.length,\n truncated: drafts.length > request.limit,\n drafts: drafts.slice(0, request.limit),\n };\n}\n\n/**\n * The AppleScript that proves `theMsg` is one of this account's drafts before\n * `verb` happens to it: it sits in the account's Drafts folder, and it is bound\n * to this account or to none.\n */\nfunction ownDraftGuard(emailAccount: string, verb: 'send' | 'delete'): string {\n return ` set inFolder to \"\"\n try\n set inFolder to (name of (folder of theMsg)) as string\n end try\n if inFolder is not draftsName or draftIds does not contain (id of theMsg) then error \"item is not in this account's Drafts folder - refusing to ${verb}\"\n set boundTo to \"\"\n try\n set boundTo to (email address of (account of theMsg)) as string\n end try\n if boundTo is not \"\" and boundTo is not ${asString(emailAccount)} then error \"draft is not bound to this account - refusing to ${verb}\"`;\n}\n\n/** Run `verb` over named drafts of the account, each proved to be its own first. */\nasync function actOnDrafts(request: EntryIdsRequest, verb: 'send' | 'delete'): Promise<{\n done: number;\n failed: ItemFailure[]\n}> {\n const {valid, invalid} = partitionMessageIds(request.entryIds);\n if (valid.length === 0) return {done: 0, failed: invalid};\n const acct = await resolveMacAccount(request.account);\n const raw = await runOsaScript(`tell application \"Microsoft Outlook\"\n${accountLookupSnippet(acct)}\n${rootFolderSnippet(acct, 'drafts', 'draftsFolder')}\n set draftsName to (name of draftsFolder) as string\n set draftIds to id of every message of draftsFolder\n set doneCount to 0\n set out to \"\"\n repeat with theId in ${asIdList(valid)}\n set subj to \"\"\n try\n set theMsg to missing value\n try\n set theMsg to message id theId\n end try\n if theMsg is missing value then error \"no such item in this account's Drafts folder\"\n try\n set subj to (subject of theMsg) as string\n end try\n${ownDraftGuard(request.account, verb)}\n ${verb} theMsg\n set doneCount to doneCount + 1\n on error errText\n set out to out & ${asRow(['(theId as string)', 'subj', 'errText'])}\n end try\n end repeat\n return ${asRow(['(doneCount as string)'])} & out\nend tell`, 'scan');\n const records = splitRecords(raw);\n return {\n done: intField(splitFields(records[0] ?? ''), 0),\n failed: [\n ...invalid,\n ...records.slice(1).map(record => {\n const parts = splitFields(record);\n return {entryId: field(parts, 0), subject: field(parts, 1), error: field(parts, 2)};\n }),\n ],\n };\n}\n\n/** Send the named drafts. */\nexport async function sendDrafts(request: EntryIdsRequest): Promise<SendDraftsResult> {\n const {done, failed} = await actOnDrafts(request, 'send');\n return {sent: done, failed};\n}\n\n/**\n * Delete the named drafts. `delete` files an item in Deleted Items, so a\n * mistaken call stays recoverable.\n */\nexport async function deleteOutlookDrafts(request: EntryIdsRequest): Promise<DeleteDraftsResult> {\n const {done, failed} = await actOnDrafts(request, 'delete');\n return {deleted: done, failed};\n}\n\n/**\n * Send every draft belonging to the account. The ids are snapshotted before the\n * first send: sending moves an item out of Drafts, and mutating the collection\n * mid-enumeration would skip every other one.\n */\nexport async function sendAllDrafts(request: AccountRequest): Promise<SendDraftsResult> {\n const acct = await resolveMacAccount(request.account);\n const raw = await runOsaScript(`tell application \"Microsoft Outlook\"\n${accountLookupSnippet(acct)}\n${rootFolderSnippet(acct, 'drafts', 'draftsFolder')}\n set wanted to id of every message of draftsFolder\n set sentCount to 0\n set out to \"\"\n repeat with theId in wanted\n set subj to \"\"\n try\n set theMsg to missing value\n try\n set theMsg to message id theId\n end try\n if theMsg is missing value then error \"draft is no longer in the Drafts folder\"\n try\n set subj to (subject of theMsg) as string\n end try\n send theMsg\n set sentCount to sentCount + 1\n on error errText\n set out to out & ${asRow(['(theId as string)', 'subj', 'errText'])}\n end try\n end repeat\n return ${asRow(['(sentCount as string)'])} & out\nend tell`, 'scan');\n const records = splitRecords(raw);\n return {\n sent: intField(splitFields(records[0] ?? ''), 0),\n failed: records.slice(1).map(record => {\n const parts = splitFields(record);\n return {entryId: field(parts, 0), subject: field(parts, 1), error: field(parts, 2)};\n }),\n };\n}\n"]}
@@ -1,28 +1,17 @@
1
+ import type { ListFoldersRequest, MoveRequest } from '../backend';
1
2
  import type { InboxFolderInfo, MoveEmailsResult } from '../types';
2
3
  /**
3
- * List the folders under an account's Inbox with their item counts.
4
- *
5
- * The recursive walk joins path segments with the LIST separator rather than a
6
- * backslash: a literal backslash would have to survive a JS template literal and
7
- * then an AppleScript string literal, and the `folderPath` shape is assembled in
8
- * TypeScript anyway (see macFolderPath).
4
+ * The folders under an account's Inbox with their message counts. Path segments
5
+ * travel joined by the LIST separator and are assembled into a folder path in
6
+ * TypeScript, rather than pushed through two layers of backslash escaping.
9
7
  */
10
- export declare function listInboxFolders(emailAccount: string, maxDepth?: number): Promise<InboxFolderInfo[]>;
8
+ export declare function listInboxFolders(request: ListFoldersRequest): Promise<InboxFolderInfo[]>;
11
9
  /**
12
- * Move emails (by message id) into any folder of the account — a filing folder
13
- * under the Inbox, or a well-known folder by name (see WELL_KNOWN_FOLDERS).
14
- *
15
- * **Moving to "Deleted Items" is how mail gets deleted reversibly**, which is why
16
- * this takes well-known roots at all: it means the destructive path and the filing
17
- * path are one tool, and the destructive one is undoable from the folder it lands in.
18
- *
19
- * `createIfMissing` builds the WHOLE missing chain, so a nested destination
20
- * ("Clients\\Acme\\2026") is one call rather than a manual mkdir first.
21
- * NOTE: moving changes a message's id — the passed ids are dead afterwards.
10
+ * File emails into a folder of the account. Moving rewrites each message's id.
22
11
  *
23
12
  * Outlook for Mac's `move` reports success even where it silently does nothing,
24
- * so the destination's message count is compared before and after. A run where
25
- * every move "succeeded" and yet the folder never grew fails loudly instead of
26
- * reporting mail that was never filed.
13
+ * so the destination's count is compared before and after: a run where every
14
+ * move "succeeded" yet the folder never grew fails rather than reporting mail
15
+ * that was never filed.
27
16
  */
28
- export declare function moveOutlookEmails(emailAccount: string, entryIds: string[], folderName: string, createIfMissing?: boolean): Promise<MoveEmailsResult>;
17
+ export declare function moveOutlookEmails(request: MoveRequest): Promise<MoveEmailsResult>;
@@ -5,18 +5,14 @@ exports.moveOutlookEmails = moveOutlookEmails;
5
5
  // Listing the folders under an Inbox, and filing mail into one.
6
6
  const run_1 = require("./run");
7
7
  const scripts_1 = require("./scripts");
8
- const mail_1 = require("../mail");
9
8
  /**
10
- * List the folders under an account's Inbox with their item counts.
11
- *
12
- * The recursive walk joins path segments with the LIST separator rather than a
13
- * backslash: a literal backslash would have to survive a JS template literal and
14
- * then an AppleScript string literal, and the `folderPath` shape is assembled in
15
- * TypeScript anyway (see macFolderPath).
9
+ * The folders under an account's Inbox with their message counts. Path segments
10
+ * travel joined by the LIST separator and are assembled into a folder path in
11
+ * TypeScript, rather than pushed through two layers of backslash escaping.
16
12
  */
17
- async function listInboxFolders(emailAccount, maxDepth = 2) {
18
- const depth = (0, mail_1.clamp)(maxDepth, 1, 4);
19
- const script = `on walkFolders(theFolder, level, maxLevel, prefix)
13
+ async function listInboxFolders(request) {
14
+ const acct = await (0, scripts_1.resolveMacAccount)(request.account);
15
+ const raw = await (0, run_1.runOsaScript)(`on walkFolders(theFolder, level, maxLevel, prefix)
20
16
  set out to ""
21
17
  tell application "Microsoft Outlook"
22
18
  set subs to mail folders of theFolder
@@ -42,65 +38,55 @@ async function listInboxFolders(emailAccount, maxDepth = 2) {
42
38
  end walkFolders
43
39
 
44
40
  tell application "Microsoft Outlook"
45
- ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
46
- set inb to inbox of targetAcct
41
+ ${(0, scripts_1.accountLookupSnippet)(acct)}
42
+ ${(0, scripts_1.rootFolderSnippet)(acct, 'inbox', 'inb')}
47
43
  end tell
48
- return my walkFolders(inb, 1, ${depth}, "")`;
49
- return (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(script, 120000)).map(record => {
44
+ return my walkFolders(inb, 1, ${(0, run_1.asInt)(request.maxDepth)}, "")`, 'standard');
45
+ return (0, run_1.splitRecords)(raw).map(record => {
50
46
  const parts = (0, run_1.splitFields)(record);
51
- const segments = (0, run_1.splitList)((0, run_1.field)(parts, 1));
52
47
  return {
53
48
  name: (0, run_1.field)(parts, 0),
54
- folderPath: (0, scripts_1.macFolderPath)(emailAccount, 'Inbox', segments),
49
+ folderPath: (0, scripts_1.macFolderPath)(request.account, 'Inbox', (0, run_1.splitList)((0, run_1.field)(parts, 1))),
55
50
  itemCount: (0, run_1.intField)(parts, 2),
56
51
  depth: (0, run_1.intField)(parts, 3, 1),
57
52
  };
58
53
  });
59
54
  }
60
55
  /**
61
- * Move emails (by message id) into any folder of the account — a filing folder
62
- * under the Inbox, or a well-known folder by name (see WELL_KNOWN_FOLDERS).
63
- *
64
- * **Moving to "Deleted Items" is how mail gets deleted reversibly**, which is why
65
- * this takes well-known roots at all: it means the destructive path and the filing
66
- * path are one tool, and the destructive one is undoable from the folder it lands in.
67
- *
68
- * `createIfMissing` builds the WHOLE missing chain, so a nested destination
69
- * ("Clients\\Acme\\2026") is one call rather than a manual mkdir first.
70
- * NOTE: moving changes a message's id — the passed ids are dead afterwards.
56
+ * File emails into a folder of the account. Moving rewrites each message's id.
71
57
  *
72
58
  * Outlook for Mac's `move` reports success even where it silently does nothing,
73
- * so the destination's message count is compared before and after. A run where
74
- * every move "succeeded" and yet the folder never grew fails loudly instead of
75
- * reporting mail that was never filed.
59
+ * so the destination's count is compared before and after: a run where every
60
+ * move "succeeded" yet the folder never grew fails rather than reporting mail
61
+ * that was never filed.
76
62
  */
77
- async function moveOutlookEmails(emailAccount, entryIds, folderName, createIfMissing = false) {
78
- if (entryIds.length === 0) {
79
- return { folderPath: '', folderCreated: false, moved: 0, failed: [] };
80
- }
81
- const ref = (0, mail_1.mailFolderRef)(folderName);
82
- const { valid, invalid } = (0, scripts_1.partitionMessageIds)(entryIds);
83
- const folderPath = (0, scripts_1.macFolderPath)(emailAccount, ref.rootLabel, ref.segments);
84
- if (valid.length === 0) {
63
+ async function moveOutlookEmails(request) {
64
+ const folderPath = (0, scripts_1.macFolderPath)(request.account, request.folder.rootLabel, request.folder.segments);
65
+ const { valid, invalid } = (0, scripts_1.partitionMessageIds)(request.entryIds);
66
+ if (valid.length === 0)
85
67
  return { folderPath, folderCreated: false, moved: 0, failed: invalid };
86
- }
87
- const script = `tell application "Microsoft Outlook"
88
- ${(0, scripts_1.accountLookupSnippet)(emailAccount)}
89
- ${(0, scripts_1.mailScopeSnippet)(ref, folderName, createIfMissing)}
68
+ const acct = await (0, scripts_1.resolveMacAccount)(request.account);
69
+ const raw = await (0, run_1.runOsaScript)(`tell application "Microsoft Outlook"
70
+ ${(0, scripts_1.accountLookupSnippet)(acct)}
71
+ ${(0, scripts_1.mailScopeSnippet)(acct, request.folder, request.folderLabel, request.createIfMissing)}
90
72
  set countBefore to count of messages of scopeFolder
91
73
  set movedCount to 0
92
74
  set out to ""
93
- repeat with theId in {${valid.join(', ')}}
75
+ repeat with theId in ${(0, run_1.asIdList)(valid)}
76
+ set subj to ""
94
77
  try
95
78
  set theMsg to missing value
96
79
  try
97
80
  set theMsg to message id theId
98
81
  end try
99
82
  if theMsg is missing value then error "no message with that id in this Outlook"
83
+ try
84
+ set subj to (subject of theMsg) as string
85
+ end try
100
86
  move theMsg to scopeFolder
101
87
  set movedCount to movedCount + 1
102
88
  on error errText
103
- set out to out & ${(0, run_1.asRow)(['(theId as string)', 'errText'])}
89
+ set out to out & ${(0, run_1.asRow)(['(theId as string)', 'subj', 'errText'])}
104
90
  end try
105
91
  end repeat
106
92
  set countAfter to count of messages of scopeFolder
@@ -108,9 +94,9 @@ ${(0, scripts_1.mailScopeSnippet)(ref, folderName, createIfMissing)}
108
94
  error "Outlook reported " & (movedCount as string) & " move(s) but '" & (name of scopeFolder) & "' did not grow - nothing was filed."
109
95
  end if
110
96
  return ${(0, run_1.asRow)(['(movedCount as string)', '(scopeCreated as string)'])} & out
111
- end tell`;
112
- const records = (0, run_1.splitRecords)(await (0, run_1.runOsaScript)(script, 300000));
113
- const summary = (0, run_1.splitFields)(records[0] || '');
97
+ end tell`, 'scan');
98
+ const records = (0, run_1.splitRecords)(raw);
99
+ const summary = (0, run_1.splitFields)(records[0] ?? '');
114
100
  return {
115
101
  folderPath,
116
102
  folderCreated: (0, run_1.boolField)(summary, 1),
@@ -119,7 +105,7 @@ end tell`;
119
105
  ...invalid,
120
106
  ...records.slice(1).map(record => {
121
107
  const parts = (0, run_1.splitFields)(record);
122
- return { entryId: (0, run_1.field)(parts, 0), error: (0, run_1.field)(parts, 1) };
108
+ return { entryId: (0, run_1.field)(parts, 0), subject: (0, run_1.field)(parts, 1), error: (0, run_1.field)(parts, 2) };
123
109
  }),
124
110
  ],
125
111
  };
@@ -1 +1 @@
1
- {"version":3,"file":"folders.js","sourceRoot":"","sources":["../../src/mac/folders.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"folders.js","sourceRoot":"","sources":["../../src/mac/folders.ts"],"names":[],"mappings":"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","sourcesContent":["// Listing the folders under an Inbox, and filing mail into one.\nimport {\n AS_LIST_SEP,\n asIdList,\n asInt,\n asRow,\n boolField,\n field,\n intField,\n runOsaScript,\n splitFields,\n splitList,\n splitRecords\n} from './run';\nimport {\n accountLookupSnippet,\n macFolderPath,\n mailScopeSnippet,\n partitionMessageIds,\n resolveMacAccount,\n rootFolderSnippet,\n} from './scripts';\nimport type { ListFoldersRequest, MoveRequest } from '../backend';\nimport type { InboxFolderInfo, MoveEmailsResult } from '../types';\n\n/**\n * The folders under an account's Inbox with their message counts. Path segments\n * travel joined by the LIST separator and are assembled into a folder path in\n * TypeScript, rather than pushed through two layers of backslash escaping.\n */\nexport async function listInboxFolders(request: ListFoldersRequest): Promise<InboxFolderInfo[]> {\n const acct = await resolveMacAccount(request.account);\n const raw = await runOsaScript(`on walkFolders(theFolder, level, maxLevel, prefix)\n set out to \"\"\n tell application \"Microsoft Outlook\"\n set subs to mail folders of theFolder\n end tell\n repeat with f in subs\n set nm to \"\"\n set cnt to 0\n tell application \"Microsoft Outlook\"\n try\n set nm to (name of f) as string\n end try\n try\n set cnt to (count of messages of f)\n end try\n end tell\n set thisPath to prefix & nm\n set out to out & ${asRow(['nm', 'thisPath', '(cnt as string)', '(level as string)'])}\n if level < maxLevel then\n set out to out & (my walkFolders(f, level + 1, maxLevel, thisPath & ${AS_LIST_SEP}))\n end if\n end repeat\n return out\nend walkFolders\n\ntell application \"Microsoft Outlook\"\n${accountLookupSnippet(acct)}\n${rootFolderSnippet(acct, 'inbox', 'inb')}\nend tell\nreturn my walkFolders(inb, 1, ${asInt(request.maxDepth)}, \"\")`, 'standard');\n return splitRecords(raw).map(record => {\n const parts = splitFields(record);\n return {\n name: field(parts, 0),\n folderPath: macFolderPath(request.account, 'Inbox', splitList(field(parts, 1))),\n itemCount: intField(parts, 2),\n depth: intField(parts, 3, 1),\n };\n });\n}\n\n/**\n * File emails into a folder of the account. Moving rewrites each message's id.\n *\n * Outlook for Mac's `move` reports success even where it silently does nothing,\n * so the destination's count is compared before and after: a run where every\n * move \"succeeded\" yet the folder never grew fails rather than reporting mail\n * that was never filed.\n */\nexport async function moveOutlookEmails(request: MoveRequest): Promise<MoveEmailsResult> {\n const folderPath = macFolderPath(request.account, request.folder.rootLabel, request.folder.segments);\n const {valid, invalid} = partitionMessageIds(request.entryIds);\n if (valid.length === 0) return {folderPath, folderCreated: false, moved: 0, failed: invalid};\n const acct = await resolveMacAccount(request.account);\n const raw = await runOsaScript(`tell application \"Microsoft Outlook\"\n${accountLookupSnippet(acct)}\n${mailScopeSnippet(acct, request.folder, request.folderLabel, request.createIfMissing)}\n set countBefore to count of messages of scopeFolder\n set movedCount to 0\n set out to \"\"\n repeat with theId in ${asIdList(valid)}\n set subj to \"\"\n try\n set theMsg to missing value\n try\n set theMsg to message id theId\n end try\n if theMsg is missing value then error \"no message with that id in this Outlook\"\n try\n set subj to (subject of theMsg) as string\n end try\n move theMsg to scopeFolder\n set movedCount to movedCount + 1\n on error errText\n set out to out & ${asRow(['(theId as string)', 'subj', 'errText'])}\n end try\n end repeat\n set countAfter to count of messages of scopeFolder\n if movedCount > 0 and countAfter is not greater than countBefore then\n error \"Outlook reported \" & (movedCount as string) & \" move(s) but '\" & (name of scopeFolder) & \"' did not grow - nothing was filed.\"\n end if\n return ${asRow(['(movedCount as string)', '(scopeCreated as string)'])} & out\nend tell`, 'scan');\n const records = splitRecords(raw);\n const summary = splitFields(records[0] ?? '');\n return {\n folderPath,\n folderCreated: boolField(summary, 1),\n moved: intField(summary, 0),\n failed: [\n ...invalid,\n ...records.slice(1).map(record => {\n const parts = splitFields(record);\n return {entryId: field(parts, 0), subject: field(parts, 1), error: field(parts, 2)};\n }),\n ],\n };\n}\n"]}