|
34 | 34 | import software.amazon.smithy.model.knowledge.OperationIndex; |
35 | 35 | import software.amazon.smithy.model.knowledge.TopDownIndex; |
36 | 36 | import software.amazon.smithy.model.pattern.SmithyPattern; |
| 37 | +import software.amazon.smithy.model.pattern.UriPattern; |
37 | 38 | import software.amazon.smithy.model.shapes.MemberShape; |
38 | 39 | import software.amazon.smithy.model.shapes.OperationShape; |
39 | 40 | import software.amazon.smithy.model.shapes.ServiceShape; |
|
47 | 48 | import software.amazon.smithy.model.traits.EndpointTrait; |
48 | 49 | import software.amazon.smithy.model.traits.HttpHeaderTrait; |
49 | 50 | import software.amazon.smithy.model.traits.HttpPayloadTrait; |
| 51 | +import software.amazon.smithy.model.traits.HttpTrait; |
50 | 52 | import software.amazon.smithy.model.traits.StreamingTrait; |
51 | 53 | import software.amazon.smithy.model.traits.Trait; |
52 | 54 | import software.amazon.smithy.model.transform.ModelTransformer; |
| 55 | +import software.amazon.smithy.rulesengine.traits.ContextParamTrait; |
53 | 56 | import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; |
54 | 57 | import software.amazon.smithy.typescript.codegen.LanguageTarget; |
55 | 58 | import software.amazon.smithy.typescript.codegen.TypeScriptDependency; |
|
58 | 61 | import software.amazon.smithy.typescript.codegen.auth.http.integration.AddHttpSigningPlugin; |
59 | 62 | import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin; |
60 | 63 | import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration; |
| 64 | +import software.amazon.smithy.typescript.codegen.schema.SchemaGenerationAllowlist; |
61 | 65 | import software.amazon.smithy.utils.ListUtils; |
62 | 66 | import software.amazon.smithy.utils.MapUtils; |
63 | 67 | import software.amazon.smithy.utils.SetUtils; |
@@ -113,6 +117,53 @@ public static Shape removeHostPrefixTrait(Shape shape) { |
113 | 117 | .orElse(shape); |
114 | 118 | } |
115 | 119 |
|
| 120 | + /** |
| 121 | + * Remove `/{Bucket}` from the operation endpoint URI IFF |
| 122 | + * - it is in a prefix position. |
| 123 | + * - input has a member called "Bucket". |
| 124 | + * - "Bucket" input member is a contextParam. |
| 125 | + */ |
| 126 | + public static Shape removeUriBucketPrefix(Shape shape, Model model) { |
| 127 | + return shape.asOperationShape() |
| 128 | + .map(OperationShape::shapeToBuilder) |
| 129 | + .map((Object object) -> { |
| 130 | + OperationShape.Builder builder = (OperationShape.Builder) object; |
| 131 | + Trait trait = builder.getAllTraits().get(HttpTrait.ID); |
| 132 | + if (trait instanceof HttpTrait httpTrait) { |
| 133 | + String uri = httpTrait.getUri().toString(); |
| 134 | + |
| 135 | + StructureShape input = model.expectShape( |
| 136 | + shape.asOperationShape().get().getInputShape() |
| 137 | + ).asStructureShape().orElseThrow( |
| 138 | + () -> new RuntimeException("operation must have input structure") |
| 139 | + ); |
| 140 | + |
| 141 | + boolean hasBucketPrefix = uri.startsWith("/{Bucket}"); |
| 142 | + Optional<MemberShape> bucket = input.getMember("Bucket"); |
| 143 | + boolean inputHasBucketMember = bucket.isPresent(); |
| 144 | + boolean bucketIsContextParam = bucket |
| 145 | + .map(ms -> ms.getTrait(ContextParamTrait.class)) |
| 146 | + .isPresent(); |
| 147 | + |
| 148 | + if (hasBucketPrefix && inputHasBucketMember && bucketIsContextParam) { |
| 149 | + String replaced = uri |
| 150 | + .replace("/{Bucket}/", "/") |
| 151 | + .replace("/{Bucket}", "/"); |
| 152 | + builder.addTrait( |
| 153 | + httpTrait |
| 154 | + .toBuilder() |
| 155 | + .uri(UriPattern.parse(replaced)) |
| 156 | + .build() |
| 157 | + ); |
| 158 | + } |
| 159 | + } |
| 160 | + return builder; |
| 161 | + }) |
| 162 | + .map(OperationShape.Builder::build) |
| 163 | + .map(s -> (Shape) s) |
| 164 | + .orElse(shape); |
| 165 | + } |
| 166 | + |
116 | 167 | @Override |
117 | 168 | public List<String> runAfter() { |
118 | 169 | return List.of( |
@@ -243,7 +294,12 @@ public Model preprocessModel(Model model, TypeScriptSettings settings) { |
243 | 294 | Model builtModel = modelBuilder.addShapes(inputShapes).build(); |
244 | 295 | if (hasRuleset) { |
245 | 296 | return ModelTransformer.create().mapShapes( |
246 | | - builtModel, AddS3Config::removeHostPrefixTrait |
| 297 | + builtModel, (shape) -> { |
| 298 | + if (SchemaGenerationAllowlist.allows(serviceShape.getId(), settings)) { |
| 299 | + return removeUriBucketPrefix(shape, model); |
| 300 | + } |
| 301 | + return shape; |
| 302 | + } |
247 | 303 | ); |
248 | 304 | } |
249 | 305 | return builtModel; |
|
0 commit comments