@remit/drizzle-service 0.0.71 → 0.0.72
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/repos/i4-address.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
desc,
|
|
19
19
|
eq,
|
|
20
20
|
getTableColumns,
|
|
21
|
+
gt,
|
|
21
22
|
inArray,
|
|
22
23
|
type SQL,
|
|
23
24
|
sql,
|
|
@@ -748,6 +749,40 @@ export class AddressRepo implements IAddressRepository {
|
|
|
748
749
|
);
|
|
749
750
|
}
|
|
750
751
|
|
|
752
|
+
async listAllByAccountConfigPage(input: {
|
|
753
|
+
accountConfigId: string;
|
|
754
|
+
cursor?: string;
|
|
755
|
+
limit?: number;
|
|
756
|
+
}): Promise<ResultList<AddressItem>> {
|
|
757
|
+
const { accountConfigId, cursor, limit = 100 } = input;
|
|
758
|
+
const afterAddressId = cursor
|
|
759
|
+
? (decodeToken(cursor).addressId as string)
|
|
760
|
+
: undefined;
|
|
761
|
+
|
|
762
|
+
const rows = await this.db
|
|
763
|
+
.select()
|
|
764
|
+
.from(addressTable)
|
|
765
|
+
.where(
|
|
766
|
+
and(
|
|
767
|
+
eq(addressTable.accountConfigId, accountConfigId),
|
|
768
|
+
afterAddressId
|
|
769
|
+
? gt(addressTable.addressId, afterAddressId)
|
|
770
|
+
: undefined,
|
|
771
|
+
),
|
|
772
|
+
)
|
|
773
|
+
.orderBy(asc(addressTable.addressId))
|
|
774
|
+
.limit(limit + 1);
|
|
775
|
+
|
|
776
|
+
const hasMore = rows.length > limit;
|
|
777
|
+
const items = rows.slice(0, limit).map(rowToAddress);
|
|
778
|
+
const lastItem = items[items.length - 1];
|
|
779
|
+
return resultList(
|
|
780
|
+
items,
|
|
781
|
+
limit,
|
|
782
|
+
hasMore && lastItem ? { addressId: lastItem.addressId } : undefined,
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
|
|
751
786
|
async createEnvelopeAddress(
|
|
752
787
|
input: CreateEnvelopeAddressInput,
|
|
753
788
|
): Promise<EnvelopeAddressItem> {
|
|
@@ -224,6 +224,59 @@ describe("OutboxMessageRepo", () => {
|
|
|
224
224
|
await repo.deleteMany(accountConfigId, created);
|
|
225
225
|
});
|
|
226
226
|
|
|
227
|
+
test("listByAccounts pages one ordering over every account (#1013)", async () => {
|
|
228
|
+
const accountConfigId = randomId();
|
|
229
|
+
const first = randomId();
|
|
230
|
+
const second = randomId();
|
|
231
|
+
const created: string[] = [];
|
|
232
|
+
const byAccount = new Map<string, string[]>([
|
|
233
|
+
[first, []],
|
|
234
|
+
[second, []],
|
|
235
|
+
]);
|
|
236
|
+
for (let i = 0; i < 6; i++) {
|
|
237
|
+
const accountId = i % 2 === 0 ? first : second;
|
|
238
|
+
const msg = await repo.create(
|
|
239
|
+
makeOutboxInput(accountId, accountConfigId),
|
|
240
|
+
);
|
|
241
|
+
created.push(msg.outboxMessageId);
|
|
242
|
+
byAccount.get(accountId)?.push(msg.outboxMessageId);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const wholeList = await repo.listByAccounts([first, second]);
|
|
246
|
+
const wholeIds = wholeList.items.map((m) => m.outboxMessageId);
|
|
247
|
+
for (const ids of byAccount.values()) {
|
|
248
|
+
for (const id of ids) {
|
|
249
|
+
assert.ok(wholeIds.includes(id), "every account's rows come back");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const seen: string[] = [];
|
|
254
|
+
let continuationToken: string | undefined;
|
|
255
|
+
let pages = 0;
|
|
256
|
+
do {
|
|
257
|
+
const page = await repo.listByAccounts([first, second], {
|
|
258
|
+
limit: 2,
|
|
259
|
+
continuationToken,
|
|
260
|
+
});
|
|
261
|
+
seen.push(...page.items.map((m) => m.outboxMessageId));
|
|
262
|
+
continuationToken = page.continuationToken;
|
|
263
|
+
pages++;
|
|
264
|
+
assert.ok(pages < 10, "pagination must terminate");
|
|
265
|
+
} while (continuationToken);
|
|
266
|
+
|
|
267
|
+
assert.equal(seen.length, 6, "every row returned exactly once");
|
|
268
|
+
assert.equal(new Set(seen).size, 6, "no duplicates across pages");
|
|
269
|
+
assert.deepEqual([...seen].sort(), [...created].sort(), "no gaps");
|
|
270
|
+
|
|
271
|
+
await repo.deleteMany(accountConfigId, created);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
test("listByAccounts answers no accounts with no rows", async () => {
|
|
275
|
+
const list = await repo.listByAccounts([]);
|
|
276
|
+
assert.deepEqual(list.items, []);
|
|
277
|
+
assert.equal(list.continuationToken, undefined);
|
|
278
|
+
});
|
|
279
|
+
|
|
227
280
|
test("listQueued returns only queued messages", async () => {
|
|
228
281
|
const accountId = randomId();
|
|
229
282
|
const accountConfigId = randomId();
|
|
@@ -272,8 +272,17 @@ export class OutboxMessageRepo implements IOutboxMessageRepository {
|
|
|
272
272
|
async listByAccount(
|
|
273
273
|
accountId: string,
|
|
274
274
|
options?: { limit?: number; continuationToken?: string },
|
|
275
|
+
): Promise<ResultList<OutboxMessageItem>> {
|
|
276
|
+
return this.listByAccounts([accountId], options);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
async listByAccounts(
|
|
280
|
+
accountIds: string[],
|
|
281
|
+
options?: { limit?: number; continuationToken?: string },
|
|
275
282
|
): Promise<ResultList<OutboxMessageItem>> {
|
|
276
283
|
const limit = options?.limit ?? 100;
|
|
284
|
+
if (accountIds.length === 0) return resultList([], limit);
|
|
285
|
+
|
|
277
286
|
const cursor = options?.continuationToken
|
|
278
287
|
? decodeToken(options.continuationToken)
|
|
279
288
|
: undefined;
|
|
@@ -289,7 +298,7 @@ export class OutboxMessageRepo implements IOutboxMessageRepository {
|
|
|
289
298
|
.from(outboxMessageTable)
|
|
290
299
|
.where(
|
|
291
300
|
and(
|
|
292
|
-
|
|
301
|
+
inArray(outboxMessageTable.accountId, accountIds),
|
|
293
302
|
after
|
|
294
303
|
? or(
|
|
295
304
|
lt(outboxMessageTable.createdAt, after.createdAt),
|