@remit/account-worker 0.0.30 → 0.0.31

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/account-worker",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
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 (event.type === "OrganizeJob") {
57
- await processOrganizeJob(event, log);
58
- return;
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
 
@@ -1,4 +1,4 @@
1
- import { getClient, type RemitClient } from "@remit/backend/client";
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?: RemitClient;
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.client ?? (await getClient());
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 { processSenderCategoryBackApply } from "./sender-category-backapply.js";
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("processSenderCategoryBackApply (#415)", () => {
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 processSenderCategoryBackApply(event, noopLogger, {
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 processSenderCategoryBackApply(event, noopLogger, {
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 processSenderCategoryBackApply(event, noopLogger, {
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 processSenderCategoryBackApply(event, noopLogger, {
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 processSenderCategoryBackApply(event, noopLogger, {
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
- processSenderCategoryBackApply(event, noopLogger, {
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
- processSenderCategoryBackApply(event, noopLogger, {
153
+ processAccountFanoutEvent(event, {
155
154
  client: clientOver({
156
155
  relabelled: [],
157
156
  listByFieldTerms: async () => {
@@ -1,4 +1,4 @@
1
- import { getClient, type RemitClient } from "@remit/backend/client";
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?: RemitClient;
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.client ?? (await getClient());
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
+ };