@remit/account-worker 0.0.30 → 0.0.32
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/package.json +5 -1
- package/src/handlers/account-fanout.ts +7 -9
- package/src/handlers/organize-job.test.ts +9 -5
- package/src/handlers/organize-job.ts +5 -5
- package/src/handlers/sender-category-backapply.test.ts +9 -10
- package/src/handlers/sender-category-backapply.ts +5 -5
- package/src/process-bundle.test.ts +66 -0
- package/src/process.ts +28 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remit/account-worker",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
"./finalize": {
|
|
24
24
|
"types": "./src/handlers/account-finalize.ts",
|
|
25
25
|
"default": "./src/handlers/account-finalize.ts"
|
|
26
|
+
},
|
|
27
|
+
"./process": {
|
|
28
|
+
"types": "./src/process.ts",
|
|
29
|
+
"default": "./src/process.ts"
|
|
26
30
|
}
|
|
27
31
|
},
|
|
28
32
|
"scripts": {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getClient } from "@remit/backend/client";
|
|
1
2
|
import { createLogger, type Logger } from "@remit/logger";
|
|
2
3
|
import {
|
|
3
4
|
queueNameFromEventSource,
|
|
@@ -20,10 +21,9 @@ import type {
|
|
|
20
21
|
AccountFanoutEvent,
|
|
21
22
|
AccountFinalizeEvent,
|
|
22
23
|
} from "../events.js";
|
|
24
|
+
import { processAccountFanoutEvent } from "../process.js";
|
|
23
25
|
import { processAccountExport } from "./account-export.js";
|
|
24
26
|
import { processAccountDataPurge } from "./account-purge.js";
|
|
25
|
-
import { processOrganizeJob } from "./organize-job.js";
|
|
26
|
-
import { processSenderCategoryBackApply } from "./sender-category-backapply.js";
|
|
27
27
|
|
|
28
28
|
installNodeLogger();
|
|
29
29
|
|
|
@@ -53,13 +53,11 @@ export const processAccountFanout = async (
|
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (event.type === "SenderCategoryBackApply") {
|
|
62
|
-
await processSenderCategoryBackApply(event, log);
|
|
56
|
+
if (
|
|
57
|
+
event.type === "OrganizeJob" ||
|
|
58
|
+
event.type === "SenderCategoryBackApply"
|
|
59
|
+
) {
|
|
60
|
+
await processAccountFanoutEvent(event, { client: await getClient() });
|
|
63
61
|
return;
|
|
64
62
|
}
|
|
65
63
|
|
|
@@ -10,6 +10,7 @@ import type { FilterItem } from "@remit/data-ports";
|
|
|
10
10
|
import { NotFoundError } from "@remit/data-ports/errors";
|
|
11
11
|
import { recordingQueue } from "@remit/data-ports/recording-queue";
|
|
12
12
|
import {
|
|
13
|
+
BETTER_SQLITE3_LIMITS,
|
|
13
14
|
createSqliteRepositories,
|
|
14
15
|
type DrizzleThreadMessageRepository,
|
|
15
16
|
} from "@remit/drizzle-service";
|
|
@@ -185,11 +186,14 @@ interface World {
|
|
|
185
186
|
|
|
186
187
|
const world = async (filters: FilterItem[]): Promise<World> => {
|
|
187
188
|
const store = createShippedSqliteDb();
|
|
188
|
-
const threadMessage = createSqliteRepositories(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
const threadMessage = createSqliteRepositories(
|
|
190
|
+
{
|
|
191
|
+
app: store.db,
|
|
192
|
+
mail: store.db,
|
|
193
|
+
search: store.db,
|
|
194
|
+
},
|
|
195
|
+
BETTER_SQLITE3_LIMITS,
|
|
196
|
+
).threadMessage;
|
|
193
197
|
const { inbox, archive } = await seedThreads(threadMessage);
|
|
194
198
|
const updates: Update[] = [];
|
|
195
199
|
const filterUpdates: World["filterUpdates"] = [];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { RemitClient } from "@remit/backend/client";
|
|
2
2
|
import {
|
|
3
3
|
type ApplyOrganizeDeps,
|
|
4
4
|
applyOrganize,
|
|
@@ -16,7 +16,7 @@ import type { Logger } from "@remit/logger";
|
|
|
16
16
|
import type { OrganizeJobEvent } from "../events.js";
|
|
17
17
|
|
|
18
18
|
export interface ProcessOrganizeJobDeps {
|
|
19
|
-
client
|
|
19
|
+
client: RemitClient<"messageManagement">;
|
|
20
20
|
matchDeps?: OrganizeMatchDeps;
|
|
21
21
|
moveService?: ApplyOrganizeDeps["moveService"];
|
|
22
22
|
}
|
|
@@ -42,7 +42,7 @@ const rejectedOutcome = (rejected: OrganizeRejection): OrganizeOutcome => ({
|
|
|
42
42
|
* folder, every requested move applied (reader #497).
|
|
43
43
|
*/
|
|
44
44
|
const runSnapshot = async (
|
|
45
|
-
client: RemitClient
|
|
45
|
+
client: RemitClient<"messageManagement">,
|
|
46
46
|
matchDeps: OrganizeMatchDeps,
|
|
47
47
|
moveService: ApplyOrganizeDeps["moveService"],
|
|
48
48
|
job: Awaited<ReturnType<RemitClient["organizeJobRequest"]["get"]>>,
|
|
@@ -95,10 +95,10 @@ const runSnapshot = async (
|
|
|
95
95
|
export const processOrganizeJob = async (
|
|
96
96
|
event: OrganizeJobEvent,
|
|
97
97
|
log: Logger,
|
|
98
|
-
deps: ProcessOrganizeJobDeps
|
|
98
|
+
deps: ProcessOrganizeJobDeps,
|
|
99
99
|
): Promise<void> => {
|
|
100
100
|
const { accountConfigId, organizeJobId } = event;
|
|
101
|
-
const client = deps
|
|
101
|
+
const { client } = deps;
|
|
102
102
|
|
|
103
103
|
const job = await client.organizeJobRequest.get(organizeJobId);
|
|
104
104
|
await client.organizeJobRequest.update(organizeJobId, { state: "Running" });
|
|
@@ -2,9 +2,8 @@ import assert from "node:assert/strict";
|
|
|
2
2
|
import { describe, it } from "node:test";
|
|
3
3
|
import type { RemitClient } from "@remit/backend/client";
|
|
4
4
|
import { NotFoundError } from "@remit/data-ports/errors";
|
|
5
|
-
import { noopLogger } from "@remit/logger";
|
|
6
5
|
import type { SenderCategoryBackApplyEvent } from "../events.js";
|
|
7
|
-
import {
|
|
6
|
+
import { processAccountFanoutEvent } from "../process.js";
|
|
8
7
|
|
|
9
8
|
const SET_AT = 1_700;
|
|
10
9
|
|
|
@@ -71,11 +70,11 @@ const clientOver = ({
|
|
|
71
70
|
},
|
|
72
71
|
}) as unknown as RemitClient;
|
|
73
72
|
|
|
74
|
-
describe("
|
|
73
|
+
describe("processAccountFanoutEvent on a sender category back-apply (#415)", () => {
|
|
75
74
|
it("re-labels the sender's stored mail to the category the event carries", async () => {
|
|
76
75
|
const relabelled: Array<{ messageId: string; category: unknown }> = [];
|
|
77
76
|
|
|
78
|
-
await
|
|
77
|
+
await processAccountFanoutEvent(event, {
|
|
79
78
|
client: clientOver({ relabelled }),
|
|
80
79
|
});
|
|
81
80
|
|
|
@@ -87,7 +86,7 @@ describe("processSenderCategoryBackApply (#415)", () => {
|
|
|
87
86
|
it("applies nothing when the user has since corrected the category", async () => {
|
|
88
87
|
const relabelled: Array<{ messageId: string; category: unknown }> = [];
|
|
89
88
|
|
|
90
|
-
await
|
|
89
|
+
await processAccountFanoutEvent(event, {
|
|
91
90
|
client: clientOver({
|
|
92
91
|
relabelled,
|
|
93
92
|
storedFlag: { value: "promotions", setAt: SET_AT + 60 },
|
|
@@ -104,7 +103,7 @@ describe("processSenderCategoryBackApply (#415)", () => {
|
|
|
104
103
|
it("applies nothing when the same category was cleared and set again", async () => {
|
|
105
104
|
const relabelled: Array<{ messageId: string; category: unknown }> = [];
|
|
106
105
|
|
|
107
|
-
await
|
|
106
|
+
await processAccountFanoutEvent(event, {
|
|
108
107
|
client: clientOver({
|
|
109
108
|
relabelled,
|
|
110
109
|
storedFlag: { value: "newsletter", setAt: SET_AT + 60 },
|
|
@@ -117,7 +116,7 @@ describe("processSenderCategoryBackApply (#415)", () => {
|
|
|
117
116
|
it("applies nothing when the override was cleared outright", async () => {
|
|
118
117
|
const relabelled: Array<{ messageId: string; category: unknown }> = [];
|
|
119
118
|
|
|
120
|
-
await
|
|
119
|
+
await processAccountFanoutEvent(event, {
|
|
121
120
|
client: clientOver({ relabelled, storedFlag: "cleared" }),
|
|
122
121
|
});
|
|
123
122
|
|
|
@@ -127,7 +126,7 @@ describe("processSenderCategoryBackApply (#415)", () => {
|
|
|
127
126
|
it("declines quietly when the address is gone", async () => {
|
|
128
127
|
const relabelled: Array<{ messageId: string; category: unknown }> = [];
|
|
129
128
|
|
|
130
|
-
await
|
|
129
|
+
await processAccountFanoutEvent(event, {
|
|
131
130
|
client: clientOver({ relabelled, storedFlag: "address-gone" }),
|
|
132
131
|
});
|
|
133
132
|
|
|
@@ -136,7 +135,7 @@ describe("processSenderCategoryBackApply (#415)", () => {
|
|
|
136
135
|
|
|
137
136
|
it("leaves a pass with a failed message unacknowledged so it redelivers", async () => {
|
|
138
137
|
await assert.rejects(
|
|
139
|
-
|
|
138
|
+
processAccountFanoutEvent(event, {
|
|
140
139
|
client: clientOver({
|
|
141
140
|
relabelled: [],
|
|
142
141
|
updateMessage: async () => {
|
|
@@ -151,7 +150,7 @@ describe("processSenderCategoryBackApply (#415)", () => {
|
|
|
151
150
|
|
|
152
151
|
it("propagates a store failure so partial batch failure redelivers the record", async () => {
|
|
153
152
|
await assert.rejects(
|
|
154
|
-
|
|
153
|
+
processAccountFanoutEvent(event, {
|
|
155
154
|
client: clientOver({
|
|
156
155
|
relabelled: [],
|
|
157
156
|
listByFieldTerms: async () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { RemitClient } from "@remit/backend/client";
|
|
2
2
|
import {
|
|
3
3
|
backApplySenderCategory,
|
|
4
4
|
SENDER_CATEGORY_BACKAPPLY_LIMIT,
|
|
@@ -8,7 +8,7 @@ import type { Logger } from "@remit/logger";
|
|
|
8
8
|
import type { SenderCategoryBackApplyEvent } from "../events.js";
|
|
9
9
|
|
|
10
10
|
export interface ProcessSenderCategoryBackApplyDeps {
|
|
11
|
-
client
|
|
11
|
+
client: RemitClient<never>;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -23,7 +23,7 @@ export interface ProcessSenderCategoryBackApplyDeps {
|
|
|
23
23
|
* must not guess.
|
|
24
24
|
*/
|
|
25
25
|
const overrideStillStands = async (
|
|
26
|
-
client: RemitClient
|
|
26
|
+
client: RemitClient<never>,
|
|
27
27
|
event: SenderCategoryBackApplyEvent,
|
|
28
28
|
): Promise<boolean> => {
|
|
29
29
|
const address = await client.address
|
|
@@ -58,10 +58,10 @@ const overrideStillStands = async (
|
|
|
58
58
|
export const processSenderCategoryBackApply = async (
|
|
59
59
|
event: SenderCategoryBackApplyEvent,
|
|
60
60
|
log: Logger,
|
|
61
|
-
deps: ProcessSenderCategoryBackApplyDeps
|
|
61
|
+
deps: ProcessSenderCategoryBackApplyDeps,
|
|
62
62
|
): Promise<void> => {
|
|
63
63
|
const { accountConfigId, addressId, normalizedEmail, category } = event;
|
|
64
|
-
const client = deps
|
|
64
|
+
const { client } = deps;
|
|
65
65
|
|
|
66
66
|
if (!(await overrideStillStands(client, event))) {
|
|
67
67
|
log.warn(
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { describe, it } from "node:test";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { build } from "esbuild";
|
|
6
|
+
|
|
7
|
+
const LAMBDA_ONLY = [
|
|
8
|
+
/(^|\/)aws-lambda(\/|$)/,
|
|
9
|
+
/(^|\/)@aws-sdk\//,
|
|
10
|
+
/(^|\/)expect-env(\/|$)/,
|
|
11
|
+
/(^|\/)sqs-client(\/|$)/,
|
|
12
|
+
/(^|\/)logger-lambda(\/|$)/,
|
|
13
|
+
/(^|\/)prom-client(\/|$)/,
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const ENV_READERS: readonly string[] = [
|
|
17
|
+
// The organize path reaches body sync through the mailbox-service barrel,
|
|
18
|
+
// and body sync reads DEFER_BODY_PARTS itself. A new reader fails here.
|
|
19
|
+
"../mailbox-service/src/body-sync.ts",
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const packageDir = fileURLToPath(new URL("..", import.meta.url));
|
|
23
|
+
|
|
24
|
+
const bundleInputs = async () => {
|
|
25
|
+
const { metafile } = await build({
|
|
26
|
+
absWorkingDir: packageDir,
|
|
27
|
+
entryPoints: ["src/process.ts"],
|
|
28
|
+
bundle: true,
|
|
29
|
+
write: false,
|
|
30
|
+
metafile: true,
|
|
31
|
+
platform: "node",
|
|
32
|
+
format: "esm",
|
|
33
|
+
logLevel: "silent",
|
|
34
|
+
});
|
|
35
|
+
return metafile.inputs;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
describe("the ./process entry", () => {
|
|
39
|
+
it("bundles without the Lambda runtime, the AWS SDK, SQS, expect-env or the Node metrics server", async () => {
|
|
40
|
+
const reached = Object.entries(await bundleInputs()).flatMap(
|
|
41
|
+
([path, input]) => [path, ...input.imports.map((entry) => entry.path)],
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
assert.deepEqual(
|
|
45
|
+
reached.filter((path) =>
|
|
46
|
+
LAMBDA_ONLY.some((pattern) => pattern.test(path)),
|
|
47
|
+
),
|
|
48
|
+
[],
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("reaches no workspace source that reads process.env", async () => {
|
|
53
|
+
const sources = Object.keys(await bundleInputs()).filter(
|
|
54
|
+
(path) => !path.startsWith("<") && !path.includes("node_modules/"),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
assert.deepEqual(
|
|
58
|
+
sources.filter((path) =>
|
|
59
|
+
/\bprocess\.env\b/.test(
|
|
60
|
+
readFileSync(new URL(path, `file://${packageDir}`), "utf8"),
|
|
61
|
+
),
|
|
62
|
+
),
|
|
63
|
+
ENV_READERS,
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
});
|
package/src/process.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { RemitClient } from "@remit/backend/client";
|
|
2
|
+
import { createLogger } from "@remit/logger";
|
|
3
|
+
import type {
|
|
4
|
+
OrganizeJobEvent,
|
|
5
|
+
SenderCategoryBackApplyEvent,
|
|
6
|
+
} from "./events.js";
|
|
7
|
+
import { processOrganizeJob } from "./handlers/organize-job.js";
|
|
8
|
+
import { processSenderCategoryBackApply } from "./handlers/sender-category-backapply.js";
|
|
9
|
+
|
|
10
|
+
export type ClientFanoutEvent = OrganizeJobEvent | SenderCategoryBackApplyEvent;
|
|
11
|
+
|
|
12
|
+
export interface AccountFanoutContext {
|
|
13
|
+
client: RemitClient<"messageManagement">;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const log = createLogger();
|
|
17
|
+
|
|
18
|
+
export const processAccountFanoutEvent = (
|
|
19
|
+
event: ClientFanoutEvent,
|
|
20
|
+
ctx: AccountFanoutContext,
|
|
21
|
+
): Promise<void> => {
|
|
22
|
+
switch (event.type) {
|
|
23
|
+
case "OrganizeJob":
|
|
24
|
+
return processOrganizeJob(event, log, { client: ctx.client });
|
|
25
|
+
case "SenderCategoryBackApply":
|
|
26
|
+
return processSenderCategoryBackApply(event, log, { client: ctx.client });
|
|
27
|
+
}
|
|
28
|
+
};
|