Skip to content

Commit 12adf84

Browse files
authored
feat: paginator factory (#1115)
1 parent 3eb09aa commit 12adf84

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

.changeset/big-kings-shop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@smithy/core": minor
3+
---
4+
5+
add paginator factory

packages/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from "./util-identity-and-auth";
44
export * from "./getSmithyContext";
55
export * from "./normalizeProvider";
66
export * from "./protocols/requestBuilder";
7+
export { createPaginator } from "./pagination/createPaginator";
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import type { Client, PaginationConfiguration, Paginator } from "@smithy/types";
2+
3+
/**
4+
* @internal
5+
*/
6+
const makePagedClientRequest = async <ClientType extends Client<any, any, any>, InputType, OutputType>(
7+
CommandCtor: any,
8+
client: ClientType,
9+
input: InputType,
10+
...args: any[]
11+
): Promise<OutputType> => {
12+
return await client.send(new CommandCtor(input), ...args);
13+
};
14+
15+
/**
16+
* @internal
17+
*
18+
* Creates a paginator.
19+
*/
20+
export function createPaginator<
21+
PaginationConfigType extends PaginationConfiguration,
22+
InputType extends object,
23+
OutputType extends object
24+
>(
25+
ClientCtor: any,
26+
CommandCtor: any,
27+
inputTokenName: string,
28+
outputTokenName: string,
29+
pageSizeTokenName?: string
30+
): (config: PaginationConfigType, input: InputType, ...additionalArguments: any[]) => Paginator<OutputType> {
31+
return async function* paginateOperation(
32+
config: PaginationConfigType,
33+
input: InputType,
34+
...additionalArguments: any[]
35+
): Paginator<OutputType> {
36+
let token: any = config.startingToken || undefined;
37+
let hasNext = true;
38+
let page: OutputType;
39+
40+
while (hasNext) {
41+
(input as any)[inputTokenName] = token;
42+
if (pageSizeTokenName) {
43+
(input as any)[pageSizeTokenName] = (input as any)[pageSizeTokenName] ?? config.pageSize;
44+
}
45+
if (config.client instanceof ClientCtor) {
46+
page = await makePagedClientRequest(CommandCtor, config.client, input, ...additionalArguments);
47+
} else {
48+
throw new Error(`Invalid client, expected instance of ${ClientCtor.name}`);
49+
}
50+
yield page;
51+
const prevToken = token;
52+
token = (page as any)[outputTokenName];
53+
hasNext = !!(token && (!config.stopOnSameToken || token !== prevToken));
54+
}
55+
// @ts-ignore
56+
return undefined;
57+
};
58+
}

0 commit comments

Comments
 (0)