Skip to content

Merge ssdk into main #315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 93 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
0f7a7d1
Support disabling client generation
JordonPhillips Feb 8, 2021
bceec98
generate response serializers
JordonPhillips Feb 10, 2021
eaba822
generate request deserializers
JordonPhillips Feb 10, 2021
98deb6e
Add ssdk generation methods to ProtocolGenerator
JordonPhillips Feb 11, 2021
dffffdf
Fix reference
JordonPhillips Feb 11, 2021
a7ef2dc
Add error serialization
JordonPhillips Feb 12, 2021
eab8bf8
Fix response header serialization
JordonPhillips Feb 12, 2021
1cab0ca
Fix request deser
JordonPhillips Feb 12, 2021
b652b73
refactor request deser / response ser
JordonPhillips Feb 12, 2021
f996fca
don't generate ssdk by default
JordonPhillips Feb 15, 2021
8080aee
Don't export clients when not generating clients
JordonPhillips Feb 15, 2021
2e1fc68
Generate IO stubs during ssdk generation
JordonPhillips Feb 15, 2021
db9ca79
Remove client config when not generating clients
JordonPhillips Feb 15, 2021
9b5d93c
Support query string deser
JordonPhillips Feb 16, 2021
8a38200
Support path deser
JordonPhillips Feb 16, 2021
825a75b
Support endpoint deser
JordonPhillips Feb 16, 2021
8a8a311
Fix path and host parsing.
adamthom-amzn Feb 19, 2021
1c38bcf
Omit the endpoint from response serialization's SerdeContext.
adamthom-amzn Feb 19, 2021
41ff1a9
Make checkstyle happy
JordonPhillips Feb 23, 2021
5621fd0
remove duplicate type generation
JordonPhillips Feb 24, 2021
b45eb6d
WIP: Add binding receivers for query and label
JordonPhillips Feb 24, 2021
dde0eec
properly reference the query
JordonPhillips Feb 24, 2021
cda3ae4
fix reference to hostRegex
JordonPhillips Feb 24, 2021
5802885
Convert query timestamps properly
JordonPhillips Feb 24, 2021
5c3b89e
bypass type check for query value reading
JordonPhillips Feb 24, 2021
24a9bfa
also convert path strings
JordonPhillips Feb 24, 2021
9dd69b4
Fix reading collections bound to the uri
JordonPhillips Feb 24, 2021
5628ea5
Fix ignored trailing slashes in path parsing.
adamthom-amzn Feb 23, 2021
cced771
Make consumption of serde functions simpler
adamthom-amzn Feb 23, 2021
abbf3e1
WIP: add empty endpoint to response ser
JordonPhillips Feb 24, 2021
1b3ccdf
fix writing out custom status codes
JordonPhillips Feb 24, 2021
9205e10
Add generateX properties to settings warn list
JordonPhillips Feb 26, 2021
3df7c28
Update path parsing regex
JordonPhillips Mar 1, 2021
289385f
Merge pull request #270 from JordonPhillips/server-serde
JordonPhillips Mar 1, 2021
2c1fc47
Add generation of server interfaces.
adamthom-amzn Feb 24, 2021
b8f2143
Add router generation for REST-JSON services.
adamthom-amzn Feb 25, 2021
b0369f2
Add handler support for server generation.
adamthom-amzn Feb 26, 2021
d520610
Merge pull request #278 from adamthom-amzn/server-serde
JordonPhillips Mar 2, 2021
523cf7e
Generate ssdk request protocol tests
JordonPhillips Feb 25, 2021
4bf58c3
Merge pull request #279 from JordonPhillips/server-serde-protocol-tests
JordonPhillips Mar 4, 2021
6e8f090
Introduce a server-specific symbol provider.
adamthom-amzn Mar 4, 2021
c389258
Merge pull request #281 from adamthom-amzn/symbolprovider
adamthom-amzn Mar 5, 2021
862f19f
Get rid of needing to cast OperationSerializers.
adamthom-amzn Mar 5, 2021
1a6a906
Merge pull request #282 from adamthom-amzn/norecord
adamthom-amzn Mar 5, 2021
59edca7
Use server symbol provider in protocol test gen
JordonPhillips Mar 12, 2021
976711c
Split up clint/server command generation
JordonPhillips Mar 12, 2021
cbcc084
Merge pull request #284 from JordonPhillips/update-ssdk-request-tests
JordonPhillips Mar 15, 2021
128fefa
Use specific type for encoder in comparators
JordonPhillips Mar 5, 2021
fb5b097
Add ssdk response tests
JordonPhillips Mar 3, 2021
7f1d368
update TypeScript dependencies version (#276)
AllanZhengYP Mar 1, 2021
250ad49
Check for only structure shapes for circular dependency (#277)
trivikr Mar 4, 2021
0068b7f
Pin fast-xml-parser to v3.17.4 (#280)
trivikr Mar 4, 2021
505b142
Remove tests for shape conflicts (#286)
Mar 17, 2021
8e9225f
Move getHandler function to service
JordonPhillips Mar 17, 2021
8299933
generate error handlers
JordonPhillips Mar 17, 2021
45d8486
Use shared operation serializer
JordonPhillips Mar 17, 2021
2a661c6
Catch modeled errors in server serde
JordonPhillips Mar 19, 2021
206de49
Use errors type
JordonPhillips Mar 22, 2021
6f3dda4
Merge pull request #285 from JordonPhillips/ssdk-response-tests
JordonPhillips Mar 22, 2021
1735105
Merge pull request #289 from JordonPhillips/ssdk-exception-handling
JordonPhillips Mar 22, 2021
4c93f11
Dont generate switch for "never" error serializers
JordonPhillips Mar 23, 2021
3c34bc5
Generate ssdk error protocol tests
JordonPhillips Mar 23, 2021
67b2a0d
Look for proper tag on server error tests
JordonPhillips Mar 24, 2021
2e2664f
Merge pull request #293 from JordonPhillips/exception-handling-updates
JordonPhillips Mar 25, 2021
2496c28
Support serializing framework exceptions
adamthom-amzn Mar 24, 2021
3eb717b
Support asynchronous service operations
adamthom-amzn Mar 26, 2021
257d395
Merge pull request #295 from adamthom-amzn/ssdk
JordonPhillips Mar 29, 2021
3af194d
Adjust ssdk protocol tests to use promises
JordonPhillips Mar 30, 2021
60f9b8b
Merge pull request #297 from JordonPhillips/fix-protocol-tests
JordonPhillips Mar 31, 2021
8f4f83d
Add ts-jest as a devDependency (#287)
trivikr Mar 19, 2021
ebac15f
Pin fast-xml-parser dependency to 3.19.0 (#290)
trivikr Mar 22, 2021
3acdf7c
Move types in dist folder (#294)
trivikr Mar 24, 2021
dc5b386
fix: create jest.config.js for clients (#291)
trivikr Mar 25, 2021
21c0bca
Use service renames (#292)
Mar 29, 2021
b021701
Support deserializing query maps
JordonPhillips Mar 31, 2021
044a7e6
Add generated error types for convenience (#298)
adamthom-amzn Apr 6, 2021
b49b293
Generate per-operation ServiceHandlers (#304)
adamthom-amzn Apr 13, 2021
d8cc74e
Add ssdk typescript libraries
JordonPhillips Apr 9, 2021
63ee958
Add explicit node types dependency
JordonPhillips Apr 12, 2021
5354c7c
Update ssdk node deps to node 14
JordonPhillips Apr 13, 2021
571f11f
Remove esm builds from ssdk libs
JordonPhillips Apr 13, 2021
6660ad6
Refresh ssdk yarn locks
JordonPhillips Apr 13, 2021
2984250
Add todo comments to update ssdk compiler targets
JordonPhillips Apr 14, 2021
b0a0cce
Parameterize ServiceHandler
JordonPhillips Apr 14, 2021
caa953a
Move ssdk lib types into dist/types
JordonPhillips Apr 14, 2021
00f8856
Merge branch 'main' into merge-ssdk
JordonPhillips Apr 19, 2021
6326801
Rework some of the project setup (#317)
adamthom-amzn Apr 23, 2021
fe6edd5
Update generated io types
JordonPhillips Apr 27, 2021
efa3f1a
Rework ssdk package setup
JordonPhillips Apr 27, 2021
02935fa
Run prettier on ssdk libs
JordonPhillips Apr 27, 2021
a1027b4
remove unused dependency
JordonPhillips Apr 27, 2021
113bf3e
Create and use ServerSerdeContext interface
JordonPhillips Apr 27, 2021
066d60f
Merge branch 'main' into merge-ssdk
JordonPhillips Apr 27, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.EventStreamIndex;
import software.amazon.smithy.model.shapes.MemberShape;
import software.amazon.smithy.model.shapes.OperationShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.shapes.StructureShape;
import software.amazon.smithy.model.traits.StreamingTrait;

/**
* Utility methods needed across Java packages.
Expand Down Expand Up @@ -91,4 +97,39 @@ private static List<String> getDefaultOperationSerdeContextTypes(TypeScriptWrite
contextInterfaceList.add("__SerdeContext");
return contextInterfaceList;
}

static List<MemberShape> getBlobStreamingMembers(Model model, StructureShape shape) {
return shape.getAllMembers().values().stream()
.filter(memberShape -> {
// Streaming blobs need to have their types modified
// See `writeStreamingMemberType`
Shape target = model.expectShape(memberShape.getTarget());
return target.isBlobShape() && target.hasTrait(StreamingTrait.class);
})
.collect(Collectors.toList());
}

/**
* Ease the input streaming member restriction so that users don't need to construct a stream every time.
* This type decoration is allowed in Smithy because it makes input type more permissive than output type
* for the same member.
* Refer here for more rationales: https://github.com/aws/aws-sdk-js-v3/issues/843
*/
static void writeStreamingMemberType(
TypeScriptWriter writer,
Symbol containerSymbol,
String typeName,
MemberShape streamingMember
) {
String memberName = streamingMember.getMemberName();
String optionalSuffix = streamingMember.isRequired() ? "" : "?";
writer.openBlock("type $LType = Omit<$T, $S> & {", "};", typeName, containerSymbol, memberName, () -> {
writer.writeDocs(String.format("For *`%1$s[\"%2$s\"]`*, see {@link %1$s.%2$s}.",
containerSymbol.getName(), memberName));
writer.write("$1L$2L: $3T[$1S]|string|Uint8Array|Buffer;", memberName, optionalSuffix, containerSymbol);
});
writer.writeDocs(String.format("This interface extends from `%1$s` interface. There are more parameters than"
+ " `%2$s` defined in {@link %1$s}", containerSymbol.getName(), memberName));
writer.write("export interface $1L extends $1LType {}", typeName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class CodegenVisitor extends ShapeVisitor.Default<Void> {
private final ServiceShape service;
private final FileManifest fileManifest;
private final SymbolProvider symbolProvider;
private final SymbolProvider serverSymbolProvider;
private final Model nonTraits;
private final TypeScriptDelegator writers;
private final List<TypeScriptIntegration> integrations = new ArrayList<>();
Expand Down Expand Up @@ -107,14 +108,20 @@ class CodegenVisitor extends ShapeVisitor.Default<Void> {
nonTraits = context.getModelWithoutTraitShapes();
service = settings.getService(model);
fileManifest = context.getFileManifest();
LOGGER.info(() -> "Generating TypeScript client for service " + service.getId());
LOGGER.info(() -> String.format("Generating TypeScript %s for service %s",
settings.generateClient() ? "client" : "server", service.getId()));

// Decorate the symbol provider using integrations.
SymbolProvider resolvedProvider = TypeScriptCodegenPlugin.createSymbolProvider(model, settings);
for (TypeScriptIntegration integration : integrations) {
resolvedProvider = integration.decorateSymbolProvider(settings, model, resolvedProvider);
}
symbolProvider = SymbolProvider.cache(resolvedProvider);
if (settings.generateServerSdk()) {
serverSymbolProvider = SymbolProvider.cache(new ServerSymbolVisitor(model, symbolProvider));
} else {
serverSymbolProvider = symbolProvider;
}

// Resolve the nullable protocol generator and application protocol.
protocolGenerator = resolveProtocolGenerator(integrations, service, settings);
Expand Down Expand Up @@ -175,11 +182,15 @@ void execute() {
// Generate the client Node and Browser configuration files. These
// files are switched between in package.json based on the targeted
// environment.
RuntimeConfigGenerator configGenerator = new RuntimeConfigGenerator(
settings, model, symbolProvider, writers, integrations);
for (LanguageTarget target : LanguageTarget.values()) {
LOGGER.fine("Generating " + target + " runtime configuration");
configGenerator.generate(target);
if (settings.generateClient()) {
// For now these are only generated for clients.
// TODO: generate ssdk config
Comment on lines +185 to +187
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since client and server SDK's plugins are divergent, why not adding a flag like isServerSdkIntegration into the TypeScriptIntegration interface or extend to a new interface like TypeScriptServerIntegration? Then 2 different codegen plugins can be applied separately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like that would be a great idea. I've got a PR that splits client/server up further where we could add something like that: #314

RuntimeConfigGenerator configGenerator = new RuntimeConfigGenerator(
settings, model, symbolProvider, writers, integrations);
for (LanguageTarget target : LanguageTarget.values()) {
LOGGER.fine("Generating " + target + " runtime configuration");
configGenerator.generate(target);
}
}

// Write each custom file.
Expand All @@ -189,12 +200,18 @@ void execute() {
}

// Generate index for client.
IndexGenerator.writeIndex(settings, model, symbolProvider, fileManifest, integrations);
IndexGenerator.writeIndex(settings, model, symbolProvider, fileManifest, integrations, protocolGenerator);

if (settings.generateServerSdk()) {
// Generate index for server
IndexGenerator.writeServerIndex(settings, model, serverSymbolProvider, fileManifest);
}

// Generate protocol tests IFF found in the model.
if (protocolGenerator != null) {
ShapeId protocol = protocolGenerator.getProtocol();
new HttpProtocolTestGenerator(settings, model, protocol, symbolProvider, writers).run();
new HttpProtocolTestGenerator(
settings, model, protocol, symbolProvider, serverSymbolProvider, writers, protocolGenerator).run();
}

// Write each pending writer.
Expand Down Expand Up @@ -270,13 +287,74 @@ public Void stringShape(StringShape shape) {
return null;
}

@Override
public Void operationShape(OperationShape operation) {
if (settings.generateServerSdk()) {
writers.useShapeWriter(operation, serverSymbolProvider, w -> {
ServerGenerator.generateOperationHandler(serverSymbolProvider, service, operation, w);
});
}
return null;
}

@Override
public Void serviceShape(ServiceShape shape) {
if (!Objects.equals(service, shape)) {
LOGGER.fine(() -> "Skipping `" + shape.getId() + "` because it is not `" + service.getId() + "`");
return null;
}

if (settings.generateClient()) {
generateClient(shape);
}
if (settings.generateClient() || settings.generateServerSdk()) {
generateCommands(shape);
}

if (settings.generateServerSdk()) {
generateServiceInterface(shape);
generateServerErrors(shape);
}

if (protocolGenerator != null) {
LOGGER.info("Generating serde for protocol " + protocolGenerator.getName() + " on " + shape.getId());
String fileName = "protocols/" + ProtocolGenerator.getSanitizedName(protocolGenerator.getName()) + ".ts";
writers.useFileWriter(fileName, writer -> {
ProtocolGenerator.GenerationContext context = new ProtocolGenerator.GenerationContext();
context.setProtocolName(protocolGenerator.getName());
context.setIntegrations(integrations);
context.setModel(model);
context.setService(shape);
context.setSettings(settings);
context.setSymbolProvider(symbolProvider);
context.setWriter(writer);
if (context.getSettings().generateClient()) {
protocolGenerator.generateRequestSerializers(context);
protocolGenerator.generateResponseDeserializers(context);
}
if (context.getSettings().generateServerSdk()) {
ProtocolGenerator.GenerationContext serverContext =
context.withSymbolProvider(serverSymbolProvider);
protocolGenerator.generateRequestDeserializers(serverContext);
protocolGenerator.generateResponseSerializers(serverContext);
protocolGenerator.generateFrameworkErrorSerializer(serverContext);
writers.useShapeWriter(shape, serverSymbolProvider, w -> {
protocolGenerator.generateServiceHandlerFactory(serverContext.withWriter(w));
});
for (OperationShape operation: TopDownIndex.of(model).getContainedOperations(service)) {
writers.useShapeWriter(operation, serverSymbolProvider, w -> {
protocolGenerator.generateOperationHandlerFactory(serverContext.withWriter(w), operation);
});
}
}
protocolGenerator.generateSharedComponents(context);
});
}

return null;
}

private void generateClient(ServiceShape shape) {
// Generate the modular service client.
writers.useShapeWriter(shape, writer -> new ServiceGenerator(
settings, model, symbolProvider, writer, integrations, runtimePlugins, applicationProtocol).run());
Expand All @@ -294,9 +372,6 @@ public Void serviceShape(ServiceShape shape) {
boolean hasPaginatedOperation = false;

for (OperationShape operation : containedOperations) {
writers.useShapeWriter(operation, commandWriter -> new CommandGenerator(
settings, model, operation, symbolProvider, commandWriter,
runtimePlugins, protocolGenerator, applicationProtocol).run());
if (operation.hasTrait(PaginatedTrait.ID)) {
hasPaginatedOperation = true;
String outputFilename = PaginationGenerator.getOutputFilelocation(operation);
Expand All @@ -323,25 +398,48 @@ public Void serviceShape(ServiceShape shape) {
serviceSymbol,
paginationWriter));
}
}

if (protocolGenerator != null) {
LOGGER.info("Generating serde for protocol " + protocolGenerator.getName() + " on " + shape.getId());
String fileName = "protocols/" + ProtocolGenerator.getSanitizedName(protocolGenerator.getName()) + ".ts";
writers.useFileWriter(fileName, writer -> {
ProtocolGenerator.GenerationContext context = new ProtocolGenerator.GenerationContext();
context.setProtocolName(protocolGenerator.getName());
context.setIntegrations(integrations);
context.setModel(model);
context.setService(shape);
context.setSettings(settings);
context.setSymbolProvider(symbolProvider);
context.setWriter(writer);
protocolGenerator.generateRequestSerializers(context);
protocolGenerator.generateResponseDeserializers(context);
protocolGenerator.generateSharedComponents(context);
});
}
private void generateServiceInterface(ServiceShape shape) {
TopDownIndex topDownIndex = TopDownIndex.of(model);
Set<OperationShape> operations = new TreeSet<>(topDownIndex.getContainedOperations(shape));
writers.useShapeWriter(shape, serverSymbolProvider, writer -> {
ServerGenerator.generateOperationsType(serverSymbolProvider, shape, operations, writer);
ServerGenerator.generateServerInterfaces(serverSymbolProvider, shape, operations, writer);
ServerGenerator.generateServiceHandler(serverSymbolProvider, shape, operations, writer);
});
}

return null;
private void generateServerErrors(ServiceShape service) {
TopDownIndex.of(model)
.getContainedOperations(service)
.stream()
.flatMap(o -> o.getErrors().stream())
.distinct()
.map(id -> model.expectShape(id).asStructureShape().orElseThrow(IllegalArgumentException::new))
.sorted()
.forEachOrdered(error -> writers.useShapeWriter(service, serverSymbolProvider, writer -> {
new ServerErrorGenerator(settings, model, error, serverSymbolProvider, writer).run();
}));
}

private void generateCommands(ServiceShape shape) {
// Generate each operation for the service.
TopDownIndex topDownIndex = TopDownIndex.of(model);
Set<OperationShape> containedOperations = new TreeSet<>(topDownIndex.getContainedOperations(shape));
for (OperationShape operation : containedOperations) {
// Right now this only generates stubs
if (settings.generateClient()) {
writers.useShapeWriter(operation, commandWriter -> new CommandGenerator(
settings, model, operation, symbolProvider, commandWriter,
runtimePlugins, protocolGenerator, applicationProtocol).run());
}

if (settings.generateServerSdk()) {
writers.useShapeWriter(operation, serverSymbolProvider, commandWriter -> new ServerCommandGenerator(
settings, model, operation, serverSymbolProvider, commandWriter,
protocolGenerator, applicationProtocol).run());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@

package software.amazon.smithy.typescript.codegen;

import static software.amazon.smithy.typescript.codegen.CodegenUtils.getBlobStreamingMembers;
import static software.amazon.smithy.typescript.codegen.CodegenUtils.writeStreamingMemberType;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
Expand All @@ -25,9 +28,7 @@
import software.amazon.smithy.model.shapes.MemberShape;
import software.amazon.smithy.model.shapes.OperationShape;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.shapes.StructureShape;
import software.amazon.smithy.model.traits.StreamingTrait;
import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator;
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
import software.amazon.smithy.utils.OptionalUtils;
Expand Down Expand Up @@ -85,6 +86,11 @@ final class CommandGenerator implements Runnable {

@Override
public void run() {
addInputAndOutputTypes();
generateClientCommand();
}

private void generateClientCommand() {
Symbol serviceSymbol = symbolProvider.toSymbol(service);
String configType = ServiceGenerator.getResolvedConfigTypeName(serviceSymbol);

Expand All @@ -98,8 +104,6 @@ public void run() {
writer.addImport("HandlerExecutionContext", "HandlerExecutionContext", "@aws-sdk/types");
writer.addImport("MiddlewareStack", "MiddlewareStack", "@aws-sdk/types");

addInputAndOutputTypes();

String name = symbol.getName();
writer.writeShapeDocs(operation);
writer.openBlock("export class $L extends $$Command<$T, $T, $L> {", "}", name, inputType, outputType,
Expand Down Expand Up @@ -190,11 +194,11 @@ private void addInputAndOutputTypes() {
private void writeInputType(String typeName, Optional<StructureShape> inputShape) {
if (inputShape.isPresent()) {
StructureShape input = inputShape.get();
List<MemberShape> blobStreamingMembers = getBlobStreamingMembers(input);
List<MemberShape> blobStreamingMembers = getBlobStreamingMembers(model, input);
if (blobStreamingMembers.isEmpty()) {
writer.write("export interface $L extends $T {}", typeName, symbolProvider.toSymbol(input));
} else {
writeStreamingInputType(typeName, input, blobStreamingMembers.get(0));
writeStreamingMemberType(writer, symbolProvider.toSymbol(input), typeName, blobStreamingMembers.get(0));
}
} else {
// If the input is non-existent, then use an empty object.
Expand All @@ -214,37 +218,6 @@ private void writeOutputType(String typeName, Optional<StructureShape> outputSha
}
}

private List<MemberShape> getBlobStreamingMembers(StructureShape shape) {
return shape.getAllMembers().values().stream()
.filter(memberShape -> {
// Streaming blobs need to have their types modified
// See `writeStreamingInputType`
Shape target = model.expectShape(memberShape.getTarget());
return target.isBlobShape() && target.hasTrait(StreamingTrait.class);
})
.collect(Collectors.toList());
}

/**
* Ease the input streaming member restriction so that users don't need to construct a stream every time.
* This type decoration is allowed in Smithy because it makes input type more permissive than output type
* for the same member.
* Refer here for more rationales: https://github.com/aws/aws-sdk-js-v3/issues/843
*/
private void writeStreamingInputType(String typeName, StructureShape inputShape, MemberShape streamingMember) {
Symbol inputSymbol = symbolProvider.toSymbol(inputShape);
String memberName = streamingMember.getMemberName();
String optionalSuffix = streamingMember.isRequired() ? "" : "?";
writer.openBlock("type $LType = Omit<$T, $S> & {", "};", typeName, inputSymbol, memberName, () -> {
writer.writeDocs(String.format("For *`%1$s[\"%2$s\"]`*, see {@link %1$s.%2$s}.",
inputSymbol.getName(), memberName));
writer.write("$1L$2L: $3T[$1S]|string|Uint8Array|Buffer;", memberName, optionalSuffix, inputSymbol);
});
writer.writeDocs(String.format("This interface extends from `%1$s` interface. There are more parameters than"
+ " `%2$s` defined in {@link %1$s}", inputSymbol.getName(), memberName));
writer.write("export interface $1L extends $1LType {}", typeName);
}

private void addCommandSpecificPlugins() {
// Some plugins might only apply to specific commands. They are added to the
// command's middleware stack here. Plugins that apply to all commands are
Expand Down
Loading