@remit/data-ports 0.0.18 → 0.0.20
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
package/src/conformance/label.ts
CHANGED
|
@@ -81,6 +81,47 @@ export function labelRepositoryConformance(
|
|
|
81
81
|
assert.equal(missing, null);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
+
test("listPageByAccountConfig pages through an account's labels, scoped to the account", async () => {
|
|
85
|
+
const accountConfigId = harness.makeId();
|
|
86
|
+
const other = harness.makeId();
|
|
87
|
+
|
|
88
|
+
// Created concurrently so their `createdAt` millisecond can tie (as it
|
|
89
|
+
// reliably does against the synchronous sqlite driver): the keyset's
|
|
90
|
+
// `labelId` tiebreak then decides order, so this asserts pagination is
|
|
91
|
+
// exhaustive and duplicate-free rather than a specific creation order.
|
|
92
|
+
const created = await Promise.all([
|
|
93
|
+
repo.create({ accountConfigId, name: "First" }),
|
|
94
|
+
repo.create({ accountConfigId, name: "Second" }),
|
|
95
|
+
]);
|
|
96
|
+
await repo.create({ accountConfigId: other, name: "Foreign" });
|
|
97
|
+
|
|
98
|
+
const page1 = await repo.listPageByAccountConfig(accountConfigId, {
|
|
99
|
+
limit: 1,
|
|
100
|
+
});
|
|
101
|
+
assert.equal(page1.items.length, 1);
|
|
102
|
+
assert.ok(page1.continuationToken);
|
|
103
|
+
|
|
104
|
+
const page2 = await repo.listPageByAccountConfig(accountConfigId, {
|
|
105
|
+
limit: 1,
|
|
106
|
+
continuationToken: page1.continuationToken,
|
|
107
|
+
});
|
|
108
|
+
assert.equal(page2.items.length, 1);
|
|
109
|
+
assert.equal(page2.continuationToken, undefined);
|
|
110
|
+
|
|
111
|
+
const seen = new Set([
|
|
112
|
+
...page1.items.map((label) => label.labelId),
|
|
113
|
+
...page2.items.map((label) => label.labelId),
|
|
114
|
+
]);
|
|
115
|
+
assert.equal(
|
|
116
|
+
seen.size,
|
|
117
|
+
created.length,
|
|
118
|
+
"every label is paged exactly once",
|
|
119
|
+
);
|
|
120
|
+
for (const label of created) {
|
|
121
|
+
assert.ok(seen.has(label.labelId));
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
84
125
|
test("delete removes the row", async () => {
|
|
85
126
|
const accountConfigId = harness.makeId();
|
|
86
127
|
const label = await repo.create({ accountConfigId, name: "Gone" });
|
package/src/interfaces/label.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
CreateLabelInput,
|
|
3
3
|
LabelItem,
|
|
4
|
+
ResultList,
|
|
4
5
|
UpdateLabelInput,
|
|
5
6
|
} from "../types.js";
|
|
6
7
|
|
|
@@ -14,6 +15,14 @@ export interface ILabelRepository {
|
|
|
14
15
|
): Promise<LabelItem>;
|
|
15
16
|
delete(accountConfigId: string, labelId: string): Promise<void>;
|
|
16
17
|
listByAccountConfig(accountConfigId: string): Promise<LabelItem[]>;
|
|
18
|
+
/**
|
|
19
|
+
* A single signed page of an account config's labels (issue #26), mirroring
|
|
20
|
+
* `IFilterRepository.listPageByAccountConfig` — the settings-page/API list.
|
|
21
|
+
*/
|
|
22
|
+
listPageByAccountConfig(
|
|
23
|
+
accountConfigId: string,
|
|
24
|
+
options?: { limit?: number; continuationToken?: string },
|
|
25
|
+
): Promise<ResultList<LabelItem>>;
|
|
17
26
|
findByNormalizedName(
|
|
18
27
|
accountConfigId: string,
|
|
19
28
|
normalizedName: string,
|
|
@@ -4,8 +4,22 @@ export interface IMessageLabelRepository {
|
|
|
4
4
|
apply(input: CreateMessageLabelInput): Promise<MessageLabelItem>;
|
|
5
5
|
remove(messageId: string, labelId: string): Promise<void>;
|
|
6
6
|
listByMessageId(messageId: string): Promise<MessageLabelItem[]>;
|
|
7
|
+
/**
|
|
8
|
+
* Batch-fetch every MessageLabel row across a page of messages in one query
|
|
9
|
+
* — the read-time enrichment a thread listing needs (issue #26), mirroring
|
|
10
|
+
* the one-BatchGet-per-page contract `enrichThreadRows` already holds for
|
|
11
|
+
* Message/Address.
|
|
12
|
+
*/
|
|
13
|
+
listByMessageIds(messageIds: string[]): Promise<MessageLabelItem[]>;
|
|
7
14
|
listByLabelId(
|
|
8
15
|
accountConfigId: string,
|
|
9
16
|
labelId: string,
|
|
10
17
|
): Promise<MessageLabelItem[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Delete every MessageLabel row for a label in one statement — the message
|
|
20
|
+
* side of a label delete's cascade (issue #26). A label delete cascades in
|
|
21
|
+
* both directions: this clears the applied-to-messages side, and the
|
|
22
|
+
* caller separately deletes any filter whose actionLabelId is this label.
|
|
23
|
+
*/
|
|
24
|
+
removeAllByLabelId(accountConfigId: string, labelId: string): Promise<void>;
|
|
11
25
|
}
|