diff --git a/build.sbt b/build.sbt index e7d6e9d..0aff685 100644 --- a/build.sbt +++ b/build.sbt @@ -35,8 +35,10 @@ IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer, IWDeps.useZIOJson, + IWDeps.zioConfig, IWDeps.zioInteropReactiveStreams, IWDeps.zioNIO, + fixSilencerDoc, excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") ) diff --git a/build.sbt b/build.sbt index e7d6e9d..0aff685 100644 --- a/build.sbt +++ b/build.sbt @@ -35,8 +35,10 @@ IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer, IWDeps.useZIOJson, + IWDeps.zioConfig, IWDeps.zioInteropReactiveStreams, IWDeps.zioNIO, + fixSilencerDoc, excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") ) diff --git a/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala b/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala index af25609..31fd775 100644 --- a/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala +++ b/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala @@ -17,11 +17,6 @@ appPath: String = "app", /** The filename for the app */ appIndex: String = "app.html", - /** Optional prefix for the SPA application. - * - * If not set, the application will be served from the root. - */ - prefix: Option[String] = None, /** Path to the files of the SPA application. * * If not set, the application will be served from the classpath under @@ -41,7 +36,6 @@ nested("SPA")( string("APPPATH").default("app") zip string("APPINDEX").default("index.html") zip - string("PREFIX").optional zip string("FILEPATH").optional zip string("RESOURCEPATH").default("app") ).to[SPAConfig] diff --git a/build.sbt b/build.sbt index e7d6e9d..0aff685 100644 --- a/build.sbt +++ b/build.sbt @@ -35,8 +35,10 @@ IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer, IWDeps.useZIOJson, + IWDeps.zioConfig, IWDeps.zioInteropReactiveStreams, IWDeps.zioNIO, + fixSilencerDoc, excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") ) diff --git a/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala b/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala index af25609..31fd775 100644 --- a/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala +++ b/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala @@ -17,11 +17,6 @@ appPath: String = "app", /** The filename for the app */ appIndex: String = "app.html", - /** Optional prefix for the SPA application. - * - * If not set, the application will be served from the root. - */ - prefix: Option[String] = None, /** Path to the files of the SPA application. * * If not set, the application will be served from the classpath under @@ -41,7 +36,6 @@ nested("SPA")( string("APPPATH").default("app") zip string("APPINDEX").default("index.html") zip - string("PREFIX").optional zip string("FILEPATH").optional zip string("RESOURCEPATH").default("app") ).to[SPAConfig] diff --git a/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala b/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala index e501ed8..5a9a631 100644 --- a/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala +++ b/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala @@ -7,10 +7,12 @@ import works.iterative.core.auth.CurrentUser class SPAEndpoints[Env](config: SPAConfig): - private val prefix: EndpointInput[Unit] = + private val prefix: EndpointInput[Unit] = emptyInput + /* config.prefix.toSeq .flatMap(_.split("/").toSeq) .foldLeft(emptyInput)((i, p) => i / p) + */ val serverEndpoints: List[ZServerEndpoint[Env & CurrentUser, Any]] = config.filePath match diff --git a/build.sbt b/build.sbt index e7d6e9d..0aff685 100644 --- a/build.sbt +++ b/build.sbt @@ -35,8 +35,10 @@ IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer, IWDeps.useZIOJson, + IWDeps.zioConfig, IWDeps.zioInteropReactiveStreams, IWDeps.zioNIO, + fixSilencerDoc, excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") ) diff --git a/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala b/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala index af25609..31fd775 100644 --- a/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala +++ b/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala @@ -17,11 +17,6 @@ appPath: String = "app", /** The filename for the app */ appIndex: String = "app.html", - /** Optional prefix for the SPA application. - * - * If not set, the application will be served from the root. - */ - prefix: Option[String] = None, /** Path to the files of the SPA application. * * If not set, the application will be served from the classpath under @@ -41,7 +36,6 @@ nested("SPA")( string("APPPATH").default("app") zip string("APPINDEX").default("index.html") zip - string("PREFIX").optional zip string("FILEPATH").optional zip string("RESOURCEPATH").default("app") ).to[SPAConfig] diff --git a/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala b/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala index e501ed8..5a9a631 100644 --- a/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala +++ b/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala @@ -7,10 +7,12 @@ import works.iterative.core.auth.CurrentUser class SPAEndpoints[Env](config: SPAConfig): - private val prefix: EndpointInput[Unit] = + private val prefix: EndpointInput[Unit] = emptyInput + /* config.prefix.toSeq .flatMap(_.split("/").toSeq) .foldLeft(emptyInput)((i, p) => i / p) + */ val serverEndpoints: List[ZServerEndpoint[Env & CurrentUser, Any]] = config.filePath match diff --git a/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala b/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala index 25dbae0..7d38587 100644 --- a/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala +++ b/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala @@ -14,10 +14,13 @@ import cats.* import cats.data.* import cats.arrow.FunctionK +import works.iterative.tapir.BaseUri +import org.http4s.server.Router class BlazeHttpServer( config: BlazeServerConfig, - pac4jConfig: Pac4jSecurityConfig + pac4jConfig: Pac4jSecurityConfig, + baseUri: BaseUri ) extends HttpServer: override def serve[Env](app: HttpApplication[Env]): URIO[Env, Nothing] = type AppTask[A] = RIO[Env, A] @@ -74,10 +77,17 @@ val eliminated: HttpRoutes[AppTask] = provideCurrentUser(securedRoutes) + def withBaseUri(routes: HttpRoutes[AppTask]): HttpRoutes[AppTask] = + baseUri.value match + case Some(u) => Router(u.toString -> routes) + case _ => routes + BlazeServerBuilder[AppTask] .bindHttp(config.port, config.host) .withHttpApp( - (publicRoutes <+> pac4jSecurity.route <+> eliminated).orNotFound + (pac4jSecurity.route <+> withBaseUri( + publicRoutes <+> eliminated + )).orNotFound ) .serve .compile @@ -86,10 +96,12 @@ } object BlazeHttpServer: - val layer: RLayer[BlazeServerConfig & Pac4jSecurityConfig, HttpServer] = + val layer + : RLayer[BlazeServerConfig & Pac4jSecurityConfig & BaseUri, HttpServer] = ZLayer { for config <- ZIO.service[BlazeServerConfig] pac4jConfig <- ZIO.service[Pac4jSecurityConfig] - yield BlazeHttpServer(config, pac4jConfig) + baseUri <- ZIO.service[BaseUri] + yield BlazeHttpServer(config, pac4jConfig, baseUri) } diff --git a/build.sbt b/build.sbt index e7d6e9d..0aff685 100644 --- a/build.sbt +++ b/build.sbt @@ -35,8 +35,10 @@ IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer, IWDeps.useZIOJson, + IWDeps.zioConfig, IWDeps.zioInteropReactiveStreams, IWDeps.zioNIO, + fixSilencerDoc, excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") ) diff --git a/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala b/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala index af25609..31fd775 100644 --- a/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala +++ b/server/http/src/main/scala/works/iterative/server/http/SPAConfig.scala @@ -17,11 +17,6 @@ appPath: String = "app", /** The filename for the app */ appIndex: String = "app.html", - /** Optional prefix for the SPA application. - * - * If not set, the application will be served from the root. - */ - prefix: Option[String] = None, /** Path to the files of the SPA application. * * If not set, the application will be served from the classpath under @@ -41,7 +36,6 @@ nested("SPA")( string("APPPATH").default("app") zip string("APPINDEX").default("index.html") zip - string("PREFIX").optional zip string("FILEPATH").optional zip string("RESOURCEPATH").default("app") ).to[SPAConfig] diff --git a/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala b/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala index e501ed8..5a9a631 100644 --- a/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala +++ b/server/http/src/main/scala/works/iterative/server/http/SPAEndpoints.scala @@ -7,10 +7,12 @@ import works.iterative.core.auth.CurrentUser class SPAEndpoints[Env](config: SPAConfig): - private val prefix: EndpointInput[Unit] = + private val prefix: EndpointInput[Unit] = emptyInput + /* config.prefix.toSeq .flatMap(_.split("/").toSeq) .foldLeft(emptyInput)((i, p) => i / p) + */ val serverEndpoints: List[ZServerEndpoint[Env & CurrentUser, Any]] = config.filePath match diff --git a/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala b/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala index 25dbae0..7d38587 100644 --- a/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala +++ b/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala @@ -14,10 +14,13 @@ import cats.* import cats.data.* import cats.arrow.FunctionK +import works.iterative.tapir.BaseUri +import org.http4s.server.Router class BlazeHttpServer( config: BlazeServerConfig, - pac4jConfig: Pac4jSecurityConfig + pac4jConfig: Pac4jSecurityConfig, + baseUri: BaseUri ) extends HttpServer: override def serve[Env](app: HttpApplication[Env]): URIO[Env, Nothing] = type AppTask[A] = RIO[Env, A] @@ -74,10 +77,17 @@ val eliminated: HttpRoutes[AppTask] = provideCurrentUser(securedRoutes) + def withBaseUri(routes: HttpRoutes[AppTask]): HttpRoutes[AppTask] = + baseUri.value match + case Some(u) => Router(u.toString -> routes) + case _ => routes + BlazeServerBuilder[AppTask] .bindHttp(config.port, config.host) .withHttpApp( - (publicRoutes <+> pac4jSecurity.route <+> eliminated).orNotFound + (pac4jSecurity.route <+> withBaseUri( + publicRoutes <+> eliminated + )).orNotFound ) .serve .compile @@ -86,10 +96,12 @@ } object BlazeHttpServer: - val layer: RLayer[BlazeServerConfig & Pac4jSecurityConfig, HttpServer] = + val layer + : RLayer[BlazeServerConfig & Pac4jSecurityConfig & BaseUri, HttpServer] = ZLayer { for config <- ZIO.service[BlazeServerConfig] pac4jConfig <- ZIO.service[Pac4jSecurityConfig] - yield BlazeHttpServer(config, pac4jConfig) + baseUri <- ZIO.service[BaseUri] + yield BlazeHttpServer(config, pac4jConfig, baseUri) } diff --git a/tapir/jvm/src/main/scala/works/iterative/tapir/BaseUriPlatformSpecific.scala b/tapir/jvm/src/main/scala/works/iterative/tapir/BaseUriPlatformSpecific.scala index 4834683..6995d1d 100644 --- a/tapir/jvm/src/main/scala/works/iterative/tapir/BaseUriPlatformSpecific.scala +++ b/tapir/jvm/src/main/scala/works/iterative/tapir/BaseUriPlatformSpecific.scala @@ -1,3 +1,17 @@ package works.iterative.tapir -trait BaseUriPlatformSpecific +import zio.* +import zio.config.* +import sttp.model.Uri.* + +trait BaseUriPlatformSpecific: + val configDesc: ConfigDescriptor[BaseUri] = + import ConfigDescriptor.* + string("BASEURI").optional.map(_.map(s => uri"$s")).to[BaseUri] + + val fromEnv: ZLayer[Any, ReadError[String], BaseUri] = + ZConfig.fromSystemEnv( + configDesc, + keyDelimiter = Some('_'), + valueDelimiter = Some(',') + )