Skip to content

Commit d929795

Browse files
authored
docs: add more information about BLOB values in structures (#1182)
* docs: add more information about BLOB values in structures * escape char * update tests, formatting
1 parent 199d9aa commit d929795

File tree

3 files changed

+283
-204
lines changed

3 files changed

+283
-204
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,12 @@ private String getCommandExample(String serviceName, String configName, String c
212212
+ String.format("const client = new %s(config);%n", serviceName)
213213
+ String.format("const input = %s%n",
214214
StructureExampleGenerator.generateStructuralHintDocumentation(
215-
model.getShape(operation.getInputShape()).get(), model, false))
215+
model.getShape(operation.getInputShape()).get(), model, false, true))
216216
+ String.format("const command = new %s(input);%n", commandName)
217217
+ "const response = await client.send(command);\n"
218218
+ String.format("%s%n",
219219
StructureExampleGenerator.generateStructuralHintDocumentation(
220-
model.getShape(operation.getOutputShape()).get(), model, true))
220+
model.getShape(operation.getOutputShape()).get(), model, true, false))
221221
+ "\n```\n"
222222
+ "\n"
223223
+ String.format("@param %s - {@link %s}%n", commandInput, commandInput)

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java

Lines changed: 75 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public abstract class StructureExampleGenerator {
3232
/**
3333
* Generates an example structure for API documentation, as an
3434
* automated gap filler for operations that do not have
35-
* hand written examples.
35+
* handwritten examples.
3636
*
3737
* Example for Athena::createPreparedStatement
3838
* ```js
@@ -44,65 +44,74 @@ public abstract class StructureExampleGenerator {
4444
* };
4545
* ```
4646
*/
47-
public static String generateStructuralHintDocumentation(Shape shape, Model model, boolean isComment) {
47+
public static String generateStructuralHintDocumentation(
48+
Shape shape,
49+
Model model,
50+
boolean isComment,
51+
boolean isInput
52+
) {
4853
StringBuilder buffer = new StringBuilder();
49-
shape(shape, buffer, model, 0, new ShapeTracker());
54+
shape(shape, buffer, model, 0, new ShapeTracker(), isInput);
5055

5156
// replace non-leading whitespace with single space.
5257
String s = Arrays.stream(
5358
buffer.toString()
54-
.split("\n"))
55-
.map(line -> line.replaceAll(
56-
"([\\w\\\",:\\[\\{] )\\s+",
57-
"$1")
58-
.replaceAll("\\s+$", ""))
59-
.collect(Collectors.joining((isComment) ? "\n// " : "\n"));
59+
.split("\n"))
60+
.map(line -> line.replaceAll(
61+
"([\\w\\\",:\\[\\{] )\\s+",
62+
"$1")
63+
.replaceAll("\\s+$", ""))
64+
.collect(Collectors.joining((isComment) ? "\n// " : "\n"));
6065

6166
return ((isComment) ? "// " : "") + s.replaceAll(",$", ";");
6267
}
6368

6469
private static void structure(StructureShape structureShape,
65-
StringBuilder buffer, Model model,
66-
int indentation,
67-
ShapeTracker shapeTracker) {
68-
if (structureShape.getAllMembers().size() == 0) {
70+
StringBuilder buffer,
71+
Model model,
72+
int indentation,
73+
ShapeTracker shapeTracker,
74+
boolean isInput) {
75+
if (structureShape.getAllMembers().isEmpty()) {
6976
append(indentation, buffer, "{},");
7077
checkRequired(indentation, buffer, structureShape);
7178
} else {
7279
append(indentation, buffer,
73-
"{" + (shapeTracker.getOccurrenceCount(structureShape) == 1
74-
? " // " + structureShape.getId().getName()
75-
: ""));
80+
"{" + (shapeTracker.getOccurrenceCount(structureShape) == 1
81+
? " // " + structureShape.getId().getName()
82+
: ""));
7683
checkRequired(indentation, buffer, structureShape);
7784
structureShape.getAllMembers().values().forEach(member -> {
7885
append(indentation + 2, buffer, member.getMemberName() + ": ");
79-
shape(member, buffer, model, indentation + 2, shapeTracker);
86+
shape(member, buffer, model, indentation + 2, shapeTracker, isInput);
8087
});
8188
append(indentation, buffer, "},\n");
8289
}
8390
}
8491

8592
private static void union(UnionShape unionShape,
86-
StringBuilder buffer,
87-
Model model,
88-
int indentation,
89-
ShapeTracker shapeTracker) {
93+
StringBuilder buffer,
94+
Model model,
95+
int indentation,
96+
ShapeTracker shapeTracker,
97+
boolean isInput) {
9098
append(indentation, buffer, "{" + (shapeTracker.getOccurrenceCount(unionShape) == 1
91-
? " // " + unionShape.getId().getName()
92-
: "// ") + " Union: only one key present");
99+
? " // " + unionShape.getId().getName()
100+
: "// ") + " Union: only one key present");
93101
checkRequired(indentation, buffer, unionShape);
94102
unionShape.getAllMembers().values().forEach(member -> {
95103
append(indentation + 2, buffer, member.getMemberName() + ": ");
96-
shape(member, buffer, model, indentation + 2, shapeTracker);
104+
shape(member, buffer, model, indentation + 2, shapeTracker, isInput);
97105
});
98106
append(indentation, buffer, "},\n");
99107
}
100108

101109
private static void shape(Shape shape,
102-
StringBuilder buffer,
103-
Model model,
104-
int indentation,
105-
ShapeTracker shapeTracker) {
110+
StringBuilder buffer,
111+
Model model,
112+
int indentation,
113+
ShapeTracker shapeTracker,
114+
boolean isInput) {
106115
Shape target;
107116
if (shape instanceof MemberShape) {
108117
target = model.getShape(((MemberShape) shape).getTarget()).get();
@@ -123,17 +132,31 @@ private static void shape(Shape shape,
123132
append(indentation, buffer, "Number(\"bigint\"),");
124133
break;
125134
case BLOB:
126-
if (target.hasTrait(StreamingTrait.class)) {
127-
append(indentation, buffer, "\"STREAMING_BLOB_VALUE\",");
135+
if (isInput) {
136+
if (target.hasTrait(StreamingTrait.class)) {
137+
append(indentation, buffer,
138+
"\"MULTIPLE_TYPES_ACCEPTED\", // see \\@smithy/types -> StreamingBlobPayloadInputTypes"
139+
);
140+
} else {
141+
append(indentation, buffer,
142+
"""
143+
new Uint8Array(), // e.g. Buffer.from("") or new TextEncoder().encode("")""");
144+
}
128145
} else {
129-
append(indentation, buffer, "\"BLOB_VALUE\",");
146+
if (target.hasTrait(StreamingTrait.class)) {
147+
append(indentation, buffer,
148+
"\"<SdkStream>\", // see \\@smithy/types -> StreamingBlobPayloadOutputTypes");
149+
} else {
150+
append(indentation, buffer,
151+
"new Uint8Array(),");
152+
}
130153
}
131154
break;
132155
case BOOLEAN:
133156
append(indentation, buffer, "true || false,");
134157
break;
135158
case BYTE:
136-
append(indentation, buffer, "\"BYTE_VALUE\",");
159+
append(indentation, buffer, "0, // BYTE_VALUE");
137160
break;
138161
case DOCUMENT:
139162
append(indentation, buffer, "\"DOCUMENT_VALUE\",");
@@ -163,50 +186,50 @@ private static void shape(Shape shape,
163186
case SET:
164187
case LIST:
165188
append(indentation, buffer, "[" + (shapeTracker.getOccurrenceCount(target) == 1
166-
? " // " + target.getId().getName()
167-
: ""));
189+
? " // " + target.getId().getName()
190+
: ""));
168191
checkRequired(indentation, buffer, shape);
169192
ListShape list = (ListShape) target;
170-
shape(list.getMember(), buffer, model, indentation + 2, shapeTracker);
193+
shape(list.getMember(), buffer, model, indentation + 2, shapeTracker, isInput);
171194
append(indentation, buffer, "],\n");
172195
break;
173196
case MAP:
174197
append(indentation, buffer, "{" + (shapeTracker.getOccurrenceCount(target) == 1
175-
? " // " + target.getId().getName()
176-
: ""));
198+
? " // " + target.getId().getName()
199+
: ""));
177200
checkRequired(indentation, buffer, shape);
178201
append(indentation + 2, buffer, "\"<keys>\": ");
179202
MapShape map = (MapShape) target;
180203
shape(model.getShape(map.getValue().getTarget()).get(), buffer, model, indentation + 2,
181-
shapeTracker);
204+
shapeTracker, isInput);
182205
append(indentation, buffer, "},\n");
183206
break;
184207

185208
case STRUCTURE:
186209
StructureShape structure = (StructureShape) target;
187-
structure(structure, buffer, model, indentation, shapeTracker);
210+
structure(structure, buffer, model, indentation, shapeTracker, isInput);
188211
break;
189212
case UNION:
190213
UnionShape union = (UnionShape) target;
191-
union(union, buffer, model, indentation, shapeTracker);
214+
union(union, buffer, model, indentation, shapeTracker, isInput);
192215
break;
193216

194217
case ENUM:
195218
EnumShape enumShape = (EnumShape) target;
196219
String enumeration = enumShape.getEnumValues()
197-
.values()
198-
.stream()
199-
.map(s -> "\"" + s + "\"")
200-
.collect(Collectors.joining(" || "));
220+
.values()
221+
.stream()
222+
.map(s -> "\"" + s + "\"")
223+
.collect(Collectors.joining(" || "));
201224
append(indentation, buffer, enumeration + ",");
202225
break;
203226
case INT_ENUM:
204227
IntEnumShape intEnumShape = (IntEnumShape) target;
205228
String intEnumeration = intEnumShape.getEnumValues()
206-
.values()
207-
.stream()
208-
.map(i -> Integer.toString(i))
209-
.collect(Collectors.joining(" || "));
229+
.values()
230+
.stream()
231+
.map(i -> Integer.toString(i))
232+
.collect(Collectors.joining(" || "));
210233
append(indentation, buffer, intEnumeration + ",");
211234
break;
212235
case OPERATION:
@@ -272,8 +295,8 @@ private static void append(int indentation, StringBuilder buffer, String tail) {
272295
* This handles the case of recursive shapes.
273296
*/
274297
private static class ShapeTracker {
275-
private Map<Shape, Set<Integer>> depths = new HashMap<Shape, Set<Integer>>();
276-
private Map<Shape, Integer> occurrences = new HashMap<Shape, Integer>();
298+
private final Map<Shape, Set<Integer>> depths = new HashMap<>();
299+
private final Map<Shape, Integer> occurrences = new HashMap<>();
277300

278301
/**
279302
* Mark that a shape is observed at depth.
@@ -291,8 +314,8 @@ public void mark(Shape shape, int depth) {
291314
*/
292315
public boolean shouldTruncate(Shape shape) {
293316
return (shape instanceof MapShape || shape instanceof UnionShape || shape instanceof StructureShape
294-
|| shape instanceof ListShape || shape instanceof SetShape)
295-
&& (getOccurrenceCount(shape) > 5 || getOccurrenceDepths(shape) > 2);
317+
|| shape instanceof ListShape || shape instanceof SetShape)
318+
&& (getOccurrenceCount(shape) > 5 || getOccurrenceDepths(shape) > 2);
296319
}
297320

298321
/**

0 commit comments

Comments
 (0)