@@ -735,31 +735,30 @@ private void writeResolvedPath(
735
735
736
736
// Handle any label bindings.
737
737
if (!labelBindings .isEmpty ()) {
738
+ writer .addImport ("resolvedPath" , "__resolvedPath" , "@aws-sdk/smithy-client" );
739
+
738
740
Model model = context .getModel ();
739
741
List <Segment > uriLabels = trait .getUri ().getLabels ();
740
742
for (HttpBinding binding : labelBindings ) {
741
743
String memberName = symbolProvider .toMemberName (binding .getMember ());
742
744
Shape target = model .expectShape (binding .getMember ().getTarget ());
743
- String labelValue = getInputValue (context , binding .getLocation (), "input." + memberName ,
744
- binding .getMember (), target );
745
+
746
+ String labelValueProvider = "() => " + getInputValue (
747
+ context ,
748
+ binding .getLocation (),
749
+ "input." + memberName + "!" ,
750
+ binding .getMember (),
751
+ target
752
+ );
753
+
745
754
// Get the correct label to use.
746
755
Segment uriLabel = uriLabels .stream ().filter (s -> s .getContent ().equals (memberName )).findFirst ().get ();
747
- writer .addImport ("extendedEncodeURIComponent" , "__extendedEncodeURIComponent" ,
748
- "@aws-sdk/smithy-client" );
749
- String encodedSegment = uriLabel .isGreedyLabel ()
750
- ? "labelValue.split(\" /\" ).map(segment => __extendedEncodeURIComponent(segment)).join(\" /\" )"
751
- : "__extendedEncodeURIComponent(labelValue)" ;
752
-
753
- // Set the label's value and throw a clear error if empty or undefined.
754
- writer .write ("if (input.$L !== undefined) {" , memberName ).indent ()
755
- .write ("const labelValue: string = $L;" , labelValue )
756
- .openBlock ("if (labelValue.length <= 0) {" , "}" , () -> {
757
- writer .write ("throw new Error('Empty value provided for input HTTP label: $L.');" , memberName );
758
- })
759
- .write ("resolvedPath = resolvedPath.replace($S, $L);" , uriLabel .toString (), encodedSegment ).dedent ()
760
- .write ("} else {" ).indent ()
761
- .write ("throw new Error('No value provided for input HTTP label: $L.');" , memberName ).dedent ()
762
- .write ("}" );
756
+ writer .write ("resolvedPath = __resolvedPath(resolvedPath, input, '$L', $L, '$L', $L)" ,
757
+ memberName ,
758
+ labelValueProvider ,
759
+ uriLabel .toString (),
760
+ uriLabel .isGreedyLabel () ? "true" : "false"
761
+ );
763
762
}
764
763
}
765
764
}
@@ -1650,11 +1649,11 @@ private void generateOperationRequestDeserializer(
1650
1649
.forEach ((memberName , memberShape ) -> writer .write (
1651
1650
"$L: undefined," , memberName ));
1652
1651
});
1652
+ readRequestHeaders (context , operation , bindingIndex , "output" );
1653
1653
});
1654
1654
readQueryString (context , operation , bindingIndex );
1655
1655
readPath (context , operation , bindingIndex , trait );
1656
1656
readHost (context , operation );
1657
- readRequestHeaders (context , operation , bindingIndex , "output" );
1658
1657
List <HttpBinding > documentBindings = readRequestBody (context , operation , bindingIndex );
1659
1658
// Track all shapes bound to the document so their deserializers may be generated.
1660
1659
documentBindings .forEach (binding -> {
@@ -1703,7 +1702,7 @@ private void handleContentType(
1703
1702
operation , getDocumentContentType ());
1704
1703
writer .write ("const contentTypeHeaderKey: string | undefined = Object.keys(output.headers)"
1705
1704
+ ".find(key => key.toLowerCase() === 'content-type');" );
1706
- writer .openBlock ("if (contentTypeHeaderKey !== undefined && contentTypeHeaderKey !== null) {" , "};" , () -> {
1705
+ writer .openBlock ("if (contentTypeHeaderKey != null) {" , "};" , () -> {
1707
1706
writer .write ("const contentType = output.headers[contentTypeHeaderKey];" );
1708
1707
if (optionalContentType .isPresent () || operation .getInput ().isPresent ()) {
1709
1708
String contentType = optionalContentType .orElse (getDocumentContentType ());
@@ -1758,7 +1757,7 @@ private void handleAccept(
1758
1757
writer .addImport ("acceptMatches" , "__acceptMatches" , "@aws-smithy/server-common" );
1759
1758
writer .write ("const acceptHeaderKey: string | undefined = Object.keys(output.headers)"
1760
1759
+ ".find(key => key.toLowerCase() === 'accept');" );
1761
- writer .openBlock ("if (acceptHeaderKey !== undefined && acceptHeaderKey !== null) {" , "};" , () -> {
1760
+ writer .openBlock ("if (acceptHeaderKey != null) {" , "};" , () -> {
1762
1761
writer .write ("const accept = output.headers[acceptHeaderKey];" );
1763
1762
String contentType = optionalContentType .orElse (getDocumentContentType ());
1764
1763
// Validate that the content type matches the protocol default, or what's modeled if there's
@@ -1793,7 +1792,7 @@ private void readQueryString(
1793
1792
return ;
1794
1793
}
1795
1794
writer .write ("const query = output.query" );
1796
- writer .openBlock ("if (query !== undefined && query !== null) {" , "}" , () -> {
1795
+ writer .openBlock ("if (query != null) {" , "}" , () -> {
1797
1796
readDirectQueryBindings (context , directQueryBindings );
1798
1797
if (!mappedQueryBindings .isEmpty ()) {
1799
1798
// There can only ever be one of these bindings on a given operation.
@@ -2041,8 +2040,10 @@ private void generateErrorDeserializer(GenerationContext context, StructureShape
2041
2040
+ " context: __SerdeContext\n "
2042
2041
+ "): Promise<$T> => {" , "};" ,
2043
2042
errorDeserMethodName , outputName , errorSymbol , () -> {
2044
- writer .write ("const contents: any = {};" );
2045
- readResponseHeaders (context , error , bindingIndex , outputName );
2043
+ writer .openBlock ("const contents: any = map({" , "});" , () -> {
2044
+ readResponseHeaders (context , error , bindingIndex , outputName );
2045
+ });
2046
+
2046
2047
List <HttpBinding > documentBindings = readErrorResponseBody (context , error , bindingIndex );
2047
2048
// Track all shapes bound to the document so their deserializers may be generated.
2048
2049
documentBindings .forEach (binding -> {
@@ -2159,26 +2160,27 @@ private void readPrefixHeaders(
2159
2160
TypeScriptWriter writer = context .getWriter ();
2160
2161
2161
2162
// Run through the headers one time, matching any prefix groups.
2162
- writer .openBlock ("...(Object.keys($L.headers).reduce((acc, header) => {" , "}, {}));" , outputName , () -> {
2163
- for (HttpBinding binding : prefixHeaderBindings ) {
2164
- // Prepare a grab bag for these headers if necessary
2165
- String memberName = symbolProvider .toMemberName (binding .getMember ());
2166
- writer .write ("acc.$L = [, {}];" , memberName );
2167
-
2168
- // Generate a single block for each group of lower-cased prefix headers.
2163
+ for (HttpBinding binding : prefixHeaderBindings ) {
2164
+ // Prepare a grab bag for these headers if necessary
2165
+ String memberName = symbolProvider .toMemberName (binding .getMember ());
2166
+ writer .openBlock ("$L: [, " , "]," , memberName , () -> {
2169
2167
String headerLocation = binding .getLocationName ().toLowerCase (Locale .US );
2170
- writer .openBlock ("if (header.startsWith($S)) {" , "}" , headerLocation , () -> {
2168
+ writer .write (
2169
+ "Object.keys($L.headers).filter(header => header.startsWith('$L'))" ,
2170
+ outputName ,
2171
+ headerLocation
2172
+ );
2173
+ writer .indent ().openBlock (".reduce((acc, header) => {" , "}, {} as any)" , () -> {
2171
2174
MapShape prefixMap = model .expectShape (binding .getMember ().getTarget ()).asMapShape ().get ();
2172
2175
Shape target = model .expectShape (prefixMap .getValue ().getTarget ());
2173
2176
String headerValue = getOutputValue (context , binding .getLocation (),
2174
- outputName + ".headers[header]" , binding .getMember (), target );
2175
-
2176
- // Extract the non-prefix portion as the key.
2177
- writer .write ("acc.$L[header.substring($L)] = [, $L];" ,
2178
- memberName , headerLocation .length (), headerValue );
2177
+ outputName + ".headers[header]" , binding .getMember (), target );
2178
+ writer .write ("acc[header.substring($L)] = $L;" ,
2179
+ headerLocation .length (), headerValue );
2180
+ writer .write ("return acc;" );
2179
2181
});
2180
- }
2181
- });
2182
+ });
2183
+ }
2182
2184
}
2183
2185
2184
2186
private List <HttpBinding > readRequestBody (
@@ -2253,12 +2255,17 @@ private List<HttpBinding> readBody(
2253
2255
// isn't set in the body.
2254
2256
// These are only relevant when a payload is not present, as it cannot
2255
2257
// coexist with a payload.
2256
- for (HttpBinding responseCodeBinding : responseCodeBindings ) {
2257
- // The name of the member to get from the input shape.
2258
- String memberName = symbolProvider .toMemberName (responseCodeBinding .getMember ());
2259
- writer .openBlock ("if (contents.$L === undefined) {" , "}" , memberName , () ->
2260
- writer .write ("contents.$L = output.statusCode;" , memberName ));
2258
+ if (!responseCodeBindings .isEmpty ()) {
2259
+ writer .openBlock ("map(contents, {" , "});" , () -> {
2260
+ for (HttpBinding responseCodeBinding : responseCodeBindings ) {
2261
+ // The name of the member to get from the input shape.
2262
+ String memberName = symbolProvider .toMemberName (responseCodeBinding .getMember ());
2263
+
2264
+ writer .write ("$L: [, output.statusCode]" , memberName );
2265
+ }
2266
+ });
2261
2267
}
2268
+
2262
2269
if (!documentBindings .isEmpty ()) {
2263
2270
return documentBindings ;
2264
2271
}
0 commit comments