@dawnlit/outlook-bridge 1.1.1 → 2.1.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 +152 -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 +79 -43
- package/dist/errors.js +93 -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 +96 -117
- package/dist/mac/bounces.js.map +1 -1
- package/dist/mac/cleanup.d.ts +11 -25
- package/dist/mac/cleanup.js +44 -107
- package/dist/mac/cleanup.js.map +1 -1
- package/dist/mac/drafts.d.ts +15 -34
- package/dist/mac/drafts.js +113 -186
- package/dist/mac/drafts.js.map +1 -1
- package/dist/mac/folders.d.ts +12 -21
- package/dist/mac/folders.js +44 -59
- 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 +21 -37
- package/dist/mac/read.js +198 -216
- package/dist/mac/read.js.map +1 -1
- package/dist/mac/run.d.ts +51 -38
- package/dist/mac/run.js +138 -103
- package/dist/mac/run.js.map +1 -1
- package/dist/mac/scripts.d.ts +90 -91
- package/dist/mac/scripts.js +167 -126
- package/dist/mac/scripts.js.map +1 -1
- package/dist/mac/send.d.ts +10 -20
- package/dist/mac/send.js +99 -89
- 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 +79 -120
- package/dist/mac/templates.js.map +1 -1
- package/dist/mail.d.ts +80 -46
- package/dist/mail.js +179 -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 +26 -20
- package/dist/shared/attachmentMatch.js +60 -23
- 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 +17 -6
- package/dist/shared/json.js +35 -24
- package/dist/shared/json.js.map +1 -1
- package/dist/shared/locate.d.ts +31 -0
- package/dist/shared/locate.js +128 -0
- package/dist/shared/locate.js.map +1 -0
- package/dist/shared/replyBody.d.ts +31 -36
- package/dist/shared/replyBody.js +83 -72
- package/dist/shared/replyBody.js.map +1 -1
- package/dist/shared/templateLimits.d.ts +14 -0
- package/dist/shared/templateLimits.js +21 -0
- package/dist/shared/templateLimits.js.map +1 -0
- package/dist/templateBody.d.ts +69 -0
- package/dist/{outlookTemplateSections.js → templateBody.js} +80 -73
- package/dist/templateBody.js.map +1 -0
- package/dist/types.d.ts +381 -168
- package/dist/types.js +8 -9
- package/dist/types.js.map +1 -1
- package/dist/windows/accounts.d.ts +7 -12
- package/dist/windows/accounts.js +19 -34
- package/dist/windows/accounts.js.map +1 -1
- package/dist/windows/attachments.d.ts +9 -24
- package/dist/windows/attachments.js +94 -119
- package/dist/windows/attachments.js.map +1 -1
- package/dist/windows/bounces.d.ts +13 -26
- package/dist/windows/bounces.js +168 -200
- package/dist/windows/bounces.js.map +1 -1
- package/dist/windows/cleanup.d.ts +23 -23
- package/dist/windows/cleanup.js +99 -113
- package/dist/windows/cleanup.js.map +1 -1
- package/dist/windows/drafts.d.ts +16 -35
- package/dist/windows/drafts.js +156 -253
- package/dist/windows/drafts.js.map +1 -1
- package/dist/windows/folders.d.ts +8 -13
- package/dist/windows/folders.js +44 -52
- package/dist/windows/folders.js.map +1 -1
- package/dist/windows/index.d.ts +2 -27
- package/dist/windows/index.js +11 -66
- package/dist/windows/index.js.map +1 -1
- package/dist/windows/read.d.ts +24 -60
- package/dist/windows/read.js +265 -306
- package/dist/windows/read.js.map +1 -1
- package/dist/windows/run.d.ts +38 -40
- package/dist/windows/run.js +151 -112
- package/dist/windows/run.js.map +1 -1
- package/dist/windows/scripts.d.ts +65 -55
- package/dist/windows/scripts.js +109 -85
- package/dist/windows/scripts.js.map +1 -1
- package/dist/windows/send.d.ts +9 -9
- package/dist/windows/send.js +76 -88
- package/dist/windows/send.js.map +1 -1
- package/dist/windows/signatures.d.ts +4 -10
- package/dist/windows/signatures.js +30 -37
- package/dist/windows/signatures.js.map +1 -1
- package/dist/windows/templates.d.ts +12 -18
- package/dist/windows/templates.js +117 -150
- 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.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 splitPositionalList,\n splitRecords,\n summaryFields,\n} from './run';\nimport { readProfileAccounts } from './profile';\nimport {\n accountLookupSnippet,\n dateProperty,\n firstRecipientSnippet,\n folderChainSnippet,\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(' ') : senderSnippet(' ')}\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 sanitizePositionalList(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 = splitPositionalList(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: splitPositionalList(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 this test is too, whatever the\n // caller's flags. Only u and v are kept: they decide how the source parses,\n // and without u, /\\p{L}/u would match the literal text \"p{L}\". Keeping g or y\n // would carry lastIndex from one subject to the next.\n const patternRe = request.subjectPattern\n ? new RegExp(request.subjectPattern.source, 'i' + request.subjectPattern.flags.replace(/[^uv]/g, ''))\n : 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 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(' ')}\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 sanitizePositionalList(attNames)', 'bodyText'])}\n end if\n end repeat\n return out\nend tell`, 'scan');\n const details = new Map(splitRecords(raw).map(record => {\n const parts = splitFields(record);\n const detail = {\n senderName: field(parts, 1),\n senderEmail: field(parts, 2),\n attachmentNames: splitPositionalList(field(parts, 3)),\n body: field(parts, 4),\n };\n return [field(parts, 0), detail] as const;\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 *\n * Where it sits comes back as a second record, so the detail row keeps its body\n * last. A mailbox with no account object answers `account of` with missing\n * value; its root folder's id is then looked up in the profile database.\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 set acctAddr to \"\"\n try\n set rawAddr to email address of (account of theMsg)\n if rawAddr is not missing value then set acctAddr to rawAddr as string\n end try\n set chainNames to {}\n set rootId to \"\"\n set theFolder to missing value\n try\n set theFolder to folder of theMsg\n end try\n if theFolder is not missing value then\n${folderChainSnippet(' ')}\n try\n set rootId to (id of cur) as string\n end try\n end if\n return ${asRow(messageDetailFields(true))} & ${asRow(['acctAddr', 'my sanitizeList(chainNames)', 'rootId'])}\nend tell`, 'quick'));\n if (records.length === 0) throw new NotFoundError('email', 'Outlook reported no selected email.');\n const parts = splitFields(records[0]);\n const where = splitFields(records[1] ?? '');\n const chain = splitList(field(where, 1)).reverse();\n const account = field(where, 0) || (chain.length ? await accountByRootFolder(field(where, 2)) : '');\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: splitPositionalList(field(parts, MessageDetail.attachmentNames)),\n folderPath: account && chain.length ? macFolderPath(account, chain[0], chain.slice(1)) : '',\n };\n}\n\n/** The address of the account whose root folder has this id, per the profile database; '' if none. */\nasync function accountByRootFolder(rootId: string): Promise<string> {\n if (!/^\\d+$/.test(rootId)) return '';\n const id = Number(rootId);\n return (await readProfileAccounts()).find(a => a.folderIds['root folder'] === id)?.emailAccount ?? '';\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"]}
|
package/dist/mac/run.d.ts
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
|
+
import { type RunBudget } from '../runtime';
|
|
2
|
+
import type { ItemFailure } from '../types';
|
|
1
3
|
/**
|
|
2
|
-
* Run
|
|
4
|
+
* Run a script from a temp file (no argument-length or quoting limits) and
|
|
5
|
+
* return what it printed, minus the newline osascript appends.
|
|
3
6
|
*
|
|
4
|
-
* `AS_HANDLERS` is prepended here rather than by each caller
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* `AS_HANDLERS` is prepended here rather than by each caller: a script missing
|
|
8
|
+
* a handler fails to compile as a WHOLE, with an error pointing nowhere near the
|
|
9
|
+
* omission, so it can't be left to each script to remember.
|
|
10
|
+
*/
|
|
11
|
+
export declare function runOsaScript(source: string, budget: RunBudget): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Escape text for the inside of an AppleScript double-quoted literal.
|
|
14
|
+
* AppleScript strings never interpolate, so escaping the quote, the backslash
|
|
15
|
+
* and line breaks is the whole job.
|
|
12
16
|
*/
|
|
13
|
-
export declare function
|
|
14
|
-
/**
|
|
15
|
-
export declare function
|
|
17
|
+
export declare function asEscape(text: string): string;
|
|
18
|
+
/** Text as an AppleScript string literal. */
|
|
19
|
+
export declare function asString(text: string): string;
|
|
16
20
|
/** AppleScript's boolean literals. */
|
|
17
21
|
export declare function asBool(value: boolean): string;
|
|
22
|
+
/** A whole number for a script; anything else is refused before it becomes code. */
|
|
23
|
+
export declare function asInt(value: number): string;
|
|
24
|
+
/** Message ids (already validated as integers) as an AppleScript list literal. */
|
|
25
|
+
export declare function asIdList(ids: readonly string[]): string;
|
|
18
26
|
export declare const FIELD_SEP = "\u001F";
|
|
19
27
|
export declare const RECORD_SEP = "\u001E";
|
|
20
28
|
export declare const LIST_SEP = "\u001D";
|
|
@@ -23,42 +31,47 @@ export declare const AS_FIELD_SEP = "(character id 31)";
|
|
|
23
31
|
export declare const AS_RECORD_SEP = "(character id 30)";
|
|
24
32
|
export declare const AS_LIST_SEP = "(character id 29)";
|
|
25
33
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* rather than merely unlikely to break. A field holding a LIST must be built
|
|
31
|
-
* with `my sanitizeList(...)`, which cleans the elements instead — `sanitize`
|
|
32
|
-
* deliberately leaves the list separator alone.
|
|
34
|
+
* One record: the AppleScript expressions in `fields`, separated and terminated
|
|
35
|
+
* so `splitRecords`/`splitFields` can take them apart again. A field holding a
|
|
36
|
+
* LIST must be built with `my sanitizeList(...)`, which cleans the elements —
|
|
37
|
+
* `sanitize` deliberately leaves the list separator alone.
|
|
33
38
|
*/
|
|
34
39
|
export declare function asRow(fields: readonly string[]): string;
|
|
35
40
|
/**
|
|
36
|
-
* The
|
|
37
|
-
* inside a `tell` block.
|
|
41
|
+
* The handlers every script relies on, called with `my` from inside a `tell`.
|
|
38
42
|
*
|
|
39
|
-
* `isoDate` produces the zero-padded 'yyyy-MM-dd HH:mm' both platforms
|
|
40
|
-
*
|
|
41
|
-
*
|
|
43
|
+
* `isoDate` produces the zero-padded 'yyyy-MM-dd HH:mm' both platforms return;
|
|
44
|
+
* `sanitize` strips the framing characters; `joinList` and `replaceText` are the
|
|
45
|
+
* text-item-delimiter dance nobody should write twice.
|
|
42
46
|
*/
|
|
43
|
-
export declare const AS_HANDLERS = "\non pad2(n)\n set s to (n as integer) as string\n if (length of s) < 2 then set s to \"0\" & s\n return s\nend pad2\n\non isoDate(d)\n if d is missing value then return \"\"\n return (year of d as string) & \"-\" & pad2(month of d as integer) & \"-\" & pad2(day of d) & \" \" & pad2(hours of d) & \":\" & pad2(minutes of d)\nend isoDate\n\non joinList(lst, sep)\n set saved to AppleScript's text item delimiters\n set AppleScript's text item delimiters to sep\n set out to lst as string\n set AppleScript's text item delimiters to saved\n return out\nend joinList\n\non replaceText(t, findWhat, replaceWith)\n set saved to AppleScript's text item delimiters\n set AppleScript's text item delimiters to findWhat\n set parts to text items of t\n set AppleScript's text item delimiters to replaceWith\n set out to parts as string\n set AppleScript's text item delimiters to saved\n return out\nend replaceText\n\n-- Strips the FIELD and RECORD separators only. The LIST separator is left\n-- alone on purpose: a field may legitimately BE a list
|
|
44
|
-
/**
|
|
47
|
+
export declare const AS_HANDLERS = "\non pad2(n)\n set s to (n as integer) as string\n if (length of s) < 2 then set s to \"0\" & s\n return s\nend pad2\n\non isoDate(d)\n if d is missing value then return \"\"\n return (year of d as string) & \"-\" & pad2(month of d as integer) & \"-\" & pad2(day of d) & \" \" & pad2(hours of d) & \":\" & pad2(minutes of d)\nend isoDate\n\non joinList(lst, sep)\n set saved to AppleScript's text item delimiters\n set AppleScript's text item delimiters to sep\n set out to lst as string\n set AppleScript's text item delimiters to saved\n return out\nend joinList\n\non replaceText(t, findWhat, replaceWith)\n set saved to AppleScript's text item delimiters\n set AppleScript's text item delimiters to findWhat\n set parts to text items of t\n set AppleScript's text item delimiters to replaceWith\n set out to parts as string\n set AppleScript's text item delimiters to saved\n return out\nend replaceText\n\n-- Strips the FIELD and RECORD separators only. The LIST separator is left\n-- alone on purpose: a field may legitimately BE a list.\non sanitize(v)\n if v is missing value then return \"\"\n set t to v as string\n repeat with codePoint in {30, 31}\n set marker to (character id (codePoint as integer))\n if t contains marker then set t to my replaceText(t, marker, \" \")\n end repeat\n return t\nend sanitize\n\n-- A list field: each element loses all three separators, then they are joined\n-- with the LIST separator that splitList() takes them apart on.\non sanitizeList(lst)\n set cleaned to {}\n repeat with item_ in lst\n set t to my sanitize(item_)\n set marker to (character id 29)\n if t contains marker then set t to my replaceText(t, marker, \" \")\n set end of cleaned to t\n end repeat\n return my joinList(cleaned, (character id 29))\nend sanitizeList\n\n-- A list whose positions matter, like an email's attachments: every element is\n-- FOLLOWED by the LIST separator, so an empty element keeps its place and an\n-- empty list stays distinct from a list of one empty name. splitPositionalList()\n-- takes it apart.\non sanitizePositionalList(lst)\n if (count of lst) is 0 then return \"\"\n return my sanitizeList(lst) & (character id 29)\nend sanitizePositionalList\n\non insertAboveQuoted(c, ins)\n if c is missing value then return ins\n set c to c as string\n if (length of c) is 0 then return ins\n -- A reply's own empty paragraph sits inside WordSection1; inserting straight\n -- after that tag puts the new text where the cursor would be. Anything else\n -- falls back to just inside <body>. ('at' is a reserved parameter name, so\n -- the cut point can't be called that.)\n set cutPoint to my tagEnd(c, \"WordSection1>\")\n if cutPoint is 0 then set cutPoint to my tagEnd(c, \"<body\")\n if cutPoint is 0 then return ins & c\n if cutPoint is (length of c) then return c & ins\n return (text 1 thru cutPoint of c) & ins & (text (cutPoint + 1) thru -1 of c)\nend insertAboveQuoted\n\n-- 'rest' is an AppleScript term, so the remainder can't be called that:\n-- assigning to it compiles and then fails at run time.\non tagEnd(c, marker)\n set ix to offset of marker in c\n if ix is 0 then return 0\n if marker ends with \">\" then return ix + (length of marker) - 1\n set tailText to text ix thru -1 of c\n set gt to offset of \">\" in tailText\n if gt is 0 then return 0\n return ix + gt - 1\nend tagEnd\n";
|
|
48
|
+
/** A script's output as records, without the trailing empty one. */
|
|
45
49
|
export declare function splitRecords(raw: string): string[];
|
|
46
|
-
/**
|
|
50
|
+
/** One record's fields. */
|
|
47
51
|
export declare function splitFields(record: string): string[];
|
|
48
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* A field that carries a list. Empty elements are dropped, so where an index
|
|
54
|
+
* into the list must match Outlook's, the field is written with
|
|
55
|
+
* `sanitizePositionalList` and read with `splitPositionalList` instead.
|
|
56
|
+
*/
|
|
49
57
|
export declare function splitList(value: string | undefined): string[];
|
|
50
|
-
/** A field by position — a missing field reads as ''. */
|
|
51
|
-
export declare function field(fields: readonly string[], index: number): string;
|
|
52
58
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
59
|
+
* A field written by `sanitizePositionalList`: every element at its position,
|
|
60
|
+
* empty ones included, so index N here is item N+1 of the AppleScript list.
|
|
55
61
|
*/
|
|
62
|
+
export declare function splitPositionalList(value: string | undefined): string[];
|
|
63
|
+
/** A field by position; a missing field reads as ''. */
|
|
64
|
+
export declare function field(fields: readonly string[], index: number): string;
|
|
65
|
+
/** The fields of a script's first record — the summary a mutation returns ahead of any per-item rows. */
|
|
56
66
|
export declare function summaryFields(raw: string): string[];
|
|
57
|
-
/** A numeric field,
|
|
67
|
+
/** A numeric field, `fallback` when absent or unparsable. */
|
|
58
68
|
export declare function intField(fields: readonly string[], index: number, fallback?: number): number;
|
|
59
|
-
/**
|
|
60
|
-
* A boolean field. AppleScript renders booleans as the bare words `true`/`false`,
|
|
61
|
-
* so this is the counterpart of `shared/json.ts`'s coercions for the framed
|
|
62
|
-
* output — the Windows side gets those free from ConvertFrom-Json.
|
|
63
|
-
*/
|
|
69
|
+
/** A boolean field; AppleScript renders booleans as the bare words true/false. */
|
|
64
70
|
export declare function boolField(fields: readonly string[], index: number): boolean;
|
|
71
|
+
/** The record a batch script appends, inside `on error errText`, for the id `theId` it failed on. */
|
|
72
|
+
export declare const ITEM_FAILURE_ROW: string;
|
|
73
|
+
/** A batch script's output: the summary record's fields, and the items that failed. */
|
|
74
|
+
export declare function splitBatch(raw: string): {
|
|
75
|
+
summary: string[];
|
|
76
|
+
failed: ItemFailure[];
|
|
77
|
+
};
|
package/dist/mac/run.js
CHANGED
|
@@ -3,114 +3,123 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.AS_HANDLERS = exports.AS_LIST_SEP = exports.AS_RECORD_SEP = exports.AS_FIELD_SEP = exports.LIST_SEP = exports.RECORD_SEP = exports.FIELD_SEP = void 0;
|
|
6
|
+
exports.ITEM_FAILURE_ROW = exports.AS_HANDLERS = exports.AS_LIST_SEP = exports.AS_RECORD_SEP = exports.AS_FIELD_SEP = exports.LIST_SEP = exports.RECORD_SEP = exports.FIELD_SEP = void 0;
|
|
7
7
|
exports.runOsaScript = runOsaScript;
|
|
8
8
|
exports.asEscape = asEscape;
|
|
9
|
+
exports.asString = asString;
|
|
9
10
|
exports.asBool = asBool;
|
|
11
|
+
exports.asInt = asInt;
|
|
12
|
+
exports.asIdList = asIdList;
|
|
10
13
|
exports.asRow = asRow;
|
|
11
14
|
exports.splitRecords = splitRecords;
|
|
12
15
|
exports.splitFields = splitFields;
|
|
13
16
|
exports.splitList = splitList;
|
|
17
|
+
exports.splitPositionalList = splitPositionalList;
|
|
14
18
|
exports.field = field;
|
|
15
19
|
exports.summaryFields = summaryFields;
|
|
16
20
|
exports.intField = intField;
|
|
17
21
|
exports.boolField = boolField;
|
|
22
|
+
exports.splitBatch = splitBatch;
|
|
18
23
|
// Getting a generated AppleScript to osascript and its output back.
|
|
19
24
|
//
|
|
20
|
-
// The macOS counterpart of windows/run.ts:
|
|
21
|
-
// and the record framing every reader here shares.
|
|
22
|
-
const child_process_1 = require("child_process");
|
|
25
|
+
// The macOS counterpart of windows/run.ts: running a script, the escaping
|
|
26
|
+
// rules, and the record framing every reader here shares.
|
|
23
27
|
const fs_1 = __importDefault(require("fs"));
|
|
24
28
|
const runtime_1 = require("../runtime");
|
|
29
|
+
const exec_1 = require("../shared/exec");
|
|
25
30
|
const errors_1 = require("../errors");
|
|
26
31
|
const replyBody_1 = require("../shared/replyBody");
|
|
27
32
|
const RUNNER = 'osascript';
|
|
28
33
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
* osascript's report of a script error: "<file>:<start>:<end>: execution error:
|
|
35
|
+
* <message> (<number>)". Only the message is worth showing — these reach people
|
|
36
|
+
* in per-item failure lists — and -2700 is the number AppleScript gives every
|
|
37
|
+
* `error "…"` a script raises itself.
|
|
38
|
+
*/
|
|
39
|
+
function parseFailure(stderr) {
|
|
40
|
+
const message = stderr
|
|
41
|
+
.replace(/^(?:.*?:)?\d+:\d+:\s*execution error:\s*/m, '')
|
|
42
|
+
.replace(/\s*\(-2700\)\s*$/, '')
|
|
43
|
+
.trim();
|
|
44
|
+
return { message };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run a script from a temp file (no argument-length or quoting limits) and
|
|
48
|
+
* return what it printed, minus the newline osascript appends.
|
|
36
49
|
*
|
|
37
|
-
* `
|
|
38
|
-
*
|
|
50
|
+
* `AS_HANDLERS` is prepended here rather than by each caller: a script missing
|
|
51
|
+
* a handler fails to compile as a WHOLE, with an error pointing nowhere near the
|
|
52
|
+
* omission, so it can't be left to each script to remember.
|
|
39
53
|
*/
|
|
40
|
-
function runOsaScript(source,
|
|
41
|
-
// The full text is what osascript
|
|
42
|
-
//
|
|
54
|
+
async function runOsaScript(source, budget) {
|
|
55
|
+
// The full text is what osascript compiles, so it is also what error offsets
|
|
56
|
+
// refer to and what the debug hook and errors carry.
|
|
43
57
|
const script = exports.AS_HANDLERS + source;
|
|
44
|
-
const
|
|
45
|
-
fs_1.default.writeFileSync(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
catch { /* ignore */
|
|
56
|
-
}
|
|
57
|
-
if (error) {
|
|
58
|
-
// Running from a file, osascript prefixes the script path:
|
|
59
|
-
// "/tmp/outlook-bridge-osa-1.applescript:12:34: execution error:
|
|
60
|
-
// Microsoft Outlook got an error: … (-1728)". Keep just the human
|
|
61
|
-
// part — these strings reach the user in per-email failure lists.
|
|
62
|
-
const msg = (stderr || error.message)
|
|
63
|
-
.replace(/^(?:.*?:)?\d+:\d+:\s*execution error:\s*/m, '')
|
|
64
|
-
.trim();
|
|
65
|
-
const failure = (0, errors_1.classifyRunFailure)({
|
|
66
|
-
runner: RUNNER,
|
|
67
|
-
script,
|
|
68
|
-
stderr: msg,
|
|
69
|
-
durationMs,
|
|
70
|
-
nodeError: error,
|
|
71
|
-
timeoutMs: effectiveTimeout,
|
|
72
|
-
signal,
|
|
73
|
-
});
|
|
74
|
-
(0, runtime_1.reportRun)({ runner: RUNNER, script, durationMs, error: failure.message });
|
|
75
|
-
reject(failure);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
(0, runtime_1.reportRun)({ runner: RUNNER, script, durationMs });
|
|
79
|
-
resolve(stdout.replace(/\n$/, ''));
|
|
80
|
-
}
|
|
58
|
+
const file = (0, runtime_1.tempFile)('osa', 'applescript');
|
|
59
|
+
fs_1.default.writeFileSync(file, script, 'utf8');
|
|
60
|
+
try {
|
|
61
|
+
const { stdout } = await (0, exec_1.runScriptProcess)({
|
|
62
|
+
runner: RUNNER,
|
|
63
|
+
command: 'osascript',
|
|
64
|
+
args: [file],
|
|
65
|
+
script,
|
|
66
|
+
budget,
|
|
67
|
+
parseFailure,
|
|
81
68
|
});
|
|
82
|
-
|
|
69
|
+
return stdout.replace(/\n$/, '');
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
(0, runtime_1.removeTempFile)(file);
|
|
73
|
+
}
|
|
83
74
|
}
|
|
84
|
-
/**
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Escape text for the inside of an AppleScript double-quoted literal.
|
|
77
|
+
* AppleScript strings never interpolate, so escaping the quote, the backslash
|
|
78
|
+
* and line breaks is the whole job.
|
|
79
|
+
*/
|
|
80
|
+
function asEscape(text) {
|
|
81
|
+
return text
|
|
87
82
|
.replace(/\\/g, '\\\\')
|
|
88
83
|
.replace(/"/g, '\\"')
|
|
89
84
|
.replace(/\r\n|\r|\n/g, '\\n');
|
|
90
85
|
}
|
|
86
|
+
/** Text as an AppleScript string literal. */
|
|
87
|
+
function asString(text) {
|
|
88
|
+
return `"${asEscape(text)}"`;
|
|
89
|
+
}
|
|
91
90
|
/** AppleScript's boolean literals. */
|
|
92
91
|
function asBool(value) {
|
|
93
92
|
return value ? 'true' : 'false';
|
|
94
93
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
/** A whole number for a script; anything else is refused before it becomes code. */
|
|
95
|
+
function asInt(value) {
|
|
96
|
+
if (!Number.isSafeInteger(value)) {
|
|
97
|
+
throw new errors_1.InvalidRequestError(`Expected a whole number, got ${String(value)}.`);
|
|
98
|
+
}
|
|
99
|
+
return String(value);
|
|
100
|
+
}
|
|
101
|
+
/** Message ids (already validated as integers) as an AppleScript list literal. */
|
|
102
|
+
function asIdList(ids) {
|
|
103
|
+
return `{${ids.map(id => asInt(Number(id))).join(', ')}}`;
|
|
104
|
+
}
|
|
105
|
+
// ── Record framing ───────────────────────────────────────────────────────
|
|
106
|
+
//
|
|
107
|
+
// Control characters separate fields, records and list items: subjects and
|
|
108
|
+
// bodies contain tabs, newlines and commas, but never these — and every emitted
|
|
109
|
+
// field passes through the `sanitize` handler, which makes the framing safe
|
|
110
|
+
// rather than merely unlikely to break.
|
|
111
|
+
exports.FIELD_SEP = '';
|
|
112
|
+
exports.RECORD_SEP = '';
|
|
113
|
+
exports.LIST_SEP = '';
|
|
102
114
|
/** The same three, as AppleScript expressions. */
|
|
103
115
|
exports.AS_FIELD_SEP = '(character id 31)';
|
|
104
116
|
exports.AS_RECORD_SEP = '(character id 30)';
|
|
105
117
|
exports.AS_LIST_SEP = '(character id 29)';
|
|
106
118
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* rather than merely unlikely to break. A field holding a LIST must be built
|
|
112
|
-
* with `my sanitizeList(...)`, which cleans the elements instead — `sanitize`
|
|
113
|
-
* deliberately leaves the list separator alone.
|
|
119
|
+
* One record: the AppleScript expressions in `fields`, separated and terminated
|
|
120
|
+
* so `splitRecords`/`splitFields` can take them apart again. A field holding a
|
|
121
|
+
* LIST must be built with `my sanitizeList(...)`, which cleans the elements —
|
|
122
|
+
* `sanitize` deliberately leaves the list separator alone.
|
|
114
123
|
*/
|
|
115
124
|
function asRow(fields) {
|
|
116
125
|
return fields
|
|
@@ -118,12 +127,11 @@ function asRow(fields) {
|
|
|
118
127
|
.join(` & ${exports.AS_FIELD_SEP} & `) + ` & ${exports.AS_RECORD_SEP}`;
|
|
119
128
|
}
|
|
120
129
|
/**
|
|
121
|
-
* The
|
|
122
|
-
* inside a `tell` block.
|
|
130
|
+
* The handlers every script relies on, called with `my` from inside a `tell`.
|
|
123
131
|
*
|
|
124
|
-
* `isoDate` produces the zero-padded 'yyyy-MM-dd HH:mm' both platforms
|
|
125
|
-
*
|
|
126
|
-
*
|
|
132
|
+
* `isoDate` produces the zero-padded 'yyyy-MM-dd HH:mm' both platforms return;
|
|
133
|
+
* `sanitize` strips the framing characters; `joinList` and `replaceText` are the
|
|
134
|
+
* text-item-delimiter dance nobody should write twice.
|
|
127
135
|
*/
|
|
128
136
|
exports.AS_HANDLERS = `
|
|
129
137
|
on pad2(n)
|
|
@@ -156,8 +164,7 @@ on replaceText(t, findWhat, replaceWith)
|
|
|
156
164
|
end replaceText
|
|
157
165
|
|
|
158
166
|
-- Strips the FIELD and RECORD separators only. The LIST separator is left
|
|
159
|
-
-- alone on purpose: a field may legitimately BE a list
|
|
160
|
-
-- collapsed every such field into one run-on string.
|
|
167
|
+
-- alone on purpose: a field may legitimately BE a list.
|
|
161
168
|
on sanitize(v)
|
|
162
169
|
if v is missing value then return ""
|
|
163
170
|
set t to v as string
|
|
@@ -174,24 +181,30 @@ on sanitizeList(lst)
|
|
|
174
181
|
set cleaned to {}
|
|
175
182
|
repeat with item_ in lst
|
|
176
183
|
set t to my sanitize(item_)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if t contains marker then set t to my replaceText(t, marker, " ")
|
|
180
|
-
end repeat
|
|
184
|
+
set marker to (character id 29)
|
|
185
|
+
if t contains marker then set t to my replaceText(t, marker, " ")
|
|
181
186
|
set end of cleaned to t
|
|
182
187
|
end repeat
|
|
183
188
|
return my joinList(cleaned, (character id 29))
|
|
184
189
|
end sanitizeList
|
|
185
190
|
|
|
191
|
+
-- A list whose positions matter, like an email's attachments: every element is
|
|
192
|
+
-- FOLLOWED by the LIST separator, so an empty element keeps its place and an
|
|
193
|
+
-- empty list stays distinct from a list of one empty name. splitPositionalList()
|
|
194
|
+
-- takes it apart.
|
|
195
|
+
on sanitizePositionalList(lst)
|
|
196
|
+
if (count of lst) is 0 then return ""
|
|
197
|
+
return my sanitizeList(lst) & (character id 29)
|
|
198
|
+
end sanitizePositionalList
|
|
199
|
+
|
|
186
200
|
on insertAboveQuoted(c, ins)
|
|
187
201
|
if c is missing value then return ins
|
|
188
202
|
set c to c as string
|
|
189
203
|
if (length of c) is 0 then return ins
|
|
190
|
-
--
|
|
191
|
-
--
|
|
192
|
-
--
|
|
193
|
-
--
|
|
194
|
-
-- called that however naturally it reads.
|
|
204
|
+
-- A reply's own empty paragraph sits inside WordSection1; inserting straight
|
|
205
|
+
-- after that tag puts the new text where the cursor would be. Anything else
|
|
206
|
+
-- falls back to just inside <body>. ('at' is a reserved parameter name, so
|
|
207
|
+
-- the cut point can't be called that.)
|
|
195
208
|
set cutPoint to my tagEnd(c, "${replyBody_1.WORD_SECTION_ANCHOR}")
|
|
196
209
|
if cutPoint is 0 then set cutPoint to my tagEnd(c, "<body")
|
|
197
210
|
if cutPoint is 0 then return ins & c
|
|
@@ -199,8 +212,8 @@ on insertAboveQuoted(c, ins)
|
|
|
199
212
|
return (text 1 thru cutPoint of c) & ins & (text (cutPoint + 1) thru -1 of c)
|
|
200
213
|
end insertAboveQuoted
|
|
201
214
|
|
|
202
|
-
-- 'rest' is an AppleScript term
|
|
203
|
-
--
|
|
215
|
+
-- 'rest' is an AppleScript term, so the remainder can't be called that:
|
|
216
|
+
-- assigning to it compiles and then fails at run time.
|
|
204
217
|
on tagEnd(c, marker)
|
|
205
218
|
set ix to offset of marker in c
|
|
206
219
|
if ix is 0 then return 0
|
|
@@ -211,40 +224,62 @@ on tagEnd(c, marker)
|
|
|
211
224
|
return ix + gt - 1
|
|
212
225
|
end tagEnd
|
|
213
226
|
`;
|
|
214
|
-
/**
|
|
227
|
+
/** A script's output as records, without the trailing empty one. */
|
|
215
228
|
function splitRecords(raw) {
|
|
216
229
|
return raw.split(exports.RECORD_SEP).filter(record => record.trim() !== '');
|
|
217
230
|
}
|
|
218
|
-
/**
|
|
231
|
+
/** One record's fields. */
|
|
219
232
|
function splitFields(record) {
|
|
220
233
|
return record.split(exports.FIELD_SEP);
|
|
221
234
|
}
|
|
222
|
-
/**
|
|
235
|
+
/**
|
|
236
|
+
* A field that carries a list. Empty elements are dropped, so where an index
|
|
237
|
+
* into the list must match Outlook's, the field is written with
|
|
238
|
+
* `sanitizePositionalList` and read with `splitPositionalList` instead.
|
|
239
|
+
*/
|
|
223
240
|
function splitList(value) {
|
|
224
241
|
return (value || '').split(exports.LIST_SEP).filter(Boolean);
|
|
225
242
|
}
|
|
226
|
-
/**
|
|
243
|
+
/**
|
|
244
|
+
* A field written by `sanitizePositionalList`: every element at its position,
|
|
245
|
+
* empty ones included, so index N here is item N+1 of the AppleScript list.
|
|
246
|
+
*/
|
|
247
|
+
function splitPositionalList(value) {
|
|
248
|
+
return value ? value.split(exports.LIST_SEP).slice(0, -1) : [];
|
|
249
|
+
}
|
|
250
|
+
/** A field by position; a missing field reads as ''. */
|
|
227
251
|
function field(fields, index) {
|
|
228
252
|
return fields[index] ?? '';
|
|
229
253
|
}
|
|
230
|
-
/**
|
|
231
|
-
* The fields of a script's ONE summary record — the shape every mutation here
|
|
232
|
-
* returns (counts first, then any per-item failures as further records).
|
|
233
|
-
*/
|
|
254
|
+
/** The fields of a script's first record — the summary a mutation returns ahead of any per-item rows. */
|
|
234
255
|
function summaryFields(raw) {
|
|
235
256
|
return splitFields(splitRecords(raw)[0] ?? '');
|
|
236
257
|
}
|
|
237
|
-
/** A numeric field,
|
|
258
|
+
/** A numeric field, `fallback` when absent or unparsable. */
|
|
238
259
|
function intField(fields, index, fallback = 0) {
|
|
239
260
|
const parsed = Number.parseInt(field(fields, index), 10);
|
|
240
261
|
return Number.isNaN(parsed) ? fallback : parsed;
|
|
241
262
|
}
|
|
242
|
-
/**
|
|
243
|
-
* A boolean field. AppleScript renders booleans as the bare words `true`/`false`,
|
|
244
|
-
* so this is the counterpart of `shared/json.ts`'s coercions for the framed
|
|
245
|
-
* output — the Windows side gets those free from ConvertFrom-Json.
|
|
246
|
-
*/
|
|
263
|
+
/** A boolean field; AppleScript renders booleans as the bare words true/false. */
|
|
247
264
|
function boolField(fields, index) {
|
|
248
265
|
return field(fields, index).trim() === 'true';
|
|
249
266
|
}
|
|
267
|
+
// ── Batches ──────────────────────────────────────────────────────────────
|
|
268
|
+
//
|
|
269
|
+
// A script acting on a list of ids returns one summary record, then one record
|
|
270
|
+
// per id that failed. The failure row and its decoder sit together so the two
|
|
271
|
+
// can't come to disagree about the field order.
|
|
272
|
+
/** The record a batch script appends, inside `on error errText`, for the id `theId` it failed on. */
|
|
273
|
+
exports.ITEM_FAILURE_ROW = asRow(['(theId as string)', 'subj', 'errText']);
|
|
274
|
+
/** A batch script's output: the summary record's fields, and the items that failed. */
|
|
275
|
+
function splitBatch(raw) {
|
|
276
|
+
const [summary = '', ...failures] = splitRecords(raw);
|
|
277
|
+
return {
|
|
278
|
+
summary: splitFields(summary),
|
|
279
|
+
failed: failures.map(record => {
|
|
280
|
+
const parts = splitFields(record);
|
|
281
|
+
return { entryId: field(parts, 0), subject: field(parts, 1), error: field(parts, 2) };
|
|
282
|
+
}),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
250
285
|
//# sourceMappingURL=run.js.map
|
package/dist/mac/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/mac/run.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/mac/run.ts"],"names":[],"mappings":"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","sourcesContent":["// Getting a generated AppleScript to osascript and its output back.\n//\n// The macOS counterpart of windows/run.ts: running a script, the escaping\n// rules, and the record framing every reader here shares.\nimport fs from 'fs';\nimport { removeTempFile, type RunBudget, tempFile } from '../runtime';\nimport { runScriptProcess } from '../shared/exec';\nimport { InvalidRequestError } from '../errors';\nimport { WORD_SECTION_ANCHOR } from '../shared/replyBody';\nimport type { ItemFailure } from '../types';\n\nconst RUNNER = 'osascript' as const;\n\n/**\n * osascript's report of a script error: \"<file>:<start>:<end>: execution error:\n * <message> (<number>)\". Only the message is worth showing — these reach people\n * in per-item failure lists — and -2700 is the number AppleScript gives every\n * `error \"…\"` a script raises itself.\n */\nfunction parseFailure(stderr: string): { message: string } {\n const message = stderr\n .replace(/^(?:.*?:)?\\d+:\\d+:\\s*execution error:\\s*/m, '')\n .replace(/\\s*\\(-2700\\)\\s*$/, '')\n .trim();\n return { message };\n}\n\n/**\n * Run a script from a temp file (no argument-length or quoting limits) and\n * return what it printed, minus the newline osascript appends.\n *\n * `AS_HANDLERS` is prepended here rather than by each caller: a script missing\n * a handler fails to compile as a WHOLE, with an error pointing nowhere near the\n * omission, so it can't be left to each script to remember.\n */\nexport async function runOsaScript(source: string, budget: RunBudget): Promise<string> {\n // The full text is what osascript compiles, so it is also what error offsets\n // refer to and what the debug hook and errors carry.\n const script = AS_HANDLERS + source;\n const file = tempFile('osa', 'applescript');\n fs.writeFileSync(file, script, 'utf8');\n try {\n const { stdout } = await runScriptProcess({\n runner: RUNNER,\n command: 'osascript',\n args: [file],\n script,\n budget,\n parseFailure,\n });\n return stdout.replace(/\\n$/, '');\n } finally {\n removeTempFile(file);\n }\n}\n\n/**\n * Escape text for the inside of an AppleScript double-quoted literal.\n * AppleScript strings never interpolate, so escaping the quote, the backslash\n * and line breaks is the whole job.\n */\nexport function asEscape(text: string): string {\n return text\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\r\\n|\\r|\\n/g, '\\\\n');\n}\n\n/** Text as an AppleScript string literal. */\nexport function asString(text: string): string {\n return `\"${asEscape(text)}\"`;\n}\n\n/** AppleScript's boolean literals. */\nexport function asBool(value: boolean): string {\n return value ? 'true' : 'false';\n}\n\n/** A whole number for a script; anything else is refused before it becomes code. */\nexport function asInt(value: number): string {\n if (!Number.isSafeInteger(value)) {\n throw new InvalidRequestError(`Expected a whole number, got ${String(value)}.`);\n }\n return String(value);\n}\n\n/** Message ids (already validated as integers) as an AppleScript list literal. */\nexport function asIdList(ids: readonly string[]): string {\n return `{${ids.map(id => asInt(Number(id))).join(', ')}}`;\n}\n\n// ── Record framing ───────────────────────────────────────────────────────\n//\n// Control characters separate fields, records and list items: subjects and\n// bodies contain tabs, newlines and commas, but never these — and every emitted\n// field passes through the `sanitize` handler, which makes the framing safe\n// rather than merely unlikely to break.\nexport const FIELD_SEP = '\u001f';\nexport const RECORD_SEP = '\u001e';\nexport const LIST_SEP = '\u001d';\n\n/** The same three, as AppleScript expressions. */\nexport const AS_FIELD_SEP = '(character id 31)';\nexport const AS_RECORD_SEP = '(character id 30)';\nexport const AS_LIST_SEP = '(character id 29)';\n\n/**\n * One record: the AppleScript expressions in `fields`, separated and terminated\n * so `splitRecords`/`splitFields` can take them apart again. A field holding a\n * LIST must be built with `my sanitizeList(...)`, which cleans the elements —\n * `sanitize` deliberately leaves the list separator alone.\n */\nexport function asRow(fields: readonly string[]): string {\n return fields\n .map(f => `my sanitize(${f})`)\n .join(` & ${AS_FIELD_SEP} & `) + ` & ${AS_RECORD_SEP}`;\n}\n\n/**\n * The handlers every script relies on, called with `my` from inside a `tell`.\n *\n * `isoDate` produces the zero-padded 'yyyy-MM-dd HH:mm' both platforms return;\n * `sanitize` strips the framing characters; `joinList` and `replaceText` are the\n * text-item-delimiter dance nobody should write twice.\n */\nexport const AS_HANDLERS = `\non pad2(n)\n set s to (n as integer) as string\n if (length of s) < 2 then set s to \"0\" & s\n return s\nend pad2\n\non isoDate(d)\n if d is missing value then return \"\"\n return (year of d as string) & \"-\" & pad2(month of d as integer) & \"-\" & pad2(day of d) & \" \" & pad2(hours of d) & \":\" & pad2(minutes of d)\nend isoDate\n\non joinList(lst, sep)\n set saved to AppleScript's text item delimiters\n set AppleScript's text item delimiters to sep\n set out to lst as string\n set AppleScript's text item delimiters to saved\n return out\nend joinList\n\non replaceText(t, findWhat, replaceWith)\n set saved to AppleScript's text item delimiters\n set AppleScript's text item delimiters to findWhat\n set parts to text items of t\n set AppleScript's text item delimiters to replaceWith\n set out to parts as string\n set AppleScript's text item delimiters to saved\n return out\nend replaceText\n\n-- Strips the FIELD and RECORD separators only. The LIST separator is left\n-- alone on purpose: a field may legitimately BE a list.\non sanitize(v)\n if v is missing value then return \"\"\n set t to v as string\n repeat with codePoint in {30, 31}\n set marker to (character id (codePoint as integer))\n if t contains marker then set t to my replaceText(t, marker, \" \")\n end repeat\n return t\nend sanitize\n\n-- A list field: each element loses all three separators, then they are joined\n-- with the LIST separator that splitList() takes them apart on.\non sanitizeList(lst)\n set cleaned to {}\n repeat with item_ in lst\n set t to my sanitize(item_)\n set marker to (character id 29)\n if t contains marker then set t to my replaceText(t, marker, \" \")\n set end of cleaned to t\n end repeat\n return my joinList(cleaned, (character id 29))\nend sanitizeList\n\n-- A list whose positions matter, like an email's attachments: every element is\n-- FOLLOWED by the LIST separator, so an empty element keeps its place and an\n-- empty list stays distinct from a list of one empty name. splitPositionalList()\n-- takes it apart.\non sanitizePositionalList(lst)\n if (count of lst) is 0 then return \"\"\n return my sanitizeList(lst) & (character id 29)\nend sanitizePositionalList\n\non insertAboveQuoted(c, ins)\n if c is missing value then return ins\n set c to c as string\n if (length of c) is 0 then return ins\n -- A reply's own empty paragraph sits inside WordSection1; inserting straight\n -- after that tag puts the new text where the cursor would be. Anything else\n -- falls back to just inside <body>. ('at' is a reserved parameter name, so\n -- the cut point can't be called that.)\n set cutPoint to my tagEnd(c, \"${WORD_SECTION_ANCHOR}\")\n if cutPoint is 0 then set cutPoint to my tagEnd(c, \"<body\")\n if cutPoint is 0 then return ins & c\n if cutPoint is (length of c) then return c & ins\n return (text 1 thru cutPoint of c) & ins & (text (cutPoint + 1) thru -1 of c)\nend insertAboveQuoted\n\n-- 'rest' is an AppleScript term, so the remainder can't be called that:\n-- assigning to it compiles and then fails at run time.\non tagEnd(c, marker)\n set ix to offset of marker in c\n if ix is 0 then return 0\n if marker ends with \">\" then return ix + (length of marker) - 1\n set tailText to text ix thru -1 of c\n set gt to offset of \">\" in tailText\n if gt is 0 then return 0\n return ix + gt - 1\nend tagEnd\n`;\n\n/** A script's output as records, without the trailing empty one. */\nexport function splitRecords(raw: string): string[] {\n return raw.split(RECORD_SEP).filter(record => record.trim() !== '');\n}\n\n/** One record's fields. */\nexport function splitFields(record: string): string[] {\n return record.split(FIELD_SEP);\n}\n\n/**\n * A field that carries a list. Empty elements are dropped, so where an index\n * into the list must match Outlook's, the field is written with\n * `sanitizePositionalList` and read with `splitPositionalList` instead.\n */\nexport function splitList(value: string | undefined): string[] {\n return (value || '').split(LIST_SEP).filter(Boolean);\n}\n\n/**\n * A field written by `sanitizePositionalList`: every element at its position,\n * empty ones included, so index N here is item N+1 of the AppleScript list.\n */\nexport function splitPositionalList(value: string | undefined): string[] {\n return value ? value.split(LIST_SEP).slice(0, -1) : [];\n}\n\n/** A field by position; a missing field reads as ''. */\nexport function field(fields: readonly string[], index: number): string {\n return fields[index] ?? '';\n}\n\n/** The fields of a script's first record — the summary a mutation returns ahead of any per-item rows. */\nexport function summaryFields(raw: string): string[] {\n return splitFields(splitRecords(raw)[0] ?? '');\n}\n\n/** A numeric field, `fallback` when absent or unparsable. */\nexport function intField(fields: readonly string[], index: number, fallback = 0): number {\n const parsed = Number.parseInt(field(fields, index), 10);\n return Number.isNaN(parsed) ? fallback : parsed;\n}\n\n/** A boolean field; AppleScript renders booleans as the bare words true/false. */\nexport function boolField(fields: readonly string[], index: number): boolean {\n return field(fields, index).trim() === 'true';\n}\n\n// ── Batches ──────────────────────────────────────────────────────────────\n//\n// A script acting on a list of ids returns one summary record, then one record\n// per id that failed. The failure row and its decoder sit together so the two\n// can't come to disagree about the field order.\n\n/** The record a batch script appends, inside `on error errText`, for the id `theId` it failed on. */\nexport const ITEM_FAILURE_ROW = asRow(['(theId as string)', 'subj', 'errText']);\n\n/** A batch script's output: the summary record's fields, and the items that failed. */\nexport function splitBatch(raw: string): { summary: string[]; failed: ItemFailure[] } {\n const [summary = '', ...failures] = splitRecords(raw);\n return {\n summary: splitFields(summary),\n failed: failures.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"]}
|