diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala deleted file mode 100644 index 55e4ca1..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala +++ /dev/null @@ -1,7 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter - -trait Http4sCustomTapir[Env] - extends CustomTapir - with ZHttp4sServerInterpreter[Env] diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala deleted file mode 100644 index 55e4ca1..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala +++ /dev/null @@ -1,7 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter - -trait Http4sCustomTapir[Env] - extends CustomTapir - with ZHttp4sServerInterpreter[Env] diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..c1e3054 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,32 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.ztapir.ZTapir + +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.capabilities.WebSockets +import sttp.client3.SttpBackend +import sttp.client3.httpclient.zio.HttpClientZioBackend +import sttp.capabilities.zio.ZioStreams + +trait CustomTapirPlatformSpecific extends ZTapir with SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Task, ZioStreams & WebSockets] + + val clientLayer: TaskLayer[Backend] = ZLayer.fromZIO( + HttpClientZioBackend() + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + toRequestThrowErrors(endpoint, baseUri.toUri)(wsToPipe)(_) + .send(backend) + .map(_.body) diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala deleted file mode 100644 index 55e4ca1..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala +++ /dev/null @@ -1,7 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter - -trait Http4sCustomTapir[Env] - extends CustomTapir - with ZHttp4sServerInterpreter[Env] diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..c1e3054 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,32 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.ztapir.ZTapir + +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.capabilities.WebSockets +import sttp.client3.SttpBackend +import sttp.client3.httpclient.zio.HttpClientZioBackend +import sttp.capabilities.zio.ZioStreams + +trait CustomTapirPlatformSpecific extends ZTapir with SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Task, ZioStreams & WebSockets] + + val clientLayer: TaskLayer[Backend] = ZLayer.fromZIO( + HttpClientZioBackend() + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + toRequestThrowErrors(endpoint, baseUri.toUri)(wsToPipe)(_) + .send(backend) + .map(_.body) diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala new file mode 100644 index 0000000..55e4ca1 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala @@ -0,0 +1,7 @@ +package works.iterative.tapir + +import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter + +trait Http4sCustomTapir[Env] + extends CustomTapir + with ZHttp4sServerInterpreter[Env] diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala deleted file mode 100644 index 55e4ca1..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala +++ /dev/null @@ -1,7 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter - -trait Http4sCustomTapir[Env] - extends CustomTapir - with ZHttp4sServerInterpreter[Env] diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..c1e3054 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,32 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.ztapir.ZTapir + +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.capabilities.WebSockets +import sttp.client3.SttpBackend +import sttp.client3.httpclient.zio.HttpClientZioBackend +import sttp.capabilities.zio.ZioStreams + +trait CustomTapirPlatformSpecific extends ZTapir with SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Task, ZioStreams & WebSockets] + + val clientLayer: TaskLayer[Backend] = ZLayer.fromZIO( + HttpClientZioBackend() + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + toRequestThrowErrors(endpoint, baseUri.toUri)(wsToPipe)(_) + .send(backend) + .map(_.body) diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala new file mode 100644 index 0000000..55e4ca1 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala @@ -0,0 +1,7 @@ +package works.iterative.tapir + +import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter + +trait Http4sCustomTapir[Env] + extends CustomTapir + with ZHttp4sServerInterpreter[Env] diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala deleted file mode 100644 index dd52e9b..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala +++ /dev/null @@ -1,14 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.Tapir -import sttp.tapir.json.zio.TapirJsonZio -import sttp.tapir.TapirAliases - -trait CustomTapir - extends Tapir - with TapirJsonZio - with TapirAliases - with CustomTapirPlatformSpecific: - given Schema[ServerError] = Schema.derived - -object CustomTapir extends CustomTapir diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala deleted file mode 100644 index 55e4ca1..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala +++ /dev/null @@ -1,7 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter - -trait Http4sCustomTapir[Env] - extends CustomTapir - with ZHttp4sServerInterpreter[Env] diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..c1e3054 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,32 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.ztapir.ZTapir + +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.capabilities.WebSockets +import sttp.client3.SttpBackend +import sttp.client3.httpclient.zio.HttpClientZioBackend +import sttp.capabilities.zio.ZioStreams + +trait CustomTapirPlatformSpecific extends ZTapir with SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Task, ZioStreams & WebSockets] + + val clientLayer: TaskLayer[Backend] = ZLayer.fromZIO( + HttpClientZioBackend() + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + toRequestThrowErrors(endpoint, baseUri.toUri)(wsToPipe)(_) + .send(backend) + .map(_.body) diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala new file mode 100644 index 0000000..55e4ca1 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala @@ -0,0 +1,7 @@ +package works.iterative.tapir + +import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter + +trait Http4sCustomTapir[Env] + extends CustomTapir + with ZHttp4sServerInterpreter[Env] diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala deleted file mode 100644 index dd52e9b..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala +++ /dev/null @@ -1,14 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.Tapir -import sttp.tapir.json.zio.TapirJsonZio -import sttp.tapir.TapirAliases - -trait CustomTapir - extends Tapir - with TapirJsonZio - with TapirAliases - with CustomTapirPlatformSpecific: - given Schema[ServerError] = Schema.derived - -object CustomTapir extends CustomTapir diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala deleted file mode 100644 index 715591d..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala +++ /dev/null @@ -1,13 +0,0 @@ -package works.iterative.tapir - -import zio.json.* - -sealed trait ServerError -case class InternalServerError(msg: String) extends ServerError -object InternalServerError: - def fromThrowable(t: Throwable): ServerError = InternalServerError( - t.getMessage - ) - -object ServerError: - given JsonCodec[ServerError] = DeriveJsonCodec.gen diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala deleted file mode 100644 index 55e4ca1..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala +++ /dev/null @@ -1,7 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter - -trait Http4sCustomTapir[Env] - extends CustomTapir - with ZHttp4sServerInterpreter[Env] diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..c1e3054 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,32 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.ztapir.ZTapir + +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.capabilities.WebSockets +import sttp.client3.SttpBackend +import sttp.client3.httpclient.zio.HttpClientZioBackend +import sttp.capabilities.zio.ZioStreams + +trait CustomTapirPlatformSpecific extends ZTapir with SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Task, ZioStreams & WebSockets] + + val clientLayer: TaskLayer[Backend] = ZLayer.fromZIO( + HttpClientZioBackend() + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + toRequestThrowErrors(endpoint, baseUri.toUri)(wsToPipe)(_) + .send(backend) + .map(_.body) diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala new file mode 100644 index 0000000..55e4ca1 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala @@ -0,0 +1,7 @@ +package works.iterative.tapir + +import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter + +trait Http4sCustomTapir[Env] + extends CustomTapir + with ZHttp4sServerInterpreter[Env] diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala deleted file mode 100644 index dd52e9b..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala +++ /dev/null @@ -1,14 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.Tapir -import sttp.tapir.json.zio.TapirJsonZio -import sttp.tapir.TapirAliases - -trait CustomTapir - extends Tapir - with TapirJsonZio - with TapirAliases - with CustomTapirPlatformSpecific: - given Schema[ServerError] = Schema.derived - -object CustomTapir extends CustomTapir diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala deleted file mode 100644 index 715591d..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala +++ /dev/null @@ -1,13 +0,0 @@ -package works.iterative.tapir - -import zio.json.* - -sealed trait ServerError -case class InternalServerError(msg: String) extends ServerError -object InternalServerError: - def fromThrowable(t: Throwable): ServerError = InternalServerError( - t.getMessage - ) - -object ServerError: - given JsonCodec[ServerError] = DeriveJsonCodec.gen diff --git a/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala b/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala new file mode 100644 index 0000000..68d7196 --- /dev/null +++ b/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala @@ -0,0 +1,12 @@ +package works.iterative.tapir + +import sttp.model.Uri + +opaque type BaseUri = Option[Uri] + +object BaseUri: + + def apply(optU: Option[Uri]): BaseUri = optU + def apply(u: Uri): BaseUri = Some(u) + + extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala deleted file mode 100644 index 55e4ca1..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala +++ /dev/null @@ -1,7 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter - -trait Http4sCustomTapir[Env] - extends CustomTapir - with ZHttp4sServerInterpreter[Env] diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..c1e3054 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,32 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.ztapir.ZTapir + +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.capabilities.WebSockets +import sttp.client3.SttpBackend +import sttp.client3.httpclient.zio.HttpClientZioBackend +import sttp.capabilities.zio.ZioStreams + +trait CustomTapirPlatformSpecific extends ZTapir with SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Task, ZioStreams & WebSockets] + + val clientLayer: TaskLayer[Backend] = ZLayer.fromZIO( + HttpClientZioBackend() + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + toRequestThrowErrors(endpoint, baseUri.toUri)(wsToPipe)(_) + .send(backend) + .map(_.body) diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala new file mode 100644 index 0000000..55e4ca1 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala @@ -0,0 +1,7 @@ +package works.iterative.tapir + +import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter + +trait Http4sCustomTapir[Env] + extends CustomTapir + with ZHttp4sServerInterpreter[Env] diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala deleted file mode 100644 index dd52e9b..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala +++ /dev/null @@ -1,14 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.Tapir -import sttp.tapir.json.zio.TapirJsonZio -import sttp.tapir.TapirAliases - -trait CustomTapir - extends Tapir - with TapirJsonZio - with TapirAliases - with CustomTapirPlatformSpecific: - given Schema[ServerError] = Schema.derived - -object CustomTapir extends CustomTapir diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala deleted file mode 100644 index 715591d..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala +++ /dev/null @@ -1,13 +0,0 @@ -package works.iterative.tapir - -import zio.json.* - -sealed trait ServerError -case class InternalServerError(msg: String) extends ServerError -object InternalServerError: - def fromThrowable(t: Throwable): ServerError = InternalServerError( - t.getMessage - ) - -object ServerError: - given JsonCodec[ServerError] = DeriveJsonCodec.gen diff --git a/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala b/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala new file mode 100644 index 0000000..68d7196 --- /dev/null +++ b/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala @@ -0,0 +1,12 @@ +package works.iterative.tapir + +import sttp.model.Uri + +opaque type BaseUri = Option[Uri] + +object BaseUri: + + def apply(optU: Option[Uri]): BaseUri = optU + def apply(u: Uri): BaseUri = Some(u) + + extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/shared/src/main/scala/works/iterative/tapir/CustomTapir.scala b/tapir/shared/src/main/scala/works/iterative/tapir/CustomTapir.scala new file mode 100644 index 0000000..dd52e9b --- /dev/null +++ b/tapir/shared/src/main/scala/works/iterative/tapir/CustomTapir.scala @@ -0,0 +1,14 @@ +package works.iterative.tapir + +import sttp.tapir.Tapir +import sttp.tapir.json.zio.TapirJsonZio +import sttp.tapir.TapirAliases + +trait CustomTapir + extends Tapir + with TapirJsonZio + with TapirAliases + with CustomTapirPlatformSpecific: + given Schema[ServerError] = Schema.derived + +object CustomTapir extends CustomTapir diff --git a/bom.sc b/bom.sc index 930a6d3..636a511 100644 --- a/bom.sc +++ b/bom.sc @@ -104,6 +104,7 @@ ivy"${sttpClientOrg}::${name}:${V.sttpClient}" lazy val sttpClientCore: Dep = sttpClientLib("core") + lazy val sttpClientZIO: Dep = sttpClientLib("httpclient-backend-zio") lazy val http4sBlazeServer: Dep = ivy"org.http4s::http4s-blaze-server:${V.http4s}" diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala b/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala deleted file mode 100644 index 68d7196..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/BaseUri.scala +++ /dev/null @@ -1,12 +0,0 @@ -package works.iterative.tapir - -import sttp.model.Uri - -opaque type BaseUri = Option[Uri] - -object BaseUri: - - def apply(optU: Option[Uri]): BaseUri = optU - def apply(u: Uri): BaseUri = Some(u) - - extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 1315e92..0000000 --- a/tapir/js/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,49 +0,0 @@ -package works.iterative.tapir - -import zio.* -import sttp.tapir.client.sttp.SttpClientInterpreter -import sttp.tapir.PublicEndpoint -import sttp.tapir.client.sttp.WebSocketToPipe -import scala.concurrent.Future -import sttp.client3.SttpBackend -import sttp.capabilities.WebSockets -import scala.concurrent.ExecutionContext -import sttp.client3.FetchBackend -import sttp.client3.FetchOptions -import org.scalajs.dom - -trait CustomTapirPlatformSpecific extends SttpClientInterpreter: - self: CustomTapir => - - type Backend = SttpBackend[Future, WebSockets] - - val clientLayer: ULayer[Backend] = ZLayer.succeed( - FetchBackend( - FetchOptions( - Some(dom.RequestCredentials.`same-origin`), - Some(dom.RequestMode.`same-origin`) - ) - ) - ) - - def makeClient[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any] - )(using - baseUri: BaseUri, - backend: Backend, - wsToPipe: WebSocketToPipe[Any] - ): I => Future[O] = - val req = toRequestThrowErrors(endpoint, baseUri.toUri) - (i: I) => { - val resp = backend.responseMonad.map( - backend.send(req(i).followRedirects(false)) - )(_.body) - resp.onComplete { - case scala.util.Failure(e: RuntimeException) - if e.getMessage == "Unexpected redirect" => - // Reload window on redirect, as it means that we need to log in again - org.scalajs.dom.window.location.reload(true) - case _ => () - }(using ExecutionContext.global) - resp - } diff --git a/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..61e0586 --- /dev/null +++ b/tapir/js/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,50 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import scala.concurrent.Future +import sttp.client3.SttpBackend +import sttp.capabilities.WebSockets +import scala.concurrent.ExecutionContext +import sttp.client3.FetchBackend +import sttp.client3.FetchOptions +import org.scalajs.dom + +trait CustomTapirPlatformSpecific extends SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Future, WebSockets] + + val clientLayer: ULayer[Backend] = ZLayer.succeed( + FetchBackend( + FetchOptions( + Some(dom.RequestCredentials.`same-origin`), + Some(dom.RequestMode.`same-origin`) + ) + ) + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + val req = toRequestThrowErrors(endpoint, baseUri.toUri) + (i: I) => + ZIO.fromFuture { implicit ec => + val resp = backend.responseMonad.map( + backend.send(req(i).followRedirects(false)) + )(_.body) + resp.onComplete { + case scala.util.Failure(e: RuntimeException) + if e.getMessage == "Unexpected redirect" => + // Reload window on redirect, as it means that we need to log in again + org.scalajs.dom.window.location.reload(true) + case _ => () + } + resp + } diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala deleted file mode 100644 index 2545fbd..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/CustomTapirPlatformSpecific.scala +++ /dev/null @@ -1,5 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.ztapir.ZTapir - -trait CustomTapirPlatformSpecific extends ZTapir diff --git a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala deleted file mode 100644 index 55e4ca1..0000000 --- a/tapir/jvm/src/main/scala/fiftyforms/tapir/Http4sCustomTapir.scala +++ /dev/null @@ -1,7 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter - -trait Http4sCustomTapir[Env] - extends CustomTapir - with ZHttp4sServerInterpreter[Env] diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala new file mode 100644 index 0000000..c1e3054 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/CustomTapirPlatformSpecific.scala @@ -0,0 +1,32 @@ +package works.iterative.tapir + +import zio.* +import sttp.tapir.ztapir.ZTapir + +import sttp.tapir.PublicEndpoint +import sttp.tapir.client.sttp.WebSocketToPipe +import sttp.tapir.client.sttp.SttpClientInterpreter +import sttp.capabilities.WebSockets +import sttp.client3.SttpBackend +import sttp.client3.httpclient.zio.HttpClientZioBackend +import sttp.capabilities.zio.ZioStreams + +trait CustomTapirPlatformSpecific extends ZTapir with SttpClientInterpreter: + self: CustomTapir => + + type Backend = SttpBackend[Task, ZioStreams & WebSockets] + + val clientLayer: TaskLayer[Backend] = ZLayer.fromZIO( + HttpClientZioBackend() + ) + + def makeClient[I, E, O]( + endpoint: PublicEndpoint[I, E, O, Any] + )(using + baseUri: BaseUri, + backend: Backend, + wsToPipe: WebSocketToPipe[Any] + ): I => Task[O] = + toRequestThrowErrors(endpoint, baseUri.toUri)(wsToPipe)(_) + .send(backend) + .map(_.body) diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala new file mode 100644 index 0000000..55e4ca1 --- /dev/null +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/Http4sCustomTapir.scala @@ -0,0 +1,7 @@ +package works.iterative.tapir + +import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter + +trait Http4sCustomTapir[Env] + extends CustomTapir + with ZHttp4sServerInterpreter[Env] diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala deleted file mode 100644 index dd52e9b..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/CustomTapir.scala +++ /dev/null @@ -1,14 +0,0 @@ -package works.iterative.tapir - -import sttp.tapir.Tapir -import sttp.tapir.json.zio.TapirJsonZio -import sttp.tapir.TapirAliases - -trait CustomTapir - extends Tapir - with TapirJsonZio - with TapirAliases - with CustomTapirPlatformSpecific: - given Schema[ServerError] = Schema.derived - -object CustomTapir extends CustomTapir diff --git a/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala b/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala deleted file mode 100644 index 715591d..0000000 --- a/tapir/shared/src/main/scala/fiftyforms/tapir/ServerError.scala +++ /dev/null @@ -1,13 +0,0 @@ -package works.iterative.tapir - -import zio.json.* - -sealed trait ServerError -case class InternalServerError(msg: String) extends ServerError -object InternalServerError: - def fromThrowable(t: Throwable): ServerError = InternalServerError( - t.getMessage - ) - -object ServerError: - given JsonCodec[ServerError] = DeriveJsonCodec.gen diff --git a/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala b/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala new file mode 100644 index 0000000..68d7196 --- /dev/null +++ b/tapir/shared/src/main/scala/works/iterative/tapir/BaseUri.scala @@ -0,0 +1,12 @@ +package works.iterative.tapir + +import sttp.model.Uri + +opaque type BaseUri = Option[Uri] + +object BaseUri: + + def apply(optU: Option[Uri]): BaseUri = optU + def apply(u: Uri): BaseUri = Some(u) + + extension (v: BaseUri) def toUri: Option[Uri] = v diff --git a/tapir/shared/src/main/scala/works/iterative/tapir/CustomTapir.scala b/tapir/shared/src/main/scala/works/iterative/tapir/CustomTapir.scala new file mode 100644 index 0000000..dd52e9b --- /dev/null +++ b/tapir/shared/src/main/scala/works/iterative/tapir/CustomTapir.scala @@ -0,0 +1,14 @@ +package works.iterative.tapir + +import sttp.tapir.Tapir +import sttp.tapir.json.zio.TapirJsonZio +import sttp.tapir.TapirAliases + +trait CustomTapir + extends Tapir + with TapirJsonZio + with TapirAliases + with CustomTapirPlatformSpecific: + given Schema[ServerError] = Schema.derived + +object CustomTapir extends CustomTapir diff --git a/tapir/shared/src/main/scala/works/iterative/tapir/ServerError.scala b/tapir/shared/src/main/scala/works/iterative/tapir/ServerError.scala new file mode 100644 index 0000000..715591d --- /dev/null +++ b/tapir/shared/src/main/scala/works/iterative/tapir/ServerError.scala @@ -0,0 +1,13 @@ +package works.iterative.tapir + +import zio.json.* + +sealed trait ServerError +case class InternalServerError(msg: String) extends ServerError +object InternalServerError: + def fromThrowable(t: Throwable): ServerError = InternalServerError( + t.getMessage + ) + +object ServerError: + given JsonCodec[ServerError] = DeriveJsonCodec.gen