28
28
import software .amazon .smithy .model .knowledge .PaginatedIndex ;
29
29
import software .amazon .smithy .model .knowledge .PaginationInfo ;
30
30
import software .amazon .smithy .model .knowledge .TopDownIndex ;
31
+ import software .amazon .smithy .model .shapes .MemberShape ;
31
32
import software .amazon .smithy .model .shapes .OperationShape ;
32
33
import software .amazon .smithy .model .shapes .ServiceShape ;
33
34
import software .amazon .smithy .model .traits .PaginatedTrait ;
@@ -41,6 +42,7 @@ final class PaginationGenerator implements Runnable {
41
42
Paths .get (CodegenUtils .SOURCE_FOLDER , PAGINATION_FOLDER , "Interfaces.ts" ).toString ();
42
43
43
44
private final TypeScriptWriter writer ;
45
+ private final String aggregatedClientName ;
44
46
private final PaginationInfo paginatedInfo ;
45
47
46
48
private final Symbol serviceSymbol ;
@@ -49,8 +51,6 @@ final class PaginationGenerator implements Runnable {
49
51
private final Symbol outputSymbol ;
50
52
51
53
private final String operationName ;
52
- private final String methodName ;
53
- private final String aggregatedClientName ;
54
54
private final String paginationType ;
55
55
56
56
PaginationGenerator (
@@ -63,18 +63,16 @@ final class PaginationGenerator implements Runnable {
63
63
) {
64
64
65
65
this .writer = writer ;
66
+ this .aggregatedClientName = aggregatedClientName ;
66
67
67
68
this .serviceSymbol = symbolProvider .toSymbol (service );
68
69
this .operationSymbol = symbolProvider .toSymbol (operation );
69
70
this .inputSymbol = symbolProvider .toSymbol (operation ).expectProperty ("inputType" , Symbol .class );
70
71
this .outputSymbol = symbolProvider .toSymbol (operation ).expectProperty ("outputType" , Symbol .class );
71
72
72
73
this .operationName = operation .getId ().getName ();
73
- this .aggregatedClientName = aggregatedClientName ;
74
74
75
- // e.g. listObjects
76
- this .methodName = Character .toLowerCase (operationName .charAt (0 )) + operationName .substring (1 );
77
- this .paginationType = this .aggregatedClientName + "PaginationConfiguration" ;
75
+ this .paginationType = aggregatedClientName + "PaginationConfiguration" ;
78
76
79
77
PaginatedIndex paginatedIndex = PaginatedIndex .of (model );
80
78
Optional <PaginationInfo > paginationInfo = paginatedIndex .getPaginationInfo (service , operation );
@@ -103,7 +101,6 @@ public void run() {
103
101
writer .addRelativeImport (paginationType , paginationType ,
104
102
Paths .get ("." , PAGINATION_INTERFACE_FILE .replace (".ts" , "" )));
105
103
106
- writeCommandRequest ();
107
104
writePager ();
108
105
}
109
106
@@ -155,10 +152,6 @@ static void writeIndex(
155
152
writer .toString ());
156
153
}
157
154
158
- private String destructurePath (String path ) {
159
- return "." + path .replace ("." , "!." );
160
- }
161
-
162
155
private void writePager () {
163
156
String serviceTypeName = serviceSymbol .getName ();
164
157
String inputTypeName = inputSymbol .getName ();
@@ -167,57 +160,42 @@ private void writePager() {
167
160
String inputTokenName = paginatedInfo .getPaginatedTrait ().getInputToken ().get ();
168
161
String outputTokenName = paginatedInfo .getPaginatedTrait ().getOutputToken ().get ();
169
162
170
- writer .writeDocs ("@public" )
171
- .openBlock (
172
- "export async function* paginate$L(config: $L, input: $L, ...additionalArguments: any): Paginator<$L>{" ,
173
- "}" , operationName , paginationType , inputTypeName , outputTypeName , () -> {
174
- String destructuredInputTokenName = destructurePath (inputTokenName );
175
- writer .write ("// ToDo: replace with actual type instead of typeof input$L" , destructuredInputTokenName );
176
- writer .write ("let token: typeof input$L | undefined = config.startingToken || undefined;" ,
177
- destructuredInputTokenName );
178
-
179
- writer .write ("let hasNext = true;" );
180
- writer .write ("let page: $L;" , outputTypeName );
181
- writer .openBlock ("while (hasNext) {" , "}" , () -> {
182
- writer .write ("input$L = token;" , destructuredInputTokenName );
183
-
184
- if (paginatedInfo .getPageSizeMember ().isPresent ()) {
185
- String pageSize = paginatedInfo .getPageSizeMember ().get ().getMemberName ();
186
- writer .write ("input[$S] = config.pageSize;" , pageSize );
187
- }
188
-
189
- writer .openBlock ("if (config.client instanceof $L) {" , "}" , serviceTypeName , () -> {
190
- writer .write ("page = await makePagedClientRequest(config.client, input, ...additionalArguments);" );
191
- });
192
- writer .openBlock ("else {" , "}" , () -> {
193
- writer .write ("throw new Error(\" Invalid client, expected $L | $L\" );" ,
194
- aggregatedClientName , serviceTypeName );
195
- });
196
-
197
- writer .write ("yield page;" );
198
- writer .write ("const prevToken = token;" );
199
- writer .write ("token = page$L;" , destructurePath (outputTokenName ));
200
- writer .write ("hasNext = !!(token && (!config.stopOnSameToken || token !== prevToken));" );
201
- });
202
-
203
- writer .write ("// @ts-ignore" );
204
- writer .write ("return undefined;" );
205
- });
206
- }
207
-
208
-
209
- /**
210
- * Paginated command that calls CommandClient().send({...}) under the hood. This is meant for client side (browser)
211
- * environments and does not generally expose the entire service.
212
- */
213
- private void writeCommandRequest () {
214
- writer .writeDocs ("@internal" );
215
- writer .openBlock (
216
- "const makePagedClientRequest = async (client: $L, input: $L, ...args: any): Promise<$L> => {" ,
217
- "}" , serviceSymbol .getName (), inputSymbol .getName (),
218
- outputSymbol .getName (), () -> {
219
- writer .write ("// @ts-ignore" );
220
- writer .write ("return await client.send(new $L(input), ...args);" , operationSymbol .getName ());
221
- });
163
+ writer .addDependency (TypeScriptDependency .SMITHY_CORE );
164
+ writer .addImport ("createPaginator" , null , TypeScriptDependency .SMITHY_CORE );
165
+
166
+ writer .writeDocs ("@public" );
167
+
168
+ writer
169
+ .pushState ()
170
+ .putContext ("operation" , operationName )
171
+ .putContext ("aggClient" , aggregatedClientName )
172
+ .putContext ("inputType" , inputTypeName )
173
+ .putContext ("outputType" , outputTypeName )
174
+ .putContext ("paginationType" , paginationType )
175
+ .putContext ("serviceTypeName" , serviceTypeName )
176
+ .putContext ("operationName" , operationSymbol .getName ())
177
+ .putContext ("inputToken" , inputTokenName )
178
+ .putContext ("outputToken" , outputTokenName )
179
+ .putContext (
180
+ "pageSizeMember" ,
181
+ paginatedInfo .getPageSizeMember ().map (MemberShape ::getMemberName ).orElse ("" )
182
+ )
183
+ .write (
184
+ """
185
+ export const paginate${operation:L}: (
186
+ config: ${aggClient:L}PaginationConfiguration,
187
+ input: ${inputType:L},
188
+ ...rest: any[]
189
+ ) => Paginator<${outputType:L}> =
190
+ createPaginator<${paginationType:L}, ${inputType:L}, ${outputType:L}>(
191
+ ${serviceTypeName:L},
192
+ ${operationName:L},
193
+ ${inputToken:S},
194
+ ${outputToken:S},
195
+ ${pageSizeMember:S}
196
+ );
197
+ """
198
+ )
199
+ .popState ();
222
200
}
223
201
}
0 commit comments