Skip to content

Commit bdd942e

Browse files
authored
feat: support httpChecksumRequired trait (#363)
1 parent 78851a7 commit bdd942e

File tree

3 files changed

+152
-1
lines changed

3 files changed

+152
-1
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptDependency.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ public enum TypeScriptDependency implements SymbolDependencyContainer {
5959

6060
AWS_SDK_UTIL_WAITERS("dependencies", "@aws-sdk/util-waiter", SdkVersion.LIVE, false),
6161

62+
// Conditionally added when httpChecksumRequired trait exists
63+
MD5_BROWSER("dependencies", "@aws-sdk/md5-js", SdkVersion.LIVE, false),
64+
STREAM_HASHER_NODE("dependencies", "@aws-sdk/hash-stream-node", SdkVersion.LIVE, false),
65+
STREAM_HASHER_BROWSER("dependencies", "@aws-sdk/hash-blob-browser", SdkVersion.LIVE, false),
66+
BODY_CHECKSUM("dependencies", "@aws-sdk/middleware-apply-body-checksum", SdkVersion.LIVE, false),
67+
6268
// Conditionally added when using an HTTP application protocol.
6369
AWS_SDK_PROTOCOL_HTTP("dependencies", "@aws-sdk/protocol-http", SdkVersion.LIVE, false),
6470
AWS_SDK_FETCH_HTTP_HANDLER("dependencies", "@aws-sdk/fetch-http-handler", SdkVersion.LIVE, false),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*
2+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.smithy.typescript.codegen.integration;
17+
18+
import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_MIDDLEWARE;
19+
20+
import java.util.Collections;
21+
import java.util.List;
22+
import java.util.Map;
23+
import java.util.Set;
24+
import java.util.function.Consumer;
25+
import software.amazon.smithy.codegen.core.SymbolProvider;
26+
import software.amazon.smithy.model.Model;
27+
import software.amazon.smithy.model.knowledge.TopDownIndex;
28+
import software.amazon.smithy.model.shapes.OperationShape;
29+
import software.amazon.smithy.model.shapes.ServiceShape;
30+
import software.amazon.smithy.model.traits.HttpChecksumRequiredTrait;
31+
import software.amazon.smithy.typescript.codegen.LanguageTarget;
32+
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
33+
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
34+
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
35+
import software.amazon.smithy.utils.ListUtils;
36+
import software.amazon.smithy.utils.MapUtils;
37+
import software.amazon.smithy.utils.SmithyInternalApi;
38+
39+
/**
40+
* Adds md5 checksum dependencies if needed.
41+
*/
42+
@SmithyInternalApi
43+
public final class AddChecksumRequiredDependency implements TypeScriptIntegration {
44+
45+
@Override
46+
public void addConfigInterfaceFields(
47+
TypeScriptSettings settings,
48+
Model model,
49+
SymbolProvider symbolProvider,
50+
TypeScriptWriter writer
51+
) {
52+
if (!hasMd5Dependency(model, settings.getService(model))) {
53+
return;
54+
}
55+
56+
writer.addImport("Readable", "Readable", "stream");
57+
writer.addImport("StreamHasher", "__StreamHasher", "@aws-sdk/types");
58+
writer.writeDocs("A function that, given a hash constructor and a stream, calculates the \n"
59+
+ "hash of the streamed value.\n"
60+
+ "@internal");
61+
writer.write("streamHasher?: __StreamHasher<Readable> | __StreamHasher<Blob>;\n");
62+
63+
writer.addImport("HashConstructor", "__HashConstructor", "@aws-sdk/types");
64+
writer.writeDocs("A constructor for a class implementing the @aws-sdk/types.Hash interface \n"
65+
+ "that computes MD5 hashes.\n"
66+
+ "@internal");
67+
writer.write("md5?: __HashConstructor;\n");
68+
}
69+
70+
@Override
71+
public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
72+
TypeScriptSettings settings,
73+
Model model,
74+
SymbolProvider symbolProvider,
75+
LanguageTarget target
76+
) {
77+
if (!hasMd5Dependency(model, settings.getService(model))) {
78+
return Collections.emptyMap();
79+
}
80+
81+
switch (target) {
82+
case NODE:
83+
return MapUtils.of(
84+
"streamHasher", writer -> {
85+
writer.addDependency(TypeScriptDependency.STREAM_HASHER_NODE);
86+
writer.addImport("fileStreamHasher", "streamHasher",
87+
TypeScriptDependency.STREAM_HASHER_NODE.packageName);
88+
writer.write("streamHasher,");
89+
},
90+
"md5", writer -> {
91+
writer.addDependency(TypeScriptDependency.AWS_SDK_TYPES);
92+
writer.addImport("HashConstructor", "__HashConstructor",
93+
TypeScriptDependency.AWS_SDK_TYPES.packageName);
94+
writer.write("md5: Hash.bind(null, \"md5\"),");
95+
});
96+
case BROWSER:
97+
return MapUtils.of(
98+
"streamHasher", writer -> {
99+
writer.addDependency(TypeScriptDependency.STREAM_HASHER_BROWSER);
100+
writer.addImport("blobHasher", "streamHasher",
101+
TypeScriptDependency.STREAM_HASHER_BROWSER.packageName);
102+
writer.write("streamHasher,");
103+
},
104+
"md5", writer -> {
105+
writer.addDependency(TypeScriptDependency.MD5_BROWSER);
106+
writer.addImport("Md5", "Md5", TypeScriptDependency.MD5_BROWSER.packageName);
107+
writer.write("md5: Md5,");
108+
});
109+
default:
110+
return Collections.emptyMap();
111+
}
112+
}
113+
114+
@Override
115+
public List<RuntimeClientPlugin> getClientPlugins() {
116+
return ListUtils.of(
117+
RuntimeClientPlugin.builder()
118+
.withConventions(TypeScriptDependency.BODY_CHECKSUM.dependency, "ApplyMd5BodyChecksum",
119+
HAS_MIDDLEWARE)
120+
.operationPredicate((m, s, o) -> hasChecksumRequiredTrait(m, s, o))
121+
.build()
122+
);
123+
}
124+
125+
126+
// return true if operation shape is decorated with `httpChecksumRequired` trait.
127+
private static boolean hasChecksumRequiredTrait(Model model, ServiceShape service, OperationShape operation) {
128+
return operation.hasTrait(HttpChecksumRequiredTrait.class);
129+
}
130+
131+
private static boolean hasMd5Dependency(
132+
Model model,
133+
ServiceShape service
134+
) {
135+
TopDownIndex topDownIndex = TopDownIndex.of(model);
136+
Set<OperationShape> operations = topDownIndex.getContainedOperations(service);
137+
for (OperationShape operation : operations) {
138+
if (hasChecksumRequiredTrait(model, service, operation)) {
139+
return true;
140+
}
141+
}
142+
return false;
143+
}
144+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
software.amazon.smithy.typescript.codegen.integration.AddEventStreamDependency
1+
software.amazon.smithy.typescript.codegen.integration.AddEventStreamDependency
2+
software.amazon.smithy.typescript.codegen.integration.AddChecksumRequiredDependency

0 commit comments

Comments
 (0)