@dawnlit/outlook-bridge 1.1.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +152 -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 +79 -43
  9. package/dist/errors.js +93 -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 +96 -117
  22. package/dist/mac/bounces.js.map +1 -1
  23. package/dist/mac/cleanup.d.ts +11 -25
  24. package/dist/mac/cleanup.js +44 -107
  25. package/dist/mac/cleanup.js.map +1 -1
  26. package/dist/mac/drafts.d.ts +15 -34
  27. package/dist/mac/drafts.js +113 -186
  28. package/dist/mac/drafts.js.map +1 -1
  29. package/dist/mac/folders.d.ts +12 -21
  30. package/dist/mac/folders.js +44 -59
  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 +21 -37
  39. package/dist/mac/read.js +198 -216
  40. package/dist/mac/read.js.map +1 -1
  41. package/dist/mac/run.d.ts +51 -38
  42. package/dist/mac/run.js +138 -103
  43. package/dist/mac/run.js.map +1 -1
  44. package/dist/mac/scripts.d.ts +90 -91
  45. package/dist/mac/scripts.js +167 -126
  46. package/dist/mac/scripts.js.map +1 -1
  47. package/dist/mac/send.d.ts +10 -20
  48. package/dist/mac/send.js +99 -89
  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 +79 -120
  55. package/dist/mac/templates.js.map +1 -1
  56. package/dist/mail.d.ts +80 -46
  57. package/dist/mail.js +179 -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 +26 -20
  66. package/dist/shared/attachmentMatch.js +60 -23
  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 +17 -6
  78. package/dist/shared/json.js +35 -24
  79. package/dist/shared/json.js.map +1 -1
  80. package/dist/shared/locate.d.ts +31 -0
  81. package/dist/shared/locate.js +128 -0
  82. package/dist/shared/locate.js.map +1 -0
  83. package/dist/shared/replyBody.d.ts +31 -36
  84. package/dist/shared/replyBody.js +83 -72
  85. package/dist/shared/replyBody.js.map +1 -1
  86. package/dist/shared/templateLimits.d.ts +14 -0
  87. package/dist/shared/templateLimits.js +21 -0
  88. package/dist/shared/templateLimits.js.map +1 -0
  89. package/dist/templateBody.d.ts +69 -0
  90. package/dist/{outlookTemplateSections.js → templateBody.js} +80 -73
  91. package/dist/templateBody.js.map +1 -0
  92. package/dist/types.d.ts +381 -168
  93. package/dist/types.js +8 -9
  94. package/dist/types.js.map +1 -1
  95. package/dist/windows/accounts.d.ts +7 -12
  96. package/dist/windows/accounts.js +19 -34
  97. package/dist/windows/accounts.js.map +1 -1
  98. package/dist/windows/attachments.d.ts +9 -24
  99. package/dist/windows/attachments.js +94 -119
  100. package/dist/windows/attachments.js.map +1 -1
  101. package/dist/windows/bounces.d.ts +13 -26
  102. package/dist/windows/bounces.js +168 -200
  103. package/dist/windows/bounces.js.map +1 -1
  104. package/dist/windows/cleanup.d.ts +23 -23
  105. package/dist/windows/cleanup.js +99 -113
  106. package/dist/windows/cleanup.js.map +1 -1
  107. package/dist/windows/drafts.d.ts +16 -35
  108. package/dist/windows/drafts.js +156 -253
  109. package/dist/windows/drafts.js.map +1 -1
  110. package/dist/windows/folders.d.ts +8 -13
  111. package/dist/windows/folders.js +44 -52
  112. package/dist/windows/folders.js.map +1 -1
  113. package/dist/windows/index.d.ts +2 -27
  114. package/dist/windows/index.js +11 -66
  115. package/dist/windows/index.js.map +1 -1
  116. package/dist/windows/read.d.ts +24 -60
  117. package/dist/windows/read.js +265 -306
  118. package/dist/windows/read.js.map +1 -1
  119. package/dist/windows/run.d.ts +38 -40
  120. package/dist/windows/run.js +151 -112
  121. package/dist/windows/run.js.map +1 -1
  122. package/dist/windows/scripts.d.ts +65 -55
  123. package/dist/windows/scripts.js +109 -85
  124. package/dist/windows/scripts.js.map +1 -1
  125. package/dist/windows/send.d.ts +9 -9
  126. package/dist/windows/send.js +76 -88
  127. package/dist/windows/send.js.map +1 -1
  128. package/dist/windows/signatures.d.ts +4 -10
  129. package/dist/windows/signatures.js +30 -37
  130. package/dist/windows/signatures.js.map +1 -1
  131. package/dist/windows/templates.d.ts +12 -18
  132. package/dist/windows/templates.js +117 -150
  133. package/dist/windows/templates.js.map +1 -1
  134. package/package.json +5 -4
  135. package/dist/OutlookService.d.ts +0 -43
  136. package/dist/OutlookService.js +0 -137
  137. package/dist/OutlookService.js.map +0 -1
  138. package/dist/outlookTemplateSections.d.ts +0 -62
  139. package/dist/outlookTemplateSections.js.map +0 -1
  140. package/dist/shared/capabilities.d.ts +0 -3
  141. package/dist/shared/capabilities.js +0 -9
  142. 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":";;AAqCA,0CAsEC;AASD,sCAoCC;AAYD,kDAuIC;AAGD,8CAuDC;AASD,4CAKC;AAnXD,yEAAyE;AACzE,mCAAmC;AACnC,+BAA2F;AAC3F,uCASmB;AACnB,yCAA2E;AAC3E,kCAA+G;AAC/G,sCAAuC;AAIvC;;;;GAIG;AACH,SAAS,YAAY,CAAC,MAAc;IAChC,IAAI,MAAM,KAAK,eAAQ,CAAC,MAAM;QAAE,OAAO,sBAAsB,CAAC;IAC9D,OAAO,IAAA,qBAAc,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,WAAW,GAAG,oFAAoF,CAAC;AAEzG,mEAAmE;AAC5D,KAAK,UAAU,eAAe,CAAC,OAAyB;IAC3D,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAA,qBAAc,EAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAiB,EAAC,GAAG,IAAA,uBAAa,EAAC,OAAO,CAAC,OAAO,CAAC;EAC1E,wBAAc;EACd,IAAA,yBAAe,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC;;EAEpD,IAAA,sBAAY,EAAC,OAAO,CAAC,QAAQ,CAAC;EAC9B,IAAA,0BAAgB,EAAC,OAAO,EAAE,QAAQ,CAAC;mBAClB,QAAQ;WAChB,IAAA,WAAK,EAAC,OAAO,CAAC,KAAK,CAAC;kBACb,IAAA,WAAK,EAAC,OAAO,CAAC,YAAY,CAAC;;;;;;;;2BAQlB,QAAQ;;;;;;;;;;;;;UAazB,IAAA,YAAM,EAAC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;CAqBzB,EAAE,UAAU,CAAC,CAAC;IACX,OAAO,IAAA,cAAO,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC7B,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,GAAG,CAAC,CAAC;QACtB,MAAM,eAAe,GAAG,IAAA,cAAO,EAAC,CAAC,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,UAAG,CAAC,CAAC;QAC5D,OAAO;YACH,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;YACvB,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;YACvB,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;YACvB,UAAU,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,UAAU,CAAC;YAC7B,WAAW,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,WAAW,CAAC;YAC/B,YAAY,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,YAAY,CAAC;YACjC,WAAW,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,WAAW,CAAC;YAC/B,eAAe;YACf,eAAe,EAAE,eAAe,CAAC,MAAM;YACvC,UAAU,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,UAAU,CAAC;SAChC,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,aAAa,CAAC,KAAmB;IACnD,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAiB,EAAC,GAAG,oBAAU;EACtD,IAAA,0BAAgB,EAAC,KAAK,CAAC;;;;;aAKZ,IAAA,mBAAU,EAAC,WAAW,EAAE,OAAO,CAAC;;;;;;EAM3C,wBAAc;;;;;;;;;wBASQ,WAAW;;;CAGlC,EAAE,OAAO,CAAC,CAAC;IACR,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,MAAM,CAAC,CAAC;IACzB,OAAO;QACH,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO;QACxC,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;QACvB,UAAU,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,UAAU,CAAC;QAC7B,WAAW,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,WAAW,CAAC;QAC/B,YAAY,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,YAAY,CAAC;QACjC,IAAI,EAAE,IAAA,iBAAU,EAAC,CAAC,CAAC,IAAI,CAAC;QACxB,eAAe,EAAE,IAAA,cAAO,EAAC,CAAC,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,UAAG,CAAC;KACvD,CAAC;AACN,CAAC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,mBAAmB,CAAC,OAAsB;IAC5D,MAAM,eAAe,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACpG,6EAA6E;IAC7E,0EAA0E;IAC1E,kEAAkE;IAClE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3G,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAiB,EAAC,GAAG,IAAA,uBAAa,EAAC,OAAO,CAAC,OAAO,CAAC;EAC1E,wBAAc;mCACmB,IAAA,WAAK,EAAC,eAAQ,CAAC,KAAK,CAAC;iBACvC,IAAA,cAAQ,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAA,wBAAiB,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC3E,IAAA,cAAQ,EAAC,WAAW,CAAC;oBAClB,IAAA,cAAQ,EAAC,OAAO,CAAC,cAAc,EAAE,MAAM,IAAI,EAAE,CAAC;kBAChD,IAAA,cAAQ,EAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,0BAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzD,IAAA,YAAM,EAAC,eAAe,CAAC;uBACpB,IAAA,YAAM,EAAC,OAAO,CAAC,iBAAiB,CAAC;iBACvC,IAAA,YAAM,EAAC,OAAO,CAAC,WAAW,CAAC;EAC1C,IAAA,sBAAY,EAAC,OAAO,CAAC,QAAQ,CAAC;;;;;sBAKV,yBAAkB,CAAC,GAAG,CAAC,WAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;eAM/C,IAAA,aAAO,EAAC,OAAO,CAAC,cAAc,CAAC;eAC/B,IAAA,aAAO,EAAC,OAAO,CAAC,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA4CxC,IAAA,0BAAgB,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCrD,wBAAc;;;;;;;;gCAQgB,WAAW;;;;;;;CAO1C,EAAE,MAAM,CAAC,CAAC;IACP,OAAO,IAAA,cAAO,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC7B,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,GAAG,CAAC,CAAC;QACtB,OAAO;YACH,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;YACvB,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;YACvB,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;YACvB,UAAU,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,UAAU,CAAC;YAC7B,WAAW,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,WAAW,CAAC;YAC/B,YAAY,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,YAAY,CAAC;YACjC,IAAI,EAAE,IAAA,iBAAU,EAAC,CAAC,CAAC,IAAI,CAAC;YACxB,eAAe,EAAE,IAAA,cAAO,EAAC,CAAC,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,UAAG,CAAC;YACpD,UAAU,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,UAAU,CAAC;SAChC,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC;AAED,2DAA2D;AACpD,KAAK,UAAU,iBAAiB;IACnC,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAiB,EAAC;;;;;;;;;;;;;;aAc9B,IAAA,mBAAU,EAAC,WAAW,EAAE,OAAO,CAAC;;;aAGhC,IAAA,mBAAU,EAAC,iBAAiB,CAAC;;;;;;;;;;EAUxC,wBAAc;;;;;;;;;;wBAUQ,WAAW;;;;CAIlC,EAAE,OAAO,CAAC,CAAC;IACR,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,MAAM,CAAC,CAAC;IACzB,OAAO;QACH,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;QACvB,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;QACvB,OAAO,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,OAAO,CAAC;QACvB,UAAU,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,UAAU,CAAC;QAC7B,WAAW,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,WAAW,CAAC;QAC/B,YAAY,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,YAAY,CAAC;QACjC,IAAI,EAAE,IAAA,iBAAU,EAAC,CAAC,CAAC,IAAI,CAAC;QACxB,eAAe,EAAE,IAAA,cAAO,EAAC,CAAC,CAAC,eAAe,CAAC;QAC3C,UAAU,EAAE,IAAA,UAAG,EAAC,CAAC,CAAC,UAAU,CAAC;KAChC,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,gBAAgB,CAAC,KAAmB;IACtD,MAAM,IAAA,mBAAa,EAAC,GAAG,oBAAU;EACnC,IAAA,0BAAgB,EAAC,KAAK,CAAC;;CAExB,EAAE,OAAO,CAAC,CAAC;AACZ,CAAC","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)}\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').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$folderPath = ''\ntry { $folderPath = [string]$item.Parent.FolderPath } 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 folderPath = $folderPath\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 folderPath: str(e.folderPath),\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,52 @@
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
- */
10
- 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;
1
+ import { type RunBudget } from '../runtime';
2
+ /** Escape text for the inside of a PowerShell single-quoted literal. */
3
+ export declare function psEscape(text: string): string;
4
+ /** Caller text as a PowerShell single-quoted literal. */
5
+ export declare function psString(text: string): string;
6
+ /** Strings as a PowerShell array expression: `@('a', 'b')`. */
7
+ export declare function psArray(values: readonly string[]): string;
23
8
  /** `$true` / `$false` — PowerShell has no bare boolean literal. */
24
9
  export declare function psBool(value: boolean): string;
25
10
  /**
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.
11
+ * A whole number for a script. The operations layer has already validated every
12
+ * count, so this refusing anything else is the second line of defence: a
13
+ * non-number never reaches a script as code.
31
14
  */
32
- export declare function runPowerShell(script: string, timeout?: number): Promise<string>;
15
+ export declare function psInt(value: number): string;
33
16
  /**
34
- * Run a generated script from a temp `.ps1` file rather than `-Command`.
17
+ * The complete script for a body: UTF-8 output, stop-on-error, and a catch that
18
+ * reports any failure as one JSON line on stderr.
35
19
  *
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.
20
+ * UTF-8 output matters because Windows PowerShell 5.1 otherwise writes in the
21
+ * console's legacy code page, whose "best fit" mapping rewrites non-ASCII — a
22
+ * curly quote in a subject becomes a straight one — which corrupts the JSON
23
+ * the scripts print. The catch matters because an uncaught PowerShell error
24
+ * prints a multi-line error record ("At line:12 char:48 …") that would
25
+ * otherwise become the error's message.
26
+ */
27
+ export declare function buildScript(body: string): string;
28
+ /** Run a script body and return what it printed, trimmed. */
29
+ export declare function runPowerShell(body: string, budget: RunBudget): Promise<string>;
30
+ /**
31
+ * Run a script body that prints JSON, and return it parsed — null when the
32
+ * script printed nothing. Output that isn't JSON is a SCRIPT_FAILED carrying
33
+ * the script, never a bare SyntaxError.
40
34
  */
41
- export declare function runPowerShellFile(script: string, timeout?: number): Promise<string>;
35
+ export declare function runPowerShellJson(body: string, budget: RunBudget): Promise<unknown>;
42
36
  /**
43
- * Write text a script will read back, and hand back a cleanup callback.
37
+ * Write text a script will read back, and hand back its cleanup.
44
38
  *
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.
39
+ * Large HTML — an email body, a Word-sized template — goes through a file rather
40
+ * than the script itself, where it would have to be escaped and would bloat
41
+ * every error and debug event that carries the script.
48
42
  */
49
43
  export declare function scriptInput(kind: string, contents: string): {
50
44
  path: string;
51
45
  cleanup(): void;
52
46
  };
53
- /** Read a file written by a script, as UTF-8, or '' when it never appeared. */
54
- export declare function readScriptOutput(path: string): string;
47
+ /**
48
+ * Read a file a script wrote, as UTF-8, and delete it; '' when it never
49
+ * appeared. .NET's UTF-8 writer opens the file with a byte-order mark, which is
50
+ * not part of the text.
51
+ */
52
+ export declare function readScriptOutput(file: string): string;
@@ -3,159 +3,198 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.requireWindows = requireWindows;
7
6
  exports.psEscape = psEscape;
8
- exports.psList = psList;
7
+ exports.psString = psString;
8
+ exports.psArray = psArray;
9
9
  exports.psBool = psBool;
10
+ exports.psInt = psInt;
11
+ exports.buildScript = buildScript;
10
12
  exports.runPowerShell = runPowerShell;
11
- exports.runPowerShellFile = runPowerShellFile;
13
+ exports.runPowerShellJson = runPowerShellJson;
12
14
  exports.scriptInput = scriptInput;
13
15
  exports.readScriptOutput = readScriptOutput;
14
16
  // Getting a generated script to Windows PowerShell and its output back.
15
17
  //
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");
18
+ // Every Windows operation is "build a script, run it, read what it printed",
19
+ // so this module owns the parts nobody should reimplement: how a script is
20
+ // wrapped and run, how a failure is read back out of it, and the escaping rules
21
+ // for putting caller text into a script safely.
21
22
  const fs_1 = __importDefault(require("fs"));
22
- const runtime_1 = require("../runtime");
23
23
  const errors_1 = require("../errors");
24
+ const runtime_1 = require("../runtime");
25
+ const exec_1 = require("../shared/exec");
24
26
  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
- */
27
+ /** Opens the line a script's catch block writes its failure on. */
28
+ const FAILURE_MARKER = '@@outlook-bridge-failure@@';
29
+ /** Refuse before writing or running a script when this isn't Windows. */
34
30
  function requireWindows() {
35
- if (process.platform !== 'win32') {
36
- throw new errors_1.UnsupportedPlatformError(process.platform, 'Outlook COM automation is only supported on Windows.');
37
- }
31
+ if (process.platform !== 'win32')
32
+ throw new errors_1.UnsupportedPlatformError(process.platform);
38
33
  }
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, "''");
34
+ // ── Escaping ─────────────────────────────────────────────────────────────
35
+ //
36
+ // Caller text goes into a script ONLY as a single-quoted literal, built by
37
+ // `psString`. Two things make that the rule:
38
+ // - A double-quoted PowerShell string expands `$(...)`, so caller text placed
39
+ // in one runs as code. Where a message needs caller text, it is assigned to a
40
+ // variable first and the double-quoted string names the variable — a
41
+ // variable's value is never evaluated again.
42
+ // - PowerShell accepts the typographic quotes ‘ ’ ‚ ‛ as single quotes too, so
43
+ // doubling only the ASCII one leaves a way out of the literal. Every quote
44
+ // character is doubled, which PowerShell reads back as that same character.
45
+ /** Escape text for the inside of a PowerShell single-quoted literal. */
46
+ function psEscape(text) {
47
+ return text.replace(/['\u2018\u2019\u201A\u201B]/g, quote => quote + quote);
48
+ }
49
+ /** Caller text as a PowerShell single-quoted literal. */
50
+ function psString(text) {
51
+ return `'${psEscape(text)}'`;
50
52
  }
51
- /** A PowerShell array literal of single-quoted strings. */
52
- function psList(values) {
53
- return values.map(v => `'${psEscape(v)}'`).join(',');
53
+ /** Strings as a PowerShell array expression: `@('a', 'b')`. */
54
+ function psArray(values) {
55
+ return `@(${values.map(psString).join(', ')})`;
54
56
  }
55
57
  /** `$true` / `$false` — PowerShell has no bare boolean literal. */
56
58
  function psBool(value) {
57
59
  return value ? '$true' : '$false';
58
60
  }
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
61
  /**
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.
62
+ * A whole number for a script. The operations layer has already validated every
63
+ * count, so this refusing anything else is the second line of defence: a
64
+ * non-number never reaches a script as code.
72
65
  */
73
- function runPowerShell(script, timeout) {
74
- requireWindows();
75
- const utf8Script = UTF8_PRELUDE + script;
76
- return spawnPowerShell(['-NoProfile', '-NonInteractive', '-Command', utf8Script], utf8Script, timeout);
66
+ function psInt(value) {
67
+ if (!Number.isSafeInteger(value)) {
68
+ throw new errors_1.InvalidRequestError(`Expected a whole number, got ${String(value)}.`);
69
+ }
70
+ return String(value);
77
71
  }
72
+ // ── Running ──────────────────────────────────────────────────────────────
78
73
  /**
79
- * Run a generated script from a temp `.ps1` file rather than `-Command`.
74
+ * The complete script for a body: UTF-8 output, stop-on-error, and a catch that
75
+ * reports any failure as one JSON line on stderr.
80
76
  *
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.
77
+ * UTF-8 output matters because Windows PowerShell 5.1 otherwise writes in the
78
+ * console's legacy code page, whose "best fit" mapping rewrites non-ASCII — a
79
+ * curly quote in a subject becomes a straight one — which corrupts the JSON
80
+ * the scripts print. The catch matters because an uncaught PowerShell error
81
+ * prints a multi-line error record ("At line:12 char:48 …") that would
82
+ * otherwise become the error's message.
85
83
  */
86
- async function runPowerShellFile(script, timeout) {
84
+ function buildScript(body) {
85
+ return `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
86
+ $ErrorActionPreference = 'Stop'
87
+ $WarningPreference = 'SilentlyContinue'
88
+ $ProgressPreference = 'SilentlyContinue'
89
+ try {
90
+ ${body}
91
+ } catch {
92
+ $failure = $_
93
+ $message = [string]$failure.Exception.Message
94
+ if (-not $message) { $message = [string]$failure }
95
+ $line = 0
96
+ try { $line = [int]$failure.InvocationInfo.ScriptLineNumber } catch {}
97
+ [Console]::Error.WriteLine('${FAILURE_MARKER}' + (ConvertTo-Json -Compress @{ message = $message; line = $line }))
98
+ exit 1
99
+ }
100
+ `;
101
+ }
102
+ /** The failure a script's catch block reported, or its raw stderr when it never got that far. */
103
+ function parseFailure(stderr) {
104
+ const at = stderr.lastIndexOf(FAILURE_MARKER);
105
+ if (at !== -1) {
106
+ const json = stderr.slice(at + FAILURE_MARKER.length).split(/\r?\n/)[0];
107
+ try {
108
+ const parsed = JSON.parse(json);
109
+ const line = typeof parsed.line === 'number' && parsed.line > 0 ? parsed.line : undefined;
110
+ return { message: String(parsed.message ?? ''), line };
111
+ }
112
+ catch {
113
+ // Fall through to the raw stderr.
114
+ }
115
+ }
116
+ // A script that fails to PARSE never enters its try block, so PowerShell's
117
+ // own report is all there is.
118
+ return { message: stderr.trim() };
119
+ }
120
+ async function execute(body, budget) {
87
121
  requireWindows();
88
- const scriptFile = (0, runtime_1.tempFile)('script', 'ps1');
89
- fs_1.default.writeFileSync(scriptFile, UTF8_PRELUDE + script, 'utf-8');
122
+ const script = buildScript(body);
123
+ // Always from a file, never `-Command`: a file has no command-line length
124
+ // limit and no second layer of quoting. The byte-order mark is what makes
125
+ // PowerShell 5.1 read it as UTF-8 rather than the ANSI code page, which
126
+ // would mangle every non-ASCII character in a subject, name or path.
127
+ const file = (0, runtime_1.tempFile)('script', 'ps1');
128
+ fs_1.default.writeFileSync(file, '\uFEFF' + script, 'utf8');
90
129
  try {
91
- return await spawnPowerShell(['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', scriptFile], script, timeout);
130
+ const { stdout, durationMs } = await (0, exec_1.runScriptProcess)({
131
+ runner: RUNNER,
132
+ command: 'powershell.exe',
133
+ args: ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', file],
134
+ script,
135
+ budget,
136
+ parseFailure,
137
+ });
138
+ return { stdout, script, durationMs };
92
139
  }
93
140
  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
- }
141
+ (0, runtime_1.removeTempFile)(file);
99
142
  }
100
143
  }
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
- }
144
+ /** Run a script body and return what it printed, trimmed. */
145
+ async function runPowerShell(body, budget) {
146
+ return (await execute(body, budget)).stdout.trim();
147
+ }
148
+ /**
149
+ * Run a script body that prints JSON, and return it parsed — null when the
150
+ * script printed nothing. Output that isn't JSON is a SCRIPT_FAILED carrying
151
+ * the script, never a bare SyntaxError.
152
+ */
153
+ async function runPowerShellJson(body, budget) {
154
+ const { stdout, script, durationMs } = await execute(body, budget);
155
+ const output = stdout.trim();
156
+ if (output === '' || output === 'null')
157
+ return null;
158
+ try {
159
+ return JSON.parse(output);
160
+ }
161
+ catch (error) {
162
+ throw new errors_1.ScriptError({
163
+ runner: RUNNER,
164
+ script,
165
+ stderr: '',
166
+ durationMs,
167
+ message: `PowerShell printed output that is not valid JSON: ${output.slice(0, 200)}`,
168
+ cause: error,
126
169
  });
127
- });
170
+ }
128
171
  }
129
172
  /**
130
- * Write text a script will read back, and hand back a cleanup callback.
173
+ * Write text a script will read back, and hand back its cleanup.
131
174
  *
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.
175
+ * Large HTML — an email body, a Word-sized template — goes through a file rather
176
+ * than the script itself, where it would have to be escaped and would bloat
177
+ * every error and debug event that carries the script.
135
178
  */
136
179
  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
- };
180
+ const file = (0, runtime_1.tempFile)(kind, 'html');
181
+ fs_1.default.writeFileSync(file, contents, 'utf8');
182
+ return { path: file, cleanup: () => (0, runtime_1.removeTempFile)(file) };
149
183
  }
150
- /** Read a file written by a script, as UTF-8, or '' when it never appeared. */
151
- function readScriptOutput(path) {
184
+ /**
185
+ * Read a file a script wrote, as UTF-8, and delete it; '' when it never
186
+ * appeared. .NET's UTF-8 writer opens the file with a byte-order mark, which is
187
+ * not part of the text.
188
+ */
189
+ function readScriptOutput(file) {
152
190
  try {
153
- const contents = fs_1.default.readFileSync(path, 'utf-8');
154
- fs_1.default.unlinkSync(path);
155
- return contents;
191
+ return fs_1.default.readFileSync(file, 'utf8').replace(/^\uFEFF/, '');
156
192
  }
157
193
  catch {
158
194
  return '';
159
195
  }
196
+ finally {
197
+ (0, runtime_1.removeTempFile)(file);
198
+ }
160
199
  }
161
200
  //# 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 { type ProcessOutput, 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 writing or running a script when this isn't Windows. */\nfunction 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<ProcessOutput & { script: string }> {\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"]}