From 086839936547496dd3a2ac29580056487efc3aac Mon Sep 17 00:00:00 2001 From: "http4s-steward[bot]" <106843772+http4s-steward[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 20:21:49 +0000 Subject: [PATCH 01/15] Update scala3-library, ... to 3.3.1 --- .github/workflows/ci.yml | 6 +++--- build.sbt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85e988e..43b4012 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - scala: [2.12.18, 2.13.11, 3.3.0] + scala: [2.12.18, 2.13.11, 3.3.1] java: [temurin@8, temurin@11, temurin@17] project: [rootJS, rootJVM, rootNative] exclude: @@ -37,9 +37,9 @@ jobs: java: temurin@11 - scala: 2.12.18 java: temurin@17 - - scala: 3.3.0 + - scala: 3.3.1 java: temurin@11 - - scala: 3.3.0 + - scala: 3.3.1 java: temurin@17 - project: rootJS java: temurin@11 diff --git a/build.sbt b/build.sbt index 8673378..73c188b 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ ThisBuild / developers := List( ) val Scala213 = "2.13.11" -ThisBuild / crossScalaVersions := Seq("2.12.18", Scala213, "3.3.0") +ThisBuild / crossScalaVersions := Seq("2.12.18", Scala213, "3.3.1") ThisBuild / scalaVersion := Scala213 // ensure missing timezones don't break tests on JS From 05afc2f906dfa517ea2c7c004c7102320dab6420 Mon Sep 17 00:00:00 2001 From: "http4s-steward[bot]" <106843772+http4s-steward[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 20:22:15 +0000 Subject: [PATCH 02/15] Regenerate GitHub Actions workflow Executed command: sbt githubWorkflowGenerate --- .github/workflows/ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 43b4012..57c6507 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -300,32 +300,32 @@ jobs: tar xf targets.tar rm targets.tar - - name: Download target directories (3.3.0, rootJS) + - name: Download target directories (3.3.1, rootJS) uses: actions/download-artifact@v3 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-3.3.0-rootJS + name: target-${{ matrix.os }}-${{ matrix.java }}-3.3.1-rootJS - - name: Inflate target directories (3.3.0, rootJS) + - name: Inflate target directories (3.3.1, rootJS) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (3.3.0, rootJVM) + - name: Download target directories (3.3.1, rootJVM) uses: actions/download-artifact@v3 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-3.3.0-rootJVM + name: target-${{ matrix.os }}-${{ matrix.java }}-3.3.1-rootJVM - - name: Inflate target directories (3.3.0, rootJVM) + - name: Inflate target directories (3.3.1, rootJVM) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (3.3.0, rootNative) + - name: Download target directories (3.3.1, rootNative) uses: actions/download-artifact@v3 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-3.3.0-rootNative + name: target-${{ matrix.os }}-${{ matrix.java }}-3.3.1-rootNative - - name: Inflate target directories (3.3.0, rootNative) + - name: Inflate target directories (3.3.1, rootNative) run: | tar xf targets.tar rm targets.tar From 4a422533f172629939d8087fcdf318d0e145e855 Mon Sep 17 00:00:00 2001 From: "http4s-steward[bot]" <106843772+http4s-steward[bot]@users.noreply.github.com> Date: Sun, 17 Sep 2023 20:14:38 +0000 Subject: [PATCH 03/15] Update fs2-data-cbor, fs2-data-csv, ... to 1.8.1 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 8673378..f87890b 100644 --- a/build.sbt +++ b/build.sbt @@ -19,7 +19,7 @@ lazy val root = tlCrossRootProject.aggregate(xml, xmlScala, csv, cbor) val http4sVersion = "0.23.23" val scalaXmlVersion = "2.2.0" val fs2Version = "3.8.0" -val fs2DataVersion = "1.8.0" +val fs2DataVersion = "1.8.1" val munitVersion = "1.0.0-M8" val munitCatsEffectVersion = "2.0.0-M3" From bd5edd9e2b30922b52332fcaeaa09db43abe3c5d Mon Sep 17 00:00:00 2001 From: Yannick Heiber Date: Sat, 30 Sep 2023 12:18:43 +0200 Subject: [PATCH 04/15] Add work around for scala-xml test flake As Scala XML has some special interpretation of when to escape, we avoid & and < in text elements to ensure roundtrip passes. --- .../scala/org/http4s/fs2data/xml/scalaxml/generators.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xml-scala/src/test/scala/org/http4s/fs2data/xml/scalaxml/generators.scala b/xml-scala/src/test/scala/org/http4s/fs2data/xml/scalaxml/generators.scala index 9e057fb..57cb21c 100644 --- a/xml-scala/src/test/scala/org/http4s/fs2data/xml/scalaxml/generators.scala +++ b/xml-scala/src/test/scala/org/http4s/fs2data/xml/scalaxml/generators.scala @@ -434,7 +434,10 @@ object generators { n <- Gen.poisson(5) s <- Gen.stringOfN(n, Gen.oneOf(char)) // Text may not contain these two in literal form, ยง2.4 of XML syntax - r = s.replace("&", "&").replace("<", "<") + // We replace them by empty strings instead of their quoted versions because Scala XML fails the roundtrip + // Relates to https://github.com/scala/scala-xml/issues/57 + // Works around https://github.com/http4s/http4s-fs2-data/issues/88 + r = s.replace("&", "").replace("<", "") } yield Text(r) val genComment: Gen[Comment] = From 82690a97b461112e9aca5c74d3ebae51cc142d87 Mon Sep 17 00:00:00 2001 From: "http4s-steward[bot]" <106843772+http4s-steward[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 20:18:37 +0000 Subject: [PATCH 05/15] Update scalafmt-core to 3.7.17 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index da9b6ec..dd3c89a 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = 3.7.12 +version = 3.7.17 style = default From 4ab7c9a319fa31b70814ac418933cdf87e64ea9f Mon Sep 17 00:00:00 2001 From: "http4s-steward[bot]" <106843772+http4s-steward[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 08:23:39 +0000 Subject: [PATCH 06/15] Update sbt to 1.9.8 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 3040987..abbbce5 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.4 +sbt.version=1.9.8 From 23b77c4fb6e0f987d485fafe805f36a3224d5e5c Mon Sep 17 00:00:00 2001 From: "http4s-steward[bot]" <106843772+http4s-steward[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:12:17 +0000 Subject: [PATCH 07/15] Update sbt-scalajs, scalajs-compiler, ... to 1.15.0 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 42521c1..8597e31 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ addSbtPlugin("org.http4s" % "sbt-http4s-org" % "0.14.13") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.13.2") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.15.0") addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.14") From 9f010d99bc6f8f303149bf3f2fb7c4b8264e8b2f Mon Sep 17 00:00:00 2001 From: ubaldop Date: Fri, 19 Jan 2024 15:42:17 +0100 Subject: [PATCH 08/15] Add support to JSON encoding and decoding --- README.md | 1 + build.sbt | 18 +++++ .../http4s/fs2data/json/JsonInstances.scala | 66 +++++++++++++++++++ .../scala/org/http4s/fs2data/json/json.scala | 19 ++++++ .../http4s/fs2data/json/JsonEventSuite.scala | 55 ++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 json/src/main/scala/org/http4s/fs2data/json/JsonInstances.scala create mode 100644 json/src/main/scala/org/http4s/fs2data/json/json.scala create mode 100644 json/src/test/scala/org/http4s/fs2data/json/JsonEventSuite.scala diff --git a/README.md b/README.md index 590f384..0dc18aa 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Home of http4s integrations with [fs2-data][fs2-data]. Initially forked from [ht * XML and Scala XML. Works as a drop-in replacement for [http4s-scala-xml][http4s-scala-xml] * CSV * CBOR +* JSON Check out the [docs][docs] for examples. diff --git a/build.sbt b/build.sbt index 8673378..8032497 100644 --- a/build.sbt +++ b/build.sbt @@ -96,6 +96,24 @@ lazy val cbor = crossProject(JVMPlatform, JSPlatform, NativePlatform) ), ) +lazy val json = crossProject(JVMPlatform, JSPlatform, NativePlatform) + .crossType(CrossType.Pure) + .in(file("json")) + .settings( + name := "http4s-fs2-data-json", + description := "Provides JSON codecs for http4s via fs2-data", + startYear := Some(2023), + tlVersionIntroduced := Map("2.12" -> "0.2", "2.13" -> "0.2", "3" -> "0.2"), + libraryDependencies ++= Seq( + "co.fs2" %%% "fs2-core" % fs2Version, + "org.http4s" %%% "http4s-core" % http4sVersion, + "org.gnieh" %%% "fs2-data-json" % fs2DataVersion, + "org.scalameta" %%% "munit-scalacheck" % munitVersion % Test, + "org.typelevel" %%% "munit-cats-effect" % munitCatsEffectVersion % Test, + "org.http4s" %%% "http4s-laws" % http4sVersion % Test, + ), + ) + lazy val docs = project .in(file("site")) .dependsOn(xml.jvm, xmlScala.jvm, csv.jvm, cbor.jvm) diff --git a/json/src/main/scala/org/http4s/fs2data/json/JsonInstances.scala b/json/src/main/scala/org/http4s/fs2data/json/JsonInstances.scala new file mode 100644 index 0000000..915734d --- /dev/null +++ b/json/src/main/scala/org/http4s/fs2data/json/JsonInstances.scala @@ -0,0 +1,66 @@ +/* + * Copyright 2023 http4s.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.http4s +package fs2data.json + +import cats.data.NonEmptyList +import cats.effect.Concurrent +import cats.syntax.applicative._ +import cats.syntax.monadError._ +import fs2.data.json._ +import fs2.Stream +import cats.syntax.show._ +import org.http4s.Charset.`UTF-8` +import org.http4s.headers.{`Content-Type`, `Transfer-Encoding`} + +trait JsonInstances { + + implicit def jsonTokensDecoder[F[_]: Concurrent]: EntityDecoder[F, Stream[F, Token]] = + EntityDecoder.decodeBy(MediaType.application.json) { msg => + DecodeResult.successT( + msg.bodyText + .through(tokens) + .adaptError { case ex: JsonException => + MalformedMessageBodyFailure( + s"Invalid Json (${ex.context.fold("No context")(jc => jc.show)}): ${ex.msg}", + Some(ex), + ) + } + ) + } + + def jsonTokensEncoder[F[_]](prettyPrint: Boolean)(implicit + charset: Charset = `UTF-8` + ): EntityEncoder[F, Stream[F, Token]] = EntityEncoder.encodeBy( + Headers( + `Content-Type`(MediaType.application.json).withCharset(charset), + `Transfer-Encoding`(TransferCoding.chunked.pure[NonEmptyList]), + ) + ) { tokens => + Entity( + tokens + .through( + if (prettyPrint) render.pretty() else render.compact + ) + .through(fs2.text.encode[F](charset.nioCharset)) + ) + } + + implicit def jsonTokensEncoder[F[_]]: EntityEncoder[F, Stream[F, Token]] = + jsonTokensEncoder(prettyPrint = false) + +} diff --git a/json/src/main/scala/org/http4s/fs2data/json/json.scala b/json/src/main/scala/org/http4s/fs2data/json/json.scala new file mode 100644 index 0000000..1ee1797 --- /dev/null +++ b/json/src/main/scala/org/http4s/fs2data/json/json.scala @@ -0,0 +1,19 @@ +/* + * Copyright 2023 http4s.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.http4s.fs2data + +package object json extends JsonInstances diff --git a/json/src/test/scala/org/http4s/fs2data/json/JsonEventSuite.scala b/json/src/test/scala/org/http4s/fs2data/json/JsonEventSuite.scala new file mode 100644 index 0000000..308ee7c --- /dev/null +++ b/json/src/test/scala/org/http4s/fs2data/json/JsonEventSuite.scala @@ -0,0 +1,55 @@ +package org.http4s.fs2data.json + +import cats.effect.IO +import cats.syntax.all._ +import fs2.Stream +import fs2.data.json._ +import fs2.data.json.literals.JsonInterpolator +import munit.CatsEffectSuite +import munit.ScalaCheckEffectSuite +import org.http4s.EntityDecoder +import org.http4s.Request + +class JsonEventSuite extends CatsEffectSuite with ScalaCheckEffectSuite { + test("round-trip Json") { + val in = json"""{"a": 1, "b": [true, false, null], "c": {"d": "e"}, "d": 1.2e3, "b": null}""" + Stream + .force(Request[IO]().withEntity(in.lift[IO]).as[Stream[IO, Token]]) + .compile + .toList + .map(_.asRight[Throwable]) + .assertEquals(in.toList) + } + + test("round-trip Json string") { + val in = """{"a":1,"b":[true,false,null],"c":{"d":"e"},"d":1.2e3,"b":null}""" + Request[IO]() + .withEntity(in) + .as[Stream[IO, Token]] + .map(Request[IO]().withEntity(_)) + .flatMap(EntityDecoder.text[IO].decode(_, false).value) + .assertEquals(Right(in)) + } + + test("round-trip Json pretty printing") { + val in = """{ + | "a": 1, + | "b": [ + | true, + | false, + | null + | ], + | "c": { + | "d": "e" + | }, + | "d": 1.2e3, + | "b": null + |}""".stripMargin + Request[IO]() + .withEntity(in) + .as[Stream[IO, Token]] + .map(Request[IO]().withEntity(_)(jsonTokensEncoder[IO](prettyPrint = true))) + .flatMap(EntityDecoder.text[IO].decode(_, false).value) + .assertEquals(Right(in)) + } +} From ada4325fa57102ff0edc93ac81a07cc3ffa18434 Mon Sep 17 00:00:00 2001 From: ubaldop Date: Fri, 19 Jan 2024 16:29:59 +0100 Subject: [PATCH 09/15] add CI missing data --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85e988e..7640ac0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,11 +152,11 @@ jobs: - name: Make target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: mkdir -p target .js/target cbor/.js/target site/target csv/.jvm/target xml/.jvm/target xml-scala/.js/target xml/.js/target cbor/.native/target xml-scala/.native/target cbor/.jvm/target xml-scala/.jvm/target csv/.native/target .jvm/target csv/.js/target .native/target xml/.native/target project/target + run: mkdir -p json/.native/target target .js/target cbor/.js/target site/target json/.jvm/target csv/.jvm/target xml/.jvm/target xml-scala/.js/target xml/.js/target cbor/.native/target xml-scala/.native/target cbor/.jvm/target xml-scala/.jvm/target csv/.native/target .jvm/target csv/.js/target .native/target xml/.native/target json/.js/target project/target - name: Compress target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: tar cf targets.tar target .js/target cbor/.js/target site/target csv/.jvm/target xml/.jvm/target xml-scala/.js/target xml/.js/target cbor/.native/target xml-scala/.native/target cbor/.jvm/target xml-scala/.jvm/target csv/.native/target .jvm/target csv/.js/target .native/target xml/.native/target project/target + run: tar cf targets.tar json/.native/target target .js/target cbor/.js/target site/target json/.jvm/target csv/.jvm/target xml/.jvm/target xml-scala/.js/target xml/.js/target cbor/.native/target xml-scala/.native/target cbor/.jvm/target xml-scala/.jvm/target csv/.native/target .jvm/target csv/.js/target .native/target xml/.native/target json/.js/target project/target - name: Upload target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') From b930c9ba89538d3ed03f62117931e7d7e1e97091 Mon Sep 17 00:00:00 2001 From: "http4s-steward[bot]" <106843772+http4s-steward[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 20:17:21 +0000 Subject: [PATCH 10/15] Update nscplugin, sbt-scala-native, ... to 0.4.17 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 42521c1..f0c78e6 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,7 +2,7 @@ addSbtPlugin("org.http4s" % "sbt-http4s-org" % "0.14.13") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.13.2") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.14") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.17") addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2") From 875b7ba03b250b618aa0d9b3c9146a80067eecf6 Mon Sep 17 00:00:00 2001 From: "http4s-steward[bot]" <106843772+http4s-steward[bot]@users.noreply.github.com> Date: Sat, 20 Jan 2024 20:16:37 +0000 Subject: [PATCH 11/15] Update fs2-core to 3.9.4 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 8673378..5595425 100644 --- a/build.sbt +++ b/build.sbt @@ -18,7 +18,7 @@ lazy val root = tlCrossRootProject.aggregate(xml, xmlScala, csv, cbor) val http4sVersion = "0.23.23" val scalaXmlVersion = "2.2.0" -val fs2Version = "3.8.0" +val fs2Version = "3.9.4" val fs2DataVersion = "1.8.0" val munitVersion = "1.0.0-M8" val munitCatsEffectVersion = "2.0.0-M3" From 4f4dcbe3335ecc17c0023aa93d5fa810b94d42c1 Mon Sep 17 00:00:00 2001 From: Ubaldo Pescatore <11474157+ubaldop@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:57:19 +0100 Subject: [PATCH 12/15] Update build.sbt Co-authored-by: Yannick Heiber --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 8032497..ac9e7ba 100644 --- a/build.sbt +++ b/build.sbt @@ -102,8 +102,8 @@ lazy val json = crossProject(JVMPlatform, JSPlatform, NativePlatform) .settings( name := "http4s-fs2-data-json", description := "Provides JSON codecs for http4s via fs2-data", - startYear := Some(2023), - tlVersionIntroduced := Map("2.12" -> "0.2", "2.13" -> "0.2", "3" -> "0.2"), + startYear := Some(2024), + tlVersionIntroduced := Map("2.12" -> "0.3", "2.13" -> "0.3", "3" -> "0.3"), libraryDependencies ++= Seq( "co.fs2" %%% "fs2-core" % fs2Version, "org.http4s" %%% "http4s-core" % http4sVersion, From 3e64478b345dde14618f03972d1f60f024a9fb54 Mon Sep 17 00:00:00 2001 From: ubaldop Date: Wed, 24 Jan 2024 17:58:17 +0100 Subject: [PATCH 13/15] Example added --- docs/index.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/index.md b/docs/index.md index 70b7190..e60e5a4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -153,3 +153,58 @@ curl -s -X "POST" "http://localhost:8080/csv/toCbor" \ Then copy the output to [https://cbor.me](https://cbor.me) or a similar CBOR viewer. Make sure to view as `cborseq` otherwise the output will be truncated. + + +## http4s-fs2-data-json + +Provides basic support for parsing and encoding `fs2.data.json.Token` streams that can be handled in a streaming fashion +using the pipes and builders `fs2-data` provides. + +```scala +libraryDependencies += "org.http4s" %% "http4s-fs2-data-json" % "@VERSION@" +``` + +### Example + +This example consumes a JSON input and returns it pretty printed. + +```scala mdoc +import cats.effect.Async +import org.http4s.{EntityDecoder, EntityEncoder, HttpRoutes} +import org.http4s.dsl.Http4sDsl +import fs2.Stream +import fs2.data.json.Token + +class JsonHttpEndpoint[F[_]](implicit F: Async[F]) extends Http4sDsl[F] { + + private implicit val payloadDecoder: EntityDecoder[F, Stream[F, Token]] = + org.http4s.fs2data.json.jsonTokensDecoder + + private implicit val payloadEncoder: EntityEncoder[F, Stream[F, Token]] = + org.http4s.fs2data.json.jsonTokensEncoder(prettyPrint = true) + + val service: HttpRoutes[F] = HttpRoutes.of { + case req @ POST -> Root / "prettyJson" => + Ok(Stream.force(req.as[Stream[F, Token]])) + } +} +``` + +You can try yourself with this snippet: + +```shell +curl -s -X "POST" "http://localhost:8080/prettyJson" \ + -H 'Content-Type: text/json; charset=utf-8' \ + -d '{"a":2024,"b":[true,false],"c":{"d":"e"},"d":1}' +{ + "a": 2024, + "b": [ + true, + false + ], + "c": { + "d": "e" + }, + "d": 1 +} +``` \ No newline at end of file From 7845b5e53ef9f4902287f055b7df3fe5ab0211c9 Mon Sep 17 00:00:00 2001 From: Yannick Heiber Date: Thu, 25 Jan 2024 09:57:19 +0100 Subject: [PATCH 14/15] Add json dependency to docs --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index ac9e7ba..a4102bd 100644 --- a/build.sbt +++ b/build.sbt @@ -116,7 +116,7 @@ lazy val json = crossProject(JVMPlatform, JSPlatform, NativePlatform) lazy val docs = project .in(file("site")) - .dependsOn(xml.jvm, xmlScala.jvm, csv.jvm, cbor.jvm) + .dependsOn(xml.jvm, xmlScala.jvm, csv.jvm, cbor.jvm, json.jvm) .settings( libraryDependencies ++= Seq( "io.circe" %%% "circe-generic" % "0.14.5", From 96bccaa6e7d30b90f91fee360295e694ddfce18d Mon Sep 17 00:00:00 2001 From: Yannick Heiber Date: Thu, 25 Jan 2024 09:58:20 +0100 Subject: [PATCH 15/15] Adjustments to tlBaseVersion & tlVersionIntroduced --- build.sbt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index a4102bd..c1e3853 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / tlBaseVersion := "0.2" +ThisBuild / tlBaseVersion := "0.3" ThisBuild / developers := List( tlGitHubDev("rossabaker", "Ross A. Baker"), tlGitHubDev("ybasket", "Yannick Heiber"), @@ -66,7 +66,6 @@ lazy val csv = crossProject(JVMPlatform, JSPlatform, NativePlatform) name := "http4s-fs2-data-csv", description := "Provides csv codecs for http4s via fs2-data", startYear := Some(2023), - tlVersionIntroduced := Map("2.12" -> "0.2", "2.13" -> "0.2", "3" -> "0.2"), libraryDependencies ++= Seq( "co.fs2" %%% "fs2-core" % fs2Version, "org.http4s" %%% "http4s-core" % http4sVersion, @@ -85,7 +84,6 @@ lazy val cbor = crossProject(JVMPlatform, JSPlatform, NativePlatform) name := "http4s-fs2-data-cbor", description := "Provides CBOR codecs for http4s via fs2-data", startYear := Some(2023), - tlVersionIntroduced := Map("2.12" -> "0.2", "2.13" -> "0.2", "3" -> "0.2"), libraryDependencies ++= Seq( "co.fs2" %%% "fs2-core" % fs2Version, "org.http4s" %%% "http4s-core" % http4sVersion, @@ -103,7 +101,6 @@ lazy val json = crossProject(JVMPlatform, JSPlatform, NativePlatform) name := "http4s-fs2-data-json", description := "Provides JSON codecs for http4s via fs2-data", startYear := Some(2024), - tlVersionIntroduced := Map("2.12" -> "0.3", "2.13" -> "0.3", "3" -> "0.3"), libraryDependencies ++= Seq( "co.fs2" %%% "fs2-core" % fs2Version, "org.http4s" %%% "http4s-core" % http4sVersion,