@remit/data-ports 0.0.85 → 0.0.86
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/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/interfaces/account-fanout-events.d.ts +58 -0
- package/dist/interfaces/account-fanout-events.js +1 -0
- package/dist/interfaces/message.d.ts +7 -0
- package/dist/interfaces/queue.d.ts +20 -0
- package/dist/interfaces/queue.js +2 -0
- package/dist/recording-queue.d.ts +13 -0
- package/dist/recording-queue.js +45 -0
- package/package.json +6 -4
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { deriveFilterTtl } from "./filter-ttl.js";
|
|
|
2
2
|
export type { IAccountRepository } from "./interfaces/account.js";
|
|
3
3
|
export type { IAccountConfigRepository } from "./interfaces/account-config.js";
|
|
4
4
|
export type { IAccountExportRequestRepository } from "./interfaces/account-export-request.js";
|
|
5
|
+
export type { AccountDataPurgeEvent, AccountDeleteEvent, AccountExportEvent, AccountFanoutEvent, OrganizeJobEvent, SenderCategoryBackApplyEvent, } from "./interfaces/account-fanout-events.js";
|
|
5
6
|
export type { IAccountSettingRepository } from "./interfaces/account-setting.js";
|
|
6
7
|
export type { IAddressRepository } from "./interfaces/address.js";
|
|
7
8
|
export type { ICalendarCollectionRepository } from "./interfaces/calendar-collection.js";
|
|
@@ -28,6 +29,7 @@ export { holdsRoom } from "./interfaces/outbox-attachment.js";
|
|
|
28
29
|
export type { IOutboxMessageRepository } from "./interfaces/outbox-message.js";
|
|
29
30
|
export { APPENDED_UID_NONE, APPENDED_UID_UNREPORTED, isSentCopyFiled, } from "./interfaces/outbox-message.js";
|
|
30
31
|
export type { IQuarantineRepository } from "./interfaces/quarantine.js";
|
|
32
|
+
export { type FifoQueueMessage, type FifoQueueProducer, type GroupedQueueMessage, type GroupedQueueProducer, QUEUE_BATCH_LIMIT, type QueueBatchResult, type QueueMessage, type QueueProducer, } from "./interfaces/queue.js";
|
|
31
33
|
export type { ISenderSignerStandingRepository } from "./interfaces/sender-signer-standing.js";
|
|
32
34
|
export type { ISyncWarningRepository, SurfacedSyncWarnings, } from "./interfaces/sync-warning.js";
|
|
33
35
|
export type { IThreadMessageRepository } from "./interfaces/thread-message.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { deriveFilterTtl } from "./filter-ttl.js";
|
|
2
2
|
export { holdsRoom } from "./interfaces/outbox-attachment.js";
|
|
3
3
|
export { APPENDED_UID_NONE, APPENDED_UID_UNREPORTED, isSentCopyFiled, } from "./interfaces/outbox-message.js";
|
|
4
|
+
export { QUEUE_BATCH_LIMIT, } from "./interfaces/queue.js";
|
|
4
5
|
export { abandonedMutationOf, hasAbandonedDelete, hasAbandonedMove, } from "./message-settlement.js";
|
|
5
6
|
export { FILTER_NO_ACTION, isSenderMuted, isSenderMuteFilter, } from "./sender-mute.js";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ThreadMessageItem } from "../types.js";
|
|
2
|
+
export type AccountDeleteEvent = {
|
|
3
|
+
type: "AccountDelete";
|
|
4
|
+
accountConfigId: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Per-account hard-delete. Purges ONE mail account's data (mailboxes,
|
|
8
|
+
* messages, body parts, thread messages, S3 objects) while
|
|
9
|
+
* keeping the AccountConfig/tenant and any sibling accounts intact. Emitted
|
|
10
|
+
* by the API on `deleteAccount`; consumed by the fanout worker.
|
|
11
|
+
*/
|
|
12
|
+
export type AccountDataPurgeEvent = {
|
|
13
|
+
type: "AccountDataPurge";
|
|
14
|
+
accountId: string;
|
|
15
|
+
accountConfigId: string;
|
|
16
|
+
};
|
|
17
|
+
export type AccountExportEvent = {
|
|
18
|
+
type: "AccountExport";
|
|
19
|
+
accountConfigId: string;
|
|
20
|
+
accountExportRequestId: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* A "all like these" back-apply job (RFC 034, #1278). Rides the same
|
|
24
|
+
* account-fanout queue as export: the API writes a Pending OrganizeJobRequest
|
|
25
|
+
* row and enqueues this; the fanout worker matches the corpus and applies the
|
|
26
|
+
* action, driving the row to Complete/Failed. Never creates a Filter row.
|
|
27
|
+
*/
|
|
28
|
+
export type OrganizeJobEvent = {
|
|
29
|
+
type: "OrganizeJob";
|
|
30
|
+
accountConfigId: string;
|
|
31
|
+
organizeJobId: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Retroactive half of a sender-category override (#415, RFC 039 Decision 3).
|
|
35
|
+
* Rides the same account-fanout queue as the organize back-apply: the API
|
|
36
|
+
* enqueues one when `Address.flags.category` is SET, and the fanout worker
|
|
37
|
+
* re-labels a bounded recent batch of that sender's already-classified mail.
|
|
38
|
+
* A CLEAR never enqueues one: reverting to auto-classification says nothing
|
|
39
|
+
* about what the classifier would have answered, and re-deriving it would need
|
|
40
|
+
* every message's body back.
|
|
41
|
+
*
|
|
42
|
+
* `category` and `categorySetAt` together name WHICH set this job was fired
|
|
43
|
+
* for, and the worker refuses a job whose set no longer stands on the Address.
|
|
44
|
+
* That check is what the standard queue's semantics make necessary rather than
|
|
45
|
+
* merely tidy: delivery is at-least-once and unordered, so without it a job
|
|
46
|
+
* that fails and redelivers after the user has corrected the category re-labels
|
|
47
|
+
* those 500 messages back to the superseded one, leaving the flag and the mail
|
|
48
|
+
* permanently disagreeing with nothing to reconcile them.
|
|
49
|
+
*/
|
|
50
|
+
export type SenderCategoryBackApplyEvent = {
|
|
51
|
+
type: "SenderCategoryBackApply";
|
|
52
|
+
accountConfigId: string;
|
|
53
|
+
addressId: string;
|
|
54
|
+
normalizedEmail: string;
|
|
55
|
+
category: ThreadMessageItem["category"];
|
|
56
|
+
categorySetAt: number;
|
|
57
|
+
};
|
|
58
|
+
export type AccountFanoutEvent = AccountDeleteEvent | AccountDataPurgeEvent | AccountExportEvent | OrganizeJobEvent | SenderCategoryBackApplyEvent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -11,6 +11,13 @@ export interface IMessageRepository {
|
|
|
11
11
|
update(messageId: string, input: UpdateMessageInput): Promise<MessageItem>;
|
|
12
12
|
clearBodyStorageKey(messageId: string): Promise<MessageItem>;
|
|
13
13
|
clearSpamReport(messageId: string): Promise<MessageItem>;
|
|
14
|
+
setSearchText(messageId: string, text: string): Promise<void>;
|
|
15
|
+
copySearchText(sourceMessageId: string, targetMessageId: string): Promise<void>;
|
|
16
|
+
syncSearch(messageIds: string[]): Promise<void>;
|
|
17
|
+
listMissingSearchText(after: string, limit: number): Promise<Array<{
|
|
18
|
+
messageId: string;
|
|
19
|
+
bodyStorageKey: string;
|
|
20
|
+
}>>;
|
|
14
21
|
delete(messageId: string): Promise<void>;
|
|
15
22
|
deleteMany(messageIds: string[]): Promise<void>;
|
|
16
23
|
/**
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface QueueMessage<T> {
|
|
2
|
+
readonly body: T;
|
|
3
|
+
readonly delaySeconds?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface GroupedQueueMessage<T> extends QueueMessage<T> {
|
|
6
|
+
readonly groupId: string;
|
|
7
|
+
}
|
|
8
|
+
export interface FifoQueueMessage<T> extends GroupedQueueMessage<T> {
|
|
9
|
+
readonly deduplicationId: string;
|
|
10
|
+
}
|
|
11
|
+
export interface QueueBatchResult {
|
|
12
|
+
readonly refused: ReadonlySet<number>;
|
|
13
|
+
}
|
|
14
|
+
export declare const QUEUE_BATCH_LIMIT = 10;
|
|
15
|
+
export interface QueueProducer<T, M extends QueueMessage<T> = QueueMessage<T>> {
|
|
16
|
+
readonly send: (message: M) => Promise<void>;
|
|
17
|
+
readonly sendBatch: (messages: readonly M[]) => Promise<QueueBatchResult>;
|
|
18
|
+
}
|
|
19
|
+
export type FifoQueueProducer<T> = QueueProducer<T, FifoQueueMessage<T>>;
|
|
20
|
+
export type GroupedQueueProducer<T> = QueueProducer<T, GroupedQueueMessage<T>>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { QueueProducer } from "./interfaces/queue.js";
|
|
2
|
+
export interface RecordedMessage {
|
|
3
|
+
body: Record<string, unknown>;
|
|
4
|
+
groupId: string | undefined;
|
|
5
|
+
deduplicationId: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface RecordingQueue extends QueueProducer<unknown> {
|
|
8
|
+
readonly sent: RecordedMessage[];
|
|
9
|
+
readonly answer: (next: () => Promise<unknown>) => void;
|
|
10
|
+
readonly refuse: (positions: readonly number[]) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const recordingQueue: () => RecordingQueue;
|
|
13
|
+
export declare const failingQueue: (error: unknown) => RecordingQueue;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2
|
+
const stringField = (message, field) => {
|
|
3
|
+
const value = Reflect.get(message, field);
|
|
4
|
+
return typeof value === "string" ? value : undefined;
|
|
5
|
+
};
|
|
6
|
+
const recorded = (message) => {
|
|
7
|
+
const body = JSON.parse(JSON.stringify(message.body));
|
|
8
|
+
if (!isRecord(body))
|
|
9
|
+
throw new Error("A queued body must be an object");
|
|
10
|
+
return {
|
|
11
|
+
body,
|
|
12
|
+
groupId: stringField(message, "groupId"),
|
|
13
|
+
deduplicationId: stringField(message, "deduplicationId"),
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export const recordingQueue = () => {
|
|
17
|
+
const sent = [];
|
|
18
|
+
let answer = async () => ({});
|
|
19
|
+
let refused = new Set();
|
|
20
|
+
return {
|
|
21
|
+
sent,
|
|
22
|
+
answer: (next) => {
|
|
23
|
+
answer = next;
|
|
24
|
+
},
|
|
25
|
+
refuse: (positions) => {
|
|
26
|
+
refused = new Set(positions);
|
|
27
|
+
},
|
|
28
|
+
send: async (message) => {
|
|
29
|
+
sent.push(recorded(message));
|
|
30
|
+
await answer();
|
|
31
|
+
},
|
|
32
|
+
sendBatch: async (messages) => {
|
|
33
|
+
sent.push(...messages.map(recorded));
|
|
34
|
+
await answer();
|
|
35
|
+
return { refused };
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export const failingQueue = (error) => {
|
|
40
|
+
const queue = recordingQueue();
|
|
41
|
+
queue.answer(async () => {
|
|
42
|
+
throw error;
|
|
43
|
+
});
|
|
44
|
+
return queue;
|
|
45
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remit/data-ports",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.86",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,11 +26,13 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@remit/domain-enums": "*",
|
|
29
|
-
"short-uuid": "
|
|
30
|
-
"uuid": "
|
|
31
|
-
"zod": "^3.25.0",
|
|
29
|
+
"short-uuid": "^6.0.3",
|
|
30
|
+
"uuid": "^13.0.2",
|
|
32
31
|
"@remit/api-zod-schemas": "*"
|
|
33
32
|
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"zod": "^3.25.0"
|
|
35
|
+
},
|
|
34
36
|
"license": "MIT",
|
|
35
37
|
"publishConfig": {
|
|
36
38
|
"access": "public"
|