@@ -299,36 +299,55 @@ private boolean writeRequestQueryString(
299
299
HttpTrait trait
300
300
) {
301
301
TypeScriptWriter writer = context .getWriter ();
302
- SymbolProvider symbolProvider = context .getSymbolProvider ();
303
302
List <HttpBinding > queryBindings = bindingIndex .getRequestBindings (operation , Location .QUERY );
303
+ List <HttpBinding > queryParamsBindings = bindingIndex .getRequestBindings (operation , Location .QUERY_PARAMS );
304
304
305
305
// Build the initial query bag.
306
306
Map <String , String > queryLiterals = trait .getUri ().getQueryLiterals ();
307
- if (!queryLiterals .isEmpty () || !queryBindings .isEmpty ()) {
307
+ if (!queryLiterals .isEmpty () || !queryBindings .isEmpty () || ! queryParamsBindings . isEmpty () ) {
308
308
writer .openBlock ("const query: any = {" , "};" , () -> {
309
309
if (!queryLiterals .isEmpty ()) {
310
310
// Write any query literals present in the uri.
311
311
queryLiterals .forEach ((k , v ) -> writer .write ("$S: $S," , k , v ));
312
312
}
313
+ // Handle any additional query params bindings.
314
+ // If query string parameter is also present in httpQuery, it would be overwritten.
315
+ // Serializing HTTP messages https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html#serializing-http-messages
316
+ if (!queryParamsBindings .isEmpty ()) {
317
+ SymbolProvider symbolProvider = context .getSymbolProvider ();
318
+ String memberName = symbolProvider .toMemberName (queryParamsBindings .get (0 ).getMember ());
319
+ writer .write ("...(input.$1L !== undefined && input.$1L)," , memberName );
320
+ }
313
321
// Handle any additional query bindings.
314
322
if (!queryBindings .isEmpty ()) {
315
- Model model = context .getModel ();
316
323
for (HttpBinding binding : queryBindings ) {
317
- String memberName = symbolProvider .toMemberName (binding .getMember ());
318
- writer .addImport ("extendedEncodeURIComponent" , "__extendedEncodeURIComponent" ,
319
- "@aws-sdk/smithy-client" );
320
- Shape target = model .expectShape (binding .getMember ().getTarget ());
321
- String queryValue = getInputValue (context , binding .getLocation (), "input." + memberName ,
322
- binding .getMember (), target );
323
- writer .write ("...(input.$L !== undefined && { $S: $L })," , memberName ,
324
- binding .getLocationName (), queryValue );
324
+ writeRequestQueryParam (context , binding );
325
325
}
326
326
}
327
327
});
328
328
}
329
329
330
330
// Any binding or literal means we generated a query bag.
331
- return !queryBindings .isEmpty () || !queryLiterals .isEmpty ();
331
+ return !queryBindings .isEmpty () || !queryLiterals .isEmpty () || !queryParamsBindings .isEmpty ();
332
+ }
333
+
334
+ private void writeRequestQueryParam (
335
+ GenerationContext context ,
336
+ HttpBinding binding
337
+ ) {
338
+ Model model = context .getModel ();
339
+ TypeScriptWriter writer = context .getWriter ();
340
+ SymbolProvider symbolProvider = context .getSymbolProvider ();
341
+
342
+ String memberName = symbolProvider .toMemberName (binding .getMember ());
343
+ writer .addImport ("extendedEncodeURIComponent" , "__extendedEncodeURIComponent" ,
344
+ "@aws-sdk/smithy-client" );
345
+
346
+ Shape target = model .expectShape (binding .getMember ().getTarget ());
347
+ String queryValue = getInputValue (context , binding .getLocation (), "input." + memberName ,
348
+ binding .getMember (), target );
349
+ writer .write ("...(input.$L !== undefined && { $S: $L })," , memberName ,
350
+ binding .getLocationName (), queryValue );
332
351
}
333
352
334
353
private void writeHeaders (
@@ -454,6 +473,8 @@ protected String getInputValue(
454
473
return getCollectionInputParam (context , bindingType , dataSource , (CollectionShape ) target );
455
474
} else if (target instanceof StructureShape || target instanceof UnionShape ) {
456
475
return getNamedMembersInputParam (context , bindingType , dataSource , target );
476
+ } else if (target instanceof MapShape ) {
477
+ return getMapInputParam (context , bindingType , dataSource , (MapShape ) target );
457
478
}
458
479
459
480
throw new CodegenException (String .format (
@@ -544,6 +565,7 @@ private String getCollectionInputParam(
544
565
case HEADER :
545
566
return iteratedParam + ".join(', ')" ;
546
567
case QUERY :
568
+ case QUERY_PARAMS :
547
569
return iteratedParam ;
548
570
default :
549
571
throw new CodegenException ("Unexpected collection binding location `" + bindingType + "`" );
@@ -587,6 +609,36 @@ private String getNamedMembersInputParam(
587
609
}
588
610
}
589
611
612
+ /**
613
+ * Given context and a source of data, generate an input value provider for the
614
+ * map.
615
+ *
616
+ * @param context The generation context.
617
+ * @param bindingType How this value is bound to the operation input.
618
+ * @param dataSource The in-code location of the data to provide an input of
619
+ * ({@code input.foo}, {@code entry}, etc.)
620
+ * @param target The shape of the value being provided.
621
+ * @return Returns a value or expression of the input collection.
622
+ */
623
+ private String getMapInputParam (
624
+ GenerationContext context ,
625
+ Location bindingType ,
626
+ String dataSource ,
627
+ MapShape target
628
+ ) {
629
+ Model model = context .getModel ();
630
+ MemberShape mapMember = target .getValue ();
631
+ SymbolProvider symbolProvider = context .getSymbolProvider ();
632
+
633
+ String valueString = getInputValue (context , bindingType , "value" , mapMember ,
634
+ model .expectShape (mapMember .getTarget ()));
635
+ return "Object.entries(" + dataSource + " || {}).reduce("
636
+ + "(acc: any, [key, value]: [string, " + symbolProvider .toSymbol (mapMember ) + "]) => ({"
637
+ + "...acc,"
638
+ + "[key]: " + valueString + ","
639
+ + "}), {})" ;
640
+ }
641
+
590
642
/**
591
643
* Given context and a source of data, generate an input value provider for the
592
644
* shape. This uses the format specified, converting to strings when in a header,
0 commit comments