Skip to content

Commit 2794649

Browse files
committed
Parse unions strictly
Unions must be objects with exactly one key set.
1 parent 53f79ea commit 2794649

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/integration/DocumentMemberDeserVisitor.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,13 +271,18 @@ public final String structureShape(StructureShape shape) {
271271

272272
@Override
273273
public final String unionShape(UnionShape shape) {
274-
return getDelegateDeserializer(shape);
274+
context.getWriter().addImport("expectUnion", "__expectUnion", "@aws-sdk/smithy-client");
275+
return getDelegateDeserializer(shape, "__expectUnion(" + dataSource + ")");
275276
}
276277

277278
private String getDelegateDeserializer(Shape shape) {
279+
return getDelegateDeserializer(shape, dataSource);
280+
}
281+
282+
private String getDelegateDeserializer(Shape shape, String customDataSource) {
278283
// Use the shape for the function name.
279284
Symbol symbol = context.getSymbolProvider().toSymbol(shape);
280285
return ProtocolGenerator.getDeserFunctionName(symbol, context.getProtocolName())
281-
+ "(" + dataSource + ", context)";
286+
+ "(" + customDataSource + ", context)";
282287
}
283288
}

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/integration/HttpBindingProtocolGenerator.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,10 +2281,16 @@ private HttpBinding readPayload(
22812281
} else if (target instanceof BlobShape) {
22822282
// If payload is non-streaming Blob, only need to collect stream to binary data (Uint8Array).
22832283
writer.write("const data: any = await collectBody(output.body, context);");
2284-
} else if (target instanceof StructureShape || target instanceof UnionShape) {
2285-
// If payload is Structure or Union, then we need to parse the string into JavaScript object.
2284+
} else if (target instanceof StructureShape) {
2285+
// If payload is a Structure, then we need to parse the string into JavaScript object.
22862286
writer.addImport("expectObject", "__expectObject", "@aws-sdk/smithy-client");
2287-
writer.write("const data: object | undefined = __expectObject(await parseBody(output.body, context));");
2287+
writer.write("const data: { [key: string]: any } | undefined "
2288+
+ "= __expectObject(await parseBody(output.body, context));");
2289+
} else if (target instanceof UnionShape) {
2290+
// If payload is a Union, then we need to parse the string into JavaScript object.
2291+
writer.addImport("expectUnion", "__expectUnion", "@aws-sdk/smithy-client");
2292+
writer.write("const data: { [key: string]: any } | undefined "
2293+
+ "= __expectUnion(await parseBody(output.body, context));");
22882294
} else if (target instanceof StringShape || target instanceof DocumentShape) {
22892295
// If payload is String or Document, we need to collect body and convert binary to string.
22902296
writer.write("const data: any = await collectBodyString(output.body, context);");

smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/integration/DocumentMemberDeserVisitorTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ public static Collection<Object[]> validMemberTargetTypes() {
9999
{SetShape.builder().id(id).member(member).build(), delegate, source},
100100
{MapShape.builder().id(id).key(key).value(value).build(), delegate, source},
101101
{StructureShape.builder().id(id).build(), delegate, source},
102-
{UnionShape.builder().id(id).addMember(member).build(), delegate, source},
103102
{
104103
TimestampShape.builder().id(id).build(),
105104
"__expectNonNull(__parseEpochTimestamp(" + DATA_SOURCE + "))",
@@ -115,6 +114,12 @@ public static Collection<Object[]> validMemberTargetTypes() {
115114
"__expectNonNull(__parseRfc7231DateTime(" + DATA_SOURCE + "))",
116115
source.toBuilder().addTrait(new TimestampFormatTrait(TimestampFormatTrait.HTTP_DATE)).build()
117116
},
117+
{
118+
UnionShape.builder().id(id).addMember(member).build(),
119+
"deserialize" + ProtocolGenerator.getSanitizedName(PROTOCOL) + "Foo"
120+
+ "(__expectUnion(" + DATA_SOURCE + "), context)",
121+
source
122+
},
118123
});
119124
}
120125

0 commit comments

Comments
 (0)