@remit/data-ports 0.0.83 → 0.0.84
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/dist/account-settings.d.ts +371 -0
- package/dist/account-settings.js +114 -0
- package/dist/conformance/account.d.ts +3 -0
- package/dist/conformance/account.js +118 -0
- package/dist/conformance/calendar-collection.d.ts +3 -0
- package/dist/conformance/calendar-collection.js +251 -0
- package/dist/conformance/calendar-event-index.d.ts +3 -0
- package/dist/conformance/calendar-event-index.js +114 -0
- package/dist/conformance/calendar-feed-token.d.ts +3 -0
- package/dist/conformance/calendar-feed-token.js +97 -0
- package/dist/conformance/calendar-object.d.ts +3 -0
- package/dist/conformance/calendar-object.js +156 -0
- package/dist/conformance/calendar-suggestion.d.ts +3 -0
- package/dist/conformance/calendar-suggestion.js +255 -0
- package/{src/conformance/harness.ts → dist/conformance/harness.d.ts} +4 -4
- package/dist/conformance/harness.js +1 -0
- package/dist/conformance/index.js +8 -0
- package/dist/conformance/label.d.ts +3 -0
- package/dist/conformance/label.js +92 -0
- package/dist/conformance/sender-signer-standing.d.ts +3 -0
- package/dist/conformance/sender-signer-standing.js +81 -0
- package/dist/display-name.d.ts +1 -0
- package/dist/display-name.js +26 -0
- package/dist/errors.d.ts +150 -0
- package/dist/errors.js +181 -0
- package/dist/filter-ttl.d.ts +7 -0
- package/{src/filter-ttl.ts → dist/filter-ttl.js} +8 -11
- package/dist/folder-role.d.ts +239 -0
- package/dist/folder-role.js +276 -0
- package/dist/id.d.ts +124 -0
- package/{src/id.ts → dist/id.js} +41 -127
- package/dist/index.d.ts +37 -0
- package/dist/index.js +5 -0
- package/dist/interfaces/account-config.d.ts +15 -0
- package/dist/interfaces/account-config.js +1 -0
- package/dist/interfaces/account-export-request.d.ts +10 -0
- package/dist/interfaces/account-export-request.js +1 -0
- package/dist/interfaces/account-setting.d.ts +7 -0
- package/dist/interfaces/account-setting.js +1 -0
- package/dist/interfaces/account.d.ts +29 -0
- package/dist/interfaces/account.js +1 -0
- package/dist/interfaces/address.d.ts +69 -0
- package/dist/interfaces/address.js +1 -0
- package/dist/interfaces/calendar-collection.d.ts +38 -0
- package/dist/interfaces/calendar-collection.js +1 -0
- package/dist/interfaces/calendar-event-index.d.ts +19 -0
- package/dist/interfaces/calendar-event-index.js +1 -0
- package/dist/interfaces/calendar-feed-token.d.ts +31 -0
- package/dist/interfaces/calendar-feed-token.js +1 -0
- package/dist/interfaces/calendar-object.d.ts +36 -0
- package/dist/interfaces/calendar-object.js +1 -0
- package/dist/interfaces/calendar-store.d.ts +93 -0
- package/dist/interfaces/calendar-store.js +1 -0
- package/dist/interfaces/calendar-suggestion.d.ts +62 -0
- package/dist/interfaces/calendar-suggestion.js +1 -0
- package/dist/interfaces/config-import.d.ts +8 -0
- package/dist/interfaces/config-import.js +1 -0
- package/dist/interfaces/envelope.d.ts +24 -0
- package/dist/interfaces/envelope.js +1 -0
- package/dist/interfaces/filter.d.ts +28 -0
- package/dist/interfaces/filter.js +1 -0
- package/dist/interfaces/label.d.ts +17 -0
- package/dist/interfaces/label.js +1 -0
- package/dist/interfaces/mailbox-lock.d.ts +12 -0
- package/dist/interfaces/mailbox-lock.js +1 -0
- package/dist/interfaces/mailbox-special-use.d.ts +54 -0
- package/dist/interfaces/mailbox-special-use.js +1 -0
- package/dist/interfaces/mailbox.d.ts +79 -0
- package/dist/interfaces/mailbox.js +1 -0
- package/dist/interfaces/message-flag-push.d.ts +9 -0
- package/dist/interfaces/message-flag-push.js +1 -0
- package/dist/interfaces/message-flag.d.ts +14 -0
- package/dist/interfaces/message-flag.js +1 -0
- package/dist/interfaces/message-label.d.ts +21 -0
- package/dist/interfaces/message-label.js +1 -0
- package/dist/interfaces/message-placement-move.d.ts +8 -0
- package/dist/interfaces/message-placement-move.js +1 -0
- package/dist/interfaces/message.d.ts +60 -0
- package/dist/interfaces/message.js +1 -0
- package/dist/interfaces/organize-job-request.d.ts +10 -0
- package/dist/interfaces/organize-job-request.js +1 -0
- package/dist/interfaces/outbox-attachment.d.ts +101 -0
- package/dist/interfaces/outbox-attachment.js +7 -0
- package/dist/interfaces/outbox-message.d.ts +70 -0
- package/dist/interfaces/outbox-message.js +20 -0
- package/dist/interfaces/quarantine.d.ts +20 -0
- package/dist/interfaces/quarantine.js +1 -0
- package/dist/interfaces/sender-signer-standing.d.ts +26 -0
- package/dist/interfaces/sender-signer-standing.js +1 -0
- package/dist/interfaces/sync-warning.d.ts +11 -0
- package/dist/interfaces/sync-warning.js +1 -0
- package/dist/interfaces/thread-message.d.ts +202 -0
- package/dist/interfaces/thread-message.js +1 -0
- package/dist/mailbox-name.d.ts +35 -0
- package/dist/mailbox-name.js +68 -0
- package/dist/message-parts.d.ts +22 -0
- package/dist/message-parts.js +18 -0
- package/dist/message-settlement.d.ts +35 -0
- package/{src/message-settlement.ts → dist/message-settlement.js} +5 -19
- package/dist/mutation-events.d.ts +19 -0
- package/{src/mutation-events.ts → dist/mutation-events.js} +2 -5
- package/dist/sender-mute.d.ts +26 -0
- package/{src/sender-mute.ts → dist/sender-mute.js} +12 -34
- package/dist/sync-warning-state.d.ts +3 -0
- package/dist/sync-warning-state.js +5 -0
- package/dist/types.d.ts +491 -0
- package/dist/types.js +1 -0
- package/dist/update-manifest.d.ts +24 -0
- package/dist/update-manifest.js +20 -0
- package/dist/virtual-copy.d.ts +8 -0
- package/{src/virtual-copy.ts → dist/virtual-copy.js} +10 -15
- package/dist/wellknown.d.ts +47 -0
- package/{src/wellknown.ts → dist/wellknown.js} +26 -49
- package/package.json +44 -79
- package/src/account-settings.ts +0 -194
- package/src/conformance/account.ts +0 -104
- package/src/conformance/calendar-collection.ts +0 -342
- package/src/conformance/calendar-event-index.ts +0 -203
- package/src/conformance/calendar-feed-token.ts +0 -148
- package/src/conformance/calendar-object.ts +0 -269
- package/src/conformance/calendar-suggestion.ts +0 -490
- package/src/conformance/label.ts +0 -136
- package/src/conformance/sender-signer-standing.ts +0 -117
- package/src/display-name.test.ts +0 -101
- package/src/display-name.ts +0 -40
- package/src/errors.ts +0 -244
- package/src/folder-role.test.ts +0 -422
- package/src/folder-role.ts +0 -447
- package/src/id.test.ts +0 -352
- package/src/index.ts +0 -170
- package/src/interfaces/account-config.ts +0 -25
- package/src/interfaces/account-export-request.ts +0 -21
- package/src/interfaces/account-setting.ts +0 -14
- package/src/interfaces/account.ts +0 -43
- package/src/interfaces/address.ts +0 -122
- package/src/interfaces/calendar-collection.ts +0 -60
- package/src/interfaces/calendar-event-index.ts +0 -34
- package/src/interfaces/calendar-feed-token.ts +0 -38
- package/src/interfaces/calendar-object.ts +0 -58
- package/src/interfaces/calendar-suggestion.ts +0 -93
- package/src/interfaces/calendar-unit-of-work.ts +0 -47
- package/src/interfaces/config-import.ts +0 -16
- package/src/interfaces/envelope.ts +0 -32
- package/src/interfaces/filter-anchor-transaction.ts +0 -23
- package/src/interfaces/filter-anchor.ts +0 -11
- package/src/interfaces/filter.ts +0 -41
- package/src/interfaces/label.ts +0 -30
- package/src/interfaces/mailbox-lock.ts +0 -32
- package/src/interfaces/mailbox-special-use.ts +0 -60
- package/src/interfaces/mailbox.ts +0 -115
- package/src/interfaces/message-flag-push.ts +0 -17
- package/src/interfaces/message-flag.ts +0 -15
- package/src/interfaces/message-label.ts +0 -25
- package/src/interfaces/message-placement-move.ts +0 -15
- package/src/interfaces/message.ts +0 -65
- package/src/interfaces/organize-job-request.ts +0 -19
- package/src/interfaces/outbox-attachment.ts +0 -132
- package/src/interfaces/outbox-message.ts +0 -106
- package/src/interfaces/quarantine.ts +0 -22
- package/src/interfaces/sender-signer-standing.ts +0 -37
- package/src/interfaces/thread-message.ts +0 -264
- package/src/interfaces/unit-of-work.ts +0 -28
- package/src/mailbox-name.test.ts +0 -106
- package/src/mailbox-name.ts +0 -90
- package/src/mailbox-state-doors.test.ts +0 -104
- package/src/message-placement-doors.test.ts +0 -100
- package/src/message-settlement.test.ts +0 -132
- package/src/sender-mute.test.ts +0 -76
- package/src/types.ts +0 -820
- package/src/update-manifest.test.ts +0 -130
- package/src/update-manifest.ts +0 -22
- package/src/virtual-copy.test.ts +0 -34
- package/tsconfig.json +0 -8
- /package/{src/conformance/index.ts → dist/conformance/index.d.ts} +0 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
import type { AccountConfigSchema, AccountSchema, AddressSchema, BodyPartParameterSchema, BodyPartSchema, BodyPartStorageSchema, CalendarCollectionSchema, CalendarEventIndexSchema, CalendarFeedTokenSchema, CalendarObjectSchema, CalendarSuggestionSchema, ConfigImportSchema, ConfigImportUnresolvedRefSchema, EnvelopeAddressSchema, EnvelopeSchema, FilterSchema, LabelSchema, MailboxLockSchema, MailboxSchema, MailboxSpecialUseEntrySchema, MailboxSpecialUseSchema, MessageFlagPushSchema, MessageFlagSchema, MessageLabelSchema, MessagePlacementMoveSchema, MessageRecordSchema, OrganizeJobRequestSchema, OutboxAttachmentSchema, OutboxMessageSchema, QuarantineSchema, RawMessageStorageSchema, SenderSignerStandingSchema, SyncWarningSchema, ThreadMessageSchema } from "@remit/api-zod-schemas";
|
|
2
|
+
import type { ReferenceType } from "@remit/domain-enums";
|
|
3
|
+
import type { z } from "zod";
|
|
4
|
+
export type ResultList<T> = {
|
|
5
|
+
items: T[];
|
|
6
|
+
continuationToken: string | undefined;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Page shape for internal, non-API-facing pagination (e.g. the scheduled-sync
|
|
10
|
+
* tick paging through every account). `cursor` is a raw backend-native token —
|
|
11
|
+
* unlike `ResultList.continuationToken` it carries no salt/tamper check, since
|
|
12
|
+
* it never crosses a trust boundary. `null` means no further pages.
|
|
13
|
+
*/
|
|
14
|
+
export type AccountSchedulerPage = {
|
|
15
|
+
items: AccountItem[];
|
|
16
|
+
cursor: string | null;
|
|
17
|
+
};
|
|
18
|
+
export type ListOptions = {
|
|
19
|
+
limit?: number;
|
|
20
|
+
continuationToken?: string;
|
|
21
|
+
};
|
|
22
|
+
export type AccountItem = z.infer<typeof AccountSchema>;
|
|
23
|
+
export type AccountConfigItem = z.infer<typeof AccountConfigSchema>;
|
|
24
|
+
export type MailboxItem = z.infer<typeof MailboxSchema>;
|
|
25
|
+
export type ThreadMessageItem = z.infer<typeof ThreadMessageSchema>;
|
|
26
|
+
export type OutboxMessageItem = z.infer<typeof OutboxMessageSchema>;
|
|
27
|
+
export type OutboxAttachmentItem = z.infer<typeof OutboxAttachmentSchema>;
|
|
28
|
+
export type MessageItem = z.infer<typeof MessageRecordSchema>;
|
|
29
|
+
export type MessageFlagItem = z.infer<typeof MessageFlagSchema>;
|
|
30
|
+
export type BodyPartItem = z.infer<typeof BodyPartSchema>;
|
|
31
|
+
export type MessageReferenceItem = {
|
|
32
|
+
messageReferenceId: string;
|
|
33
|
+
messageId: string;
|
|
34
|
+
envelopeId: string;
|
|
35
|
+
messageIdValue: string;
|
|
36
|
+
referenceType: string;
|
|
37
|
+
referenceOrder: number;
|
|
38
|
+
createdAt: number;
|
|
39
|
+
updatedAt: number;
|
|
40
|
+
};
|
|
41
|
+
export type MessageReferenceInput = Pick<MessageReferenceItem, "messageIdValue" | "referenceOrder"> & {
|
|
42
|
+
referenceType: (typeof ReferenceType)[keyof typeof ReferenceType];
|
|
43
|
+
};
|
|
44
|
+
export type EnvelopeAddressItem = z.infer<typeof EnvelopeAddressSchema>;
|
|
45
|
+
export type BodyPartParameterItem = z.infer<typeof BodyPartParameterSchema>;
|
|
46
|
+
export type RawMessageStorageItem = z.infer<typeof RawMessageStorageSchema>;
|
|
47
|
+
export type BodyPartStorageItem = z.infer<typeof BodyPartStorageSchema>;
|
|
48
|
+
export type EnvelopeItem = z.infer<typeof EnvelopeSchema>;
|
|
49
|
+
export type MailboxLockItem = z.infer<typeof MailboxLockSchema>;
|
|
50
|
+
export type MailboxSpecialUseItem = z.infer<typeof MailboxSpecialUseEntrySchema>;
|
|
51
|
+
export type AddressItem = z.infer<typeof AddressSchema>;
|
|
52
|
+
export type LabelItem = z.infer<typeof LabelSchema>;
|
|
53
|
+
export type MessageLabelItem = z.infer<typeof MessageLabelSchema>;
|
|
54
|
+
export type FilterItem = z.infer<typeof FilterSchema>;
|
|
55
|
+
export type MessagePlacementMoveItem = z.infer<typeof MessagePlacementMoveSchema>;
|
|
56
|
+
export type MessageFlagPushItem = z.infer<typeof MessageFlagPushSchema>;
|
|
57
|
+
export type QuarantineItem = z.infer<typeof QuarantineSchema>;
|
|
58
|
+
export type QuarantineMimeNodeItem = QuarantineItem["structure"][number];
|
|
59
|
+
/**
|
|
60
|
+
* What a caller supplies to quarantine a message.
|
|
61
|
+
*
|
|
62
|
+
* `quarantineId` is absent on purpose. The column carries a random-id default
|
|
63
|
+
* (the house pattern for every entity here), so an input that merely allowed
|
|
64
|
+
* the id would let a writer omit it, take a fresh random one on every retry,
|
|
65
|
+
* and turn the idempotent write this record depends on into an accumulating
|
|
66
|
+
* pile of rows that the derived-id lookup never finds. The repository derives
|
|
67
|
+
* it from the four fields that name the message, which are all required here.
|
|
68
|
+
*/
|
|
69
|
+
export type QuarantineUpsertInput = Omit<QuarantineItem, "quarantineId" | "createdAt" | "updatedAt" | "structure"> & {
|
|
70
|
+
structure?: QuarantineMimeNodeItem[];
|
|
71
|
+
};
|
|
72
|
+
export type SyncWarningItem = z.infer<typeof SyncWarningSchema>;
|
|
73
|
+
export type SyncWarningKey = Pick<SyncWarningItem, "accountConfigId" | "accountId" | "mailboxId" | "uidValidity" | "uid" | "stage">;
|
|
74
|
+
export type MailboxSpecialUseValue = z.infer<typeof MailboxSpecialUseSchema>;
|
|
75
|
+
export type AccountSettingValue = {
|
|
76
|
+
kind: "Boolean";
|
|
77
|
+
value: boolean;
|
|
78
|
+
} | {
|
|
79
|
+
kind: "String";
|
|
80
|
+
value: string;
|
|
81
|
+
} | {
|
|
82
|
+
kind: "Number";
|
|
83
|
+
value: number;
|
|
84
|
+
} | {
|
|
85
|
+
kind: "StringList";
|
|
86
|
+
value: string[];
|
|
87
|
+
} | {
|
|
88
|
+
kind: "Map";
|
|
89
|
+
value: Record<string, string>;
|
|
90
|
+
} | {
|
|
91
|
+
kind: "MutedFlag";
|
|
92
|
+
value: {
|
|
93
|
+
value: boolean;
|
|
94
|
+
setAt: number;
|
|
95
|
+
setBy?: string;
|
|
96
|
+
expiresAt?: number;
|
|
97
|
+
reason?: string;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
export type AccountSettingItem = {
|
|
101
|
+
accountSettingId: string;
|
|
102
|
+
accountConfigId: string;
|
|
103
|
+
name: string;
|
|
104
|
+
value: AccountSettingValue;
|
|
105
|
+
createdAt: number;
|
|
106
|
+
updatedAt: number;
|
|
107
|
+
};
|
|
108
|
+
export type AccountExportRequestItem = {
|
|
109
|
+
accountExportRequestId: string;
|
|
110
|
+
accountConfigId: string;
|
|
111
|
+
userId: string;
|
|
112
|
+
state: "Failed" | "Pending" | "Processing" | "Ready";
|
|
113
|
+
createdAt: number;
|
|
114
|
+
updatedAt: number;
|
|
115
|
+
expiresAt?: number;
|
|
116
|
+
objectKey?: string;
|
|
117
|
+
downloadUrl?: string;
|
|
118
|
+
errorMessage?: string;
|
|
119
|
+
};
|
|
120
|
+
export type AccountDescription = {
|
|
121
|
+
account: AccountItem[];
|
|
122
|
+
mailbox: MailboxItem[];
|
|
123
|
+
};
|
|
124
|
+
export type AccountConfigDescription = {
|
|
125
|
+
accountConfig: AccountConfigItem[];
|
|
126
|
+
account: AccountItem[];
|
|
127
|
+
address: AddressItem[];
|
|
128
|
+
};
|
|
129
|
+
export type MessageData = {
|
|
130
|
+
envelope: EnvelopeItem[];
|
|
131
|
+
messageReference: MessageReferenceItem[];
|
|
132
|
+
envelopeAddress: EnvelopeAddressItem[];
|
|
133
|
+
bodyPart: BodyPartItem[];
|
|
134
|
+
bodyPartParameter: BodyPartParameterItem[];
|
|
135
|
+
rawMessageStorage: RawMessageStorageItem[];
|
|
136
|
+
bodyPartStorage: BodyPartStorageItem[];
|
|
137
|
+
};
|
|
138
|
+
export type MessageDescription = {
|
|
139
|
+
message: MessageItem[];
|
|
140
|
+
messageFlag: MessageFlagItem[];
|
|
141
|
+
envelope: EnvelopeItem[];
|
|
142
|
+
messageReference: MessageReferenceItem[];
|
|
143
|
+
envelopeAddress: EnvelopeAddressItem[];
|
|
144
|
+
bodyPart: BodyPartItem[];
|
|
145
|
+
bodyPartParameter: BodyPartParameterItem[];
|
|
146
|
+
rawMessageStorage: RawMessageStorageItem[];
|
|
147
|
+
bodyPartStorage: BodyPartStorageItem[];
|
|
148
|
+
};
|
|
149
|
+
export type WithMailboxLockResult<T> = {
|
|
150
|
+
executed: boolean;
|
|
151
|
+
result?: T;
|
|
152
|
+
};
|
|
153
|
+
export type CreateAccountInput = Omit<AccountItem, "accountId" | "createdAt" | "updatedAt" | "authType" | "smtpEnabled" | "smtpHost" | "smtpPort" | "smtpTls" | "smtpStartTls" | "smtpUsername" | "syncedServices" | "grantedScopes"> & {
|
|
154
|
+
accountId?: string;
|
|
155
|
+
authType?: AccountItem["authType"];
|
|
156
|
+
syncedServices?: AccountItem["syncedServices"];
|
|
157
|
+
grantedScopes?: AccountItem["grantedScopes"];
|
|
158
|
+
smtpEnabled?: AccountItem["smtpEnabled"];
|
|
159
|
+
smtpHost?: AccountItem["smtpHost"];
|
|
160
|
+
smtpPort?: AccountItem["smtpPort"];
|
|
161
|
+
smtpTls?: AccountItem["smtpTls"];
|
|
162
|
+
smtpStartTls?: AccountItem["smtpStartTls"];
|
|
163
|
+
smtpUsername?: AccountItem["smtpUsername"];
|
|
164
|
+
};
|
|
165
|
+
export type UpdateAccountInput = Partial<Omit<CreateAccountInput, "accountId" | "accountConfigId">>;
|
|
166
|
+
export type RemovableAccountField = "lastError" | "lastConnectedAt" | "lastSyncAt" | "syncPhase";
|
|
167
|
+
export type CreateAccountConfigInput = Omit<AccountConfigItem, "accountConfigId" | "createdAt" | "updatedAt" | "state"> & {
|
|
168
|
+
accountConfigId?: string;
|
|
169
|
+
state?: AccountConfigItem["state"];
|
|
170
|
+
};
|
|
171
|
+
export type UpdateAccountConfigInput = Partial<Omit<CreateAccountConfigInput, "userId">>;
|
|
172
|
+
export type CreateAccountExportRequestInput = Omit<AccountExportRequestItem, "accountExportRequestId" | "createdAt" | "updatedAt">;
|
|
173
|
+
export type UpdateAccountExportRequestInput = Partial<Pick<AccountExportRequestItem, "state" | "expiresAt" | "errorMessage"> & {
|
|
174
|
+
objectKey?: string;
|
|
175
|
+
}>;
|
|
176
|
+
export type OrganizeJobRequestItem = z.infer<typeof OrganizeJobRequestSchema>;
|
|
177
|
+
export type CreateOrganizeJobRequestInput = Omit<OrganizeJobRequestItem, "organizeJobId" | "createdAt" | "updatedAt" | "state" | "matchedCount" | "appliedCount" | "failedCount" | "errorMessage"> & {
|
|
178
|
+
state?: OrganizeJobRequestItem["state"];
|
|
179
|
+
};
|
|
180
|
+
export type UpdateOrganizeJobRequestInput = Partial<Pick<OrganizeJobRequestItem, "state" | "matchedCount" | "appliedCount" | "failedCount" | "errorMessage">>;
|
|
181
|
+
export type ConfigImportItem = z.infer<typeof ConfigImportSchema>;
|
|
182
|
+
export type ConfigImportUnresolvedRefItem = z.infer<typeof ConfigImportUnresolvedRefSchema>;
|
|
183
|
+
export type CreateConfigImportInput = Omit<ConfigImportItem, "importId" | "createdAt" | "updatedAt" | "state" | "completedAt"> & {
|
|
184
|
+
state?: ConfigImportItem["state"];
|
|
185
|
+
completedAt?: ConfigImportItem["completedAt"];
|
|
186
|
+
};
|
|
187
|
+
export type UpdateConfigImportInput = Partial<Pick<ConfigImportItem, "state" | "unresolvedRefs" | "completedAt">>;
|
|
188
|
+
export type UpsertAccountSettingInput = {
|
|
189
|
+
accountConfigId: string;
|
|
190
|
+
name: string;
|
|
191
|
+
value: AccountSettingValue;
|
|
192
|
+
};
|
|
193
|
+
export type AddressFlags = NonNullable<AddressItem["flags"]>;
|
|
194
|
+
export type FlagsMergePatch = {
|
|
195
|
+
[K in keyof AddressFlags]?: AddressFlags[K] | null;
|
|
196
|
+
};
|
|
197
|
+
export type CreateAddressInput = Omit<AddressItem, "addressId" | "createdAt" | "updatedAt" | "flags" | "inboundCount" | "outboundCount" | "replyCount" | "lastInboundAt" | "lastReplyAt"> & {
|
|
198
|
+
addressId: string;
|
|
199
|
+
flags?: AddressFlags;
|
|
200
|
+
inboundCount?: AddressItem["inboundCount"];
|
|
201
|
+
outboundCount?: AddressItem["outboundCount"];
|
|
202
|
+
replyCount?: AddressItem["replyCount"];
|
|
203
|
+
lastInboundAt?: AddressItem["lastInboundAt"];
|
|
204
|
+
lastReplyAt?: AddressItem["lastReplyAt"];
|
|
205
|
+
};
|
|
206
|
+
export type UpdateAddressInput = Partial<Omit<CreateAddressInput, "accountConfigId">>;
|
|
207
|
+
export type CreateEnvelopeAddressInput = Omit<EnvelopeAddressItem, "envelopeAddressId" | "createdAt" | "updatedAt">;
|
|
208
|
+
export type CreateEnvelopeInput = Omit<EnvelopeItem, "envelopeId" | "createdAt" | "updatedAt"> & {
|
|
209
|
+
envelopeId: string;
|
|
210
|
+
};
|
|
211
|
+
export type UpdateEnvelopeInput = Partial<Omit<CreateEnvelopeInput, "messageId">>;
|
|
212
|
+
export type BodyPartParameterUpsertInput = {
|
|
213
|
+
parameterName: string;
|
|
214
|
+
parameterValue: string;
|
|
215
|
+
};
|
|
216
|
+
export type BodyPartUpsertInput = {
|
|
217
|
+
partPath: string;
|
|
218
|
+
parentPartPath: string | null;
|
|
219
|
+
mediaType: BodyPartItem["mediaType"];
|
|
220
|
+
mediaSubtype: string;
|
|
221
|
+
contentId?: string;
|
|
222
|
+
contentDescription?: string;
|
|
223
|
+
transferEncoding: BodyPartItem["transferEncoding"];
|
|
224
|
+
sizeOctets: number;
|
|
225
|
+
lineCount?: number;
|
|
226
|
+
md5Hash?: string;
|
|
227
|
+
disposition?: BodyPartItem["disposition"];
|
|
228
|
+
dispositionFilename?: string;
|
|
229
|
+
language?: string;
|
|
230
|
+
location?: string;
|
|
231
|
+
isMultipart: boolean;
|
|
232
|
+
multipartSubtype?: BodyPartItem["multipartSubtype"];
|
|
233
|
+
parameters: BodyPartParameterUpsertInput[];
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* A mailbox row as an insert states it. `pendingPath` is absent: a create
|
|
237
|
+
* records no rename target (folder-rename-and-delete.md T1), and the transition
|
|
238
|
+
* is the only writer of it.
|
|
239
|
+
*/
|
|
240
|
+
export type CreateMailboxInput = Omit<MailboxItem, "mailboxId" | "createdAt" | "updatedAt" | "namespaceType" | "parentMailboxId" | "cursorState" | "syncStatus" | "pendingPath" | "syncFailureReason"> & {
|
|
241
|
+
namespaceType?: MailboxItem["namespaceType"];
|
|
242
|
+
parentMailboxId?: MailboxItem["parentMailboxId"];
|
|
243
|
+
/** Total per RFC 032 (defaults to `normal`) — optional at the input boundary, callers rarely set it explicitly. */
|
|
244
|
+
cursorState?: MailboxItem["cursorState"];
|
|
245
|
+
/** Total per D1 (defaults to `synced`) — the insert paths that record an intent say so; the sweep's discovery insert does not have to. */
|
|
246
|
+
syncStatus?: MailboxItem["syncStatus"];
|
|
247
|
+
};
|
|
248
|
+
export type CreateMailboxResult = {
|
|
249
|
+
outcome: "Created";
|
|
250
|
+
mailbox: MailboxItem;
|
|
251
|
+
} | {
|
|
252
|
+
outcome: "PathTaken";
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* Everything about a mailbox that is not its mutation state.
|
|
256
|
+
*
|
|
257
|
+
* `syncStatus` and `pendingPath` are omitted rather than merely discouraged
|
|
258
|
+
* (docs/architecture/folder-rename-and-delete.md D3): where they are gone from
|
|
259
|
+
* the only general-purpose writer, a folder state written without a predicate
|
|
260
|
+
* is a type error rather than a convention someone has to remember. The two
|
|
261
|
+
* doors are `transition` and `transitionSubtree`, and they are the whole set.
|
|
262
|
+
*/
|
|
263
|
+
export type UpdateMailboxInput = Partial<Omit<CreateMailboxInput, "accountId" | "syncStatus">>;
|
|
264
|
+
/**
|
|
265
|
+
* The state a mailbox transition expects to find, as the six states this design
|
|
266
|
+
* defines rather than as the four enum values
|
|
267
|
+
* (docs/architecture/folder-rename-and-delete.md D3). `from` becomes an
|
|
268
|
+
* `IN (…)` term; `wherePendingPath` becomes an equality or an `IS NULL` term,
|
|
269
|
+
* and is omitted only by a caller that genuinely does not care which of the two
|
|
270
|
+
* states sharing a `syncStatus` it is looking at.
|
|
271
|
+
*/
|
|
272
|
+
export type MailboxStatePredicate = {
|
|
273
|
+
from: readonly MailboxItem["syncStatus"][];
|
|
274
|
+
wherePendingPath?: string | null;
|
|
275
|
+
};
|
|
276
|
+
/**
|
|
277
|
+
* What a winning mailbox transition writes. `pendingPath` takes `null` to
|
|
278
|
+
* clear, and is only honoured at all when the state being written is one that
|
|
279
|
+
* may carry a rename target — a transition to `synced` or `deleting` drops it
|
|
280
|
+
* whatever the caller passes, which is what makes the invariant hold by
|
|
281
|
+
* construction rather than by convention.
|
|
282
|
+
*/
|
|
283
|
+
export type MailboxTransitionWrite = {
|
|
284
|
+
fullPath?: string;
|
|
285
|
+
pendingPath?: string | null;
|
|
286
|
+
syncFailureReason?: string;
|
|
287
|
+
};
|
|
288
|
+
export type MailboxTransitionIntent = MailboxStatePredicate & {
|
|
289
|
+
to: MailboxItem["syncStatus"];
|
|
290
|
+
set?: MailboxTransitionWrite;
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* A subtree intent recorded all-or-nothing (D6): every row of the subtree takes
|
|
294
|
+
* `newPath` in place of the named folder's path as its `pendingPath`. It
|
|
295
|
+
* carries no `wherePendingPath`: its accepted from-states are `synced` and the
|
|
296
|
+
* two failed variants, and both failed variants are legal starting points.
|
|
297
|
+
*/
|
|
298
|
+
export type MailboxSubtreeTransitionIntent = {
|
|
299
|
+
from: readonly MailboxItem["syncStatus"][];
|
|
300
|
+
to: MailboxItem["syncStatus"];
|
|
301
|
+
newPath: string;
|
|
302
|
+
};
|
|
303
|
+
export type CreateMessageInput = Omit<MessageItem, "messageId" | "createdAt" | "updatedAt" | "status" | "syncStatus" | "abandonedMutation" | "category" | "classificationState" | "authenticityVerdict" | "hasListUnsubscribe" | "movedByRemit"> & {
|
|
304
|
+
messageId: string;
|
|
305
|
+
status?: MessageItem["status"];
|
|
306
|
+
syncStatus?: MessageItem["syncStatus"];
|
|
307
|
+
abandonedMutation?: MessageItem["abandonedMutation"];
|
|
308
|
+
category?: MessageItem["category"];
|
|
309
|
+
classificationState?: MessageItem["classificationState"];
|
|
310
|
+
authenticityVerdict?: MessageItem["authenticityVerdict"];
|
|
311
|
+
hasListUnsubscribe?: MessageItem["hasListUnsubscribe"];
|
|
312
|
+
movedByRemit?: MessageItem["movedByRemit"];
|
|
313
|
+
};
|
|
314
|
+
/**
|
|
315
|
+
* Everything about a message that is not its placement.
|
|
316
|
+
*
|
|
317
|
+
* The six placement fields are omitted rather than merely discouraged
|
|
318
|
+
* (docs/architecture/imap-mutations.md R3): where they are gone from the only
|
|
319
|
+
* general-purpose writer, a placement written without a predicate is a type
|
|
320
|
+
* error rather than a convention someone has to remember. `transitionPlacement`,
|
|
321
|
+
* `repointIfPlacement` and the settle in `updateUid` are the doors, and they
|
|
322
|
+
* are the whole set.
|
|
323
|
+
*/
|
|
324
|
+
export type UpdateMessageInput = Partial<Omit<CreateMessageInput, "mailboxId" | "uid" | "status" | "syncStatus" | "abandonedMutation" | "originalMailboxId" | "originalUid">>;
|
|
325
|
+
/**
|
|
326
|
+
* The placement a transition expects to find, as the caller read it
|
|
327
|
+
* (docs/architecture/imap-mutations.md R3). Every field named here becomes a
|
|
328
|
+
* term of the UPDATE's WHERE clause; what the caller did not read, it does not
|
|
329
|
+
* supply. `syncStatus` takes a set because several of the six placement states
|
|
330
|
+
* share one `status`.
|
|
331
|
+
*/
|
|
332
|
+
export type PlacementPredicate = {
|
|
333
|
+
status?: MessageItem["status"] | readonly MessageItem["status"][];
|
|
334
|
+
syncStatus?: MessageItem["syncStatus"] | readonly MessageItem["syncStatus"][];
|
|
335
|
+
mailboxId?: string;
|
|
336
|
+
uid?: number;
|
|
337
|
+
};
|
|
338
|
+
/**
|
|
339
|
+
* What a winning transition writes. `originalMailboxId` and `originalUid` take
|
|
340
|
+
* `null` to clear, which is how a settle spells a dropped pre-move pair.
|
|
341
|
+
*/
|
|
342
|
+
export type PlacementTransitionInput = {
|
|
343
|
+
status?: MessageItem["status"];
|
|
344
|
+
syncStatus?: MessageItem["syncStatus"];
|
|
345
|
+
abandonedMutation?: MessageItem["abandonedMutation"];
|
|
346
|
+
mailboxId?: string;
|
|
347
|
+
uid?: number;
|
|
348
|
+
originalMailboxId?: string | null;
|
|
349
|
+
originalUid?: number | null;
|
|
350
|
+
};
|
|
351
|
+
export type MessageIdSource = {
|
|
352
|
+
messageId?: string;
|
|
353
|
+
uid: number;
|
|
354
|
+
mailboxId: string;
|
|
355
|
+
date?: string;
|
|
356
|
+
subject?: string;
|
|
357
|
+
fromMailbox?: string;
|
|
358
|
+
fromHost?: string;
|
|
359
|
+
};
|
|
360
|
+
export type CreateMessageFlagInput = Omit<MessageFlagItem, "messageFlagId" | "createdAt" | "updatedAt">;
|
|
361
|
+
export type PutMessagePlacementMoveInput = Omit<MessagePlacementMoveItem, "state" | "createdAt" | "updatedAt">;
|
|
362
|
+
export type PutMessageFlagPushInput = Omit<MessageFlagPushItem, "state" | "createdAt" | "updatedAt">;
|
|
363
|
+
export type CreateOutboxMessageInput = Omit<OutboxMessageItem, "outboxMessageId" | "createdAt" | "updatedAt" | "ccAddresses" | "bccAddresses" | "references" | "appendedUid"> & {
|
|
364
|
+
ccAddresses?: string[];
|
|
365
|
+
bccAddresses?: string[];
|
|
366
|
+
references?: string[];
|
|
367
|
+
};
|
|
368
|
+
export type UpdateOutboxMessageInput = Partial<Pick<OutboxMessageItem, "status" | "lastError" | "lastSmtpCode" | "sentAt" | "smtpMessageId" | "appendedUid" | "toAddresses" | "ccAddresses" | "bccAddresses" | "subject" | "textBody" | "htmlBody" | "inReplyTo" | "references">>;
|
|
369
|
+
export type CreateThreadMessageInput = Omit<ThreadMessageItem, "threadMessageId" | "createdAt" | "updatedAt" | "star" | "category"> & {
|
|
370
|
+
star?: ThreadMessageItem["star"];
|
|
371
|
+
category?: ThreadMessageItem["category"];
|
|
372
|
+
};
|
|
373
|
+
export type UpdateThreadMessageInput = Partial<Omit<CreateThreadMessageInput, "accountConfigId" | "threadId" | "messageId">>;
|
|
374
|
+
/**
|
|
375
|
+
* One substring criterion over a text column of a ThreadMessage row, named by
|
|
376
|
+
* the column it selects on rather than by whatever rule derived it. `sender`
|
|
377
|
+
* covers the From address and display name together, the same pair
|
|
378
|
+
* `SearchOptions.from` reads.
|
|
379
|
+
*
|
|
380
|
+
* Matching is accent- and case-insensitive substring, identical to the search
|
|
381
|
+
* predicates, so a term is a NARROWING a caller refines further in memory. It
|
|
382
|
+
* may return more than the criterion it stands for and never less — a term an
|
|
383
|
+
* implementation cannot evaluate faithfully is dropped, not approximated.
|
|
384
|
+
*/
|
|
385
|
+
export type ThreadMessageFieldTerm = {
|
|
386
|
+
field: "sender" | "subject" | "listId";
|
|
387
|
+
contains: string;
|
|
388
|
+
};
|
|
389
|
+
export type SearchOptions = {
|
|
390
|
+
query?: string;
|
|
391
|
+
subject?: string;
|
|
392
|
+
from?: string;
|
|
393
|
+
unread?: boolean;
|
|
394
|
+
starred?: boolean;
|
|
395
|
+
attachments?: boolean;
|
|
396
|
+
/**
|
|
397
|
+
* Whether the From address is muted, as a three-state filter: `false`
|
|
398
|
+
* excludes muted senders, `true` keeps only them, absent filters nothing.
|
|
399
|
+
*
|
|
400
|
+
* The one criterion here that is not a column on the ThreadMessage row —
|
|
401
|
+
* muting is a flag on the Address, reached through the row's `fromEmail` —
|
|
402
|
+
* and it is a predicate rather than a pass over a page for the same reason
|
|
403
|
+
* every other criterion is: a caller that hides muted mail while counting
|
|
404
|
+
* with it in states a number larger than the list it renders (#1137).
|
|
405
|
+
*/
|
|
406
|
+
muted?: boolean;
|
|
407
|
+
/**
|
|
408
|
+
* Any-of set over the denormalized `category` column on the ThreadMessage
|
|
409
|
+
* row. An empty or absent set means no category filter. `uncategorized` is
|
|
410
|
+
* a member like any other — the column is NOT NULL with that default, so it
|
|
411
|
+
* names "no category" rather than standing for absence (issue #45). It
|
|
412
|
+
* matches mail the classifier has not reached and mail it declined to
|
|
413
|
+
* categorize alike; `Message.classificationState` is what separates those,
|
|
414
|
+
* and no read path filters on it (issue #331).
|
|
415
|
+
*/
|
|
416
|
+
category?: ThreadMessageItem["category"][];
|
|
417
|
+
};
|
|
418
|
+
export type CreateLabelInput = Omit<LabelItem, "labelId" | "normalizedName" | "createdAt" | "updatedAt" | "color"> & {
|
|
419
|
+
color?: LabelItem["color"];
|
|
420
|
+
};
|
|
421
|
+
export type UpdateLabelInput = Partial<Pick<LabelItem, "name" | "normalizedName" | "color">>;
|
|
422
|
+
export type CreateMessageLabelInput = Omit<MessageLabelItem, "messageLabelId" | "createdAt" | "updatedAt" | "appliedByFilterId"> & {
|
|
423
|
+
appliedByFilterId?: MessageLabelItem["appliedByFilterId"];
|
|
424
|
+
};
|
|
425
|
+
export type CreateFilterInput = Omit<FilterItem, "filterId" | "createdAt" | "updatedAt" | "state" | "disabledReason" | "ruleChangedAt" | "actionChangedAt" | "matchOperator" | "actionLabelId" | "actionMailboxId"> & {
|
|
426
|
+
state?: FilterItem["state"];
|
|
427
|
+
disabledReason?: FilterItem["disabledReason"];
|
|
428
|
+
matchOperator?: FilterItem["matchOperator"];
|
|
429
|
+
actionLabelId?: FilterItem["actionLabelId"];
|
|
430
|
+
actionMailboxId?: FilterItem["actionMailboxId"];
|
|
431
|
+
};
|
|
432
|
+
export type UpdateFilterInput = Partial<Omit<CreateFilterInput, "accountConfigId">>;
|
|
433
|
+
export type CalendarCollectionItem = z.infer<typeof CalendarCollectionSchema>;
|
|
434
|
+
export type CalendarObjectItem = z.infer<typeof CalendarObjectSchema>;
|
|
435
|
+
export type CalendarEventIndexItem = z.infer<typeof CalendarEventIndexSchema>;
|
|
436
|
+
export type CreateCalendarCollectionInput = Omit<CalendarCollectionItem, "calendarId" | "syncSequence" | "createdAt" | "updatedAt" | "color" | "componentSet" | "source" | "timezone" | "subscriptionUrl" | "subscriptionEnabled" | "subscriptionCheckedAt" | "subscriptionFetchedAt" | "subscriptionError"> & {
|
|
437
|
+
color?: CalendarCollectionItem["color"];
|
|
438
|
+
componentSet?: CalendarCollectionItem["componentSet"];
|
|
439
|
+
source?: CalendarCollectionItem["source"];
|
|
440
|
+
timezone?: CalendarCollectionItem["timezone"];
|
|
441
|
+
subscriptionUrl?: CalendarCollectionItem["subscriptionUrl"];
|
|
442
|
+
subscriptionEnabled?: CalendarCollectionItem["subscriptionEnabled"];
|
|
443
|
+
};
|
|
444
|
+
export type UpdateCalendarCollectionInput = Partial<Pick<CalendarCollectionItem, "displayName" | "color" | "timezone" | "subscriptionEnabled" | "subscriptionCheckedAt" | "subscriptionFetchedAt" | "subscriptionError">>;
|
|
445
|
+
export type CalendarFeedTokenItem = z.infer<typeof CalendarFeedTokenSchema>;
|
|
446
|
+
export type PutCalendarFeedTokenInput = Omit<CalendarFeedTokenItem, "feedTokenId" | "rotatedAt" | "createdAt" | "updatedAt">;
|
|
447
|
+
/**
|
|
448
|
+
* A whole calendar resource. Every projected column is supplied together with
|
|
449
|
+
* the `icalData` it was projected from — the repository never derives one from
|
|
450
|
+
* the other, so the projection can only ever be produced by the one place that
|
|
451
|
+
* owns it (`@remit/calendar-service`) and can never drift from the bytes.
|
|
452
|
+
*
|
|
453
|
+
* `calendarObjectId` is derived from calendarId + resourceName, so this is an
|
|
454
|
+
* upsert: writing the same resource twice rewrites its own row.
|
|
455
|
+
*/
|
|
456
|
+
export type PutCalendarObjectInput = Omit<CalendarObjectItem, "calendarObjectId" | "createdAt" | "updatedAt">;
|
|
457
|
+
/**
|
|
458
|
+
* One expanded occurrence. Written only as part of a full replacement of a
|
|
459
|
+
* resource's occurrences — there is no single-occurrence write, because a row
|
|
460
|
+
* here is never authoritative and never edited in place.
|
|
461
|
+
*/
|
|
462
|
+
export type CalendarOccurrenceInput = Omit<CalendarEventIndexItem, "calendarId" | "calendarObjectId" | "createdAt" | "updatedAt">;
|
|
463
|
+
export type CalendarSuggestionItem = z.infer<typeof CalendarSuggestionSchema>;
|
|
464
|
+
/**
|
|
465
|
+
* A whole suggestion, as the producer read it out of a message. Every field is
|
|
466
|
+
* derived from the message — nothing here is client-supplied — and
|
|
467
|
+
* `suggestionId` is derived from messageId + bodyPartId + icalUid, so this is
|
|
468
|
+
* an upsert: re-reading the same message rewrites its own row rather than
|
|
469
|
+
* stacking a second card on the message.
|
|
470
|
+
*
|
|
471
|
+
* `state` and `acceptedCalendarObjectId` are excluded: a producer only ever
|
|
472
|
+
* writes a `Pending` suggestion, and the two fields that record what a person
|
|
473
|
+
* decided move exclusively through `settle`, so a re-sync can never walk an
|
|
474
|
+
* answered card back to Pending. `supersededByMessageId` moves only through
|
|
475
|
+
* `supersedeIfPending`, with the state it explains.
|
|
476
|
+
*/
|
|
477
|
+
export type PutCalendarSuggestionInput = Omit<CalendarSuggestionItem, "suggestionId" | "state" | "acceptedCalendarObjectId" | "supersededByMessageId" | "createdAt" | "updatedAt">;
|
|
478
|
+
export type SenderSignerStandingItem = z.infer<typeof SenderSignerStandingSchema>;
|
|
479
|
+
/**
|
|
480
|
+
* One message observed arriving for a `(senderKey, signerDomain)` pair.
|
|
481
|
+
*
|
|
482
|
+
* `observedAt` is supplied rather than taken from the clock so a caller
|
|
483
|
+
* replaying a body-sync batch records the arrival's own time, and so the
|
|
484
|
+
* `firstSeenAt`-immutability contract is assertable without sleeping.
|
|
485
|
+
*/
|
|
486
|
+
export type ObserveSenderSignerStandingInput = {
|
|
487
|
+
accountConfigId: string;
|
|
488
|
+
senderKey: string;
|
|
489
|
+
signerDomain: string;
|
|
490
|
+
observedAt: number;
|
|
491
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const SUMMARY_MAX_LENGTH = 140;
|
|
3
|
+
export declare const UpdateManifestSchema: z.ZodObject<{
|
|
4
|
+
version: z.ZodString;
|
|
5
|
+
publishedAt: z.ZodString;
|
|
6
|
+
summary: z.ZodString;
|
|
7
|
+
releaseNotesUrl: z.ZodEffects<z.ZodString, string, string>;
|
|
8
|
+
registry: z.ZodString;
|
|
9
|
+
schemaVersion: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
summary: string;
|
|
12
|
+
version: string;
|
|
13
|
+
publishedAt: string;
|
|
14
|
+
releaseNotesUrl: string;
|
|
15
|
+
registry: string;
|
|
16
|
+
schemaVersion?: number | undefined;
|
|
17
|
+
}, {
|
|
18
|
+
summary: string;
|
|
19
|
+
version: string;
|
|
20
|
+
publishedAt: string;
|
|
21
|
+
releaseNotesUrl: string;
|
|
22
|
+
registry: string;
|
|
23
|
+
schemaVersion?: number | undefined;
|
|
24
|
+
}>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const SUMMARY_MAX_LENGTH = 140;
|
|
3
|
+
export const UpdateManifestSchema = z.object({
|
|
4
|
+
version: z.string().regex(/^v\d+\.\d+\.\d+$/),
|
|
5
|
+
publishedAt: z.string().datetime(),
|
|
6
|
+
summary: z.string().min(1).max(SUMMARY_MAX_LENGTH),
|
|
7
|
+
releaseNotesUrl: z
|
|
8
|
+
.string()
|
|
9
|
+
.url()
|
|
10
|
+
.refine((url) => url.startsWith("https://"), {
|
|
11
|
+
message: "releaseNotesUrl must be an https:// URL",
|
|
12
|
+
}),
|
|
13
|
+
registry: z.string().min(1),
|
|
14
|
+
// The highest schema migration the release applies, as a count of the
|
|
15
|
+
// migrations shipped at that release. The updater compares it against the
|
|
16
|
+
// running instance's version to tell whether installing this release runs a
|
|
17
|
+
// migration. Optional so a manifest published before this field validates and
|
|
18
|
+
// reads as an unknown schema version rather than an error.
|
|
19
|
+
schemaVersion: z.number().int().nonnegative().optional(),
|
|
20
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MailboxItem } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Whether this folder holds mail that also lives in a real folder. Such a
|
|
4
|
+
* folder is a view, not a filing location: seeing a message in it says nothing
|
|
5
|
+
* about where the message was filed, so it neither picks which duplicate a
|
|
6
|
+
* listing drops nor decides where a message lives.
|
|
7
|
+
*/
|
|
8
|
+
export declare const isVirtualCopyMailbox: (mailbox: MailboxItem) => boolean;
|
|
@@ -1,33 +1,28 @@
|
|
|
1
1
|
import { MailboxSpecialUse } from "@remit/domain-enums";
|
|
2
|
-
import type { MailboxItem } from "./types.js";
|
|
3
|
-
|
|
4
2
|
/**
|
|
5
3
|
* Special-use folders that hold a second copy of mail already reachable through
|
|
6
4
|
* the folder it actually lives in — Gmail's All Mail, Starred and Important.
|
|
7
5
|
*/
|
|
8
|
-
const VIRTUAL_COPY_SPECIAL_USE
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
const VIRTUAL_COPY_SPECIAL_USE = [
|
|
7
|
+
MailboxSpecialUse.All,
|
|
8
|
+
MailboxSpecialUse.Flagged,
|
|
9
|
+
MailboxSpecialUse.Important,
|
|
12
10
|
];
|
|
13
|
-
|
|
14
11
|
/**
|
|
15
12
|
* Well-known Gmail virtual paths, for servers that do not advertise the
|
|
16
13
|
* special-use attribute. Whole path, never a prefix — a user's own
|
|
17
14
|
* `Starred ideas` folder is real mail.
|
|
18
15
|
*/
|
|
19
|
-
const VIRTUAL_COPY_FULL_PATHS
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
const VIRTUAL_COPY_FULL_PATHS = [
|
|
17
|
+
"[gmail]/all mail",
|
|
18
|
+
"[gmail]/starred",
|
|
19
|
+
"[gmail]/important",
|
|
23
20
|
];
|
|
24
|
-
|
|
25
21
|
/**
|
|
26
22
|
* Whether this folder holds mail that also lives in a real folder. Such a
|
|
27
23
|
* folder is a view, not a filing location: seeing a message in it says nothing
|
|
28
24
|
* about where the message was filed, so it neither picks which duplicate a
|
|
29
25
|
* listing drops nor decides where a message lives.
|
|
30
26
|
*/
|
|
31
|
-
export const isVirtualCopyMailbox = (mailbox
|
|
32
|
-
|
|
33
|
-
true || VIRTUAL_COPY_FULL_PATHS.includes(mailbox.fullPath.toLowerCase());
|
|
27
|
+
export const isVirtualCopyMailbox = (mailbox) => mailbox.specialUse?.some((use) => VIRTUAL_COPY_SPECIAL_USE.includes(use)) ===
|
|
28
|
+
true || VIRTUAL_COPY_FULL_PATHS.includes(mailbox.fullPath.toLowerCase());
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wellknown promotion rule (issue #233).
|
|
3
|
+
*
|
|
4
|
+
* Pure predicate over an Address engagement snapshot. Returns `true` when
|
|
5
|
+
* the address should be auto-promoted to `flags.wellknown.value === true`.
|
|
6
|
+
*
|
|
7
|
+
* Three conjuncts:
|
|
8
|
+
* 1. `flags.wellknown.value` is not already `true` (idempotent).
|
|
9
|
+
* 2. Engagement threshold:
|
|
10
|
+
* - `replyCount >= 1` always promotes (a real two-way conversation).
|
|
11
|
+
* - `inboundCount >= 3` promotes ONLY for non-bulk senders. Bulk senders
|
|
12
|
+
* (newsletters, marketing, automated, or List-Unsubscribe present) reach
|
|
13
|
+
* high inbound counts by volume alone — that is not engagement. Only a
|
|
14
|
+
* real reply from the user (`replyCount >= 1`) promotes a bulk sender.
|
|
15
|
+
* 3. `lastInboundAt` exists and is within the last 90 days
|
|
16
|
+
* (keeps dormant senders from being promoted by stale counters).
|
|
17
|
+
*
|
|
18
|
+
* The body-sync inbound path always writes `lastInboundAt = now`, so the
|
|
19
|
+
* 90-day check trivially passes there. The SMTP reply path reads the
|
|
20
|
+
* existing `lastInboundAt` (the user is replying to an inbound, which
|
|
21
|
+
* implies a recent inbound, but we still gate on it explicitly).
|
|
22
|
+
*/
|
|
23
|
+
export declare const WELLKNOWN_INBOUND_THRESHOLD = 3;
|
|
24
|
+
export declare const WELLKNOWN_REPLY_THRESHOLD = 1;
|
|
25
|
+
export declare const WELLKNOWN_INBOUND_WINDOW_MS: number;
|
|
26
|
+
export interface WellknownEngagementSnapshot {
|
|
27
|
+
inboundCount?: number;
|
|
28
|
+
replyCount?: number;
|
|
29
|
+
lastInboundAt?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Whether this sender is a bulk/automated sender (newsletter, marketing,
|
|
32
|
+
* automated category, or List-Unsubscribe header present). Bulk senders
|
|
33
|
+
* can only be promoted via `replyCount >= 1`, not by inbound volume.
|
|
34
|
+
*/
|
|
35
|
+
isBulk?: boolean;
|
|
36
|
+
flags?: {
|
|
37
|
+
wellknown?: {
|
|
38
|
+
value: boolean;
|
|
39
|
+
} | undefined;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export declare const shouldPromoteWellknown: (snapshot: WellknownEngagementSnapshot, now: number) => boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Returns true when the category or presence of List-Unsubscribe marks the
|
|
45
|
+
* sender as bulk, meaning they cannot be promoted by inbound volume alone.
|
|
46
|
+
*/
|
|
47
|
+
export declare function isBulkSender(category: string | undefined, hasListUnsubscribe: boolean): boolean;
|