@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
|
@@ -1,79 +1,89 @@
|
|
|
1
|
-
import type { MailFolderRef } from '../types';
|
|
1
|
+
import type { EmailLocator, MailFolderRef } from '../types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `$storeFolder`.
|
|
3
|
+
* Open the MAPI session, binding `$outlook` and `$ns`.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
5
|
+
* `Logon()` is a no-op against an Outlook that is already running and starts
|
|
6
|
+
* one that isn't, which removes a class of "works only while Outlook is open"
|
|
7
|
+
* failure.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SESSION_PS = "\n$outlook = New-Object -ComObject Outlook.Application\n$ns = $outlook.GetNamespace('MAPI')\n$ns.Logon()\n";
|
|
10
|
+
/**
|
|
11
|
+
* The session plus the mailbox an address names; binds `$target`, `$account`
|
|
12
|
+
* and `$storeFolder`.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `
|
|
14
|
+
* An address can name a mailbox two ways, and only one is an Account. A mailbox
|
|
15
|
+
* mounted as a secondary store — a shared mailbox, or one added after Outlook
|
|
16
|
+
* started — has no Account object, so both are resolved and EITHER is enough:
|
|
17
|
+
* `$account` is null for a store-only mailbox, and the operations that need an
|
|
18
|
+
* identity to act as (sending) check for it themselves.
|
|
18
19
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* Never falls back to the default account: a bad address must not silently
|
|
21
|
+
* read or send from the wrong mailbox.
|
|
22
|
+
*
|
|
23
|
+
* The store is matched on the address BEFORE the account's display name, so a
|
|
24
|
+
* profile where the two differ selects the same folders it always has.
|
|
22
25
|
*/
|
|
23
26
|
export declare function accountScript(emailAccount: string): string;
|
|
24
27
|
/**
|
|
25
|
-
* The mailbox's
|
|
28
|
+
* The mailbox's store as `$store` (and its id as `$storeId`), reached through
|
|
29
|
+
* the account's delivery store. Requires `accountScript`.
|
|
26
30
|
*
|
|
27
|
-
* Falls back to the resolved store folder because a store-only mailbox has no
|
|
28
|
-
* account to read a
|
|
29
|
-
* what makes an operation fail on exactly those mailboxes.
|
|
31
|
+
* Falls back to the resolved store folder, because a store-only mailbox has no
|
|
32
|
+
* account to read a delivery store off.
|
|
30
33
|
*/
|
|
31
34
|
export declare const DELIVERY_STORE_PS = "\n$store = if ($account -ne $null) { $account.DeliveryStore } else { $storeFolder.Store }\n$storeId = $store.StoreID\n";
|
|
32
35
|
/**
|
|
33
|
-
* The store
|
|
34
|
-
*
|
|
36
|
+
* The mailbox's store as `$store`, reached through the namespace's top-level
|
|
37
|
+
* folder for it. Requires `accountScript`.
|
|
35
38
|
*
|
|
36
|
-
* Kept
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
|
|
39
|
+
* Kept beside DELIVERY_STORE_PS rather than replaced by it: the readers resolve
|
|
40
|
+
* their store this way, and on a profile where a mailbox is open under a display
|
|
41
|
+
* name that differs from its delivery store's, the two routes do not select the
|
|
42
|
+
* same folders. Each operation keeps the route it was verified against.
|
|
43
|
+
*/
|
|
44
|
+
export declare const NAMED_STORE_PS: string;
|
|
45
|
+
/**
|
|
46
|
+
* Resolve one email into `$<variable>`, or fail as NOT_FOUND.
|
|
41
47
|
*
|
|
42
|
-
* The
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* not open in this profile.
|
|
48
|
+
* The StoreID is tried first, since it lets an id from any mounted mailbox
|
|
49
|
+
* resolve; the bare lookup (default store) is the fallback for a caller holding
|
|
50
|
+
* a stale StoreID or none.
|
|
46
51
|
*/
|
|
47
|
-
export declare function
|
|
52
|
+
export declare function itemLookupScript(email: EmailLocator, variable?: string): string;
|
|
48
53
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
54
|
+
* The sender's SMTP address as `$senderSmtp`. Requires `$item`.
|
|
55
|
+
*
|
|
56
|
+
* An Exchange sender's SenderEmailAddress is an X.500 DN, not an address; a
|
|
57
|
+
* caller replying to it or matching it against anything needs the address.
|
|
51
58
|
*/
|
|
52
|
-
export declare
|
|
59
|
+
export declare const SENDER_SMTP_PS = "\n$senderSmtp = ''\ntry {\n if ($item.SenderEmailType -eq 'EX') { $senderSmtp = [string]$item.Sender.GetExchangeUser().PrimarySmtpAddress }\n} catch {}\nif (-not $senderSmtp) { try { $senderSmtp = [string]$item.SenderEmailAddress } catch {} }\n";
|
|
60
|
+
/** Recursive, case-insensitive folder search by name, depth-capped so a huge tree can't hang it. */
|
|
61
|
+
export declare const FIND_FOLDER_PS = "\nfunction Find-FolderByName($root, [string]$name, [int]$depth) {\n foreach ($f in $root.Folders) {\n if ($f.Name -ieq $name) { return $f }\n }\n if ($depth -le 1) { return $null }\n foreach ($f in $root.Folders) {\n $hit = Find-FolderByName $f $name ($depth - 1)\n if ($hit -ne $null) { return $hit }\n }\n return $null\n}\n";
|
|
53
62
|
/**
|
|
54
|
-
*
|
|
63
|
+
* `$cutoff`, the moment `daysBack` days ago, and `$cutoffFilter`, that moment
|
|
64
|
+
* as a date string for an `Items.Restrict` filter.
|
|
55
65
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
66
|
+
* Restrict parses date strings in the machine's own regional format, so the
|
|
67
|
+
* string is formatted in it ('g': short date and time) rather than a fixed
|
|
68
|
+
* pattern — 'MM/dd/yyyy' reads as a different day on a day-first locale. Every
|
|
69
|
+
* reader re-checks each item against `$cutoff` too, so the window holds even
|
|
70
|
+
* where a store reads the filter loosely.
|
|
59
71
|
*/
|
|
60
|
-
export declare
|
|
72
|
+
export declare function cutoffScript(daysBack: number): string;
|
|
61
73
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
74
|
+
* `$<variable>` = the items of `$<folderVariable>` with `property` on or after
|
|
75
|
+
* `$cutoff`. Requires `cutoffScript`. A store that rejects the filter outright
|
|
76
|
+
* yields every item instead, which the per-item re-check then narrows.
|
|
64
77
|
*/
|
|
65
|
-
export declare
|
|
78
|
+
export declare function itemsSinceScript(folderVariable: string, property: string, variable: string): string;
|
|
66
79
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* Split out so the emitted script can be parse-checked without an Outlook
|
|
71
|
-
* session — the folder walk is the only part that varies per call, and a syntax
|
|
72
|
-
* error in it would only ever surface as a failed live run.
|
|
80
|
+
* Resolve `$scope` from `$store`: a well-known root walked down through any
|
|
81
|
+
* further segments. Also binds `$scopeCreated`.
|
|
73
82
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
83
|
+
* Segments match direct children; a bare name that isn't a direct child falls
|
|
84
|
+
* back to a recursive search, so one folder string works across operations. A
|
|
85
|
+
* missing folder fails as NOT_FOUND naming what the caller typed and what the
|
|
86
|
+
* deepest folder reached does hold — never a silent fall back to the root. With
|
|
87
|
+
* `createMissing`, the whole missing chain is created instead.
|
|
78
88
|
*/
|
|
79
|
-
export declare function mailScopeScript(ref: MailFolderRef, folderLabel
|
|
89
|
+
export declare function mailScopeScript(ref: MailFolderRef, folderLabel: string, createMissing?: boolean): string;
|
package/dist/windows/scripts.js
CHANGED
|
@@ -1,53 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FIND_FOLDER_PS = exports.SENDER_SMTP_PS = exports.DELIVERY_STORE_PS = void 0;
|
|
3
|
+
exports.FIND_FOLDER_PS = exports.SENDER_SMTP_PS = exports.NAMED_STORE_PS = exports.DELIVERY_STORE_PS = exports.SESSION_PS = void 0;
|
|
4
4
|
exports.accountScript = accountScript;
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
5
|
+
exports.itemLookupScript = itemLookupScript;
|
|
6
|
+
exports.cutoffScript = cutoffScript;
|
|
7
|
+
exports.itemsSinceScript = itemsSinceScript;
|
|
7
8
|
exports.mailScopeScript = mailScopeScript;
|
|
8
9
|
// The PowerShell fragments more than one Windows operation is built from.
|
|
9
10
|
//
|
|
10
|
-
// A fragment lives here once
|
|
11
|
-
// operation stays beside that operation, where its rules
|
|
12
|
-
//
|
|
11
|
+
// A fragment lives here once two modules emit it; one used by a single
|
|
12
|
+
// operation stays beside that operation, where its rules read next to the code
|
|
13
|
+
// relying on them. Every fragment follows run.ts's escaping rule: caller text
|
|
14
|
+
// only ever appears as a psString literal.
|
|
13
15
|
const run_1 = require("./run");
|
|
16
|
+
const errors_1 = require("../errors");
|
|
14
17
|
/**
|
|
15
|
-
* Open
|
|
18
|
+
* Open the MAPI session, binding `$outlook` and `$ns`.
|
|
16
19
|
*
|
|
17
|
-
* `Logon()` is a no-op against an Outlook that is already running and starts
|
|
18
|
-
* that isn't,
|
|
19
|
-
*
|
|
20
|
+
* `Logon()` is a no-op against an Outlook that is already running and starts
|
|
21
|
+
* one that isn't, which removes a class of "works only while Outlook is open"
|
|
22
|
+
* failure.
|
|
20
23
|
*/
|
|
21
|
-
|
|
22
|
-
$ErrorActionPreference = 'Stop'
|
|
24
|
+
exports.SESSION_PS = `
|
|
23
25
|
$outlook = New-Object -ComObject Outlook.Application
|
|
24
|
-
$ns = $outlook.GetNamespace('
|
|
26
|
+
$ns = $outlook.GetNamespace('MAPI')
|
|
25
27
|
$ns.Logon()
|
|
26
28
|
`;
|
|
27
29
|
/**
|
|
28
|
-
*
|
|
29
|
-
* `$storeFolder`.
|
|
30
|
+
* The session plus the mailbox an address names; binds `$target`, `$account`
|
|
31
|
+
* and `$storeFolder`.
|
|
30
32
|
*
|
|
31
|
-
* An address can name a mailbox two
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* the operations that genuinely require an identity to act as (sending) check
|
|
37
|
-
* for it themselves rather than being denied the mailbox up front.
|
|
33
|
+
* An address can name a mailbox two ways, and only one is an Account. A mailbox
|
|
34
|
+
* mounted as a secondary store — a shared mailbox, or one added after Outlook
|
|
35
|
+
* started — has no Account object, so both are resolved and EITHER is enough:
|
|
36
|
+
* `$account` is null for a store-only mailbox, and the operations that need an
|
|
37
|
+
* identity to act as (sending) check for it themselves.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* sentence is the one `classifyRunFailure` recognises to raise
|
|
42
|
-
* `AccountNotFoundError`, so the wording is load-bearing.
|
|
39
|
+
* Never falls back to the default account: a bad address must not silently
|
|
40
|
+
* read or send from the wrong mailbox.
|
|
43
41
|
*
|
|
44
|
-
* The store is matched on the
|
|
45
|
-
*
|
|
46
|
-
* the folders it selected before on a profile where the two differ.
|
|
42
|
+
* The store is matched on the address BEFORE the account's display name, so a
|
|
43
|
+
* profile where the two differ selects the same folders it always has.
|
|
47
44
|
*/
|
|
48
45
|
function accountScript(emailAccount) {
|
|
49
|
-
return `${
|
|
50
|
-
$target =
|
|
46
|
+
return `${exports.SESSION_PS}
|
|
47
|
+
$target = ${(0, run_1.psString)(emailAccount)}
|
|
51
48
|
$account = $null
|
|
52
49
|
foreach ($a in $ns.Accounts) {
|
|
53
50
|
if ($a.SmtpAddress -ieq $target) { $account = $a; break }
|
|
@@ -61,71 +58,75 @@ if ($storeFolder -eq $null -and $account -ne $null) {
|
|
|
61
58
|
if ($f.Name -ieq $account.DisplayName) { $storeFolder = $f; break }
|
|
62
59
|
}
|
|
63
60
|
}
|
|
64
|
-
if ($account -eq $null -and $storeFolder -eq $null) {
|
|
61
|
+
if ($account -eq $null -and $storeFolder -eq $null) {
|
|
62
|
+
throw "${(0, errors_1.failureTag)('ACCOUNT_NOT_FOUND')}Account '$target' not found in this Outlook profile."
|
|
63
|
+
}
|
|
65
64
|
`;
|
|
66
65
|
}
|
|
67
66
|
/**
|
|
68
|
-
* The mailbox's
|
|
67
|
+
* The mailbox's store as `$store` (and its id as `$storeId`), reached through
|
|
68
|
+
* the account's delivery store. Requires `accountScript`.
|
|
69
69
|
*
|
|
70
|
-
* Falls back to the resolved store folder because a store-only mailbox has no
|
|
71
|
-
* account to read a
|
|
72
|
-
* what makes an operation fail on exactly those mailboxes.
|
|
70
|
+
* Falls back to the resolved store folder, because a store-only mailbox has no
|
|
71
|
+
* account to read a delivery store off.
|
|
73
72
|
*/
|
|
74
73
|
exports.DELIVERY_STORE_PS = `
|
|
75
74
|
$store = if ($account -ne $null) { $account.DeliveryStore } else { $storeFolder.Store }
|
|
76
75
|
$storeId = $store.StoreID
|
|
77
76
|
`;
|
|
78
77
|
/**
|
|
79
|
-
* The store
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* Kept alongside `DELIVERY_STORE_PS` rather than replaced by it: the reading
|
|
83
|
-
* operations resolve the store this way, and on a profile where a mailbox is
|
|
84
|
-
* open under a display name that differs from the delivery store's, the two do
|
|
85
|
-
* not select the same folders. Changing which one a reader uses changes what it
|
|
86
|
-
* returns, so each keeps the route it was verified against.
|
|
78
|
+
* The mailbox's store as `$store`, reached through the namespace's top-level
|
|
79
|
+
* folder for it. Requires `accountScript`.
|
|
87
80
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
81
|
+
* Kept beside DELIVERY_STORE_PS rather than replaced by it: the readers resolve
|
|
82
|
+
* their store this way, and on a profile where a mailbox is open under a display
|
|
83
|
+
* name that differs from its delivery store's, the two routes do not select the
|
|
84
|
+
* same folders. Each operation keeps the route it was verified against.
|
|
92
85
|
*/
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
exports.NAMED_STORE_PS = `
|
|
87
|
+
if ($storeFolder -eq $null) {
|
|
88
|
+
throw "${(0, errors_1.failureTag)('ACCOUNT_NOT_FOUND')}Account '$target' has no mailbox open in this Outlook profile."
|
|
89
|
+
}
|
|
96
90
|
$store = $storeFolder.Store
|
|
97
91
|
$storeId = $store.StoreID
|
|
98
92
|
`;
|
|
99
|
-
}
|
|
100
93
|
/**
|
|
101
|
-
* Resolve one
|
|
102
|
-
*
|
|
94
|
+
* Resolve one email into `$<variable>`, or fail as NOT_FOUND.
|
|
95
|
+
*
|
|
96
|
+
* The StoreID is tried first, since it lets an id from any mounted mailbox
|
|
97
|
+
* resolve; the bare lookup (default store) is the fallback for a caller holding
|
|
98
|
+
* a stale StoreID or none.
|
|
103
99
|
*/
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
?
|
|
107
|
-
:
|
|
100
|
+
function itemLookupScript(email, variable = 'item') {
|
|
101
|
+
const byStore = email.storeId
|
|
102
|
+
? `try { $${variable} = $ns.GetItemFromID($lookupId, ${(0, run_1.psString)(email.storeId)}) } catch { $${variable} = $null }`
|
|
103
|
+
: '';
|
|
104
|
+
return `
|
|
105
|
+
$lookupId = ${(0, run_1.psString)(email.entryId)}
|
|
106
|
+
$${variable} = $null
|
|
107
|
+
${byStore}
|
|
108
|
+
if ($${variable} -eq $null) { try { $${variable} = $ns.GetItemFromID($lookupId) } catch { $${variable} = $null } }
|
|
109
|
+
if ($${variable} -eq $null) {
|
|
110
|
+
throw "${(0, errors_1.failureTag)('NOT_FOUND', 'email')}No email found for entry id '$lookupId'. It may have been moved or deleted - list the mail again for a current id."
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
108
113
|
}
|
|
109
114
|
/**
|
|
110
|
-
* The sender's
|
|
115
|
+
* The sender's SMTP address as `$senderSmtp`. Requires `$item`.
|
|
111
116
|
*
|
|
112
|
-
* An Exchange sender's
|
|
113
|
-
*
|
|
114
|
-
* needs the address it resolves to.
|
|
117
|
+
* An Exchange sender's SenderEmailAddress is an X.500 DN, not an address; a
|
|
118
|
+
* caller replying to it or matching it against anything needs the address.
|
|
115
119
|
*/
|
|
116
120
|
exports.SENDER_SMTP_PS = `
|
|
117
121
|
$senderSmtp = ''
|
|
118
122
|
try {
|
|
119
|
-
if ($item.SenderEmailType -eq 'EX') { $senderSmtp = $item.Sender.GetExchangeUser().PrimarySmtpAddress }
|
|
123
|
+
if ($item.SenderEmailType -eq 'EX') { $senderSmtp = [string]$item.Sender.GetExchangeUser().PrimarySmtpAddress }
|
|
120
124
|
} catch {}
|
|
121
|
-
if (-not $senderSmtp) { $senderSmtp =
|
|
125
|
+
if (-not $senderSmtp) { try { $senderSmtp = [string]$item.SenderEmailAddress } catch {} }
|
|
122
126
|
`;
|
|
123
|
-
/**
|
|
124
|
-
* Recursive folder-by-name search. Case-insensitive, depth-capped so a huge
|
|
125
|
-
* mailbox tree can't hang the scan.
|
|
126
|
-
*/
|
|
127
|
+
/** Recursive, case-insensitive folder search by name, depth-capped so a huge tree can't hang it. */
|
|
127
128
|
exports.FIND_FOLDER_PS = `
|
|
128
|
-
function Find-FolderByName($root, $name, $depth) {
|
|
129
|
+
function Find-FolderByName($root, [string]$name, [int]$depth) {
|
|
129
130
|
foreach ($f in $root.Folders) {
|
|
130
131
|
if ($f.Name -ieq $name) { return $f }
|
|
131
132
|
}
|
|
@@ -138,25 +139,50 @@ function Find-FolderByName($root, $name, $depth) {
|
|
|
138
139
|
}
|
|
139
140
|
`;
|
|
140
141
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
142
|
+
* `$cutoff`, the moment `daysBack` days ago, and `$cutoffFilter`, that moment
|
|
143
|
+
* as a date string for an `Items.Restrict` filter.
|
|
143
144
|
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
145
|
+
* Restrict parses date strings in the machine's own regional format, so the
|
|
146
|
+
* string is formatted in it ('g': short date and time) rather than a fixed
|
|
147
|
+
* pattern — 'MM/dd/yyyy' reads as a different day on a day-first locale. Every
|
|
148
|
+
* reader re-checks each item against `$cutoff` too, so the window holds even
|
|
149
|
+
* where a store reads the filter loosely.
|
|
150
|
+
*/
|
|
151
|
+
function cutoffScript(daysBack) {
|
|
152
|
+
return `
|
|
153
|
+
$cutoff = (Get-Date).AddDays(-${(0, run_1.psInt)(daysBack)})
|
|
154
|
+
$cutoffFilter = $cutoff.ToString('g').Replace("'", "''")
|
|
155
|
+
`;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* `$<variable>` = the items of `$<folderVariable>` with `property` on or after
|
|
159
|
+
* `$cutoff`. Requires `cutoffScript`. A store that rejects the filter outright
|
|
160
|
+
* yields every item instead, which the per-item re-check then narrows.
|
|
161
|
+
*/
|
|
162
|
+
function itemsSinceScript(folderVariable, property, variable) {
|
|
163
|
+
return `
|
|
164
|
+
$${variable} = $null
|
|
165
|
+
try { $${variable} = $${folderVariable}.Items.Restrict("[${property}] >= '$cutoffFilter'") } catch { $${variable} = $${folderVariable}.Items }
|
|
166
|
+
`;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Resolve `$scope` from `$store`: a well-known root walked down through any
|
|
170
|
+
* further segments. Also binds `$scopeCreated`.
|
|
147
171
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
172
|
+
* Segments match direct children; a bare name that isn't a direct child falls
|
|
173
|
+
* back to a recursive search, so one folder string works across operations. A
|
|
174
|
+
* missing folder fails as NOT_FOUND naming what the caller typed and what the
|
|
175
|
+
* deepest folder reached does hold — never a silent fall back to the root. With
|
|
176
|
+
* `createMissing`, the whole missing chain is created instead.
|
|
152
177
|
*/
|
|
153
|
-
function mailScopeScript(ref, folderLabel
|
|
154
|
-
const root = `$store.GetDefaultFolder(${ref.rootId})`;
|
|
178
|
+
function mailScopeScript(ref, folderLabel, createMissing = false) {
|
|
179
|
+
const root = `$store.GetDefaultFolder(${(0, run_1.psInt)(ref.rootId)})`;
|
|
155
180
|
if (ref.segments.length === 0)
|
|
156
181
|
return `$scope = ${root}\n$scopeCreated = $false`;
|
|
157
182
|
return `
|
|
158
183
|
${exports.FIND_FOLDER_PS}
|
|
159
|
-
$
|
|
184
|
+
$folderLabel = ${(0, run_1.psString)(folderLabel)}
|
|
185
|
+
$segments = @(${ref.segments.map(run_1.psString).join(', ')})
|
|
160
186
|
$scopeRoot = ${root}
|
|
161
187
|
$scope = $scopeRoot
|
|
162
188
|
$deepest = $scopeRoot
|
|
@@ -167,13 +193,11 @@ foreach ($seg in $segments) {
|
|
|
167
193
|
if ($next -eq $null) { $deepest = $scope; $scope = $null; break }
|
|
168
194
|
$scope = $next
|
|
169
195
|
}
|
|
170
|
-
# A bare name that isn't a direct child still resolves by recursive search, so one
|
|
171
|
-
# folder string keeps working across tools.
|
|
172
196
|
if ($scope -eq $null -and $segments.Count -eq 1) {
|
|
173
197
|
$scope = Find-FolderByName $scopeRoot $segments[0] 3
|
|
174
198
|
}
|
|
175
199
|
if ($scope -eq $null -and ${createMissing ? '$true' : '$false'}) {
|
|
176
|
-
# Rebuild the
|
|
200
|
+
# Rebuild the chain from the root, creating only what is genuinely absent.
|
|
177
201
|
$scope = $scopeRoot
|
|
178
202
|
foreach ($seg in $segments) {
|
|
179
203
|
$next = $null
|
|
@@ -185,7 +209,7 @@ if ($scope -eq $null -and ${createMissing ? '$true' : '$false'}) {
|
|
|
185
209
|
if ($scope -eq $null) {
|
|
186
210
|
$names = @()
|
|
187
211
|
foreach ($f in $deepest.Folders) { $names += $f.Name }
|
|
188
|
-
throw "
|
|
212
|
+
throw "${(0, errors_1.failureTag)('NOT_FOUND', 'folder')}Folder '$folderLabel' not found. Folders under '$($deepest.Name)': $($names -join ', ')"
|
|
189
213
|
}`;
|
|
190
214
|
}
|
|
191
215
|
//# sourceMappingURL=scripts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scripts.js","sourceRoot":"","sources":["../../src/windows/scripts.ts"],"names":[],"mappings":";;;AA2CA,sCAkBC;AA6BD,4CAMC;AAMD,sCAIC;AAgDD,0CAoCC;AA9LD,0EAA0E;AAC1E,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,iCAAiC;AACjC,+BAAiC;AAGjC;;;;;;GAMG;AACH,MAAM,UAAU,GAAG;;;;;CAKlB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,aAAa,CAAC,YAAoB;IAC9C,OAAO,GAAG,UAAU;aACX,IAAA,cAAQ,EAAC,YAAY,CAAC;;;;;;;;;;;;;;;CAelC,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACU,QAAA,iBAAiB,GAAG;;;CAGhC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,SAAgB,gBAAgB,CAAC,YAAoB;IACjD,OAAO;2EACgE,IAAA,cAAQ,EAAC,YAAY,CAAC;;;CAGhG,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAgB,aAAa,CAAC,OAAe,EAAE,OAAgB;IAC3D,OAAO,OAAO;QACV,CAAC,CAAC,8BAA8B,IAAA,cAAQ,EAAC,OAAO,CAAC,OAAO,IAAA,cAAQ,EAAC,OAAO,CAAC,IAAI;QAC7E,CAAC,CAAC,8BAA8B,IAAA,cAAQ,EAAC,OAAO,CAAC,IAAI,CAAC;AAC9D,CAAC;AAED;;;;;;GAMG;AACU,QAAA,cAAc,GAAG;;;;;;CAM7B,CAAC;AAEF;;;GAGG;AACU,QAAA,cAAc,GAAG;;;;;;;;;;;;CAY7B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,SAAgB,eAAe,CAAC,GAAkB,EAAE,WAAW,GAAG,EAAE,EAAE,aAAa,GAAG,KAAK;IACvF,MAAM,IAAI,GAAG,2BAA2B,GAAG,CAAC,MAAM,GAAG,CAAC;IACtD,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,IAAI,0BAA0B,CAAC;IACjF,OAAO;EACT,sBAAc;gBACA,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAA,cAAQ,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;eACpD,IAAI;;;;;;;;;;;;;;;4BAeS,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;;;;;;;;;;;;;qBAazC,IAAA,cAAQ,EAAC,WAAW,CAAC;EACxC,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"scripts.js","sourceRoot":"","sources":["../../src/windows/scripts.ts"],"names":[],"mappings":";;;AAuCA,sCAoBC;AAsCD,4CAaC;AAyCD,oCAKC;AAOD,4CAKC;AAYD,0CAmCC;AAvND,0EAA0E;AAC1E,EAAE;AACF,uEAAuE;AACvE,+EAA+E;AAC/E,8EAA8E;AAC9E,2CAA2C;AAC3C,+BAAwC;AACxC,sCAAuC;AAGvC;;;;;;GAMG;AACU,QAAA,UAAU,GAAG;;;;CAIzB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,aAAa,CAAC,YAAoB;IAC9C,OAAO,GAAG,kBAAU;YACZ,IAAA,cAAQ,EAAC,YAAY,CAAC;;;;;;;;;;;;;;;aAerB,IAAA,mBAAU,EAAC,mBAAmB,CAAC;;CAE3C,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACU,QAAA,iBAAiB,GAAG;;;CAGhC,CAAC;AAEF;;;;;;;;GAQG;AACU,QAAA,cAAc,GAAG;;aAEjB,IAAA,mBAAU,EAAC,mBAAmB,CAAC;;;;CAI3C,CAAC;AAEF;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,KAAmB,EAAE,QAAQ,GAAG,MAAM;IACnE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO;QACzB,CAAC,CAAC,UAAU,QAAQ,mCAAmC,IAAA,cAAQ,EAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,QAAQ,YAAY;QAClH,CAAC,CAAC,EAAE,CAAC;IACT,OAAO;cACG,IAAA,cAAQ,EAAC,KAAK,CAAC,OAAO,CAAC;GAClC,QAAQ;EACT,OAAO;OACF,QAAQ,wBAAwB,QAAQ,8CAA8C,QAAQ;OAC9F,QAAQ;aACF,IAAA,mBAAU,EAAC,WAAW,EAAE,OAAO,CAAC;;CAE5C,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACU,QAAA,cAAc,GAAG;;;;;;CAM7B,CAAC;AAEF,oGAAoG;AACvF,QAAA,cAAc,GAAG;;;;;;;;;;;;CAY7B,CAAC;AAEF;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAAC,QAAgB;IACzC,OAAO;gCACqB,IAAA,WAAK,EAAC,QAAQ,CAAC;;CAE9C,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,cAAsB,EAAE,QAAgB,EAAE,QAAgB;IACvF,OAAO;GACR,QAAQ;SACF,QAAQ,OAAO,cAAc,qBAAqB,QAAQ,qCAAqC,QAAQ,OAAO,cAAc;CACpI,CAAC;AACF,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,eAAe,CAAC,GAAkB,EAAE,WAAmB,EAAE,aAAa,GAAG,KAAK;IAC1F,MAAM,IAAI,GAAG,2BAA2B,IAAA,WAAK,EAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;IAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,IAAI,0BAA0B,CAAC;IACjF,OAAO;EACT,sBAAc;iBACC,IAAA,cAAQ,EAAC,WAAW,CAAC;gBACtB,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;eACtC,IAAI;;;;;;;;;;;;;4BAaS,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;;;;;;;;;;;;;aAajD,IAAA,mBAAU,EAAC,WAAW,EAAE,QAAQ,CAAC;EAC5C,CAAC;AACH,CAAC","sourcesContent":["// The PowerShell fragments more than one Windows operation is built from.\n//\n// A fragment lives here once two modules emit it; one used by a single\n// operation stays beside that operation, where its rules read next to the code\n// relying on them. Every fragment follows run.ts's escaping rule: caller text\n// only ever appears as a psString literal.\nimport { psInt, psString } from './run';\nimport { failureTag } from '../errors';\nimport type { EmailLocator, MailFolderRef } from '../types';\n\n/**\n * Open the MAPI session, binding `$outlook` and `$ns`.\n *\n * `Logon()` is a no-op against an Outlook that is already running and starts\n * one that isn't, which removes a class of \"works only while Outlook is open\"\n * failure.\n */\nexport const SESSION_PS = `\n$outlook = New-Object -ComObject Outlook.Application\n$ns = $outlook.GetNamespace('MAPI')\n$ns.Logon()\n`;\n\n/**\n * The session plus the mailbox an address names; binds `$target`, `$account`\n * and `$storeFolder`.\n *\n * An address can name a mailbox two ways, and only one is an Account. A mailbox\n * mounted as a secondary store — a shared mailbox, or one added after Outlook\n * started — has no Account object, so both are resolved and EITHER is enough:\n * `$account` is null for a store-only mailbox, and the operations that need an\n * identity to act as (sending) check for it themselves.\n *\n * Never falls back to the default account: a bad address must not silently\n * read or send from the wrong mailbox.\n *\n * The store is matched on the address BEFORE the account's display name, so a\n * profile where the two differ selects the same folders it always has.\n */\nexport function accountScript(emailAccount: string): string {\n return `${SESSION_PS}\n$target = ${psString(emailAccount)}\n$account = $null\nforeach ($a in $ns.Accounts) {\n if ($a.SmtpAddress -ieq $target) { $account = $a; break }\n}\n$storeFolder = $null\nforeach ($f in $ns.Folders) {\n if ($f.Name -ieq $target) { $storeFolder = $f; break }\n}\nif ($storeFolder -eq $null -and $account -ne $null) {\n foreach ($f in $ns.Folders) {\n if ($f.Name -ieq $account.DisplayName) { $storeFolder = $f; break }\n }\n}\nif ($account -eq $null -and $storeFolder -eq $null) {\n throw \"${failureTag('ACCOUNT_NOT_FOUND')}Account '$target' not found in this Outlook profile.\"\n}\n`;\n}\n\n/**\n * The mailbox's store as `$store` (and its id as `$storeId`), reached through\n * the account's delivery store. Requires `accountScript`.\n *\n * Falls back to the resolved store folder, because a store-only mailbox has no\n * account to read a delivery store off.\n */\nexport const DELIVERY_STORE_PS = `\n$store = if ($account -ne $null) { $account.DeliveryStore } else { $storeFolder.Store }\n$storeId = $store.StoreID\n`;\n\n/**\n * The mailbox's store as `$store`, reached through the namespace's top-level\n * folder for it. Requires `accountScript`.\n *\n * Kept beside DELIVERY_STORE_PS rather than replaced by it: the readers resolve\n * their store this way, and on a profile where a mailbox is open under a display\n * name that differs from its delivery store's, the two routes do not select the\n * same folders. Each operation keeps the route it was verified against.\n */\nexport const NAMED_STORE_PS = `\nif ($storeFolder -eq $null) {\n throw \"${failureTag('ACCOUNT_NOT_FOUND')}Account '$target' has no mailbox open in this Outlook profile.\"\n}\n$store = $storeFolder.Store\n$storeId = $store.StoreID\n`;\n\n/**\n * Resolve one email into `$<variable>`, or fail as NOT_FOUND.\n *\n * The StoreID is tried first, since it lets an id from any mounted mailbox\n * resolve; the bare lookup (default store) is the fallback for a caller holding\n * a stale StoreID or none.\n */\nexport function itemLookupScript(email: EmailLocator, variable = 'item'): string {\n const byStore = email.storeId\n ? `try { $${variable} = $ns.GetItemFromID($lookupId, ${psString(email.storeId)}) } catch { $${variable} = $null }`\n : '';\n return `\n$lookupId = ${psString(email.entryId)}\n$${variable} = $null\n${byStore}\nif ($${variable} -eq $null) { try { $${variable} = $ns.GetItemFromID($lookupId) } catch { $${variable} = $null } }\nif ($${variable} -eq $null) {\n throw \"${failureTag('NOT_FOUND', 'email')}No email found for entry id '$lookupId'. It may have been moved or deleted - list the mail again for a current id.\"\n}\n`;\n}\n\n/**\n * The sender's SMTP address as `$senderSmtp`. Requires `$item`.\n *\n * An Exchange sender's SenderEmailAddress is an X.500 DN, not an address; a\n * caller replying to it or matching it against anything needs the address.\n */\nexport const SENDER_SMTP_PS = `\n$senderSmtp = ''\ntry {\n if ($item.SenderEmailType -eq 'EX') { $senderSmtp = [string]$item.Sender.GetExchangeUser().PrimarySmtpAddress }\n} catch {}\nif (-not $senderSmtp) { try { $senderSmtp = [string]$item.SenderEmailAddress } catch {} }\n`;\n\n/** Recursive, case-insensitive folder search by name, depth-capped so a huge tree can't hang it. */\nexport const FIND_FOLDER_PS = `\nfunction Find-FolderByName($root, [string]$name, [int]$depth) {\n foreach ($f in $root.Folders) {\n if ($f.Name -ieq $name) { return $f }\n }\n if ($depth -le 1) { return $null }\n foreach ($f in $root.Folders) {\n $hit = Find-FolderByName $f $name ($depth - 1)\n if ($hit -ne $null) { return $hit }\n }\n return $null\n}\n`;\n\n/**\n * `$cutoff`, the moment `daysBack` days ago, and `$cutoffFilter`, that moment\n * as a date string for an `Items.Restrict` filter.\n *\n * Restrict parses date strings in the machine's own regional format, so the\n * string is formatted in it ('g': short date and time) rather than a fixed\n * pattern — 'MM/dd/yyyy' reads as a different day on a day-first locale. Every\n * reader re-checks each item against `$cutoff` too, so the window holds even\n * where a store reads the filter loosely.\n */\nexport function cutoffScript(daysBack: number): string {\n return `\n$cutoff = (Get-Date).AddDays(-${psInt(daysBack)})\n$cutoffFilter = $cutoff.ToString('g').Replace(\"'\", \"''\")\n`;\n}\n\n/**\n * `$<variable>` = the items of `$<folderVariable>` with `property` on or after\n * `$cutoff`. Requires `cutoffScript`. A store that rejects the filter outright\n * yields every item instead, which the per-item re-check then narrows.\n */\nexport function itemsSinceScript(folderVariable: string, property: string, variable: string): string {\n return `\n$${variable} = $null\ntry { $${variable} = $${folderVariable}.Items.Restrict(\"[${property}] >= '$cutoffFilter'\") } catch { $${variable} = $${folderVariable}.Items }\n`;\n}\n\n/**\n * Resolve `$scope` from `$store`: a well-known root walked down through any\n * further segments. Also binds `$scopeCreated`.\n *\n * Segments match direct children; a bare name that isn't a direct child falls\n * back to a recursive search, so one folder string works across operations. A\n * missing folder fails as NOT_FOUND naming what the caller typed and what the\n * deepest folder reached does hold — never a silent fall back to the root. With\n * `createMissing`, the whole missing chain is created instead.\n */\nexport function mailScopeScript(ref: MailFolderRef, folderLabel: string, createMissing = false): string {\n const root = `$store.GetDefaultFolder(${psInt(ref.rootId)})`;\n if (ref.segments.length === 0) return `$scope = ${root}\\n$scopeCreated = $false`;\n return `\n${FIND_FOLDER_PS}\n$folderLabel = ${psString(folderLabel)}\n$segments = @(${ref.segments.map(psString).join(', ')})\n$scopeRoot = ${root}\n$scope = $scopeRoot\n$deepest = $scopeRoot\n$scopeCreated = $false\nforeach ($seg in $segments) {\n $next = $null\n foreach ($f in $scope.Folders) { if ($f.Name -ieq $seg) { $next = $f; break } }\n if ($next -eq $null) { $deepest = $scope; $scope = $null; break }\n $scope = $next\n}\nif ($scope -eq $null -and $segments.Count -eq 1) {\n $scope = Find-FolderByName $scopeRoot $segments[0] 3\n}\nif ($scope -eq $null -and ${createMissing ? '$true' : '$false'}) {\n # Rebuild the chain from the root, creating only what is genuinely absent.\n $scope = $scopeRoot\n foreach ($seg in $segments) {\n $next = $null\n foreach ($f in $scope.Folders) { if ($f.Name -ieq $seg) { $next = $f; break } }\n if ($next -eq $null) { $next = $scope.Folders.Add($seg); $scopeCreated = $true }\n $scope = $next\n }\n}\nif ($scope -eq $null) {\n $names = @()\n foreach ($f in $deepest.Folders) { $names += $f.Name }\n throw \"${failureTag('NOT_FOUND', 'folder')}Folder '$folderLabel' not found. Folders under '$($deepest.Name)': $($names -join ', ')\"\n}`;\n}\n"]}
|
package/dist/windows/send.d.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* The body may be given directly or named as a saved template — see
|
|
8
|
-
* `composeReplyHtml`, which resolves the template, its section and its
|
|
9
|
-
* placeholders before anything reaches Outlook.
|
|
10
|
-
*/
|
|
11
|
-
export declare function replyOutlookEmail(params: ReplyEmailParams): Promise<ReplyEmailResult>;
|
|
1
|
+
import type { ReplyRequest, SendRequest } from '../backend';
|
|
2
|
+
import type { ReplyEmailResult } from '../types';
|
|
3
|
+
/** Send, display or file a new email. */
|
|
4
|
+
export declare function sendOutlookEmail(request: SendRequest): Promise<void>;
|
|
5
|
+
/** Reply to an email, with the composed HTML above the quoted original. */
|
|
6
|
+
export declare function replyOutlookEmail(request: ReplyRequest): Promise<ReplyEmailResult>;
|