@dawnlit/outlook-bridge 1.1.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -183
- package/dist/backend.d.ts +151 -0
- package/dist/backend.js +3 -0
- package/dist/backend.js.map +1 -0
- package/dist/bridge.d.ts +56 -0
- package/dist/bridge.js +507 -0
- package/dist/bridge.js.map +1 -0
- package/dist/errors.d.ts +81 -43
- package/dist/errors.js +98 -52
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +25 -52
- package/dist/index.js.map +1 -1
- package/dist/mac/accounts.d.ts +7 -2
- package/dist/mac/accounts.js +23 -6
- package/dist/mac/accounts.js.map +1 -1
- package/dist/mac/attachments.d.ts +5 -25
- package/dist/mac/attachments.js +40 -99
- package/dist/mac/attachments.js.map +1 -1
- package/dist/mac/bounces.d.ts +12 -27
- package/dist/mac/bounces.js +95 -112
- package/dist/mac/bounces.js.map +1 -1
- package/dist/mac/cleanup.d.ts +11 -25
- package/dist/mac/cleanup.js +50 -76
- package/dist/mac/cleanup.js.map +1 -1
- package/dist/mac/drafts.d.ts +13 -34
- package/dist/mac/drafts.js +95 -169
- package/dist/mac/drafts.js.map +1 -1
- package/dist/mac/folders.d.ts +10 -21
- package/dist/mac/folders.js +33 -47
- package/dist/mac/folders.js.map +1 -1
- package/dist/mac/index.d.ts +2 -22
- package/dist/mac/index.js +19 -81
- package/dist/mac/index.js.map +1 -1
- package/dist/mac/profile.d.ts +13 -0
- package/dist/mac/profile.js +149 -0
- package/dist/mac/profile.js.map +1 -0
- package/dist/mac/read.d.ts +18 -38
- package/dist/mac/read.js +154 -210
- package/dist/mac/read.js.map +1 -1
- package/dist/mac/run.d.ts +35 -39
- package/dist/mac/run.js +97 -102
- package/dist/mac/run.js.map +1 -1
- package/dist/mac/scripts.d.ts +78 -86
- package/dist/mac/scripts.js +125 -115
- package/dist/mac/scripts.js.map +1 -1
- package/dist/mac/send.d.ts +10 -20
- package/dist/mac/send.js +64 -86
- package/dist/mac/send.js.map +1 -1
- package/dist/mac/signatures.d.ts +2 -2
- package/dist/mac/signatures.js +9 -11
- package/dist/mac/signatures.js.map +1 -1
- package/dist/mac/templates.d.ts +14 -26
- package/dist/mac/templates.js +75 -113
- package/dist/mac/templates.js.map +1 -1
- package/dist/mail.d.ts +77 -45
- package/dist/mail.js +166 -73
- package/dist/mail.js.map +1 -1
- package/dist/runtime.d.ts +76 -43
- package/dist/runtime.js +103 -48
- package/dist/runtime.js.map +1 -1
- package/dist/shared/args.d.ts +48 -0
- package/dist/shared/args.js +216 -0
- package/dist/shared/args.js.map +1 -0
- package/dist/shared/attachmentMatch.d.ts +28 -16
- package/dist/shared/attachmentMatch.js +60 -22
- package/dist/shared/attachmentMatch.js.map +1 -1
- package/dist/shared/bounceReport.d.ts +11 -0
- package/dist/shared/bounceReport.js +45 -0
- package/dist/shared/bounceReport.js.map +1 -0
- package/dist/shared/bounceRules.d.ts +38 -10
- package/dist/shared/bounceRules.js +50 -32
- package/dist/shared/bounceRules.js.map +1 -1
- package/dist/shared/exec.d.ts +21 -0
- package/dist/shared/exec.js +47 -0
- package/dist/shared/exec.js.map +1 -0
- package/dist/shared/json.d.ts +12 -6
- package/dist/shared/json.js +29 -23
- package/dist/shared/json.js.map +1 -1
- package/dist/shared/locate.d.ts +39 -0
- package/dist/shared/locate.js +129 -0
- package/dist/shared/locate.js.map +1 -0
- package/dist/shared/replyBody.d.ts +42 -32
- package/dist/shared/replyBody.js +84 -71
- package/dist/shared/replyBody.js.map +1 -1
- package/dist/templateBody.d.ts +63 -0
- package/dist/{outlookTemplateSections.js → templateBody.js} +72 -72
- package/dist/templateBody.js.map +1 -0
- package/dist/types.d.ts +360 -167
- package/dist/types.js +8 -9
- package/dist/types.js.map +1 -1
- package/dist/windows/accounts.d.ts +7 -12
- package/dist/windows/accounts.js +19 -34
- package/dist/windows/accounts.js.map +1 -1
- package/dist/windows/attachments.d.ts +9 -24
- package/dist/windows/attachments.js +94 -119
- package/dist/windows/attachments.js.map +1 -1
- package/dist/windows/bounces.d.ts +13 -26
- package/dist/windows/bounces.js +168 -200
- package/dist/windows/bounces.js.map +1 -1
- package/dist/windows/cleanup.d.ts +19 -23
- package/dist/windows/cleanup.js +92 -111
- package/dist/windows/cleanup.js.map +1 -1
- package/dist/windows/drafts.d.ts +16 -35
- package/dist/windows/drafts.js +167 -253
- package/dist/windows/drafts.js.map +1 -1
- package/dist/windows/folders.d.ts +8 -13
- package/dist/windows/folders.js +44 -52
- package/dist/windows/folders.js.map +1 -1
- package/dist/windows/index.d.ts +2 -27
- package/dist/windows/index.js +11 -66
- package/dist/windows/index.js.map +1 -1
- package/dist/windows/read.d.ts +24 -60
- package/dist/windows/read.js +261 -306
- package/dist/windows/read.js.map +1 -1
- package/dist/windows/run.d.ts +39 -39
- package/dist/windows/run.js +151 -111
- package/dist/windows/run.js.map +1 -1
- package/dist/windows/scripts.d.ts +65 -55
- package/dist/windows/scripts.js +109 -85
- package/dist/windows/scripts.js.map +1 -1
- package/dist/windows/send.d.ts +6 -11
- package/dist/windows/send.js +68 -88
- package/dist/windows/send.js.map +1 -1
- package/dist/windows/signatures.d.ts +4 -10
- package/dist/windows/signatures.js +30 -37
- package/dist/windows/signatures.js.map +1 -1
- package/dist/windows/templates.d.ts +12 -18
- package/dist/windows/templates.js +122 -149
- package/dist/windows/templates.js.map +1 -1
- package/package.json +4 -3
- package/dist/OutlookService.d.ts +0 -43
- package/dist/OutlookService.js +0 -137
- package/dist/OutlookService.js.map +0 -1
- package/dist/outlookTemplateSections.d.ts +0 -62
- package/dist/outlookTemplateSections.js.map +0 -1
- package/dist/shared/capabilities.d.ts +0 -3
- package/dist/shared/capabilities.js +0 -9
- package/dist/shared/capabilities.js.map +0 -1
package/dist/windows/read.js.map
CHANGED
|
@@ -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"]}
|
package/dist/windows/run.d.ts
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
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
|
|
17
|
+
export declare function psInt(value: number): string;
|
|
33
18
|
/**
|
|
34
|
-
*
|
|
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
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* the
|
|
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
|
|
37
|
+
export declare function runPowerShellJson(body: string, budget: RunBudget): Promise<unknown>;
|
|
42
38
|
/**
|
|
43
|
-
* Write text a script will read back, and hand back
|
|
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
|
|
46
|
-
*
|
|
47
|
-
*
|
|
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
|
-
/**
|
|
54
|
-
|
|
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;
|
package/dist/windows/run.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
|
17
|
-
// this module owns the
|
|
18
|
-
//
|
|
19
|
-
//
|
|
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
|
-
|
|
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
|
|
37
|
-
}
|
|
32
|
+
if (process.platform !== 'win32')
|
|
33
|
+
throw new errors_1.UnsupportedPlatformError(process.platform);
|
|
38
34
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
/**
|
|
52
|
-
function
|
|
53
|
-
return values.map(
|
|
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
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
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
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* the
|
|
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
|
-
|
|
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
|
|
89
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
/**
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
|
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
|
|
133
|
-
*
|
|
134
|
-
*
|
|
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
|
|
138
|
-
fs_1.default.writeFileSync(
|
|
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
|
-
/**
|
|
151
|
-
|
|
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
|
-
|
|
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
|
package/dist/windows/run.js.map
CHANGED
|
@@ -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"]}
|