@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 +1 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/windows/read.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/windows/read.ts"],"names":[],"mappings":"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","sourcesContent":["// Reading mail: one folder, one item, a whole Inbox tree, or whatever is\n// selected in the running Outlook.\nimport { psArray, psBool, psInt, psString, runPowerShell, runPowerShellJson } from './run';\nimport {\n accountScript,\n cutoffScript,\n itemLookupScript,\n itemsSinceScript,\n mailScopeScript,\n NAMED_STORE_PS,\n SENDER_SMTP_PS,\n SESSION_PS,\n} from './scripts';\nimport { base64Text, record, str, strList, toArray } from '../shared/json';\nimport { FolderId, isOutgoingRoot, NON_INCOMING_ROOTS, REPLY_PREFIX_SOURCE, subjectGlobSource } from '../mail';\nimport { failureTag } from '../errors';\nimport type { RawEmail, ReadInboxRequest, SearchRequest } from '../backend';\nimport type { EmailLocator, InboxEmail, InboxSearchMatch, SelectedEmail } from '../types';\n\n/**\n * The COM property carrying each kind of folder's timestamp. Sent Items and\n * Drafts have no ReceivedTime, and filtering them on it returns an empty set\n * that looks exactly like an empty folder.\n */\nfunction dateProperty(rootId: number): string {\n if (rootId === FolderId.Drafts) return 'LastModificationTime';\n return isOutgoingRoot(rootId) ? 'SentOn' : 'ReceivedTime';\n}\n\n/**\n * Bodies cross the PowerShell boundary base64-encoded: they carry quotes,\n * control characters and non-ASCII that would otherwise have to survive JSON\n * escaping in two languages intact.\n */\nconst BODY_B64_PS = `[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes([string]$bodyRaw))`;\n\n/** Recent mail from the Inbox root or one folder, newest first. */\nexport async function readInboxEmails(request: ReadInboxRequest): Promise<InboxEmail[]> {\n const dateProp = dateProperty(request.folder.rootId);\n const outgoing = isOutgoingRoot(request.folder.rootId);\n const output = await runPowerShellJson(`${accountScript(request.account)}\n${NAMED_STORE_PS}\n${mailScopeScript(request.folder, request.folderLabel)}\n$scopePath = [string]$scope.FolderPath\n${cutoffScript(request.daysBack)}\n${itemsSinceScript('scope', dateProp, 'filtered')}\n$filtered.Sort('[${dateProp}]', $true)\n$limit = ${psInt(request.limit)}\n$previewChars = ${psInt(request.previewChars)}\n$rows = @()\n$count = $filtered.Count\nfor ($i = 1; $i -le $count -and $rows.Count -lt $limit; $i++) {\n $item = $null\n try { $item = $filtered.Item($i) } catch {}\n if ($item -eq $null) { continue }\n $stamp = $null\n try { $stamp = $item.${dateProp} } catch {}\n # Sorted newest first, so the first item older than the window ends it.\n if ($stamp -ne $null -and $stamp -lt $cutoff) { break }\n $preview = ''\n if ($previewChars -gt 0) {\n $bodyText = ''\n try { $bodyText = [string]$item.Body } catch {}\n $preview = if ($bodyText.Length -gt $previewChars) { $bodyText.Substring(0, $previewChars) } else { $bodyText }\n }\n $attachmentNames = @()\n try { foreach ($att in $item.Attachments) { $attachmentNames += [string]$att.FileName } } catch {}\n $who = ''\n $whoEmail = ''\n if (${psBool(outgoing)}) {\n # Outgoing mail reports who it went TO; \"from\" is always the mailbox itself.\n try { $who = [string]$item.To } catch {}\n $whoEmail = $who\n } else {\n try { $who = [string]$item.SenderName } catch {}\n try { $whoEmail = [string]$item.SenderEmailAddress } catch {}\n }\n $rows += [PSCustomObject]@{\n entryId = [string]$item.EntryID\n storeId = $storeId\n folderPath = $scopePath\n subject = ([string]$item.Subject).Trim()\n senderName = $who\n senderEmail = $whoEmail\n receivedTime = if ($stamp -ne $null) { $stamp.ToString('yyyy-MM-dd HH:mm') } else { '' }\n bodyPreview = $preview\n attachmentNames = @($attachmentNames)\n }\n}\nConvertTo-Json -Depth 4 -InputObject @($rows)\n`, 'standard');\n return toArray(output).map(row => {\n const e = record(row);\n const attachmentNames = toArray(e.attachmentNames).map(str);\n return {\n entryId: str(e.entryId),\n storeId: str(e.storeId),\n subject: str(e.subject),\n senderName: str(e.senderName),\n senderEmail: str(e.senderEmail),\n receivedTime: str(e.receivedTime),\n bodyPreview: str(e.bodyPreview),\n attachmentNames,\n attachmentCount: attachmentNames.length,\n folderPath: str(e.folderPath),\n };\n });\n}\n\n/**\n * One email's full plain-text body, by id.\n *\n * `Body`, not `HTMLBody`: Outlook's own plain-text rendering is what every other\n * reader here consumes, and markup costs an order of magnitude more for the same\n * sentences. The tradeoff is that an HTML table's rows flatten.\n */\nexport async function readEmailBody(email: EmailLocator): Promise<RawEmail> {\n const output = await runPowerShellJson(`${SESSION_PS}\n${itemLookupScript(email)}\n$class = 0\ntry { $class = [int]$item.Class } catch {}\n# 43 = olMail, 46 = olReport (a non-delivery report is still worth reading).\nif ($class -ne 43 -and $class -ne 46) {\n throw \"${failureTag('NOT_FOUND', 'email')}The item with entry id '$lookupId' is not an email (class $class).\"\n}\n$bodyRaw = ''\ntry { $bodyRaw = [string]$item.Body } catch {}\n$attachmentNames = @()\ntry { foreach ($att in $item.Attachments) { $attachmentNames += [string]$att.FileName } } catch {}\n${SENDER_SMTP_PS}\n$received = ''\ntry { $received = $item.ReceivedTime.ToString('yyyy-MM-dd HH:mm') } catch {}\nConvertTo-Json -Compress -Depth 3 -InputObject ([PSCustomObject]@{\n entryId = [string]$item.EntryID\n subject = ([string]$item.Subject).Trim()\n senderName = [string]$item.SenderName\n senderEmail = $senderSmtp\n receivedTime = $received\n body = ${BODY_B64_PS}\n attachmentNames = @($attachmentNames)\n})\n`, 'quick');\n const e = record(output);\n return {\n entryId: str(e.entryId) || email.entryId,\n subject: str(e.subject),\n senderName: str(e.senderName),\n senderEmail: str(e.senderEmail),\n receivedTime: str(e.receivedTime),\n body: base64Text(e.body),\n attachmentNames: toArray(e.attachmentNames).map(str),\n };\n}\n\n/**\n * Walk every folder under the Inbox for the mail matching the request.\n *\n * The window is enforced twice — a date Restrict per folder, then a per-item\n * check — because Restrict is not reliable across stores, and a scan that\n * silently widens on some mailboxes is the failure this guards against.\n * `subjectLike` also drives a server-side prefilter, purely as an optimization:\n * every subject is re-checked, so a store that can't run the query (IMAP stores\n * accept it and match nothing) returns the same set, only slower.\n */\nexport async function searchInboxByFilter(request: SearchRequest): Promise<InboxSearchMatch[]> {\n const subjectFiltered = !!(request.subjectLike || request.subjectPattern || request.excludeReplies);\n // The server-side prefilter speaks DASL, whose `like` wildcards are % and _.\n // A literal % or _ in the glob is left as a wildcard there: that can only\n // widen the prefilter, and the exact test below narrows it again.\n const subjectDasl = request.subjectLike ? request.subjectLike.replace(/\\*/g, '%').replace(/\\?/g, '_') : '';\n const output = await runPowerShellJson(`${accountScript(request.account)}\n${NAMED_STORE_PS}\n$inbox = $store.GetDefaultFolder(${psInt(FolderId.Inbox)})\n$subjectLike = ${psString(request.subjectLike ? subjectGlobSource(request.subjectLike) : '')}\n$subjectDasl = ${psString(subjectDasl)}\n$subjectPattern = ${psString(request.subjectPattern?.source ?? '')}\n$replyPattern = ${psString(request.excludeReplies ? REPLY_PREFIX_SOURCE : '')}\n$requireSubject = ${psBool(subjectFiltered)}\n$requireAttachment = ${psBool(request.requireAttachment)}\n$includeBody = ${psBool(request.includeBody)}\n${cutoffScript(request.daysBack)}\n# Sent, Drafts, Deleted and Junk are siblings of the Inbox on an Exchange profile\n# and CHILDREN of it on an IMAP one. They are cut by id — their names are\n# localized — before the walk, so each takes its whole subtree with it.\n$skipIds = @{}\nforeach ($role in @(${NON_INCOMING_ROOTS.map(psInt).join(', ')})) {\n try {\n $roleFolder = $store.GetDefaultFolder($role)\n if ($roleFolder -ne $null) { $skipIds[[string]$roleFolder.EntryID] = $true }\n } catch {}\n}\n$skipNames = ${psArray(request.excludeFolders)}\n$onlyNames = ${psArray(request.includeFolders)}\nfunction Test-FolderNamed([string]$name, [string]$path, $list) {\n foreach ($entry in $list) {\n if ($name -ieq $entry -or $path -ieq $entry) { return $true }\n }\n return $false\n}\n# Traversal and scanning are separate, and the two lists are not symmetric: an\n# excluded folder is never queued, so its subtree goes with it, while an\n# included one only marks a folder the walk reached anyway — the walk still\n# passes through folders nobody named to reach a nested one somebody did.\n$rootName = ''\ntry { $rootName = [string]$inbox.Name } catch {}\n$rootPath = ''\ntry { $rootPath = [string]$inbox.FolderPath } catch {}\n$folders = [System.Collections.ArrayList]@($inbox)\n$inScope = [System.Collections.ArrayList]@(($onlyNames.Count -eq 0) -or (Test-FolderNamed $rootName $rootPath $onlyNames))\n$walked = 0\nwhile ($walked -lt $folders.Count) {\n try {\n foreach ($sub in $folders[$walked].Folders) {\n if ($skipIds.ContainsKey([string]$sub.EntryID)) { continue }\n $subName = ''\n try { $subName = [string]$sub.Name } catch {}\n $subPath = ''\n try { $subPath = [string]$sub.FolderPath } catch {}\n if (Test-FolderNamed $subName $subPath $skipNames) { continue }\n [void]$folders.Add($sub)\n [void]$inScope.Add(($onlyNames.Count -eq 0) -or (Test-FolderNamed $subName $subPath $onlyNames))\n }\n } catch {}\n $walked++\n}\n# The subject prefilter is DASL rather than Jet: some stores reject Jet's\n# \"[Subject] like\" outright, while DASL is accepted wherever Restrict is. The\n# two syntaxes can't share one filter, so it is a second Restrict on top of the\n# date one. The pattern is concatenated into the query, never interpolated.\n$subjectQuery = '@SQL=' + [char]34 + 'urn:schemas:httpmail:subject' + [char]34 + ' like ' + [char]39 + $subjectDasl.Replace(\"'\", \"''\") + [char]39\n# A list, not an array: += copies the whole array per row, and a wide scan returns thousands.\n$rows = New-Object System.Collections.ArrayList\n$seen = @{}\nfor ($fx = 0; $fx -lt $folders.Count; $fx++) {\n if (-not $inScope[$fx]) { continue }\n $folder = $folders[$fx]\n ${itemsSinceScript('folder', 'ReceivedTime', 'filtered').trim()}\n if ($subjectDasl) {\n try {\n $candidate = $filtered.Restrict($subjectQuery)\n if ($candidate.Count -gt 0) { $filtered = $candidate }\n } catch {}\n }\n $folderPath = ''\n try { $folderPath = [string]$folder.FolderPath } catch {}\n $count = $filtered.Count\n for ($i = 1; $i -le $count; $i++) {\n $item = $null\n try { $item = $filtered.Item($i) } catch {}\n # A restricted collection can hand back nothing for an index, and an item\n # with no id can't be acted on by anything this package does.\n if ($item -eq $null) { continue }\n $entryId = [string]$item.EntryID\n if (-not $entryId -or $seen.ContainsKey($entryId)) { continue }\n $seen[$entryId] = $true\n $subject = ''\n try { $subject = ([string]$item.Subject).Trim() } catch {}\n if ($requireSubject -and -not $subject) { continue }\n if ($subjectLike -and $subject -notmatch $subjectLike) { continue }\n if ($subjectPattern -and $subject -notmatch $subjectPattern) { continue }\n if ($replyPattern -and $subject -imatch $replyPattern) { continue }\n $received = $null\n try { $received = $item.ReceivedTime } catch {}\n if ($received -ne $null -and $received -lt $cutoff) { continue }\n $attachmentNames = @()\n try { foreach ($att in $item.Attachments) { $attachmentNames += [string]$att.FileName } } catch {}\n if ($requireAttachment -and $attachmentNames.Count -eq 0) { continue }\n $bodyRaw = ''\n if ($includeBody) { try { $bodyRaw = [string]$item.Body } catch {} }\n${SENDER_SMTP_PS}\n [void]$rows.Add([PSCustomObject]@{\n entryId = $entryId\n storeId = $storeId\n subject = $subject\n senderName = [string]$item.SenderName\n senderEmail = $senderSmtp\n receivedTime = if ($received -ne $null) { $received.ToString('yyyy-MM-dd HH:mm') } else { '' }\n body = ${BODY_B64_PS}\n attachmentNames = @($attachmentNames)\n folderPath = $folderPath\n })\n }\n}\nConvertTo-Json -Depth 4 -InputObject @($rows)\n`, 'scan');\n return toArray(output).map(row => {\n const e = record(row);\n return {\n entryId: str(e.entryId),\n storeId: str(e.storeId),\n subject: str(e.subject),\n senderName: str(e.senderName),\n senderEmail: str(e.senderEmail),\n receivedTime: str(e.receivedTime),\n body: base64Text(e.body),\n attachmentNames: toArray(e.attachmentNames).map(str),\n folderPath: str(e.folderPath),\n };\n });\n}\n\n/** The email currently selected — or open — in Outlook. */\nexport async function readSelectedEmail(): Promise<SelectedEmail> {\n const output = await runPowerShellJson(`\n$outlook = New-Object -ComObject Outlook.Application\n$item = $null\ntry {\n $explorer = $outlook.ActiveExplorer()\n if ($explorer -ne $null -and $explorer.Selection.Count -ge 1) { $item = $explorer.Selection.Item(1) }\n} catch {}\nif ($item -eq $null) {\n try {\n $inspector = $outlook.ActiveInspector()\n if ($inspector -ne $null) { $item = $inspector.CurrentItem }\n } catch {}\n}\nif ($item -eq $null) {\n throw \"${failureTag('NOT_FOUND', 'email')}No email is selected in Outlook. Select or open an email, then try again.\"\n}\nif ([string]$item.MessageClass -notlike 'IPM.Note*') {\n throw \"${failureTag('INVALID_REQUEST')}The item selected in Outlook is not an email.\"\n}\n$attachmentNames = @()\ntry { foreach ($att in $item.Attachments) { $attachmentNames += [string]$att.FileName } } catch {}\n$bodyRaw = ''\ntry { $bodyRaw = [string]$item.Body } catch {}\n$storeId = ''\ntry { $storeId = [string]$item.Parent.Store.StoreID } catch {}\n${SENDER_SMTP_PS}\n$received = ''\ntry { $received = $item.ReceivedTime.ToString('yyyy-MM-dd HH:mm') } catch {}\nConvertTo-Json -Compress -Depth 3 -InputObject ([PSCustomObject]@{\n entryId = [string]$item.EntryID\n storeId = $storeId\n subject = ([string]$item.Subject).Trim()\n senderName = [string]$item.SenderName\n senderEmail = $senderSmtp\n receivedTime = $received\n body = ${BODY_B64_PS}\n attachmentNames = @($attachmentNames)\n})\n`, 'quick');\n const e = record(output);\n return {\n entryId: str(e.entryId),\n storeId: str(e.storeId),\n subject: str(e.subject),\n senderName: str(e.senderName),\n senderEmail: str(e.senderEmail),\n receivedTime: str(e.receivedTime),\n body: base64Text(e.body),\n attachmentNames: strList(e.attachmentNames),\n };\n}\n\n/**\n * Open an email in Outlook.\n *\n * Entry ids are rewritten when an item MOVES between folders, so an id recorded\n * before its mail was filed can stop resolving. That fails as NOT_FOUND rather\n * than guessing — the caller is the one who knows what the email was.\n */\nexport async function openOutlookEmail(email: EmailLocator): Promise<void> {\n await runPowerShell(`${SESSION_PS}\n${itemLookupScript(email)}\n$item.Display()\n`, 'quick');\n}\n"]}
@@ -1,54 +1,54 @@
1
- /**
2
- * Refuse before generating anything when this isn't Windows.
3
- *
4
- * Called at the top of each operation as well as inside the two runners, so a
5
- * call that would have written temp files or made preparatory reads doesn't do
6
- * any of that first. The runners hold the only copy of the check itself — three
7
- * near-identical guards worded three different ways is how "not supported" came
8
- * to mean two different sentences.
9
- */
1
+ import { type RunBudget } from '../runtime';
2
+ /** Refuse before generating anything when this isn't Windows. */
10
3
  export declare function requireWindows(): void;
11
- /**
12
- * Escape a string for a PowerShell SINGLE-quoted literal — the only context
13
- * caller-supplied text may go in.
14
- *
15
- * A double-quoted PowerShell string expands `$(...)` subexpressions, so text
16
- * placed there would execute. Where a generated script needs user text inside a
17
- * double-quoted string (a Restrict query, which must expand `$cutoff`), assign
18
- * it to a variable with this first and concatenate — see read.ts.
19
- */
20
- export declare function psEscape(s: string): string;
21
- /** A PowerShell array literal of single-quoted strings. */
22
- export declare function psList(values: readonly string[]): string;
4
+ /** Escape text for the inside of a PowerShell single-quoted literal. */
5
+ export declare function psEscape(text: string): string;
6
+ /** Caller text as a PowerShell single-quoted literal. */
7
+ export declare function psString(text: string): string;
8
+ /** Strings as a PowerShell array expression: `@('a', 'b')`. */
9
+ export declare function psArray(values: readonly string[]): string;
23
10
  /** `$true` / `$false` — PowerShell has no bare boolean literal. */
24
11
  export declare function psBool(value: boolean): string;
25
12
  /**
26
- * Run a generated script and return its stdout.
27
- *
28
- * `timeout` overrides the configured default for this one call — pass it where a
29
- * call has a genuinely different budget (a full-mailbox walk, a purge) rather
30
- * than relying on the global. See `configure()` for both knobs.
13
+ * A whole number for a script. The operations layer has already validated every
14
+ * count, so this refusing anything else is the second line of defence: a
15
+ * non-number never reaches a script as code.
31
16
  */
32
- export declare function runPowerShell(script: string, timeout?: number): Promise<string>;
17
+ export declare function psInt(value: number): string;
33
18
  /**
34
- * Run a generated script from a temp `.ps1` file rather than `-Command`.
19
+ * The complete script for a body: UTF-8 output, stop-on-error, and a catch that
20
+ * reports any failure as one JSON line on stderr.
35
21
  *
36
- * For the two calls that drive a compose window: a script passed on the command
37
- * line competes with the command-line length limit, and these carry enough
38
- * inline text to reach it. Failures classify exactly as `runPowerShell`'s do —
39
- * the file is an implementation detail, not a second error contract.
22
+ * UTF-8 output matters because Windows PowerShell 5.1 otherwise writes in the
23
+ * console's legacy code page, whose "best fit" mapping rewrites non-ASCII — a
24
+ * curly quote in a subject becomes a straight one — which corrupts the JSON
25
+ * the scripts print. The catch matters because an uncaught PowerShell error
26
+ * prints a multi-line error record ("At line:12 char:48 …") that would
27
+ * otherwise become the error's message.
28
+ */
29
+ export declare function buildScript(body: string): string;
30
+ /** Run a script body and return what it printed, trimmed. */
31
+ export declare function runPowerShell(body: string, budget: RunBudget): Promise<string>;
32
+ /**
33
+ * Run a script body that prints JSON, and return it parsed — null when the
34
+ * script printed nothing. Output that isn't JSON is a SCRIPT_FAILED carrying
35
+ * the script, never a bare SyntaxError.
40
36
  */
41
- export declare function runPowerShellFile(script: string, timeout?: number): Promise<string>;
37
+ export declare function runPowerShellJson(body: string, budget: RunBudget): Promise<unknown>;
42
38
  /**
43
- * Write text a script will read back, and hand back a cleanup callback.
39
+ * Write text a script will read back, and hand back its cleanup.
44
40
  *
45
- * Large HTML — an email body, a Word-sized template — goes to a file rather than
46
- * into the script text: inline, it is what pushes a generated script past the
47
- * command-line length limit.
41
+ * Large HTML — an email body, a Word-sized template — goes through a file rather
42
+ * than the script itself, where it would have to be escaped and would bloat
43
+ * every error and debug event that carries the script.
48
44
  */
49
45
  export declare function scriptInput(kind: string, contents: string): {
50
46
  path: string;
51
47
  cleanup(): void;
52
48
  };
53
- /** Read a file written by a script, as UTF-8, or '' when it never appeared. */
54
- export declare function readScriptOutput(path: string): string;
49
+ /**
50
+ * Read a file a script wrote, as UTF-8, and delete it; '' when it never
51
+ * appeared. .NET's UTF-8 writer opens the file with a byte-order mark, which is
52
+ * not part of the text.
53
+ */
54
+ export declare function readScriptOutput(file: string): string;
@@ -5,157 +5,197 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.requireWindows = requireWindows;
7
7
  exports.psEscape = psEscape;
8
- exports.psList = psList;
8
+ exports.psString = psString;
9
+ exports.psArray = psArray;
9
10
  exports.psBool = psBool;
11
+ exports.psInt = psInt;
12
+ exports.buildScript = buildScript;
10
13
  exports.runPowerShell = runPowerShell;
11
- exports.runPowerShellFile = runPowerShellFile;
14
+ exports.runPowerShellJson = runPowerShellJson;
12
15
  exports.scriptInput = scriptInput;
13
16
  exports.readScriptOutput = readScriptOutput;
14
17
  // Getting a generated script to Windows PowerShell and its output back.
15
18
  //
16
- // Every Windows function here is "build a script, run it, coerce the JSON", so
17
- // this module owns the two halves nobody should reimplement: the run itself
18
- // (encoding, timeout, cancellation, failure classification, the debug hook) and
19
- // the escaping rules for putting caller text into a script safely.
20
- const child_process_1 = require("child_process");
19
+ // Every Windows operation is "build a script, run it, read what it printed",
20
+ // so this module owns the parts nobody should reimplement: how a script is
21
+ // wrapped and run, how a failure is read back out of it, and the escaping rules
22
+ // for putting caller text into a script safely.
21
23
  const fs_1 = __importDefault(require("fs"));
22
- const runtime_1 = require("../runtime");
23
24
  const errors_1 = require("../errors");
25
+ const runtime_1 = require("../runtime");
26
+ const exec_1 = require("../shared/exec");
24
27
  const RUNNER = 'powershell';
25
- /**
26
- * Refuse before generating anything when this isn't Windows.
27
- *
28
- * Called at the top of each operation as well as inside the two runners, so a
29
- * call that would have written temp files or made preparatory reads doesn't do
30
- * any of that first. The runners hold the only copy of the check itself — three
31
- * near-identical guards worded three different ways is how "not supported" came
32
- * to mean two different sentences.
33
- */
28
+ /** Opens the line a script's catch block writes its failure on. */
29
+ const FAILURE_MARKER = '@@outlook-bridge-failure@@';
30
+ /** Refuse before generating anything when this isn't Windows. */
34
31
  function requireWindows() {
35
- if (process.platform !== 'win32') {
36
- throw new errors_1.UnsupportedPlatformError(process.platform, 'Outlook COM automation is only supported on Windows.');
37
- }
32
+ if (process.platform !== 'win32')
33
+ throw new errors_1.UnsupportedPlatformError(process.platform);
38
34
  }
39
- /**
40
- * Escape a string for a PowerShell SINGLE-quoted literal — the only context
41
- * caller-supplied text may go in.
42
- *
43
- * A double-quoted PowerShell string expands `$(...)` subexpressions, so text
44
- * placed there would execute. Where a generated script needs user text inside a
45
- * double-quoted string (a Restrict query, which must expand `$cutoff`), assign
46
- * it to a variable with this first and concatenate — see read.ts.
47
- */
48
- function psEscape(s) {
49
- return s.replace(/'/g, "''");
35
+ // ── Escaping ─────────────────────────────────────────────────────────────
36
+ //
37
+ // Caller text goes into a script ONLY as a single-quoted literal, built by
38
+ // `psString`. Two things make that the rule:
39
+ // - A double-quoted PowerShell string expands `$(...)`, so caller text placed
40
+ // in one runs as code. Where a message needs caller text, it is assigned to a
41
+ // variable first and the double-quoted string names the variable — a
42
+ // variable's value is never evaluated again.
43
+ // - PowerShell accepts the typographic quotes ‘ ’ ‚ ‛ as single quotes too, so
44
+ // doubling only the ASCII one leaves a way out of the literal. Every quote
45
+ // character is doubled, which PowerShell reads back as that same character.
46
+ /** Escape text for the inside of a PowerShell single-quoted literal. */
47
+ function psEscape(text) {
48
+ return text.replace(/['\u2018\u2019\u201A\u201B]/g, quote => quote + quote);
49
+ }
50
+ /** Caller text as a PowerShell single-quoted literal. */
51
+ function psString(text) {
52
+ return `'${psEscape(text)}'`;
50
53
  }
51
- /** A PowerShell array literal of single-quoted strings. */
52
- function psList(values) {
53
- return values.map(v => `'${psEscape(v)}'`).join(',');
54
+ /** Strings as a PowerShell array expression: `@('a', 'b')`. */
55
+ function psArray(values) {
56
+ return `@(${values.map(psString).join(', ')})`;
54
57
  }
55
58
  /** `$true` / `$false` — PowerShell has no bare boolean literal. */
56
59
  function psBool(value) {
57
60
  return value ? '$true' : '$false';
58
61
  }
59
- // Force UTF-8 on stdout. Windows PowerShell 5.1 otherwise encodes output in the
60
- // OEM/ANSI console code page, whose "best-fit" mapping silently rewrites
61
- // non-ASCII characters — e.g. a curly quote (U+201C) in an email body becomes a
62
- // plain " — which corrupts the JSON these scripts emit (an unescaped quote) and
63
- // breaks JSON.parse. Setting the output encoding first makes non-ASCII survive
64
- // as real UTF-8 bytes, which Node then decodes correctly.
65
- const UTF8_PRELUDE = '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8\n';
66
62
  /**
67
- * Run a generated script and return its stdout.
68
- *
69
- * `timeout` overrides the configured default for this one call — pass it where a
70
- * call has a genuinely different budget (a full-mailbox walk, a purge) rather
71
- * than relying on the global. See `configure()` for both knobs.
63
+ * A whole number for a script. The operations layer has already validated every
64
+ * count, so this refusing anything else is the second line of defence: a
65
+ * non-number never reaches a script as code.
72
66
  */
73
- function runPowerShell(script, timeout) {
74
- requireWindows();
75
- const utf8Script = UTF8_PRELUDE + script;
76
- return spawnPowerShell(['-NoProfile', '-NonInteractive', '-Command', utf8Script], utf8Script, timeout);
67
+ function psInt(value) {
68
+ if (!Number.isSafeInteger(value)) {
69
+ throw new errors_1.InvalidRequestError(`Expected a whole number, got ${String(value)}.`);
70
+ }
71
+ return String(value);
77
72
  }
73
+ // ── Running ──────────────────────────────────────────────────────────────
78
74
  /**
79
- * Run a generated script from a temp `.ps1` file rather than `-Command`.
75
+ * The complete script for a body: UTF-8 output, stop-on-error, and a catch that
76
+ * reports any failure as one JSON line on stderr.
80
77
  *
81
- * For the two calls that drive a compose window: a script passed on the command
82
- * line competes with the command-line length limit, and these carry enough
83
- * inline text to reach it. Failures classify exactly as `runPowerShell`'s do —
84
- * the file is an implementation detail, not a second error contract.
78
+ * UTF-8 output matters because Windows PowerShell 5.1 otherwise writes in the
79
+ * console's legacy code page, whose "best fit" mapping rewrites non-ASCII — a
80
+ * curly quote in a subject becomes a straight one — which corrupts the JSON
81
+ * the scripts print. The catch matters because an uncaught PowerShell error
82
+ * prints a multi-line error record ("At line:12 char:48 …") that would
83
+ * otherwise become the error's message.
85
84
  */
86
- async function runPowerShellFile(script, timeout) {
85
+ function buildScript(body) {
86
+ return `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
87
+ $ErrorActionPreference = 'Stop'
88
+ $WarningPreference = 'SilentlyContinue'
89
+ $ProgressPreference = 'SilentlyContinue'
90
+ try {
91
+ ${body}
92
+ } catch {
93
+ $failure = $_
94
+ $message = [string]$failure.Exception.Message
95
+ if (-not $message) { $message = [string]$failure }
96
+ $line = 0
97
+ try { $line = [int]$failure.InvocationInfo.ScriptLineNumber } catch {}
98
+ [Console]::Error.WriteLine('${FAILURE_MARKER}' + (ConvertTo-Json -Compress @{ message = $message; line = $line }))
99
+ exit 1
100
+ }
101
+ `;
102
+ }
103
+ /** The failure a script's catch block reported, or its raw stderr when it never got that far. */
104
+ function parseFailure(stderr) {
105
+ const at = stderr.lastIndexOf(FAILURE_MARKER);
106
+ if (at !== -1) {
107
+ const json = stderr.slice(at + FAILURE_MARKER.length).split(/\r?\n/)[0];
108
+ try {
109
+ const parsed = JSON.parse(json);
110
+ const line = typeof parsed.line === 'number' && parsed.line > 0 ? parsed.line : undefined;
111
+ return { message: String(parsed.message ?? ''), line };
112
+ }
113
+ catch {
114
+ // Fall through to the raw stderr.
115
+ }
116
+ }
117
+ // A script that fails to PARSE never enters its try block, so PowerShell's
118
+ // own report is all there is.
119
+ return { message: stderr.trim() };
120
+ }
121
+ async function execute(body, budget) {
87
122
  requireWindows();
88
- const scriptFile = (0, runtime_1.tempFile)('script', 'ps1');
89
- fs_1.default.writeFileSync(scriptFile, UTF8_PRELUDE + script, 'utf-8');
123
+ const script = buildScript(body);
124
+ // Always from a file, never `-Command`: a file has no command-line length
125
+ // limit and no second layer of quoting. The byte-order mark is what makes
126
+ // PowerShell 5.1 read it as UTF-8 rather than the ANSI code page, which
127
+ // would mangle every non-ASCII character in a subject, name or path.
128
+ const file = (0, runtime_1.tempFile)('script', 'ps1');
129
+ fs_1.default.writeFileSync(file, '\uFEFF' + script, 'utf8');
90
130
  try {
91
- return await spawnPowerShell(['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', scriptFile], script, timeout);
131
+ const { stdout, durationMs } = await (0, exec_1.runScriptProcess)({
132
+ runner: RUNNER,
133
+ command: 'powershell.exe',
134
+ args: ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', file],
135
+ script,
136
+ budget,
137
+ parseFailure,
138
+ });
139
+ return { stdout, script, durationMs };
92
140
  }
93
141
  finally {
94
- try {
95
- fs_1.default.unlinkSync(scriptFile);
96
- }
97
- catch { /* the run is done; a leftover scratch file is not worth failing on */
98
- }
142
+ (0, runtime_1.removeTempFile)(file);
99
143
  }
100
144
  }
101
- /** The one place a PowerShell child is spawned, timed, classified and reported. */
102
- function spawnPowerShell(args, script, timeout) {
103
- const { timeoutMs, maxBufferBytes, signal } = (0, runtime_1.getConfig)();
104
- const effectiveTimeout = timeout ?? timeoutMs;
105
- const startedAt = Date.now();
106
- return new Promise((resolve, reject) => {
107
- (0, child_process_1.execFile)('powershell.exe', args, { maxBuffer: maxBufferBytes, timeout: effectiveTimeout, signal }, (error, stdout, stderr) => {
108
- const durationMs = Date.now() - startedAt;
109
- if (error) {
110
- const failure = (0, errors_1.classifyRunFailure)({
111
- runner: RUNNER,
112
- script,
113
- stderr: (stderr || error.message).trim(),
114
- durationMs,
115
- nodeError: error,
116
- timeoutMs: effectiveTimeout,
117
- signal,
118
- });
119
- (0, runtime_1.reportRun)({ runner: RUNNER, script, durationMs, error: failure.message });
120
- reject(failure);
121
- }
122
- else {
123
- (0, runtime_1.reportRun)({ runner: RUNNER, script, durationMs });
124
- resolve(stdout.trim());
125
- }
145
+ /** Run a script body and return what it printed, trimmed. */
146
+ async function runPowerShell(body, budget) {
147
+ return (await execute(body, budget)).stdout.trim();
148
+ }
149
+ /**
150
+ * Run a script body that prints JSON, and return it parsed — null when the
151
+ * script printed nothing. Output that isn't JSON is a SCRIPT_FAILED carrying
152
+ * the script, never a bare SyntaxError.
153
+ */
154
+ async function runPowerShellJson(body, budget) {
155
+ const { stdout, script, durationMs } = await execute(body, budget);
156
+ const output = stdout.trim();
157
+ if (output === '' || output === 'null')
158
+ return null;
159
+ try {
160
+ return JSON.parse(output);
161
+ }
162
+ catch (error) {
163
+ throw new errors_1.ScriptError({
164
+ runner: RUNNER,
165
+ script,
166
+ stderr: '',
167
+ durationMs,
168
+ message: `PowerShell printed output that is not valid JSON: ${output.slice(0, 200)}`,
169
+ cause: error,
126
170
  });
127
- });
171
+ }
128
172
  }
129
173
  /**
130
- * Write text a script will read back, and hand back a cleanup callback.
174
+ * Write text a script will read back, and hand back its cleanup.
131
175
  *
132
- * Large HTML — an email body, a Word-sized template — goes to a file rather than
133
- * into the script text: inline, it is what pushes a generated script past the
134
- * command-line length limit.
176
+ * Large HTML — an email body, a Word-sized template — goes through a file rather
177
+ * than the script itself, where it would have to be escaped and would bloat
178
+ * every error and debug event that carries the script.
135
179
  */
136
180
  function scriptInput(kind, contents) {
137
- const path = (0, runtime_1.tempFile)(kind, 'html');
138
- fs_1.default.writeFileSync(path, contents, 'utf-8');
139
- return {
140
- path,
141
- cleanup() {
142
- try {
143
- fs_1.default.unlinkSync(path);
144
- }
145
- catch { /* ignore */
146
- }
147
- },
148
- };
181
+ const file = (0, runtime_1.tempFile)(kind, 'html');
182
+ fs_1.default.writeFileSync(file, contents, 'utf8');
183
+ return { path: file, cleanup: () => (0, runtime_1.removeTempFile)(file) };
149
184
  }
150
- /** Read a file written by a script, as UTF-8, or '' when it never appeared. */
151
- function readScriptOutput(path) {
185
+ /**
186
+ * Read a file a script wrote, as UTF-8, and delete it; '' when it never
187
+ * appeared. .NET's UTF-8 writer opens the file with a byte-order mark, which is
188
+ * not part of the text.
189
+ */
190
+ function readScriptOutput(file) {
152
191
  try {
153
- const contents = fs_1.default.readFileSync(path, 'utf-8');
154
- fs_1.default.unlinkSync(path);
155
- return contents;
192
+ return fs_1.default.readFileSync(file, 'utf8').replace(/^\uFEFF/, '');
156
193
  }
157
194
  catch {
158
195
  return '';
159
196
  }
197
+ finally {
198
+ (0, runtime_1.removeTempFile)(file);
199
+ }
160
200
  }
161
201
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/windows/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/windows/run.ts"],"names":[],"mappings":"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","sourcesContent":["// Getting a generated script to Windows PowerShell and its output back.\n//\n// Every Windows operation is \"build a script, run it, read what it printed\",\n// so this module owns the parts nobody should reimplement: how a script is\n// wrapped and run, how a failure is read back out of it, and the escaping rules\n// for putting caller text into a script safely.\nimport fs from 'fs';\nimport { InvalidRequestError, ScriptError, UnsupportedPlatformError } from '../errors';\nimport { removeTempFile, type RunBudget, tempFile } from '../runtime';\nimport { runScriptProcess } from '../shared/exec';\n\nconst RUNNER = 'powershell' as const;\n\n/** Opens the line a script's catch block writes its failure on. */\nconst FAILURE_MARKER = '@@outlook-bridge-failure@@';\n\n/** Refuse before generating anything when this isn't Windows. */\nexport function requireWindows(): void {\n if (process.platform !== 'win32') throw new UnsupportedPlatformError(process.platform);\n}\n\n// ── Escaping ─────────────────────────────────────────────────────────────\n//\n// Caller text goes into a script ONLY as a single-quoted literal, built by\n// `psString`. Two things make that the rule:\n// - A double-quoted PowerShell string expands `$(...)`, so caller text placed\n// in one runs as code. Where a message needs caller text, it is assigned to a\n// variable first and the double-quoted string names the variable — a\n// variable's value is never evaluated again.\n// - PowerShell accepts the typographic quotes ‘ ’ ‚ ‛ as single quotes too, so\n// doubling only the ASCII one leaves a way out of the literal. Every quote\n// character is doubled, which PowerShell reads back as that same character.\n\n/** Escape text for the inside of a PowerShell single-quoted literal. */\nexport function psEscape(text: string): string {\n return text.replace(/['\\u2018\\u2019\\u201A\\u201B]/g, quote => quote + quote);\n}\n\n/** Caller text as a PowerShell single-quoted literal. */\nexport function psString(text: string): string {\n return `'${psEscape(text)}'`;\n}\n\n/** Strings as a PowerShell array expression: `@('a', 'b')`. */\nexport function psArray(values: readonly string[]): string {\n return `@(${values.map(psString).join(', ')})`;\n}\n\n/** `$true` / `$false` — PowerShell has no bare boolean literal. */\nexport function psBool(value: boolean): string {\n return value ? '$true' : '$false';\n}\n\n/**\n * A whole number for a script. The operations layer has already validated every\n * count, so this refusing anything else is the second line of defence: a\n * non-number never reaches a script as code.\n */\nexport function psInt(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// ── Running ──────────────────────────────────────────────────────────────\n\n/**\n * The complete script for a body: UTF-8 output, stop-on-error, and a catch that\n * reports any failure as one JSON line on stderr.\n *\n * UTF-8 output matters because Windows PowerShell 5.1 otherwise writes in the\n * console's legacy code page, whose \"best fit\" mapping rewrites non-ASCII — a\n * curly quote in a subject becomes a straight one — which corrupts the JSON\n * the scripts print. The catch matters because an uncaught PowerShell error\n * prints a multi-line error record (\"At line:12 char:48 …\") that would\n * otherwise become the error's message.\n */\nexport function buildScript(body: string): string {\n return `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8\n$ErrorActionPreference = 'Stop'\n$WarningPreference = 'SilentlyContinue'\n$ProgressPreference = 'SilentlyContinue'\ntry {\n${body}\n} catch {\n $failure = $_\n $message = [string]$failure.Exception.Message\n if (-not $message) { $message = [string]$failure }\n $line = 0\n try { $line = [int]$failure.InvocationInfo.ScriptLineNumber } catch {}\n [Console]::Error.WriteLine('${FAILURE_MARKER}' + (ConvertTo-Json -Compress @{ message = $message; line = $line }))\n exit 1\n}\n`;\n}\n\n/** The failure a script's catch block reported, or its raw stderr when it never got that far. */\nfunction parseFailure(stderr: string): { message: string; line?: number } {\n const at = stderr.lastIndexOf(FAILURE_MARKER);\n if (at !== -1) {\n const json = stderr.slice(at + FAILURE_MARKER.length).split(/\\r?\\n/)[0];\n try {\n const parsed = JSON.parse(json) as { message?: unknown; line?: unknown };\n const line = typeof parsed.line === 'number' && parsed.line > 0 ? parsed.line : undefined;\n return {message: String(parsed.message ?? ''), line};\n } catch {\n // Fall through to the raw stderr.\n }\n }\n // A script that fails to PARSE never enters its try block, so PowerShell's\n // own report is all there is.\n return {message: stderr.trim()};\n}\n\nasync function execute(body: string, budget: RunBudget): Promise<{\n stdout: string;\n script: string;\n durationMs: number\n}> {\n requireWindows();\n const script = buildScript(body);\n // Always from a file, never `-Command`: a file has no command-line length\n // limit and no second layer of quoting. The byte-order mark is what makes\n // PowerShell 5.1 read it as UTF-8 rather than the ANSI code page, which\n // would mangle every non-ASCII character in a subject, name or path.\n const file = tempFile('script', 'ps1');\n fs.writeFileSync(file, '\\uFEFF' + script, 'utf8');\n try {\n const {stdout, durationMs} = await runScriptProcess({\n runner: RUNNER,\n command: 'powershell.exe',\n args: ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', file],\n script,\n budget,\n parseFailure,\n });\n return {stdout, script, durationMs};\n } finally {\n removeTempFile(file);\n }\n}\n\n/** Run a script body and return what it printed, trimmed. */\nexport async function runPowerShell(body: string, budget: RunBudget): Promise<string> {\n return (await execute(body, budget)).stdout.trim();\n}\n\n/**\n * Run a script body that prints JSON, and return it parsed — null when the\n * script printed nothing. Output that isn't JSON is a SCRIPT_FAILED carrying\n * the script, never a bare SyntaxError.\n */\nexport async function runPowerShellJson(body: string, budget: RunBudget): Promise<unknown> {\n const {stdout, script, durationMs} = await execute(body, budget);\n const output = stdout.trim();\n if (output === '' || output === 'null') return null;\n try {\n return JSON.parse(output);\n } catch (error) {\n throw new ScriptError({\n runner: RUNNER,\n script,\n stderr: '',\n durationMs,\n message: `PowerShell printed output that is not valid JSON: ${output.slice(0, 200)}`,\n cause: error,\n });\n }\n}\n\n/**\n * Write text a script will read back, and hand back its cleanup.\n *\n * Large HTML — an email body, a Word-sized template — goes through a file rather\n * than the script itself, where it would have to be escaped and would bloat\n * every error and debug event that carries the script.\n */\nexport function scriptInput(kind: string, contents: string): { path: string; cleanup(): void } {\n const file = tempFile(kind, 'html');\n fs.writeFileSync(file, contents, 'utf8');\n return {path: file, cleanup: () => removeTempFile(file)};\n}\n\n/**\n * Read a file a script wrote, as UTF-8, and delete it; '' when it never\n * appeared. .NET's UTF-8 writer opens the file with a byte-order mark, which is\n * not part of the text.\n */\nexport function readScriptOutput(file: string): string {\n try {\n return fs.readFileSync(file, 'utf8').replace(/^\\uFEFF/, '');\n } catch {\n return '';\n } finally {\n removeTempFile(file);\n }\n}\n"]}