diff --git a/smithy-typescript-codegen/build.gradle.kts b/smithy-typescript-codegen/build.gradle.kts index 8f26bc6d566..8a1680dec29 100644 --- a/smithy-typescript-codegen/build.gradle.kts +++ b/smithy-typescript-codegen/build.gradle.kts @@ -32,6 +32,7 @@ buildscript { dependencies { api("software.amazon.smithy:smithy-codegen-core:$smithyVersion") + api("software.amazon.smithy:smithy-model:$smithyVersion") api("software.amazon.smithy:smithy-rules-engine:$smithyVersion") api("software.amazon.smithy:smithy-waiters:$smithyVersion") implementation("software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion") diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/integration/HttpBindingProtocolGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/integration/HttpBindingProtocolGenerator.java index 601dc0827b6..22074d99802 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/integration/HttpBindingProtocolGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/integration/HttpBindingProtocolGenerator.java @@ -64,6 +64,7 @@ import software.amazon.smithy.model.traits.HttpErrorTrait; import software.amazon.smithy.model.traits.HttpQueryTrait; import software.amazon.smithy.model.traits.HttpTrait; +import software.amazon.smithy.model.traits.IdempotencyTokenTrait; import software.amazon.smithy.model.traits.MediaTypeTrait; import software.amazon.smithy.model.traits.StreamingTrait; import software.amazon.smithy.model.traits.TimestampFormatTrait.Format; @@ -848,22 +849,30 @@ private void writeRequestQueryParam( "@aws-sdk/smithy-client"); Shape target = model.expectShape(binding.getMember().getTarget()); + + boolean isIdempotencyToken = binding.getMember().hasTrait(IdempotencyTokenTrait.class); + if (isIdempotencyToken) { + writer.addImport("v4", "generateIdempotencyToken", "uuid"); + } + boolean isRequired = binding.getMember().isRequired(); + String idempotencyComponent = (isIdempotencyToken && !isRequired) ? " ?? generateIdempotencyToken()" : ""; + String memberAssertionComponent = (idempotencyComponent.isEmpty() ? "!" : ""); + String queryValue = getInputValue( context, binding.getLocation(), - "input." + memberName + "!", + "input." + memberName + memberAssertionComponent, binding.getMember(), target ); - boolean isRequired = binding.getMember().isRequired(); writer.addImport("expectNonNull", "__expectNonNull", "@aws-sdk/smithy-client"); - if (Objects.equals("input." + memberName + "!", queryValue)) { + if (Objects.equals("input." + memberName + memberAssertionComponent, queryValue)) { String value = isRequired ? "__expectNonNull($L, `" + memberName + "`)" : "$L"; // simple undefined check writer.write( - "$S: [," + value + "],", + "$S: [," + value + idempotencyComponent + "],", binding.getLocationName(), queryValue ); @@ -875,15 +884,16 @@ private void writeRequestQueryParam( binding.getLocationName(), memberName, memberName, - queryValue + queryValue // no idempotency token default for required members ); } else { // undefined check with lazy eval writer.write( - "$S: [() => input.$L !== void 0, () => $L],", + "$S: [() => input.$L !== void 0, () => ($L)$L],", binding.getLocationName(), memberName, - queryValue + queryValue, + idempotencyComponent ); } }