From 4a5b3573f8dee8426ead25ddfbb5c4c54f255c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Thu, 11 Apr 2024 23:52:52 +0200 Subject: [PATCH 01/23] Bump smithy to 1.47.0 --- project/Dependencies.scala | 2 +- smithy-build.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index cd8472283..6dc35360f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -19,7 +19,7 @@ object Dependencies { val Smithy = new { val org = "software.amazon.smithy" - val smithyVersion = "1.45.0" + val smithyVersion = "1.47.0" val model = org % "smithy-model" % smithyVersion val testTraits = org % "smithy-protocol-test-traits" % smithyVersion val build = org % "smithy-build" % smithyVersion diff --git a/smithy-build.json b/smithy-build.json index 250867cd2..8b0f74136 100644 --- a/smithy-build.json +++ b/smithy-build.json @@ -3,8 +3,8 @@ "imports": ["./sampleSpecs", "./modules/protocol/resources"], "maven": { "dependencies": [ - "software.amazon.smithy:smithy-protocol-test-traits:1.45.0", - "com.disneystreaming.alloy:alloy-core:0.3.2" + "software.amazon.smithy:smithy-protocol-test-traits:1.47.0", + "com.disneystreaming.alloy:alloy-core:0.3.6" ] } } From a6af1238576a303cb0f56f1b2f588529fc38de8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 12 Apr 2024 00:05:58 +0200 Subject: [PATCH 02/23] silence the deprecation --- build.sbt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 0f01fedb5..91203aacf 100644 --- a/build.sbt +++ b/build.sbt @@ -212,7 +212,10 @@ lazy val core = projectMatrix .map(f => (f, f.relativeTo(base))) // this excludes modules/core/src/generated/PartiallyAppliedStruct.scala .collect { case (f, Some(relF)) => f -> relF.getPath() } - } + }, + scalacOptions ++= Seq( + "-Wconf:msg=value noInlineDocumentSupport in class ProtocolDefinition is deprecated:silent" + ) ) .jvmPlatform(allJvmScalaVersions, jvmDimSettings) .jsPlatform(allJsScalaVersions, jsDimSettings) From cff8e06c16f33d8f2dcb0e03e746da98b227f6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20M=C3=A9lois?= Date: Fri, 12 Apr 2024 15:26:42 +0200 Subject: [PATCH 03/23] Add lenient tagged union decoder to Json (for AWS) --- .../aws/internals/AwsJsonCodecs.scala | 1 + .../aws/internals/AwsRestJsonCodecs.scala | 1 + .../compliancetests/AwsComplianceSuite.scala | 3 - .../smithy4s/json/JsoniterCodecCompiler.scala | 6 + .../internals/JsoniterCodecCompilerImpl.scala | 8 +- .../json/internals/SchemaVisitorJCodec.scala | 110 +++++++++++++++++- .../json/SchemaVisitorJCodecTests.scala | 24 ++++ 7 files changed, 148 insertions(+), 5 deletions(-) diff --git a/modules/aws-http4s/src/smithy4s/aws/internals/AwsJsonCodecs.scala b/modules/aws-http4s/src/smithy4s/aws/internals/AwsJsonCodecs.scala index 73834a4ff..e975a9e2d 100644 --- a/modules/aws-http4s/src/smithy4s/aws/internals/AwsJsonCodecs.scala +++ b/modules/aws-http4s/src/smithy4s/aws/internals/AwsJsonCodecs.scala @@ -38,6 +38,7 @@ private[aws] object AwsJsonCodecs { .withFlexibleCollectionsSupport(true) .withHintMask(hintMask) .withMaxArity(Int.MaxValue) + .withLenientTaggedUnionDecoding ) private[aws] val jsonDecoders = jsonPayloadCodecs.decoders diff --git a/modules/aws-http4s/src/smithy4s/aws/internals/AwsRestJsonCodecs.scala b/modules/aws-http4s/src/smithy4s/aws/internals/AwsRestJsonCodecs.scala index 5dabdcd48..30701cdc0 100644 --- a/modules/aws-http4s/src/smithy4s/aws/internals/AwsRestJsonCodecs.scala +++ b/modules/aws-http4s/src/smithy4s/aws/internals/AwsRestJsonCodecs.scala @@ -38,6 +38,7 @@ private[aws] object AwsRestJsonCodecs { .withFlexibleCollectionsSupport(true) .withHintMask(hintMask) .withMaxArity(Int.MaxValue) + .withLenientTaggedUnionDecoding ) def nullToEmptyObject(blob: Blob): Blob = diff --git a/modules/aws-http4s/test/src/smithy4s/aws/compliancetests/AwsComplianceSuite.scala b/modules/aws-http4s/test/src/smithy4s/aws/compliancetests/AwsComplianceSuite.scala index 8f32f44a7..d0708fe11 100644 --- a/modules/aws-http4s/test/src/smithy4s/aws/compliancetests/AwsComplianceSuite.scala +++ b/modules/aws-http4s/test/src/smithy4s/aws/compliancetests/AwsComplianceSuite.scala @@ -50,15 +50,12 @@ object AwsComplianceSuite extends ProtocolComplianceSuite { "QueryIdempotencyTokenAutoFill", // TODO https://github.com/disneystreaming/smithy4s/issues/1424 - "AwsJson10DeserializeIgnoreType", "AwsJson10ClientPopulatesDefaultValuesInInput", "AwsJson10ClientPopulatesDefaultsValuesWhenMissingInResponse", "AwsJson10ClientPopulatesNestedDefaultValuesWhenMissing", "AwsJson10ClientPopulatesNestedDefaultsWhenMissingInResponseBody", "AwsJson10ClientErrorCorrectsWhenServerFailsToSerializeRequiredValues", - "AwsJson11DeserializeIgnoreType", "RestJsonHttpPayloadWithUnsetUnion", - "RestJsonDeserializeIgnoreType", "RestXmlHttpPayloadWithUnsetUnion" ) (complianceTest: ComplianceTest[IO]) => diff --git a/modules/json/src/smithy4s/json/JsoniterCodecCompiler.scala b/modules/json/src/smithy4s/json/JsoniterCodecCompiler.scala index abd63fdd4..6cabb6d68 100644 --- a/modules/json/src/smithy4s/json/JsoniterCodecCompiler.scala +++ b/modules/json/src/smithy4s/json/JsoniterCodecCompiler.scala @@ -72,6 +72,12 @@ trait JsoniterCodecCompiler extends CachedSchemaCompiler[JsonCodec] { */ def withHintMask(hintMask: HintMask): JsoniterCodecCompiler + /** + * Enables lenient decoding of tagged unions, where unset alternatives are encoded as null + * values in the json payload. Also ignores unrecognised union keys. + */ + def withLenientTaggedUnionDecoding: JsoniterCodecCompiler + } object JsoniterCodecCompiler { diff --git a/modules/json/src/smithy4s/json/internals/JsoniterCodecCompilerImpl.scala b/modules/json/src/smithy4s/json/internals/JsoniterCodecCompilerImpl.scala index 242897605..09fbc9bc3 100644 --- a/modules/json/src/smithy4s/json/internals/JsoniterCodecCompilerImpl.scala +++ b/modules/json/src/smithy4s/json/internals/JsoniterCodecCompilerImpl.scala @@ -26,7 +26,8 @@ private[smithy4s] case class JsoniterCodecCompilerImpl( flexibleCollectionsSupport: Boolean, infinitySupport: Boolean, preserveMapOrder: Boolean, - hintMask: Option[HintMask] + hintMask: Option[HintMask], + lenientTaggedUnionDecoding: Boolean ) extends CachedSchemaCompiler.Impl[JCodec] with JsoniterCodecCompiler { @@ -55,6 +56,9 @@ private[smithy4s] case class JsoniterCodecCompilerImpl( ): JsoniterCodecCompiler = copy(preserveMapOrder = preserveMapOrder) + def withLenientTaggedUnionDecoding: JsoniterCodecCompiler = + copy(lenientTaggedUnionDecoding = true) + def fromSchema[A](schema: Schema[A], cache: Cache): JCodec[A] = { val visitor = new SchemaVisitorJCodec( maxArity, @@ -62,6 +66,7 @@ private[smithy4s] case class JsoniterCodecCompilerImpl( infinitySupport, flexibleCollectionsSupport, preserveMapOrder, + lenientTaggedUnionDecoding, cache ) val amendedSchema = @@ -82,6 +87,7 @@ private[smithy4s] object JsoniterCodecCompilerImpl { infinitySupport = false, flexibleCollectionsSupport = false, preserveMapOrder = false, + lenientTaggedUnionDecoding = false, hintMask = Some(JsoniterCodecCompiler.defaultHintMask) ) diff --git a/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala b/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala index e4528c37a..1179e3122 100644 --- a/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala +++ b/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala @@ -45,6 +45,7 @@ private[smithy4s] class SchemaVisitorJCodec( infinitySupport: Boolean, flexibleCollectionsSupport: Boolean, preserveMapOrder: Boolean, + lenientTaggedUnionDecoding: Boolean, val cache: CompilationCache[JCodec] ) extends SchemaVisitor.Cached[JCodec] { self => private val emptyMetadata: MMap[String, Any] = MMap.empty @@ -1001,6 +1002,111 @@ private[smithy4s] class SchemaVisitorJCodec( out.encodeError("Cannot use coproducts as keys") } + private def lenientTaggedUnion[U]( + alternatives: Vector[Alt[U, _]] + )(dispatch: Alt.Dispatcher[U]): JCodec[U] = + new JCodec[U] { + val expecting: String = "tagged-union" + + override def canBeKey: Boolean = false + + def jsonLabel[A](alt: Alt[U, A]): String = + alt.hints.get(JsonName) match { + case None => alt.label + case Some(x) => x.value + } + + private[this] val handlerMap = + new util.HashMap[String, (Cursor, JsonReader) => U] { + def handler[A](alt: Alt[U, A]) = { + val codec = apply(alt.schema) + (cursor: Cursor, reader: JsonReader) => + alt.inject(cursor.decode(codec, reader)) + } + + alternatives.foreach(alt => put(jsonLabel(alt), handler(alt))) + } + + def decodeValue(cursor: Cursor, in: JsonReader): U = { + var result: U = null.asInstanceOf[U] + if (in.isNextToken('{')) { + // In this case, metadata and payload are mixed together + // and values field values must be sought from either. + if (!in.isNextToken('}')) { + in.rollbackToken() + while ({ + val key = in.readKeyAsString() + val handler = handlerMap.get(key) + if (handler eq null) in.skip() + else if (in.isNextToken('n')) { + in.readNullOrError((), "expected null") + } else { + in.rollbackToken() + if (result != null) { + in.decodeError("Expected a single non-null value") + } else { + result = handler(cursor, in) + } + } + in.isNextToken(',') + }) () + if (!in.isCurrentToken('}')) in.objectEndOrCommaError() + } + if (result != null) { + result + } else { + in.decodeError("Expected a single non-null value") + } + } else in.decodeError("Expected JSON object") + } + + // if (in.isNextToken('{')) { + // var result: U = null.asInstanceOf[U] + // if (in.isNextToken('}')) + // in.decodeError("Expected a single non-null key/value pair") + // else { + // in.rollbackToken() + // val key = in.readKeyAsString() + // cursor.push(key) + // val handler = handlerMap.get(key) + // if (handler eq null) in.discriminatorValueError(key) + // result = handler(cursor, in) + // cursor.pop() + // if (in.isNextToken('}')) result + // else { + // in.rollbackToken() + // in.decodeError(s"Expected no other set field after $key") + // } + // } + // } else in.decodeError("Expected JSON object") + + val precompiler = new smithy4s.schema.Alt.Precompiler[Writer] { + def apply[A](label: String, instance: Schema[A]): Writer[A] = { + val jsonLabel = + instance.hints.get(JsonName).map(_.value).getOrElse(label) + val jcodecA = instance.compile(self) + a => + out => { + out.writeObjectStart() + out.writeKey(jsonLabel) + jcodecA.encodeValue(a, out) + out.writeObjectEnd() + } + } + } + val writer = dispatch.compile(precompiler) + + def encodeValue(u: U, out: JsonWriter): Unit = { + writer(u)(out) + } + + def decodeKey(in: JsonReader): U = + in.decodeError("Cannot use coproducts as keys") + + def encodeKey(u: U, out: JsonWriter): Unit = + out.encodeError("Cannot use coproducts as keys") + } + private def untaggedUnion[U]( alternatives: Vector[Alt[U, _]] )(dispatch: Alt.Dispatcher[U]): JCodec[U] = new JCodec[U] { @@ -1139,7 +1245,9 @@ private[smithy4s] class SchemaVisitorJCodec( ): JCodec[U] = hints match { case Untagged.hint(_) => untaggedUnion(alternatives)(dispatch) case Discriminated.hint(d) => discriminatedUnion(alternatives, d)(dispatch) - case _ => taggedUnion(alternatives)(dispatch) + case _ => + if (lenientTaggedUnionDecoding) lenientTaggedUnion(alternatives)(dispatch) + else taggedUnion(alternatives)(dispatch) } override def enumeration[E]( diff --git a/modules/json/test/src/smithy4s/json/SchemaVisitorJCodecTests.scala b/modules/json/test/src/smithy4s/json/SchemaVisitorJCodecTests.scala index 1a21e3551..f868dfad3 100644 --- a/modules/json/test/src/smithy4s/json/SchemaVisitorJCodecTests.scala +++ b/modules/json/test/src/smithy4s/json/SchemaVisitorJCodecTests.scala @@ -39,6 +39,8 @@ import smithy4s.schema.Schema._ import scala.collection.immutable.ListMap import scala.util.Try +import smithy4s.json.internals.JsoniterCodecCompilerImpl +import smithy4s.schema.Schema class SchemaVisitorJCodecTests() extends FunSuite { @@ -317,6 +319,28 @@ class SchemaVisitorJCodecTests() extends FunSuite { } } + test("Lenient union") { + val json = """|{ + | "right" : "foo", + | "left" : null + |} + |""".stripMargin + + val json2 = """|{ + | "right": null, + | "left" : 1 + |} + |""".stripMargin + val schema = Schema.either(Schema.int, Schema.string) + + implicit val codec: JsonCodec[Either[Int, String]] = + JsoniterCodecCompilerImpl.defaultJsoniterCodecCompiler.withLenientTaggedUnionDecoding + .fromSchema(schema) + + expect.same(readFromString[Either[Int, String]](json), Right("foo")) + expect.same(readFromString[Either[Int, String]](json2), Left(1)) + } + test("Untagged union are encoded / decoded") { val oneJ = """ {"three":"three_value"}""" val twoJ = """ {"four":4}""" From 46bd0308f0dd39c70e9c2300ef612f4257e307a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20M=C3=A9lois?= Date: Fri, 12 Apr 2024 15:27:53 +0200 Subject: [PATCH 04/23] cleanup --- .../json/internals/SchemaVisitorJCodec.scala | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala b/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala index 1179e3122..697fd1769 100644 --- a/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala +++ b/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala @@ -1059,27 +1059,6 @@ private[smithy4s] class SchemaVisitorJCodec( } } else in.decodeError("Expected JSON object") } - - // if (in.isNextToken('{')) { - // var result: U = null.asInstanceOf[U] - // if (in.isNextToken('}')) - // in.decodeError("Expected a single non-null key/value pair") - // else { - // in.rollbackToken() - // val key = in.readKeyAsString() - // cursor.push(key) - // val handler = handlerMap.get(key) - // if (handler eq null) in.discriminatorValueError(key) - // result = handler(cursor, in) - // cursor.pop() - // if (in.isNextToken('}')) result - // else { - // in.rollbackToken() - // in.decodeError(s"Expected no other set field after $key") - // } - // } - // } else in.decodeError("Expected JSON object") - val precompiler = new smithy4s.schema.Alt.Precompiler[Writer] { def apply[A](label: String, instance: Schema[A]): Writer[A] = { val jsonLabel = From 3e77a6c2b9fe65a6661dd9f656047500b832a9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20M=C3=A9lois?= Date: Fri, 12 Apr 2024 15:30:12 +0200 Subject: [PATCH 05/23] Update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4e7ce861..38a1edd31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # 0.18.16 +* Makes the json decoding of tagged-unions lenient for AWS * Add support for converting smithy4s services and schemas to smithy models -* Add `smithy4s.meta#only` annotation allowing to filter operations in +* Add `smithy4s.meta#only` annotation allowing to filter operations in services, intended to reduce the amount of code generated from AWS specs # 0.18.15 From e7637b0c6aa6a3358c3a0fd51810ff17efdb2ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20M=C3=A9lois?= Date: Fri, 12 Apr 2024 15:38:26 +0200 Subject: [PATCH 06/23] Cleanup comments --- .../smithy4s/json/internals/SchemaVisitorJCodec.scala | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala b/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala index 697fd1769..5551ed245 100644 --- a/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala +++ b/modules/json/src/smithy4s/json/internals/SchemaVisitorJCodec.scala @@ -1030,8 +1030,6 @@ private[smithy4s] class SchemaVisitorJCodec( def decodeValue(cursor: Cursor, in: JsonReader): U = { var result: U = null.asInstanceOf[U] if (in.isNextToken('{')) { - // In this case, metadata and payload are mixed together - // and values field values must be sought from either. if (!in.isNextToken('}')) { in.rollbackToken() while ({ @@ -1449,8 +1447,6 @@ private[smithy4s] class SchemaVisitorJCodec( ): scala.collection.Map[String, Any] => Z = { val buffer = new util.HashMap[String, Any](handlers.size << 1, 0.5f) if (in.isNextToken('{')) { - // In this case, metadata and payload are mixed together - // and values field values must be sought from either. if (!in.isNextToken('}')) { in.rollbackToken() while ({ @@ -1466,9 +1462,8 @@ private[smithy4s] class SchemaVisitorJCodec( // At this point, we have parsed the json and retrieved // all the values that interest us for the construction // of our domain object. - // We therefore reconcile the values pulled from the json - // with the ones pull the metadata, and call the constructor - // on it. + // We re-order the values following the order of the schema + // fields before calling the constructor. { (meta: scala.collection.Map[String, Any]) => meta.foreach(kv => buffer.put(kv._1, kv._2)) val stage2 = new VectorBuilder[Any] From 85acc337447756cb3c54ef59846912e7574a97e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Thu, 9 May 2024 21:10:46 +0200 Subject: [PATCH 07/23] bump smithy to 1.48.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 125b099f4..271da435b 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -19,7 +19,7 @@ object Dependencies { val Smithy = new { val org = "software.amazon.smithy" - val smithyVersion = "1.47.0" + val smithyVersion = "1.48.0" val model = org % "smithy-model" % smithyVersion val testTraits = org % "smithy-protocol-test-traits" % smithyVersion val build = org % "smithy-build" % smithyVersion @@ -31,7 +31,7 @@ object Dependencies { val Alloy = new { val org = "com.disneystreaming.alloy" - val alloyVersion = "0.3.6" + val alloyVersion = "0.3.7" val core = org % "alloy-core" % alloyVersion val openapi = org %% "alloy-openapi" % alloyVersion val protobuf = org % "alloy-protobuf" % alloyVersion From 6eecd86cf75daca35fc90253c84858bc9c7783cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Thu, 9 May 2024 21:10:59 +0200 Subject: [PATCH 08/23] comment --- project/Dependencies.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 271da435b..11241aac0 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -31,6 +31,7 @@ object Dependencies { val Alloy = new { val org = "com.disneystreaming.alloy" + // TODO: bump after release of smithy 1.48.0 bump val alloyVersion = "0.3.7" val core = org % "alloy-core" % alloyVersion val openapi = org %% "alloy-openapi" % alloyVersion From 51800e5f66ec5fda42897b94b84495ae49de981c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Thu, 9 May 2024 21:17:25 +0200 Subject: [PATCH 09/23] Add mima exclusions --- build.sbt | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/build.sbt b/build.sbt index ce44493e9..76b590396 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,7 @@ +import com.typesafe.tools.mima.core.ProblemFilters +import com.typesafe.tools.mima.core.MissingClassProblem +import com.typesafe.tools.mima.core.IncompatibleResultTypeProblem +import com.typesafe.tools.mima.core.IncompatibleMethTypeProblem import _root_.java.util.stream.Collectors import java.nio.file.Files import sbt.internal.IvyConsole @@ -217,6 +221,39 @@ lazy val core = projectMatrix }, scalacOptions ++= Seq( "-Wconf:msg=value noInlineDocumentSupport in class ProtocolDefinition is deprecated:silent" + ), + mimaBinaryIssueFilters ++= Seq( + // Incompatible change from smithy 1.46.0 + // Introduced in https://github.com/smithy-lang/smithy/pull/2156 + // Discussed in https://github.com/smithy-lang/smithy/issues/2243 + // Brought to smithy4s in https://github.com/disneystreaming/smithy4s/pull/1485 + ProblemFilters.exclude[MissingClassProblem]( + "smithy.api.TraitChangeSeverity*" + ), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "smithy.api.TraitDiffRule.apply" + ), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "smithy.api.TraitDiffRule.$default$2" + ), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "smithy.api.TraitDiffRule.this" + ), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "smithy.api.TraitDiffRule.severity" + ), + ProblemFilters.exclude[IncompatibleMethTypeProblem]( + "smithy.api.TraitDiffRule.copy" + ), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "smithy.api.TraitDiffRule.copy$default$2" + ), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "smithy.api.TraitDiffRule._2" + ), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "smithy.api.TraitDiffRule.apply$default$2" + ) ) ) .jvmPlatform(allJvmScalaVersions, jvmDimSettings) From c9dc233f9442ecb75d416fdd635ebdfd7fe24ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Thu, 9 May 2024 21:28:32 +0200 Subject: [PATCH 10/23] Fix test with arity problem --- .../smithy4s/http4s/SimpleRestJsonComplianceSuite.scala | 9 ++++++++- .../src/smithy4s/json/JsonPayloadCodecCompiler.scala | 7 +++++++ .../json/internals/JsonPayloadCodecCompilerImpl.scala | 8 ++++++++ .../src/smithy4s/tests/ProtocolComplianceSuite.scala | 7 +++++-- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/modules/http4s/test/src/smithy4s/http4s/SimpleRestJsonComplianceSuite.scala b/modules/http4s/test/src/smithy4s/http4s/SimpleRestJsonComplianceSuite.scala index 77d264f73..6c82c5d35 100644 --- a/modules/http4s/test/src/smithy4s/http4s/SimpleRestJsonComplianceSuite.scala +++ b/modules/http4s/test/src/smithy4s/http4s/SimpleRestJsonComplianceSuite.scala @@ -123,7 +123,14 @@ object SimpleRestJsonComplianceSuite extends ProtocolComplianceSuite { .compile .toVector .map(_.toArray) - .map(decodeDocument(_, smithy4s.json.Json.payloadDecoders)) + .map( + decodeDocument( + _, + smithy4s.json.Json.payloadCodecs + .configureJsoniterCodecCompiler(_.withMaxArity(Int.MaxValue)) + .decoders + ) + ) .flatMap(loadDynamic(_).liftTo[IO]) } yield dsi } diff --git a/modules/json/src/smithy4s/json/JsonPayloadCodecCompiler.scala b/modules/json/src/smithy4s/json/JsonPayloadCodecCompiler.scala index 8d65737e2..c87516220 100644 --- a/modules/json/src/smithy4s/json/JsonPayloadCodecCompiler.scala +++ b/modules/json/src/smithy4s/json/JsonPayloadCodecCompiler.scala @@ -32,6 +32,13 @@ trait JsonPayloadCodecCompiler { */ def withJsoniterCodecCompiler(jsoniterCodecCompiler: JsoniterCodecCompiler): JsonPayloadCodecCompiler + /** + * Like withJsoniterCodecCompiler, but allows you to modify the current codec compiler more easily. + */ + def configureJsoniterCodecCompiler( + jsoniterCodecCompiler: JsoniterCodecCompiler => JsoniterCodecCompiler + ): JsonPayloadCodecCompiler + /** * Changes the jsoniter reader config that is used when parsing json payloads into data. */ diff --git a/modules/json/src/smithy4s/json/internals/JsonPayloadCodecCompilerImpl.scala b/modules/json/src/smithy4s/json/internals/JsonPayloadCodecCompilerImpl.scala index c02450ed8..353df1fc0 100644 --- a/modules/json/src/smithy4s/json/internals/JsonPayloadCodecCompilerImpl.scala +++ b/modules/json/src/smithy4s/json/internals/JsonPayloadCodecCompilerImpl.scala @@ -39,6 +39,14 @@ private[json] case class JsonPayloadCodecCompilerImpl( jsoniterCodecCompiler: JsoniterCodecCompiler ): JsonPayloadCodecCompiler = copy(jsoniterCodecCompiler = jsoniterCodecCompiler) + + def configureJsoniterCodecCompiler( + jsoniterCodecCompiler: JsoniterCodecCompiler => JsoniterCodecCompiler + ): JsonPayloadCodecCompiler = + copy(jsoniterCodecCompiler = + jsoniterCodecCompiler(this.jsoniterCodecCompiler) + ) + def withJsoniterReaderConfig( jsoniterReaderConfig: JsoniterReaderConfig ): JsonPayloadCodecCompiler = diff --git a/modules/tests/src/smithy4s/tests/ProtocolComplianceSuite.scala b/modules/tests/src/smithy4s/tests/ProtocolComplianceSuite.scala index 30fadb667..073b3592b 100644 --- a/modules/tests/src/smithy4s/tests/ProtocolComplianceSuite.scala +++ b/modules/tests/src/smithy4s/tests/ProtocolComplianceSuite.scala @@ -132,8 +132,11 @@ abstract class ProtocolComplianceSuite val codec: PayloadDecoder[Document] = codecApi.fromSchema(Schema.document) codec .decode(Blob(bytes)) - .getOrElse(sys.error("unable to decode smithy model into document")) - + .leftMap( + new RuntimeException("unable to decode smithy model into document", _) + ) + .toTry + .get } private def runInWeaver( From 4e2fef75c571bd28ff129d3dfb021a288c76cb81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Thu, 9 May 2024 21:47:13 +0200 Subject: [PATCH 11/23] new alloy who dis --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 11241aac0..141e57218 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -32,7 +32,7 @@ object Dependencies { val Alloy = new { val org = "com.disneystreaming.alloy" // TODO: bump after release of smithy 1.48.0 bump - val alloyVersion = "0.3.7" + val alloyVersion = "0.3.8" val core = org % "alloy-core" % alloyVersion val openapi = org %% "alloy-openapi" % alloyVersion val protobuf = org % "alloy-protobuf" % alloyVersion From cfbf402f6deab90de5ed048661eaf8a70c916faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Thu, 9 May 2024 23:29:46 +0200 Subject: [PATCH 12/23] empty commit From f7b7173d9224302b3f97f77ca3aac8c730c303ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 00:06:28 +0200 Subject: [PATCH 13/23] Update CHANGELOG --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c21ae411a..c23ece2e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## Maintainers' notice + +This file serves as a template for release notes in GitHub releases. +When adding entries, please treat them as if they could end up in a release any time. This makes it much easier for us to make frequent releases! + +Thank you! + +# 0.18.18 - binary-breaking changes in `core` + +**WARNING**: This release includes binary-breaking changes in the `core` module. This is indirectly caused by an upstream change in [smithy-lang/smithy](https://github.com/smithy-lang/smithy/), +and it'll most likely cause runtime issues in all applications that use a mix of versions in the ranges `0.18.0 ≤ 0.18.17` and `0.18.18+`. + +For your applications' safety, when upgrading beyond `0.18.17`, make sure all your dependencies are compiled against a version of Smithy4s at least equal to `0.18.18`. This can be done with the `whatDependsOn` task in sbt. + + We apologize for the inconvenience. + +* Update smithy: 1.45.0 to 1.48.0 (binary breaking) in https://github.com/disneystreaming/smithy4s/pull/1485 + # 0.18.17 * Constraints applied to list or map members are now correctly rendered in the generated code. From b961bd7ea8e778a54a02219043e029c8a43a547c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 00:07:17 +0200 Subject: [PATCH 14/23] fix versions --- .../update-lsp-config/expected.json | 34 +++++++++---------- smithy-build.json | 4 +-- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json b/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json index 4cc982ecf..36a3b94ca 100644 --- a/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json +++ b/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json @@ -1,20 +1,18 @@ { - "version" : "1.0", - "imports" : [ - "subproj2/src/main/smithy", - "subproj2/target/scala-2.12/src_managed/main/smithy" - ], - "maven" : { - "dependencies" : [ - "com.disneystreaming.alloy:alloy-core:0.3.6" - ], - "repositories" : [ - { - "url" : "https://oss.sonatype.org/content/repositories/snapshots" - }, - { - "url" : "https://s01.oss.sonatype.org/content/repositories/snapshots" - } - ] - } + "version": "1.0", + "imports": [ + "subproj2/src/main/smithy", + "subproj2/target/scala-2.12/src_managed/main/smithy" + ], + "maven": { + "dependencies": ["com.disneystreaming.alloy:alloy-core:0.3.8"], + "repositories": [ + { + "url": "https://oss.sonatype.org/content/repositories/snapshots" + }, + { + "url": "https://s01.oss.sonatype.org/content/repositories/snapshots" + } + ] + } } diff --git a/smithy-build.json b/smithy-build.json index 8b0f74136..a15aabd63 100644 --- a/smithy-build.json +++ b/smithy-build.json @@ -3,8 +3,8 @@ "imports": ["./sampleSpecs", "./modules/protocol/resources"], "maven": { "dependencies": [ - "software.amazon.smithy:smithy-protocol-test-traits:1.47.0", - "com.disneystreaming.alloy:alloy-core:0.3.6" + "software.amazon.smithy:smithy-protocol-test-traits:1.48.0", + "com.disneystreaming.alloy:alloy-core:0.3.8" ] } } From 25715932e85ba19c245e9bf4eb2e5b15c1f38dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 00:35:00 +0200 Subject: [PATCH 15/23] update lsp file --- .../update-lsp-config/expected.json | 48 ++++++++++++------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json b/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json index 36a3b94ca..8a21c9425 100644 --- a/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json +++ b/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json @@ -1,18 +1,32 @@ { - "version": "1.0", - "imports": [ - "subproj2/src/main/smithy", - "subproj2/target/scala-2.12/src_managed/main/smithy" - ], - "maven": { - "dependencies": ["com.disneystreaming.alloy:alloy-core:0.3.8"], - "repositories": [ - { - "url": "https://oss.sonatype.org/content/repositories/snapshots" - }, - { - "url": "https://s01.oss.sonatype.org/content/repositories/snapshots" - } - ] - } -} + "version" : "1.0", + "imports" : [ + "subproj2/src/main/smithy", + "subproj2/target/scala-2.12/src_managed/main/smithy" + ], + "maven" : { + "dependencies" : [ + "com.disneystreaming.alloy:alloy-core:0.3.6" + ], + "repositories" : [ + { + "url" : "https://oss.sonatype.org/content/repositories/snapshots" + }, + { + "url" : "https://s01.oss.sonatype.org/content/repositories/snapshots" + }, + { + "url" : "https://oss.sonatype.org/content/repositories/snapshots" + }, + { + "url" : "https://s01.oss.sonatype.org/content/repositories/snapshots" + }, + { + "url" : "https://oss.sonatype.org/content/repositories/snapshots" + }, + { + "url" : "https://s01.oss.sonatype.org/content/repositories/snapshots" + } + ] + } +} \ No newline at end of file From 495051f612a47aa2ee5d904ac601d003c1f256dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 00:48:21 +0200 Subject: [PATCH 16/23] remove todo --- project/Dependencies.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 141e57218..d09c1c7c4 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -31,7 +31,6 @@ object Dependencies { val Alloy = new { val org = "com.disneystreaming.alloy" - // TODO: bump after release of smithy 1.48.0 bump val alloyVersion = "0.3.8" val core = org % "alloy-core" % alloyVersion val openapi = org %% "alloy-openapi" % alloyVersion From 8a28a12ddcff9ac4a2cb57b7bd8fc957269aa62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 00:52:28 +0200 Subject: [PATCH 17/23] fix lsp again --- .../codegen-plugin/update-lsp-config/expected.json | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json b/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json index 8a21c9425..4cc982ecf 100644 --- a/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json +++ b/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json @@ -9,18 +9,6 @@ "com.disneystreaming.alloy:alloy-core:0.3.6" ], "repositories" : [ - { - "url" : "https://oss.sonatype.org/content/repositories/snapshots" - }, - { - "url" : "https://s01.oss.sonatype.org/content/repositories/snapshots" - }, - { - "url" : "https://oss.sonatype.org/content/repositories/snapshots" - }, - { - "url" : "https://s01.oss.sonatype.org/content/repositories/snapshots" - }, { "url" : "https://oss.sonatype.org/content/repositories/snapshots" }, @@ -29,4 +17,4 @@ } ] } -} \ No newline at end of file +} From 9c44a439a01058a7040fef4dfa773e94d48eefcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 01:07:41 +0200 Subject: [PATCH 18/23] restore version number --- .../src/sbt-test/codegen-plugin/update-lsp-config/expected.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json b/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json index 4cc982ecf..338a06340 100644 --- a/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json +++ b/modules/codegen-plugin/src/sbt-test/codegen-plugin/update-lsp-config/expected.json @@ -6,7 +6,7 @@ ], "maven" : { "dependencies" : [ - "com.disneystreaming.alloy:alloy-core:0.3.6" + "com.disneystreaming.alloy:alloy-core:0.3.8" ], "repositories" : [ { From 4e3f252a25ecc70eae7fc1bde574a43a0bb728a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 01:08:27 +0200 Subject: [PATCH 19/23] Remove leftover println --- .../src/smithy4s/codegen/GenerateSmithyBuild.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/codegen-plugin/src/smithy4s/codegen/GenerateSmithyBuild.scala b/modules/codegen-plugin/src/smithy4s/codegen/GenerateSmithyBuild.scala index 4d4c5e114..81a79e953 100644 --- a/modules/codegen-plugin/src/smithy4s/codegen/GenerateSmithyBuild.scala +++ b/modules/codegen-plugin/src/smithy4s/codegen/GenerateSmithyBuild.scala @@ -100,7 +100,6 @@ private[codegen] object GenerateSmithyBuild { pr: ProjectRef, settings: Settings[Scope] ): ListSet[String] = { - println("extract Repos") (pr / resolvers) .get(settings) .toList From 7025ad563c7b66f339e2e93216cadc188cdff3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 01:20:08 +0200 Subject: [PATCH 20/23] Update to 1.49.0 --- CHANGELOG.md | 2 +- project/Dependencies.scala | 2 +- smithy-build.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c23ece2e3..23b264b01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ For your applications' safety, when upgrading beyond `0.18.17`, make sure all yo We apologize for the inconvenience. -* Update smithy: 1.45.0 to 1.48.0 (binary breaking) in https://github.com/disneystreaming/smithy4s/pull/1485 +* Update smithy: 1.45.0 to 1.49.0 (binary breaking) in https://github.com/disneystreaming/smithy4s/pull/1485 # 0.18.17 diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d09c1c7c4..c7e97435e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -19,7 +19,7 @@ object Dependencies { val Smithy = new { val org = "software.amazon.smithy" - val smithyVersion = "1.48.0" + val smithyVersion = "1.49.0" val model = org % "smithy-model" % smithyVersion val testTraits = org % "smithy-protocol-test-traits" % smithyVersion val build = org % "smithy-build" % smithyVersion diff --git a/smithy-build.json b/smithy-build.json index a15aabd63..966316dcc 100644 --- a/smithy-build.json +++ b/smithy-build.json @@ -3,7 +3,7 @@ "imports": ["./sampleSpecs", "./modules/protocol/resources"], "maven": { "dependencies": [ - "software.amazon.smithy:smithy-protocol-test-traits:1.48.0", + "software.amazon.smithy:smithy-protocol-test-traits:1.49.0", "com.disneystreaming.alloy:alloy-core:0.3.8" ] } From c44f207175622611a517d3cd9b2f0abc34c044f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 01:41:13 +0200 Subject: [PATCH 21/23] Skip empty lists in ec2query --- .../smithy4s/aws/internals/AwsEc2QueryCodecs.scala | 2 +- .../src/smithy4s/aws/internals/AwsQueryCodecs.scala | 2 +- .../UrlFormDataEncoderDecoderSchemaVisitorSpec.scala | 2 +- modules/core/src/smithy4s/http/UrlForm.scala | 11 +++++++++-- .../internals/UrlFormDataEncoderSchemaVisitor.scala | 8 ++++++-- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/modules/aws-http4s/src/smithy4s/aws/internals/AwsEc2QueryCodecs.scala b/modules/aws-http4s/src/smithy4s/aws/internals/AwsEc2QueryCodecs.scala index 059b41bc9..5c79d51c9 100644 --- a/modules/aws-http4s/src/smithy4s/aws/internals/AwsEc2QueryCodecs.scala +++ b/modules/aws-http4s/src/smithy4s/aws/internals/AwsEc2QueryCodecs.scala @@ -88,7 +88,7 @@ private[aws] object AwsEcsQueryCodecs { // without UrlFormDataEncoderSchemaVisitor having to be more aware than necessary of these protocol quirks. private[aws] val inputEncoders = { UrlForm - .Encoder(capitalizeStructAndUnionMemberNames = true) + .Encoder(capitalizeStructAndUnionMemberNames = true, alwaysSkipEmptyLists = true) .mapK { smithy4s.codecs.Encoder.andThenK((form: UrlForm) => Blob(form.render)) } } diff --git a/modules/aws-http4s/src/smithy4s/aws/internals/AwsQueryCodecs.scala b/modules/aws-http4s/src/smithy4s/aws/internals/AwsQueryCodecs.scala index 9aaaf7721..412d6d267 100644 --- a/modules/aws-http4s/src/smithy4s/aws/internals/AwsQueryCodecs.scala +++ b/modules/aws-http4s/src/smithy4s/aws/internals/AwsQueryCodecs.scala @@ -37,7 +37,7 @@ private[aws] object AwsQueryCodecs { private[aws] val inputEncoders = { UrlForm - .Encoder(capitalizeStructAndUnionMemberNames = false) + .Encoder(capitalizeStructAndUnionMemberNames = false, alwaysSkipEmptyLists = false) .mapK { smithy4s.codecs.Encoder.andThenK((form: UrlForm) => Blob(form.render)) } } diff --git a/modules/bootstrapped/test/src/smithy4s/http/internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala b/modules/bootstrapped/test/src/smithy4s/http/internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala index e10734756..c52f99650 100644 --- a/modules/bootstrapped/test/src/smithy4s/http/internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala +++ b/modules/bootstrapped/test/src/smithy4s/http/internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala @@ -195,7 +195,7 @@ object UrlFormDataEncoderDecoderSchemaVisitorSpec extends SimpleIOSuite { expect.same( UrlForm .Encoder( - capitalizeStructAndUnionMemberNames = false + capitalizeStructAndUnionMemberNames = false, ) .fromSchema(Foo.schema) .encode(Foo(42, defaultValue)) diff --git a/modules/core/src/smithy4s/http/UrlForm.scala b/modules/core/src/smithy4s/http/UrlForm.scala index 47641e732..3efdb631c 100644 --- a/modules/core/src/smithy4s/http/UrlForm.scala +++ b/modules/core/src/smithy4s/http/UrlForm.scala @@ -195,9 +195,15 @@ object UrlForm { object Encoder { - /** Constructs an [[Encoder]] that encodes data as [[UrlForm]]s. Can be configured using `@alloyurlformname`. */ def apply( capitalizeStructAndUnionMemberNames: Boolean + ): CachedSchemaCompiler[Encoder] = + apply(capitalizeStructAndUnionMemberNames, alwaysSkipEmptyLists = false) + + /** Constructs an [[Encoder]] that encodes data as [[UrlForm]]s. Can be configured using `@alloy#urlformname`. */ + def apply( + capitalizeStructAndUnionMemberNames: Boolean, + alwaysSkipEmptyLists: Boolean ): CachedSchemaCompiler[Encoder] = new CachedSchemaCompiler.Impl[Encoder] { protected override type Aux[A] = UrlFormDataEncoder[A] @@ -213,7 +219,8 @@ object UrlForm { } val schemaVisitor = new UrlFormDataEncoderSchemaVisitor( cache, - capitalizeStructAndUnionMemberNames + capitalizeStructAndUnionMemberNames, + alwaysSkipEmptyLists ) val urlFormDataEncoder = schemaVisitor(schema) maybeStaticUrlFormData match { diff --git a/modules/core/src/smithy4s/http/internals/UrlFormDataEncoderSchemaVisitor.scala b/modules/core/src/smithy4s/http/internals/UrlFormDataEncoderSchemaVisitor.scala index 5d790ea96..318cb5732 100644 --- a/modules/core/src/smithy4s/http/internals/UrlFormDataEncoderSchemaVisitor.scala +++ b/modules/core/src/smithy4s/http/internals/UrlFormDataEncoderSchemaVisitor.scala @@ -28,7 +28,8 @@ private[http] class UrlFormDataEncoderSchemaVisitor( val cache: CompilationCache[UrlFormDataEncoder], // These are used by AwsEc2QueryCodecs to conform to the requirements of // https://smithy.io/2.0/aws/protocols/aws-ec2-query-protocol.html?highlight=ec2%20query%20protocol#query-key-resolution. - capitalizeStructAndUnionMemberNames: Boolean + capitalizeStructAndUnionMemberNames: Boolean, + alwaysSkipEmptyLists: Boolean ) extends SchemaVisitor.Cached[UrlFormDataEncoder] { compile => override def primitive[P]( @@ -60,7 +61,10 @@ private[http] class UrlFormDataEncoderSchemaVisitor( val maybeKey = if (hints.has[UrlFormFlattened]) None else Option(getKey(member.hints, "member")) - val skipEmpty = hints.toMap.contains(SkipEmpty.keyId) + + val skipEmpty = + hints.toMap.contains(SkipEmpty.keyId) || alwaysSkipEmptyLists + collection => // This is to handle a quirk of the AWS Query protocol at // https://github.com/smithy-lang/smithy/blob/f8a846df3c67fa4ae55ecaa57002d22499dc439f/smithy-aws-protocol-tests/model/awsQuery/input-lists.smithy#L43-L57 From 4c595531078aec3fe1b00e68d7fe19c8610f17b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 10 May 2024 01:43:19 +0200 Subject: [PATCH 22/23] format --- .../internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/bootstrapped/test/src/smithy4s/http/internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala b/modules/bootstrapped/test/src/smithy4s/http/internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala index c52f99650..e10734756 100644 --- a/modules/bootstrapped/test/src/smithy4s/http/internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala +++ b/modules/bootstrapped/test/src/smithy4s/http/internals/UrlFormDataEncoderDecoderSchemaVisitorSpec.scala @@ -195,7 +195,7 @@ object UrlFormDataEncoderDecoderSchemaVisitorSpec extends SimpleIOSuite { expect.same( UrlForm .Encoder( - capitalizeStructAndUnionMemberNames = false, + capitalizeStructAndUnionMemberNames = false ) .fromSchema(Foo.schema) .encode(Foo(42, defaultValue)) From bc76147e83fa6893e4fef751938c93242d408e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Tue, 14 May 2024 18:58:45 +0200 Subject: [PATCH 23/23] update changelog to be less scary --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b8af7854..08ae454ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,13 @@ Thank you! # 0.18.19 - binary-breaking changes in `core` -**WARNING**: This release includes binary-breaking changes in the `core` module. This is indirectly caused by an upstream change in [smithy-lang/smithy](https://github.com/smithy-lang/smithy/), -and it'll most likely cause runtime issues in all applications that use a mix of versions in the ranges `0.18.0 ≤ 0.18.17` and `0.18.18+`. +**WARNING**: This release includes binary-breaking changes in the `core` module. This is indirectly caused by an upstream change in [smithy-lang/smithy](https://github.com/smithy-lang/smithy/). -For your applications' safety, when upgrading beyond `0.18.17`, make sure all your dependencies are compiled against a version of Smithy4s at least equal to `0.18.18`. This can be done with the `whatDependsOn` task in sbt. +In the vast majority of applications using Smithy4s, it will not cause runtime issues. However, in the unlikely event that you have custom interpreters that query the `.breakingChanges` field of a `Trait` hint, or have that field populated by a non-stdlib trait/hint, you'll have to ensure that all the libraries pulled by your application are compiled against smithy4s 0.18.19 or above. - We apologize for the inconvenience. +In sbt, you can check what versions of smithy4s are used by your dependencies using the `whatDependsOn` task. + +We apologize for the inconvenience. * Update smithy: 1.45.0 to 1.49.0 (binary breaking) in https://github.com/disneystreaming/smithy4s/pull/1485